| | 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 | } |