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

Last change on this file was 18231, checked in by Don-vip, 2 months ago

fix #20742 - warns about barrier with inappropriate access tags on highway (patch by reichg)

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