| 1 | package org.openstreetmap.josm.data.validation.tests; |
| 2 | |
| 3 | import java.util.Arrays; |
| 4 | import java.util.Collection; |
| 5 | import java.util.HashSet; |
| 6 | import org.openstreetmap.josm.data.osm.Node; |
| 7 | import org.openstreetmap.josm.data.osm.OsmPrimitive; |
| 8 | import org.openstreetmap.josm.data.osm.Relation; |
| 9 | import org.openstreetmap.josm.data.osm.Way; |
| 10 | import org.openstreetmap.josm.data.validation.Severity; |
| 11 | import static org.openstreetmap.josm.tools.I18n.tr; |
| 12 | |
| 13 | import org.openstreetmap.josm.data.validation.Test; |
| 14 | import org.openstreetmap.josm.data.validation.TestError; |
| 15 | |
| 16 | public class TagCombinations extends Test { |
| 17 | |
| 18 | private static final Collection<String> IMPLIES_HIGHWAY = new HashSet<String>(Arrays.asList( |
| 19 | "surface,oneway,lanes,maxspeed,tracktype,name_1,lit,junction,sac_scale,int_ref,motor_vehicle,segregated,route_ref,smoothness,living_street,trail_visibility,sidewalk,name_2,nat_ref,toll,old_ref, motorroad,lcn,incline,review,zip_left,zip_right,unsigned_ref,snowplowing,old_ref_legislative,ntd_id,maintenance,trolley_wire,ncn_ref,sorting_name,median,ref_name,moped,step_count". |
| 20 | split(","))); |
| 21 | private static final Collection<String> IMPLIES_RAILWAY = new HashSet<String>(Arrays.asList( |
| 22 | "electrified,gauge,tracks,usage,old_railway_operator,detail,traffic_mode,etcs,eddy_current_brake,tilting_technology,pzb,lzb,grade_of_track,radio,structure_gauge,track_class,operating_procedure, combined_transport_c,kursbuchstrecke,workrules". |
| 23 | split(","))); |
| 24 | private static final Collection<String> IMPLIES_WATERWAY = new HashSet<String>(Arrays.asList( |
| 25 | "stream,intermittent,boat,length_unit,llid,canal,have_riverbank".split(","))); |
| 26 | private static final Collection<String> IMPLIES_ANY_WAY = new HashSet<String>(Arrays.asList( |
| 27 | "tunnel,bridge,width,psv".split(","))); |
| 28 | |
| 29 | /* QUERY for taginfo database to get keys for IMPLIES_HIGHWAY, IMPLIES_RAILWAY, IMPLIES_WATERWAY |
| 30 | select |
| 31 | keypairs.key1, |
| 32 | keypairs.key2, |
| 33 | keypairs.count_all, |
| 34 | keys.count_all, |
| 35 | cast(keypairs.count_all as real)/keys.count_all as from_fraction_all |
| 36 | from keys, keypairs |
| 37 | where |
| 38 | key1='waterway' and |
| 39 | keys.key=keypairs.key2 and |
| 40 | (key1<>'highway' or keypairs.count_all>12000) and |
| 41 | (key1<>'railway' or keypairs.count_all>3000) and |
| 42 | (key1<>'waterway' or keypairs.count_all>800) and |
| 43 | key2 not like '%:%' and |
| 44 | from_fraction_all>0.97 and |
| 45 | 1 |
| 46 | union select |
| 47 | keypairs.key2, |
| 48 | keypairs.key1, |
| 49 | keypairs.count_all, |
| 50 | keys.count_all, |
| 51 | cast(keypairs.count_all as real)/keys.count_all as from_fraction_all |
| 52 | from keys, keypairs |
| 53 | where |
| 54 | key2='waterway' and |
| 55 | keys.key=keypairs.key1 and |
| 56 | (key2<>'highway' or keypairs.count_all>12000) and |
| 57 | (key2<>'railway' or keypairs.count_all>3000) and |
| 58 | (key2<>'waterway' or keypairs.count_all>800) and |
| 59 | key1 not like '%:%' and |
| 60 | from_fraction_all>0.97 and |
| 61 | 1 |
| 62 | order by keypairs.count_all |
| 63 | desc limit 1000; |
| 64 | */ |
| 65 | |
| 66 | public TagCombinations() { |
| 67 | super(tr("Common tag combinations")); |
| 68 | } |
| 69 | |
| 70 | public void visit(OsmPrimitive p) { |
| 71 | for (String key : p.keySet()) { |
| 72 | if (IMPLIES_HIGHWAY.contains(key) && !p.hasKey("highway")) { |
| 73 | addError(p, key, "highway"); |
| 74 | } |
| 75 | if (IMPLIES_RAILWAY.contains(key) && !p.hasKey("railway")) { |
| 76 | addError(p, key, "railway"); |
| 77 | } |
| 78 | if (IMPLIES_WATERWAY.contains(key) && !p.hasKey("waterway")) { |
| 79 | addError(p, key, "waterway"); |
| 80 | } |
| 81 | if (IMPLIES_ANY_WAY.contains(key) && !p.hasKey("highway") && !p.hasKey("railway") && !p.hasKey("waterway")) { |
| 82 | addError(p, key, "highway/railway/waterway"); |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | private void addError(OsmPrimitive p, String key1, String key2) { |
| 88 | errors.add(new TestError(this, Severity.WARNING, |
| 89 | tr("{0} is usually used with {1}", key1, key2), |
| 90 | 2401, p)); |
| 91 | } |
| 92 | |
| 93 | @Override |
| 94 | public void visit(Node n) { |
| 95 | visit((OsmPrimitive) n); |
| 96 | } |
| 97 | |
| 98 | @Override |
| 99 | public void visit(Way w) { |
| 100 | visit((OsmPrimitive) w); |
| 101 | } |
| 102 | |
| 103 | @Override |
| 104 | public void visit(Relation r) { |
| 105 | visit((OsmPrimitive) r); |
| 106 | } |
| 107 | } |