source: josm/trunk/resources/data/validator/combinations.mapcss@ 18132

Last change on this file since 18132 was 18112, checked in by Don-vip, 4 years ago

fix #21115 - Update highway validator rules to include highway=busway (patch by Famlam)

  • Property svn:eol-style set to native
File size: 49.1 KB
Line 
1/* Rules partially derived from Taginfo statistics - see ticket #5017
2 * Taginfo query: select keypairs.key1, keypairs.key2, keypairs.count_all, keys.count_all, cast(keypairs.count_all as real)/keys.count_all as from_fraction_all from keys, keypairs where key1='waterway' and keys.key=keypairs.key2 and (key1<>'highway' or keypairs.count_all>12000) and (key1<>'railway' or keypairs.count_all>3000) and (key1<>'waterway' or keypairs.count_all>800) and key2 not like '%:%' and from_fraction_all>0.97 and 1 union select keypairs.key2, keypairs.key1, keypairs.count_all, keys.count_all, cast(keypairs.count_all as real)/keys.count_all as from_fraction_all from keys, keypairs where key2='waterway' and keys.key=keypairs.key1 and (key2<>'highway' or keypairs.count_all>12000) and (key2<>'railway' or keypairs.count_all>3000) and (key2<>'waterway' or keypairs.count_all>800) and key1 not like '%:%' and from_fraction_all>0.97 and 1 order by keypairs.count_all desc limit 1000;
3 */
4
5way[surface=~/^(unpaved|compacted|gravel|fine_gravel|pebblestone|ground|earth|dirt|grass|sand|mud|ice|salt|snow|woodchips)$/] { /* without grass_paver as it is controversial */
6 set unpaved_surface;
7}
8
9/* {0.key} without {1.key} (warning level) */
10way[junction ][!highway][junction!=yes][!area:highway],
11way[living_street ][!highway],
12way[maintenance ][!highway],
13way[median ][!highway],
14way[motorroad ][!highway],
15node[ntd_id ][!highway],
16way[sac_scale ][!highway],
17way[sidewalk ][!highway],
18way[step_count ][!highway][man_made!=tower],
19way[tracktype ][!highway],
20way[trail_visibility ][!highway], /* #15029 */
21way[trolley_wire ][!highway],
22way[zip_left ][!highway],
23way[zip_right ][!highway],
24way[detail ][!railway][route!=railway],
25way[eddy_current_brake ][!railway][route!=railway],
26way[electrified ][!railway][route!=railway][!highway], /* #16007 */
27way[etcs ][!railway][route!=railway],
28way[gauge ][!railway][route!=railway],
29way[grade_of_track ][!railway][route!=railway],
30way[kursbuchstrecke ][!railway][route!=railway],
31way[lzb ][!railway][route!=railway],
32way[old_railway_operator ][!railway][route!=railway],
33way[operating_procedure ][!railway][route!=railway],
34way[pzb ][!railway][route!=railway],
35way[structure_gauge ][!railway][route!=railway],
36way[tilting_technology ][!railway][route!=railway],
37way[track_class ][!railway][route!=railway],
38way[tracks ][!railway][route!=railway],
39way[traffic_mode ][!railway][route!=railway],
40way[workrules ][!railway][route!=railway],
41way[length_unit ][!waterway],
42way[canal ][!waterway],
43way[have_riverbank ][!waterway],
44*[border_type ][!boundary],
45*[piste:difficulty ][!piste:type],
46*[place ][!name][place!=islet][place!=plot][noname!=yes],
47*[transformer ][!power],
48*[source:date ][!source],
49*[source:name ][!name][noname!=yes],
50*[source:maxspeed:forward ][!maxspeed:forward][!maxspeed],
51*[source:maxspeed:backward ][!maxspeed:backward][!maxspeed],
52*[source:building ][!building],
53*[source:ref ][!ref][noref!=yes],
54*[source:population ][!population],
55*[source:postal_code ][!postal_code],
56*[source:ele ][!ele],
57*[source:ref:INSEE ][!ref:INSEE],
58*[source:lit ][!lit],
59*[source:hgv ][!hgv],
60*[source:highway ][!highway],
61*[source:maxaxleload ][!maxaxleload],
62*[source:surface ][!surface],
63*[source:bridge ][!bridge],
64*[source:old_name ][!old_name],
65*[source:bicycle ][!bicycle],
66*[source:designation ][!designation],
67*[source:height ][!height],
68*[source:lanes ][!lanes],
69*[source:postcode ][!addr:postcode],
70*[source:housenumber ][!addr:housenumber],
71*[source:addr:postcode ][!addr:postcode],
72*[source:addr:housenumber ][!addr:housenumber] {
73 throwWarning: tr("{0} without {1}", "{0.key}", "{1.key}");
74 group: tr("missing tag");
75 assertMatch: "node source:addr:postcode=postman";
76}
77
78/* {0.key} without {1.key} (info level) */
79way[lanes:forward][!lanes:backward][oneway!=yes][oneway!=-1],
80way[lanes:backward][!lanes:forward][oneway!=yes][oneway!=-1],
81*[leaf_type ][!leaf_cycle],
82*[leaf_cycle][!leaf_type] {
83 throwOther: tr("{0} without {1}", "{0.key}", "{1.key}");
84 group: tr("missing tag");
85}
86
87/* {0.key} without {1.tag}, #17997 */
88node[railway:switch ][railway!=switch],
89*[generator:source ][power!=generator],
90*[generator:method ][power!=generator],
91*[generator:type ][power!=generator],
92node[fire_hydrant:type ][emergency!=fire_hydrant][disused:emergency!=fire_hydrant],
93node[manhole ][man_made!=manhole],
94way[fence_type ][barrier!=fence],
95*[recycling_type ][amenity!=recycling],
96*[information ][tourism!=information],
97node[board_type ][information!=board],
98*[shelter_type ][amenity!=shelter],
99node[lamp_type ][highway!=street_lamp],
100node[map_type ][information!=map],
101*[site_type ][historic!=archaeological_site],
102*[artwork_type ][tourism!=artwork][exhibit!=artwork],
103*[castle_type ][historic!=castle],
104*[parking ][amenity!~/^(parking|parking_space|parking_entrance|motorcycle_parking)$/][parking!=yes][parking!=no],
105way[cutline ][man_made!=cutline],
106*[zoo ][tourism!=zoo],
107*[bunker_type ][military!=bunker] {
108 throwWarning: tr("{0} without {1}", "{0.key}", "{1.tag}");
109 group: tr("missing tag");
110}
111
112/* {0.key} without {1.tag} or {2.tag} */
113*[bridge:movable ][bridge!=movable][man_made!=bridge],
114*[substation ][power!=substation][pipeline!=substation],
115*[reservoir_type ][landuse!=reservoir][water!=reservoir],
116way[waterway=pressurised ][tunnel!=flooded][man_made!=pipeline] {
117 throwWarning: tr("{0} without {1} or {2}", "{0.key}", "{1.tag}", "{2.tag}");
118 group: tr("missing tag");
119}
120
121/* {0.key} without {1.tag}, {2.tag} or {3.tag}, #15107, #20241 */
122*[iata ][aeroway!=aerodrome][aeroway!=heliport][aeroway!=helipad],
123*[icao ][aeroway!=aerodrome][aeroway!=heliport][aeroway!=helipad] {
124 throwWarning: tr("{0} without {1}, {2} or {3}", "{0.key}", "{1.tag}", "{2.tag}", "{3.tag}");
125 group: tr("missing tag");
126}
127
128/* {0.tag} without {1.key} (warning level), #18411, #18246 */
129way[railway=construction][!construction],
130way[highway=construction][!construction],
131node[traffic_sign=maxspeed][!maxspeed][!/^maxspeed:.+/],
132node[actuator=manual][!handle],
133node[emergency=fire_hydrant][!fire_hydrant:type],
134way[ boundary=administrative][!admin_level],
135relation[boundary=administrative][!admin_level],
136relation[route=bicycle ][!network][type=route],
137relation[route=hiking ][!network][type=route],
138relation[route=foot ][!network][type=route],
139relation[route=horse ][!network][type=route],
140relation[route=piste][!piste:type][type=route],
141relation[route=ski ][!piste:type][type=route],
142*[tourism=information][!information],
143*[leisure=pitch][!sport],
144*[aeroway=terminal][!building],
145*[office=government][!government],
146*[power=generator][!generator:source],
147*[amenity=social_facility][!social_facility],
148*[amenity=place_of_worship][!religion],
149*[man_made=tower][!tower:type] {
150 throwWarning: tr("{0} without {1}", "{0.tag}", "{1.key}");
151 group: tr("missing tag");
152 assertNoMatch: "node traffic_sign=maxspeed maxspeed:hgv:conditional=\"80 @ (weight>7.5 AND 22:00-05:00)\"";
153}
154
155/* {0.tag} without {1.key} (info level), #15107 */
156*[aeroway=runway ][!ref],
157*[aeroway=runway ][!surface],
158node[highway=crossing ][!crossing],
159way[highway=track ][!tracktype],
160way[power=cable ][!location],
161node[power=transformer ][!voltage:primary],
162node[power=transformer ][!voltage:secondary],
163node[transformer=distribution ][!voltage:primary][power=pole],
164node[transformer=distribution ][!voltage:secondary][power=pole],
165way[power=line ][!voltage],
166way[power=minor_line ][!voltage],
167way[power=cable ][!voltage],
168*[power=generator ][!voltage][generator:output:electricity],
169*[power=plant ][!voltage][plant:output:electricity],
170*[power=substation ][!substation],
171*[power=switch ][!switch],
172*[power=transformer ][!transformer],
173*[amenity=bank ][!operator],
174*[amenity=cinema ][!operator],
175*[amenity=fast_food ][!operator],
176*[amenity=fuel ][!operator],
177*[mountain_pass=yes ][!ele],
178*[natural=peak ][!ele],
179*[natural=water ][!water],
180*[amenity=place_of_worship ][!denomination],
181*[amenity=parking ][!parking],
182*[amenity=parking_entrance ][!parking] {
183 throwOther: tr("{0} without {1}", "{0.tag}", "{1.key}");
184 group: tr("missing tag");
185 assertMatch: "way power=line";
186 assertNoMatch: "way power=line voltage=1";
187 assertMatch: "way power=switch";
188 assertMatch: "way power=substation";
189 assertMatch: "way power=substation transformer=foobar";
190 assertNoMatch: "way power=substation substation=foobar";
191 assertMatch: "way power=generator generator:output:electricity=yes";
192 assertNoMatch: "way power=generator";
193 assertNoMatch: "way power=generator generator:output:electricity=yes voltage=1";
194}
195
196/* {0.key} without {1.key} or {2.tag} */
197way[bridge:structure ][!bridge][man_made!=bridge],
198*[segregated ][!highway][railway!=crossing] {
199 throwWarning: tr("{0} without {1} or {2}", "{0.key}", "{1.key}", "{2.tag}");
200 group: tr("missing tag");
201}
202
203/* {0.tag} without {1.tag} (info level) see #11600 #11393 #11850 */
204way[highway=motorway][!oneway][junction!=roundabout],
205way[highway=motorway_link][!oneway][junction!=roundabout] {
206 throwOther: tr("{0} without {1}", "{0.tag}", "{1.tag}");
207 group: tr("missing tag");
208}
209
210/* {0.tag} without {1.tag} */
211way[usage=penstock][man_made!=pipeline],
212way[usage=penstock][waterway!=pressurised] {
213 throwWarning: tr("{0} without {1}", "{0.tag}", "{1.tag}");
214 group: tr("missing tag");
215}
216
217/* {0.tag} without {1.tag} or {2.tag} */
218*[amenity=recycling][recycling_type!=container][recycling_type!=centre] {
219 throwWarning: tr("{0} without {1} or {2}", "{0.tag}", "{1.tag}", "{2.tag}");
220 group: tr("missing tag");
221}
222
223/* {0.key} without {1.key}, {2.tag}, {3.tag} or {4.key} */
224*[smoothness][!highway][amenity!~/^(parking|parking_space|parking_entrance|motorcycle_parking|bicycle_parking)$/][barrier!=kerb][!kerb] {
225 throwWarning: tr("{0} without {1}, {2}, {3} or {4}", "{0.key}", "{1.key}", "{2.tag}", "{3.tag}", "{4.key}");
226 group: tr("missing tag");
227}
228
229/* {0.key} without {1.key}, {2.tag}, {3.tag} or {4.tag} */
230*[intermittent ][!waterway][natural!~/^(water|spring)$/][landuse!~/^(basin|reservoir)$/][ford!~/^(yes|stepping_stones)$/],
231*[boat ][!waterway][natural!=water ][landuse!~/^(basin|reservoir)$/][ford!=yes] {
232 throwWarning: tr("{0} without {1}, {2}, {3} or {4}", "{0.key}", "{1.key}", "{2.tag}", "{3.tag}", "{4.tag}");
233 group: tr("missing tag");
234}
235
236/* {0.key} without {1.key}, {2.key} or {3.key} */
237*[snowplowing][!highway][!amenity][!leisure] {
238 throwWarning: tr("{0} without {1}, {2} or {3}", "{0.key}", "{1.key}", "{2.key}", "{3.key}");
239 group: tr("missing tag");
240}
241
242/* {0.key} without {1.key}, {2.key} or {3.tag} */
243*[toll ][!highway][!barrier][route!~/^(ferry|road)$/] {
244 throwWarning: tr("{0} without {1}, {2} or {3}", "{0.key}", "{1.key}", "{2.key}", "{3.tag}");
245 group: tr("missing tag");
246}
247
248/* {0.tag} together with {1.key}, see #17664, #17707, #16464, #10837, #14034, #9389, #11977, #13156, #16888 */
249*[power=plant][/^generator:/],
250*[power=generator][/^plant:/],
251*[power=plant][voltage],
252*[power=plant][frequency],
253*[internet_access=no][internet_access:fee],
254node[power=transformer][voltage],
255node[transformer=distribution][voltage][power=pole],
256*[amenity=vending_machine][shop],
257*[noname?][name],
258way[oneway=yes][/:backward/][!traffic_sign:backward][bicycle:backward!=use_sidepath][oneway:bicycle!=no][oneway:psv!=no],
259way[oneway=yes][/:forward/ ][!traffic_sign:forward ][bicycle:forward!=use_sidepath ][oneway:bicycle!=no][oneway:psv!=no],
260way[oneway=-1 ][/:backward/][!traffic_sign:backward][bicycle:backward!=use_sidepath][oneway:bicycle!=no][oneway:psv!=no],
261way[oneway=-1 ][/:forward/ ][!traffic_sign:forward ][bicycle:forward!=use_sidepath ][oneway:bicycle!=no][oneway:psv!=no] {
262 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.key}");
263 group: tr("suspicious tag combination");
264 assertMatch: "way power=plant generator:source=wind";
265 assertMatch: "way power=generator plant:source=combustion";
266}
267
268/* {0.tag} together with {1.tag} (info level), see #9696 */
269way[highway=footway][oneway=no] {
270 throwOther: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
271 group: tr("suspicious tag combination");
272}
273
274/* {0.tag} together with {1.tag}, see #18411, #17950, #17330, #17623, #17592, #17594, #17542, #16861, #16147, #10186, #18815 */
275*[barrier=kerb][kerb=no],
276way[highway=construction][construction=yes],
277way[railway=construction][construction=yes],
278*[man_made=bridge][bridge=yes],
279*[man_made=tunnel][tunnel=yes],
280*[amenity=police][police],
281node[highway=crossing][crossing=no],
282node[railway=crossing][crossing=no],
283way[junction=yes][highway],
284way[tracktype=grade1][surface].unpaved_surface,
285way[tracktype=grade2][surface][surface=~/^(sand|mud)$/],
286way[segregated][bicycle=no],
287way[segregated][foot=no],
288way[man_made=pipeline][tunnel=flooded] {
289 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
290 group: tr("suspicious tag combination");
291}
292
293/* {0.tag} together with {1.tag} (error level) */
294relation[type=multipolygon][area=no] {
295 throwError: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
296 group: tr("suspicious tag combination");
297}
298
299/* {0.key} together with {1.key}, #18267, #17630, #17604 */
300node[marker][cover],
301node[marker][voltage],
302node[marker][pressure],
303node[marker][diameter],
304node[marker][substance],
305*[building:part][building],
306*[addr:street][addr:place][outside("CZ,DK")] {
307 throwWarning: tr("{0} together with {1}", "{0.key}", "{1.key}");
308 group: tr("suspicious tag combination");
309}
310
311/* {0.tag} together with {1.tag} and {2.key}, #18471 */
312way[highway=~/^(cycleway|footway|path)$/][segregated=no][sidewalk =~/^(left|right|both)$/] {
313 throwWarning: tr("{0} together with {1} and {2}", "{0.tag}", "{1.tag}", "{2.key}");
314 group: tr("suspicious tag combination");
315}
316
317/* {0.key} together with {1.tag} and {2.key}, #19747 */
318way[railway][electrified=no][frequency],
319way[railway][electrified=no][voltage] {
320 throwWarning: tr("{0} together with {1} and {2}", "{0.key}", "{1.tag}", "{2.key}");
321 group: tr("suspicious tag combination");
322}
323
324/* #11127, #13727 */
325way[waterway][bridge=yes][waterway!=weir] {
326 throwWarning: tr("{0} together with {1}", "{0.key}", "{1.tag}");
327 suggestAlternative: "bridge=aqueduct";
328 group: tr("suspicious tag combination");
329 fixAdd: "bridge=aqueduct";
330}
331way[waterway=weir][bridge=yes][highway] {
332 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
333 suggestAlternative: "waterway=weir + ford=yes";
334 suggestAlternative: "waterway=dam";
335 suggestAlternative: tr("two objects, one with {0} and one with {1} + {2} + {3}", "{0.tag}", "{2.key}", "{1.tag}", "layer");
336 group: tr("suspicious tag combination");
337}
338
339/* #16214 */
340relation[type=multipolygon] >[role="inner"] way[area][eval(number_of_tags()) = 1] {
341 throwWarning: tr("{0} on an inner multipolygon ring without further tags", "{0.tag}");
342 fixRemove: "area";
343 set area_yes_autofix;
344 group: tr("suspicious tag combination");
345}
346
347/* only {0.key}, #11104, #12422, #14950, #19572, #20902 */
348/* relations excluded as there is a test for missing type=* plus several other test depending on the type exist */
349node[access][eval(number_of_tags()) = 1],
350way[access][eval(number_of_tags()) = 1],
351node[area][eval(number_of_tags()) = 1]!.area_yes_autofix,
352way[area][eval(number_of_tags()) = 1]!.area_yes_autofix,
353node[lanes][eval(number_of_tags()) = 1],
354way[lanes][eval(number_of_tags()) = 1],
355node[layer][eval(number_of_tags()) = 1],
356way[layer][eval(number_of_tags()) = 1],
357way[level][eval(number_of_tags()) = 1], /* nodes might be valid, e.g. start and end nodes of steps */
358node[lit][eval(number_of_tags()) = 1],
359way[lit][eval(number_of_tags()) = 1],
360node[name][eval(number_of_tags()) = 1],
361way[name][eval(number_of_tags()) = 1],
362node[ref][eval(number_of_tags()) = 1],
363way[ref][eval(number_of_tags()) = 1],
364node[surface][eval(number_of_tags()) = 1],
365way[surface][eval(number_of_tags()) = 1] {
366 throwWarning: tr("incomplete object: only {0}", "{0.key}");
367 set only_one_tag;
368 group: tr("missing tag");
369}
370/* only {0.key} and {1.key} */
371node[name][area][eval(number_of_tags()) = 2],
372way[name][area][eval(number_of_tags()) = 2],
373node[name][ref][eval(number_of_tags()) = 2],
374way[name][ref][eval(number_of_tags()) = 2] {
375 throwWarning: tr("incomplete object: only {0} and {1}", "{0.key}", "{1.key}");
376 group: tr("missing tag");
377}
378/* only {0.tag}, #15269 */
379node[tourism=attraction][eval(number_of_tags()) = 1],
380way[tourism=attraction][eval(number_of_tags()) = 1] {
381 throwWarning: tr("incomplete object: only {0}", "{0.tag}");
382 group: tr("missing tag");
383}
384/* only {0.key} and {1.tag} */
385node[name][tourism=attraction][eval(number_of_tags()) = 2],
386way[name][tourism=attraction][eval(number_of_tags()) = 2] {
387 throwWarning: tr("incomplete object: only {0} and {1}", "{0.key}", "{1.tag}");
388 group: tr("missing tag");
389}
390
391/* #9811, #11491, #12865, #14310 */
392*[place][place!=farm][place!=plot][/^(addr:housenumber|addr:housename|addr:flats|addr:conscriptionnumber|addr:street|addr:place|addr:city|addr:country|addr:full|addr:hamlet|addr:suburb|addr:subdistrict|addr:district|addr:province|addr:state|addr:interpolation|addr:interpolation|addr:inclusion)$/],
393/* addr:postcode is used together with place in some countries */
394*[boundary][/^addr:/],
395*[highway][/^addr:/][highway!=services][highway!=rest_area][!"addr:postcode"] {
396 throwWarning: tr("{0} together with {1}", "{0.key}", "addr:*");
397 group: tr("suspicious tag combination");
398 assertMatch: "node place=foo addr:housenumber=5";
399 assertMatch: "node place=foo addr:housenumber=5 addr:postcode=12345";
400 assertNoMatch: "node place=foo addr:postcode=12345";
401}
402*[!highway][postal_code]["addr:postcode"][postal_code=*"addr:postcode"] {
403 throwWarning: tr("{0} together with {1}", "{1.key}", "{2.key}");
404 group: tr("suspicious tag combination");
405}
406*[!highway][postal_code]["addr:postcode"][postal_code!=*"addr:postcode"] {
407 throwWarning: tr("{0} together with {1} and conflicting values", "{1.key}", "{2.key}");
408 group: tr("suspicious tag combination");
409}
410way[highway][postal_code]["addr:postcode"][postal_code=*"addr:postcode"] {
411 throwWarning: tr("{0} together with {1}", "{1.key}", "{2.key}");
412 group: tr("suspicious tag combination");
413 fixRemove: "addr:postcode";
414}
415way[highway][postal_code]["addr:postcode"][postal_code!=*"addr:postcode"] {
416 throwWarning: tr("{0} together with {1} and conflicting values", "{1.key}", "{2.key}");
417 group: tr("suspicious tag combination");
418}
419way[highway][highway!=services][highway!=rest_area][!postal_code]["addr:postcode"] {
420 throwWarning: tr("{0} together with {1}", "{0.key}", "{4.key}");
421 suggestAlternative: "postal_code";
422 group: tr("suspicious tag combination");
423 fixChangeKey: "addr:postcode=>postal_code";
424}
425
426/* #9195 */
427way[highway=footway][cycleway=lane] {
428 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
429 suggestAlternative: "highway=path + foot=designated + bicycle=designated + segregated=yes";
430 group: tr("suspicious tag combination");
431}
432
433/* {0} on suspicious object, #17255, #19650, #19572, #17253, #19821, #15667, #19930, #20435, #20471, #18815 */
434way[oneway ][!highway][!area:highway][!railway][!aerialway][attraction!=summer_toboggan][aeroway!~/^(runway|taxiway)$/][leisure!=track][waterway !~ /^(canal|fairway|lock|river|tidal_channel)$/],
435node[lanes ][!barrier][!ford][highway!=mini_roundabout][!junction][leisure!~/^(bowling_alley|slipway|swimming_pool|track)$/][!traffic_calming]!.only_one_tag,
436way[lanes ][!barrier][!ford][!highway ][!area:highway][!junction][leisure!~/^(bowling_alley|slipway|swimming_pool|track)$/][!traffic_calming]!.only_one_tag,
437*[tunnel ][!highway][!area:highway][!railway][!waterway][!piste:type][type!=tunnel][public_transport!=platform][route!=ferry][man_made!=pipeline][man_made!=goods_conveyor][man_made!=wildlife_crossing][man_made!=tunnel][power!=cable],
438*[bridge ][!highway][!area:highway][!railway][!waterway][!piste:type][type!=bridge][public_transport!=platform][route!=ferry][man_made!=pipeline][man_made!=goods_conveyor][man_made!=wildlife_crossing][man_made!=bridge][building!=bridge],
439*[psv ][!highway][!area:highway][!railway][!waterway][barrier!=bollard][amenity !~ /^parking.*/],
440*[width ][!highway][!area:highway][!railway][!waterway][!aeroway][!cycleway][!footway][!barrier][!man_made][!entrance][natural!=stone][leisure!=track],
441*[maxspeed ][!highway][!area:highway][!railway][traffic_sign !~ /^((.*;)?maxspeed(;.*)?|[A-Z][A-Z]:.+)$/][traffic_sign:forward !~ /^((.*;)?maxspeed(;.*)?|[A-Z][A-Z]:.+)$/][traffic_sign:backward !~ /^((.*;)?maxspeed(;.*)?|[A-Z][A-Z]:.+)$/][type != enforcement][waterway !~ /^(canal|fairway|lock|river|tidal_channel)$/][!traffic_calming][aerialway!=zip_line],
442way[incline][!highway][!area:highway][!railway][aeroway!~/^(runway|taxiway)$/][attraction!=summer_toboggan][leisure!=slipway] {
443 throwWarning: tr("{0} on suspicious object", "{0.key}");
444 group: tr("suspicious tag combination");
445}
446
447/* #15667, #19930 */
448way[waterway][oneway][waterway =~ /^(canal|fairway|lock|river|tidal_channel)$/] {
449 throwOther: tr("{0} together with {1}. The flow direction is defined by the way direction. Use {1} on {0} only in the rare case of a access restriction.", "{0.key}", "{1.key}");
450 group: tr("suspicious tag combination");
451}
452
453*[amenity][amenity =~ /^(restaurant|cafe|fast_food|pub|place_of_worship|school|university|hospital|library|theatre|courthouse|bank|cinema|pharmacy|fuel)$/][!name][noname!=yes] {
454 throwOther: tr("{0} without {1}", "{0.tag}", "{2.key}");
455 group: tr("missing tag");
456 assertMatch: "node amenity=restaurant";
457 assertNoMatch: "node amenity=restaurant noname=yes";
458 assertNoMatch: "node amenity=restaurant name=Foobar";
459}
460
461/* #10193, #16157 */
462way[highway][barrier],
463*[highway][waterway][waterway!=dam][waterway!=weir],
464way[highway][natural][natural!=ridge],
465*[landuse][building][landuse!=retail] {
466 throwWarning: tr("{0} together with {1}", "{0.key}", "{1.key}");
467 group: tr("suspicious tag combination");
468 assertNoMatch: "node highway=street_lamp natural=birds_nest";
469}
470
471/* #6932 */
472*[natural=water][leisure=swimming_pool] {
473 throwWarning: tr("natural water used for swimming pool");
474 group: tr("suspicious tag combination");
475 fixRemove: "natural";
476}
477
478/* #9593, #11183, #12418, #12761, #17254, #19311 */
479*[sport][sport!=skiing][!building][!club][tourism != hotel][highway !~ /^(pedestrian|raceway)$/][!leisure][natural !~ /^(beach|bare_rock|cliff|peak|water)$/][amenity !~ /^(bar|dojo|pub|restaurant|swimming_pool)$/][landuse !~ /^(recreation_ground|piste|farm|farmland)$/][barrier !~ /^(wall|retaining_wall)$/][!"piste:type"][shop!=sports][attraction!=summer_toboggan] {
480 throwWarning: tr("sport without physical feature");
481 group: tr("missing tag");
482 assertMatch: "node sport=tennis";
483 assertNoMatch: "node sport=tennis leisure=pitch";
484 assertNoMatch: "node sport=beachvolleyball natural=beach";
485 assertNoMatch: "node sport=skiing"; /* skiing has deprecated warning */
486 assertNoMatch: "node sport=swimming tourism=hotel";
487 assertNoMatch: "node sport=10pin amenity=restaurant";
488}
489
490/* {0.key} without {1.key} or {2.key} see #10140 */
491*[building:levels][!building][!building:part],
492way[usage][!railway][!waterway][route!=railway][man_made!=pipeline] {
493 throwWarning: tr("{0} without {1} or {2}", "{0.key}", "{1.key}", "{2.key}");
494 group: tr("missing tag");
495}
496
497/* any other *_name tag (with some exceptions) but not a name , see #10837 #11297 #11539 #16437 #17026 */
498*[/_name$/][!name][!old_name][!loc_name][!reg_name][!uic_name][!artist_name][!lock_name][!"osak:municipality_name"][!"osak:street_name"][noname!=yes] {
499 throwWarning: tr("alternative name without {0}", "{1.key}");
500 group: tr("missing tag");
501}
502
503/* #19604 */
504way[name][alt_name][name=*alt_name] {
505 throwWarning: tr("Same value of {0} and {1}", "{0.key}", "{1.key}");
506 group: tr("suspicious tag combination");
507 fixRemove: "alt_name";
508}
509
510/* #10837 */
511way[destination][!oneway?][junction!=roundabout][highway] {
512 throwWarning: tr("incomplete usage of {0} on a way without {1}", "{0.key}", "{1.key}");
513 suggestAlternative: "destination:forward";
514 suggestAlternative: "destination:backward";
515}
516
517/* #11389, #19010 */
518way[maxspeed:forward][maxspeed:backward][!maxspeed]["maxspeed:forward"=*"maxspeed:backward"] {
519 throwWarning: tr("Same value of {0} and {1}", "{0.key}", "{1.key}");
520 suggestAlternative: "maxspeed";
521 group: tr("suspicious tag combination");
522 fixChangeKey: "maxspeed:forward=>maxspeed";
523 fixRemove: "maxspeed:backward";
524}
525way[maxspeed:forward][maxspeed:backward][maxspeed]["maxspeed:forward"=*maxspeed]["maxspeed:backward"=*maxspeed] {
526 throwWarning: tr("Same value of {0}, {1} and {2}", "{0.key}", "{1.key}", "{2.key}");
527 set AllSameMaxspeed;
528 suggestAlternative: "maxspeed";
529 group: tr("suspicious tag combination");
530 fixRemove: "maxspeed:forward";
531 fixRemove: "maxspeed:backward";
532}
533way[cycleway:left][cycleway:right][!cycleway]["cycleway:left"=*"cycleway:right"] {
534 throwWarning: tr("Same value of {0} and {1}", "{0.key}", "{1.key}");
535 suggestAlternative: "cycleway";
536 group: tr("suspicious tag combination");
537 fixChangeKey: "cycleway:left=>cycleway";
538 fixRemove: "cycleway:right";
539}
540way[cycleway:left][cycleway:right][cycleway]["cycleway:left"=*cycleway]["cycleway:right"=*cycleway] {
541 throwWarning: tr("Same value of {0}, {1} and {2}", "{0.key}", "{1.key}", "{2.key}");
542 set AllSameCycleway;
543 suggestAlternative: "cycleway";
544 group: tr("suspicious tag combination");
545 fixRemove: "cycleway:left";
546 fixRemove: "cycleway:right";
547}
548way[sidewalk:left][sidewalk:right][!sidewalk]["sidewalk:left"=*"sidewalk:right"] {
549 throwWarning: tr("Same value of {0} and {1}", "{0.key}", "{1.key}");
550 suggestAlternative: "sidewalk";
551 group: tr("suspicious tag combination");
552 fixChangeKey: "sidewalk:left=>sidewalk";
553 fixRemove: "sidewalk:right";
554}
555way[sidewalk:left][sidewalk:right][sidewalk]["sidewalk:left"=*sidewalk]["sidewalk:right"=*sidewalk] {
556 throwWarning: tr("Same value of {0}, {1} and {2}", "{0.key}", "{1.key}", "{2.key}");
557 set AllSameSidewalk;
558 suggestAlternative: "sidewalk";
559 group: tr("suspicious tag combination");
560 fixRemove: "sidewalk:left";
561 fixRemove: "sidewalk:right";
562}
563way["maxspeed:forward"]["maxspeed:backward"][maxspeed]!.AllSameMaxspeed,
564way["cycleway:left"]["cycleway:right"][cycleway]!.AllSameCycleway,
565way["sidewalk:left"]["sidewalk:right"][sidewalk]!.AllSameSidewalk {
566 throwWarning: tr("{0} and {1} together with {2} and conflicting values", "{0.key}", "{1.key}", "{2.key}");
567 group: tr("suspicious tag combination");
568}
569way["maxspeed:forward"][maxspeed][!"maxspeed:backward"],
570way["maxspeed:backward"][maxspeed][!"maxspeed:forward"],
571way["cycleway:left"][cycleway][!"cycleway:right"],
572way["cycleway:right"][cycleway][!"cycleway:left"],
573way["sidewalk:left"][sidewalk][!"sidewalk:right"],
574way["sidewalk:right"][sidewalk][!"sidewalk:left"] {
575 throwWarning: tr("{0} together with {1}", "{0.key}", "{1.key}");
576 group: tr("suspicious tag combination");
577}
578
579/* #11837 */
580way[layer][layer<0][bridge][bridge!=no][location!=underground][indoor!=yes][!tunnel],
581way[layer][layer>0][tunnel][tunnel!=no][location!=overground][indoor!=yes][!bridge] {
582 throwWarning: tr("{0} together with {1}", "{2.tag}", "{0.tag}");
583 group: tr("suspicious tag combination");
584}
585
586/* #12942 */
587relation[oneway][type!=route] {
588 throwWarning: tr("{0} on a relation without {1}", "{0.key}", "{1.tag}");
589}
590
591/* #9182 */
592way[waterway][layer][layer=~/^(-1|-2|-3|-4|-5)$/][!tunnel][culvert!=yes][covered!=yes][pipeline!=yes][location!=underground][eval(waylength()) > 400] {
593 throwWarning: tr("Long waterway with {0} but without a tag which defines it as tunnel or underground. Remove {1} or add a tunnel tag if applicable. Also check crossing bridges and their {1} tags.", "{1.tag}", "{1.key}");
594 group: tr("suspicious tag combination");
595}
596way[waterway][layer][layer=~/^(-1|-2|-3|-4|-5)$/][!tunnel][culvert!=yes][covered!=yes][pipeline!=yes][location!=underground][eval(waylength()) <= 400] {
597 throwOther: tr("Short waterway with {0} but without a tag which defines it as tunnel or underground. Remove {1} or add a tunnel tag if applicable. Also check crossing bridges and their {1} tags.", "{1.tag}", "{1.key}");
598 group: tr("suspicious tag combination");
599}
600
601/* #13144, #15536 */
602*[unisex=yes][female=yes][male!=yes][shop=hairdresser],
603*[unisex=yes][male=yes][female!=yes][shop=hairdresser] {
604 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
605 group: tr("suspicious tag combination");
606}
607*[unisex=yes][female=yes][male=yes][shop=hairdresser] {
608 throwWarning: tr("{0} together with {1} and {2}. Remove {1} and {2}", "{0.tag}", "{1.tag}", "{2.tag}");
609 group: tr("suspicious tag combination");
610 fixRemove: "female";
611 fixRemove: "male";
612}
613*[female=yes][male=yes][!unisex][shop=hairdresser] {
614 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
615 suggestAlternative: "unisex=yes";
616 group: tr("suspicious tag combination");
617 fixRemove: "female";
618 fixRemove: "male";
619 fixAdd: "unisex=yes";
620}
621
622/* {1.key} without {2.tag} see #13138, #14468 */
623way!:closed[water][natural!~/water|bay|strait/][water!=intermittent][amenity!=lavoir], /* water=intermittent is deprecated and has an own warning */
624area:closed[water][natural!~/water|bay|strait/][water!=intermittent][amenity!=lavoir] {
625 throwWarning: tr("{0} without {1}", "{1.key}", "{2.tag}");
626 group: tr("missing tag");
627}
628
629/* #13680 */
630area[golf=bunker][natural=beach] {
631 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
632 suggestAlternative: "natural=sand";
633 suggestAlternative: "surface=sand";
634 group: tr("suspicious tag combination");
635}
636
637/* #13705 */
638relation[type=multipolygon][building] > way {
639 set part_of_building_MP;
640}
641way["addr:housenumber"][!building][!"building:part"][!"demolished:building"][!note][!amenity][!leisure][!landuse][!man_made][!tourism][!barrier][place!=plot]!.part_of_building_MP {
642 /* don't exclude shop because a lot of real missing bulding tag cases have a shop tag. */
643 throwOther: tr("possibly missing {0} tag", "{1.key}");
644 group: tr("missing tag");
645}
646
647/* see #8519, #11529, limited to motorways and trunks to avoid false positives for streets with lanes for non motorized traffic */
648way[highway =~ /^(motorway|motorway_link|trunk|trunk_link)$/] {
649 set MotorwayTrunk;
650}
651way.MotorwayTrunk[lanes][turn:lanes ][tag(lanes)!=eval(count(split("|", tag("turn:lanes"))))],
652way.MotorwayTrunk[lanes][change:lanes ][tag(lanes)!=eval(count(split("|", tag("change:lanes"))))],
653way.MotorwayTrunk[lanes][maxspeed:lanes ][tag(lanes)!=eval(count(split("|", tag("maxspeed:lanes"))))],
654way.MotorwayTrunk[lanes][minspeed:lanes ][tag(lanes)!=eval(count(split("|", tag("minspeed:lanes"))))],
655way.MotorwayTrunk[lanes][destination:lanes ][tag(lanes)!=eval(count(split("|", tag("destination:lanes"))))],
656way.MotorwayTrunk[lanes][destination:ref:lanes ][tag(lanes)!=eval(count(split("|", tag("destination:ref:lanes"))))],
657way.MotorwayTrunk[lanes][destination:symbol:lanes][tag(lanes)!=eval(count(split("|", tag("destination:symbol:lanes"))))] {
658 throwWarning: tr("Different number of lanes in the keys {0} and {1}", "{1.key}", "{2.key}");
659 group: tr("suspicious tag combination");
660}
661
662/* #14125, #14323, #18185 */
663way[highway][lanes][!lanes:forward][!lanes:backward][oneway!=yes][oneway!=-1][oneway!=reversible][highway!=motorway][junction!=roundabout][lanes>2][mod(tag(lanes),2)=1] {
664 throwWarning: tr("street with odd number of {0}, but without {1} and {2} or {3}", "{1.key}", "{2.key}", "{3.key}", "{4.key}");
665 group: tr("missing tag");
666 assertNoMatch: "way highway=primary lanes=2";
667 assertNoMatch: "way highway=primary lanes=3 lanes:backward=2";
668 assertNoMatch: "way highway=primary lanes=3 oneway=-1";
669 assertNoMatch: "way highway=primary lanes=4";
670 assertMatch: "way highway=primary lanes=3";
671}
672
673/* #10932, #19609 */
674way[highway][!lanes][/^.*:lanes$/][!source:lanes],
675way[highway][!lanes][/^.*:lanes:(forward|backward|both_ways)$/],
676way[highway][!lanes:both_ways][/^.*:lanes:both_ways$/] {
677 throwWarning: tr("{0} without {1}", "{2.key}", "{1.key}");
678 group: tr("missing tag");
679 assertMatch: "way highway=primary turn:lanes=left|right";
680 assertMatch: "way highway=primary turn:lanes:forward=left|right";
681 assertNoMatch: "way highway=primary turn:lanes=left|right lanes=2";
682}
683way[highway][!lanes:forward][/^.*:lanes:forward$/][!lanes:backward][mod(tag(lanes),2)=0],
684way[highway][!lanes:backward][/^.*:lanes:backward$/][!lanes:forward][mod(tag(lanes),2)=0] {
685 throwOther: tr("{0} without {1}", "{2.key}", "{1.key}");
686 group: tr("missing tag");
687 assertMatch: "way highway=primary turn:lanes:forward=left|right lanes=2";
688 assertNoMatch: "way highway=primary turn:lanes:forward=left|right lanes:forward=2";
689 assertNoMatch: "way highway=primary turn:lanes:forward=left|right lanes=3";
690}
691
692/* #15774 */
693node[emergency=fire_hydrant][fire_hydrant:count][fire_hydrant:count!=1] {
694 throwOther: tr("{0} together with {1}. Tag each hydrant separately.", "{0.tag}", "{1.tag}");
695}
696
697/* #12502 */
698node[leisure=park][natural=tree] {
699 throwWarning: tr("{0} together with {1} on a node. Remove {0}.", "{0.tag}", "{1.tag}");
700 group: tr("suspicious tag combination");
701 fixRemove: "leisure";
702}
703
704/* #17305 */
705area[boundary=administrative][landuse=residential] {
706 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
707 group: tr("suspicious tag combination");
708}
709
710/* #17391 */
711way[highway=pedestrian][width][width<3] {
712 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
713 suggestAlternative: "highway=footway";
714 group: tr("suspicious tag combination");
715 fixAdd: "highway=footway";
716 assertMatch: "way highway=pedestrian width=0.8";
717 assertMatch: "way highway=pedestrian width=1";
718 assertNoMatch: "way highway=pedestrian width=3";
719 assertNoMatch: "way highway=pedestrian width=5.5";
720}
721
722/* see #17623 */
723way:areaStyle[highway][highway =~ /motorway|trunk|primary|secondary|tertiary|unclassified|residential|service$|living_street|pedestrian|track|path|footway|cycleway|busway|bus_guideway|bridleway/][area!=yes] {
724 throwOther: tr("A linear object {0} without {1} has a tag indicating that it is an area.", "{1.tag}", "{3.tag}");
725 group: tr("suspicious tag combination");
726}
727
728/* #17804 */
729area[cemetery=sector][landuse=cemetery] {
730 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
731 group: tr("suspicious tag combination");
732}
733
734/* #17967 */
735*[highway=cycleway][cycleway=track] {
736 throwWarning: tr("{0} together with {1}. Remove {1}.", "{0.tag}", "{1.tag}");
737 group: tr("suspicious tag combination");
738 fixRemove: "cycleway";
739}
740
741/* #17973, #18183, #18331, #20318 */
742way[highway=path ][!segregated][foot=designated][bicycle=designated],
743way[highway=footway ][!segregated][bicycle=designated],
744way[highway=cycleway][!segregated][foot=designated] {
745 throwWarning: tr("Combined foot- and cycleway without {0}.", "{1.key}");
746 group: tr("missing tag");
747}
748
749/* #17989 */
750node[emergency_ward_entrance][emergency!=emergency_ward_entrance] {
751 throwWarning: tr("{0} without {1}", "{0.tag}", "{1.tag}");
752 group: tr("missing tag");
753 fixAdd: "emergency=emergency_ward_entrance";
754}
755
756/* missing or conflicting construction, see #17607 */
757/* {0.key} without {1.key} and {2.key} */
758*[construction:building][!building][!construction],
759*[construction:highway][!highway][!construction],
760*[construction:railway][!railway][!construction],
761*[construction:landuse][!landuse][!construction] {
762 throwWarning: tr("{0} without {1} and {2}", "{0.key}", "{1.key}", "{2.key}");
763 group: tr("missing tag");
764 fixAdd: "{1.key}=construction";
765 fixAdd: "construction={0.value}";
766 assertMatch: "way construction:building=house";
767 assertNoMatch: "way construction:building=house building=house ";
768 assertNoMatch: "way construction:building=house construction=house";
769}
770/* {0.key} and {1.key} without {2.key} */
771*[building=construction]["construction:building"][!construction],
772*[highway=construction]["construction:highway"][!construction],
773*[railway=construction]["construction:railway"][!construction],
774*[landuse=construction]["construction:landuse"][!construction] {
775 throwWarning: tr("{0} together with {1} but without {2}", "{0.key}", "{1.key}", "{2.key}");
776 group: tr("missing tag");
777 fixAdd: "construction={1.value}";
778 assertMatch: "way construction:building=house building=construction";
779 assertNoMatch: "way construction:building=house building=house ";
780 assertNoMatch: "way construction:building=house construction=house";
781}
782/* {0.key} and {1.key} without {2.key} */
783*[building]["construction:building"][!construction][building!=construction],
784*[highway]["construction:highway"][!construction][highway!=construction],
785*[railway]["construction:railway"][!construction][railway!=construction],
786*[landuse]["construction:landuse"][!construction][landuse!=construction] {
787 throwWarning: tr("{0} together with {1} and conflicting values plus no {2}", "{0.key}", "{1.key}", "{2.key}");
788 group: tr("suspicious tag combination");
789 assertMatch: "way construction:building=house building=office";
790 assertNoMatch: "way construction:building=house building=construction";
791 assertNoMatch: "way construction:building=house construction=house";
792}
793
794*["construction:building"][construction][construction:building != *construction],
795*["construction:highway"][construction][construction:highway != *construction],
796*["construction:railway"][construction][construction:railway != *construction],
797*["construction:landuse"][construction][construction:landuse != *construction] {
798 throwWarning: tr("{0} together with {1} and conflicting values", "{0.key}", "{1.key}");
799 group: tr("suspicious tag combination");
800 assertMatch: "way construction:building=house construction=office";
801 assertNoMatch: "way construction:building=house construction=house";
802}
803
804/* #18203 */
805way[construction][construction!=yes][construction!=minor][highway][highway!=construction] {
806 throwWarning: tr("{0} together with {1}", "{3.tag}", "{0.tag}");
807 group: tr("suspicious tag combination");
808}
809
810/* #18374 */
811*[amenity=recycling][collection_times="24/7"][!opening_hours],
812*[amenity=recycling][collection_times ][!opening_hours][collection_times=~/[a-z]-[A-Z].*[0-9]-[0-9]/] {
813 throwWarning: tr("{0} together with {1}. Probably {2} is meant.", "{1.key}", "{0.tag}", "{2.key}");
814 group: tr("suspicious tag combination");
815 fixChangeKey: "collection_times => opening_hours";
816 assertMatch: "node amenity=recycling collection_times=\"Mo-Fr 06:00-20:00\"";
817 assertNoMatch: "node amenity=recycling collection_times=\"Mo-Fr 15:00\"";
818 assertNoMatch: "node amenity=recycling collection_times=\"Mo 08:00-11:00\"";
819 assertNoMatch: "node amenity=recycling collection_times=\"Sa[2,4] 8:00-11:00\"";
820}
821*[amenity=recycling][collection_times="24/7"][opening_hours],
822*[amenity=recycling][collection_times ][opening_hours][collection_times=~/[a-z]-[A-Z].*[0-9]-[0-9]/] {
823 throwWarning: tr("{0} together with {1}. Probably {2} is meant.", "{1.key}", "{0.tag}", "{2.key}");
824 group: tr("suspicious tag combination");
825}
826
827/* #19018 */
828way[highway][crossing][highway =~ /^(motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential|service|living_street)$/] {
829 throwWarning: tr("{0} together with {1}. Should be used on a minor highway type or a node", "{1.key}", "{0.tag}");
830 group: tr("suspicious tag combination");
831 fixRemove: "crossing";
832 assertMatch: "way highway=trunk crossing=unmarked";
833 assertNoMatch: "way highway=construction construction=footway crossing=unmarked";
834}
835
836/* #19066 */
837*[amenity=recycling][!/^recycling:/][recycling_type!=centre] {
838 throwWarning: tr("{0} without {1}", "{0.tag}", "recycling:*");
839 group: tr("missing tag");
840}
841*[source:addr][!/^addr:/] {
842 throwWarning: tr("{0} without {1}", "{0.key}", "addr:*");
843 group: tr("missing tag");
844 assertMatch: "node source:addr=postman";
845 assertNoMatch: "node source:addr=postman addr:housenumber=42";
846}
847*[source:maxspeed][!/^maxspeed:?/] {
848 throwWarning: tr("{0} without {1} or {2}", "{0.key}", "maxspeed", "maxspeed:*");
849 group: tr("missing tag");
850}
851
852/* #16898, tower vs. communications_tower, wiki suggests 100m as rough guideline, so we warn for < 75m */
853*[man_made=communications_tower][height][height =~ /^((7[0-4]|[1-6]?[0-9])(\.[0-9]*)?( m)?|(2(4[0-5]|[0-3][0-9])|1?[0-9]?[0-9])((\.[0-9]*)?( ft|\')|\'(11|10|[0-9])(\.[0-9]*)?\"))$/] { /* 75m ~ 246ft ~ 246' */
854 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
855 suggestAlternative: "man_made=tower + tower:type=communication + height";
856 group: tr("suspicious tag combination");
857 assertMatch: "node man_made=communications_tower height=58";
858 assertMatch: "node man_made=communications_tower height=\"74 m\"";
859 assertMatch: "node man_made=communications_tower height=0.8";
860 assertMatch: "node man_made=communications_tower height=245'";
861 assertMatch: "node man_made=communications_tower height=\"224.22 ft\"";
862 assertMatch: "node man_made=communications_tower height=231'10.22\"";
863 assertNoMatch: "node man_made=communications_tower height=\"75 m\"";
864 assertNoMatch: "node man_made=communications_tower height=75.72";
865 assertNoMatch: "node man_made=communications_tower height=\"328.22 ft\"";
866 assertNoMatch: "node man_made=communications_tower height=4358'8\"";
867 assertNoMatch: "node height=4358'";
868}
869
870/* #17296, If the value of fixme is only an osm key, it is often a leftover from a time when the object didn't have this key. The fixme was forgotten to remove when the key was added. Or the value of fixme should be described better what exactly needs to be fixed. */
871*[fixme][count(split(" ", tag("fixme"))) == 1][has_tag_key(tag("fixme"))],
872*[FIXME][count(split(" ", tag("FIXME"))) == 1][has_tag_key(tag("FIXME"))] {
873 throwWarning: tr("{0} together with {1}. Is the fixme fixed?", "{0.tag}", "{0.value}");
874 group: tr("suspicious tag combination");
875 assertMatch: "way name=\"Florist Gump\" fixme=name";
876 assertMatch: "way name=\"Florist Gump\" FIXME=name";
877 assertNoMatch: "way fixme=name";
878 assertNoMatch: "way name=\"Florist Gump\"";
879 assertNoMatch: "way name=\"Florist Gump\" fixme=\"the name might have changed\"";
880}
881
882/* #19094 */
883way[highway][placement=transition][join_list("", uniq_list(tag_regex("^placement:.*$")))==transition],
884way[highway][!placement][/^placement:.*$/][join_list("", uniq_list(tag_regex("^placement:.*$")))==transition] {
885 throwWarning: tr("Use {0} only as value of {1}", "transition", "placement");
886 set PlacementTransitionWarning;
887 fixAdd: "placement=transition";
888 fixRemove: "placement:forward";
889 fixRemove: "placement:backward";
890 fixRemove: "placement:both_ways";
891 assertMatch: "way highway=primary placement=transition placement:both_ways=transition";
892 assertMatch: "way highway=primary placement:backward=transition placement:forward=transition";
893 assertNoMatch: "way highway=primary placement:backward=middle_of:1 placement:forward=transition";
894 assertNoMatch: "way highway=primary placement=middle_of:1 placement:backward=transition placement:forward=transition";
895}
896way[highway][placement][/^placement:.*$/]!.PlacementTransitionWarning,
897way[highway]["placement:forward"]["placement:backward"]!.PlacementTransitionWarning,
898way[highway]["placement:forward"]["placement:both_ways"]!.PlacementTransitionWarning,
899way[highway]["placement:backward"]["placement:both_ways"]!.PlacementTransitionWarning {
900 throwError: tr("{0} together with {1}", "{1.key}", "{2.key}");
901 group: tr("suspicious tag combination");
902 assertMatch: "way highway=primary placement=left_of:2 placement:forward=right_of:1";
903 assertNoMatch: "way highway=primary placement:forward=right_of:1";
904 assertNoMatch: "way highway=primary placement:forward=transition placement:both_ways=transition";
905}
906
907/* #19742 */
908node:righthandtraffic[highway=mini_roundabout][direction=clockwise] {
909 throwWarning: tr("{0} together with {1} at right-hand traffic", "{1.tag}", "{2.tag}");
910 group: tr("suspicious tag combination");
911}
912node!:righthandtraffic[highway=mini_roundabout][direction=anticlockwise] {
913 throwWarning: tr("{0} together with {1} at left-hand traffic", "{1.tag}", "{2.tag}");
914 group: tr("suspicious tag combination");
915}
916
917/* #19603 */
918way[footway][highway][footway=sidewalk ][highway!~/^(path|footway|cycleway|construction|proposed)$/] {
919 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
920 group: tr("suspicious tag combination");
921 suggestAlternative: "sidewalk=left";
922 suggestAlternative: "sidewalk=right";
923 suggestAlternative: "sidewalk=both";
924 suggestAlternative: "sidewalk=separate";
925}
926way[footway][highway][footway!=sidewalk][highway!~/^(path|footway|cycleway|construction|proposed)$/] {
927 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
928 group: tr("suspicious tag combination");
929}
930way[footway][!highway][!/:highway$/],
931way[cycleway][!highway][!/:highway$/] {
932 throwWarning: tr("{0} without {1}", "{0.key}", "{1.key}");
933 group: tr("missing tag");
934 assertNoMatch: "way footway=sidewalk abandoned:highway=unclassified";
935}
936
937/* #17498 */
938way[bicycle][/^cycleway(:|$)/][!/^bicycle:/][bicycle=~/^(no|use_sidepath)$/][/^cycleway(:|$)/!~/^(no|none|separate)$/] {
939 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
940 group: tr("suspicious tag combination");
941 assertMatch: "way bicycle=no cycleway=track";
942 assertMatch: "way bicycle=use_sidepath cycleway=lane";
943 assertMatch: "way bicycle=use_sidepath cycleway:left=lane";
944 assertNoMatch: "way bicycle=use_sidepath cycleway=no";
945 assertNoMatch: "way bicycle=use_sidepath bicycle:backward=yes cycleway:left=lane"; /* instead of :backward, could also be :forward or :conditional */
946 assertNoMatch: "way bicycle=no cycleway:right=no";
947 assertNoMatch: "way bicycle=use_sidepath cycleway:left=none";
948 assertNoMatch: "way highway=cycleway cycleway=separate";
949 assertNoMatch: "way highway=residential bicycle=use_sidepath";
950}
951
952/* #19980 */
953way[highway=living_street][maxspeed][maxspeed=~/mph/][get(split(" ", tag(maxspeed)), 0) > 15],
954way[highway=living_street][maxspeed][maxspeed!~/mph/][get(split(" ", tag(maxspeed)), 0) > 20] {
955 throwWarning: tr("{0} together with {1}", "{0.tag}", "{1.tag}");
956 group: tr("suspicious tag combination");
957 assertNoMatch: "way highway=living_street";
958 assertNoMatch: "way highway=living_street maxspeed=20";
959 assertNoMatch: "way highway=living_street maxspeed=\"15 mph\"";
960 assertNoMatch: "way highway=living_street maxspeed=walk";
961 assertMatch: "way highway=living_street maxspeed=30";
962 assertMatch: "way highway=living_street maxspeed=\"20 mph\"";
963}
964
965/* piste subtags, see #17606 */
966way[piste:type=nordic][!piste:grooming] {
967 throwWarning: tr("No grooming defined for {0} skiing, add {1}", "nordic", "piste:grooming=");
968 group: tr("missing tag");
969 assertMatch: "way piste:type=nordic";
970 assertNoMatch: "way piste:type=nordic piste:grooming=classic";
971}
972
973way[piste:type =~ /^downhill|nordic|skitour$/][!piste:difficulty][count(parent_tags("piste:difficulty")) == 0] {
974 set missing_parent_piste_difficulty;
975}
976way.missing_parent_piste_difficulty:new,
977way.missing_parent_piste_difficulty:in-downloaded-area!:new {
978 throwWarning: tr("No difficulty defined for skiing, add {0}", "piste:difficulty=");
979 group: tr("missing tag");
980 set missing_piste_difficulty;
981 assertNoMatch: "way piste:type=nordic piste:difficulty=easy";
982}
983relation[piste:type =~ /^downhill|nordic|skitour$/][!piste:difficulty] >
984 way[!piste:difficulty]!.missing_piste_difficulty {
985 throwWarning: tr("No difficulty defined for skiing, add {0}", "piste:difficulty=");
986 group: tr("missing tag");
987 set missing_piste_difficulty_both;
988 assertNoMatch: "way piste:type=nordic piste:difficulty=easy";
989}
990way[piste:type=nordic][!piste:difficulty]!.missing_piste_difficulty!.missing_piste_difficulty_both {
991 throwOther: tr("No difficulty defined for skiing, add {0}", "piste:difficulty=");
992 group: tr("missing tag");
993 assertMatch: "way piste:type=nordic";
994 assertNoMatch: "way piste:type=nordic piste:difficulty=easy";
995}
996
997relation[piste:type =~ /^downhill|nordic|skitour$/][!piste:difficulty] {
998 throwOther: tr("No difficulty defined for skiing, add {0}", "piste:difficulty=");
999 group: tr("missing tag");
1000 assertMatch: "relation piste:type=nordic";
1001 assertNoMatch: "relation piste:type=nordic piste:difficulty=easy";
1002}
1003relation[piste:type=nordic][!piste:grooming]{
1004 throwOther: tr("No grooming defined for {0} skiing, add {1}", "nordic", "piste:grooming=");
1005 group: tr("missing tag");
1006 assertMatch: "relation piste:type=nordic";
1007 assertNoMatch: "relation piste:type=nordic piste:grooming=classic";
1008}
Note: See TracBrowser for help on using the repository browser.