Opened 21 months ago
Closed 20 months ago
#22822 closed enhancement (fixed)
Add runway heading (ref) validator
Reported by: | gaben | Owned by: | gaben |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | External rule | Version: | |
Keywords: | runway heading ref | Cc: |
Description
Tag:aeroway=runways have reference numbers and the numbers contain the heading of the ways determined by the magnetic azimuth in that place.
OSM wiki is saying:
The two designators of a runway will always differ by 18 (180 degrees) and can have one letter appended (L, C, or R)
L = left
C = center
R = right
in addition:
S = STOL runway
G = glider runway
W = water sealane or waterway and
U = ultralight runway
See also https://en.wikipedia.org/wiki/Runway#Naming
and https://www.faa.gov/documentLibrary/media/advisory_circular/150-5200-35/150_5200_35.pdf
Attachments (1)
Change History (17)
comment:1 by , 21 months ago
Component: | Core validator → External rule |
---|---|
Owner: | changed from | to
comment:2 by , 21 months ago
I wrote a Java version and the following MapCSS rule produces the same output on OSM planet, although more strict (~200 ways) than the original.
/* #22822 - runway heading validator */ way[aeroway=runway][ref][ref =~ /^([0-9]{1,3}[LCRWSGU]? ?- ?[0-9]{1,3}[LCRWSGU]?)$/][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 1)), 1)) >= to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 0)), 1)))][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 1)), 1)) - to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 0)), 1))) != 18], way[aeroway=runway][ref][ref =~ /^([0-9]{1,3}[LCRWSGU]? ?- ?[0-9]{1,3}[LCRWSGU]?)$/][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 0)), 1)) >= to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 1)), 1)))][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 0)), 1)) - to_int(get(regexp_match(".*?([0-9]+).*", get(split("-", tag("ref")), 1)), 1))) != 18], way[aeroway=runway][ref][ref =~ /^([0-9]{1,3}[LCRWSGU]? ?\/ ?[0-9]{1,3}[LCRWSGU]?)$/][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 1)), 1)) >= to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 0)), 1)))][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 1)), 1)) - to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 0)), 1))) != 18], way[aeroway=runway][ref][ref =~ /^([0-9]{1,3}[LCRWSGU]? ?\/ ?[0-9]{1,3}[LCRWSGU]?)$/][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 0)), 1)) >= to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 1)), 1)))][eval(to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 0)), 1)) - to_int(get(regexp_match(".*?([0-9]+).*", get(split("/", tag("ref")), 1)), 1))) != 18] { throwError: tr("Runway reference numbers don''t follow the 180 degree rule"); assertMatch: "way aeroway=runway ref=01-02"; assertMatch: "way aeroway=runway ref=17W-36W"; assertMatch: "way aeroway=runway ref=36W-17W"; assertMatch: "way aeroway=runway ref=01/01"; assertNoMatch: "way aeroway=runway ref=01-19"; assertNoMatch: "way aeroway=runway ref=36/18"; assertNoMatch: "way aeroway=runway ref=3/21"; assertNoMatch: "way aeroway=runway ref=09L/27R"; }
comment:3 by , 21 months ago
According to Tag:aeroway=runway the smallest designator should be listed first, e.g. ref=36/18
is wrong and should be ref=18/36
.
comment:4 by , 21 months ago
Yes, it is wrong. The above rule only checks for the difference. I can add another one with a different, clear message for cases where the first number is used as a bigger designator.
(I'm going to edit the previous comment with the result.)
follow-up: 11 comment:5 by , 21 months ago
Maybe, it is better to split the rule as the wrong separator and the wrong order (bigger designator in front) might work with an auto-fix if the rest is ok.
comment:6 by , 21 months ago
Thanks, good point.
While writing the new rule, I noticed a weird thing:
way[aeroway=runway][ref =~ /^[0-9]- ?[0-9]$/] { throwError: tr("Runway reference - designators should be in increasing order"); assertMatch: "way aeroway=runway ref=2- 1"; }
Spaces for some reason don't want to work in regexes, @skyper do you have an idea what I'm messing up?
comment:7 by , 21 months ago
Try [ ]?
or remove empty spaces in advance.
Edit: There is some escape symbol for assertMatch
but I forgot which one and have no time to look it up, atm. Sorry.
follow-up: 10 comment:8 by , 21 months ago
I'd like to filter by valid values first, so I need spaces. Unfortunately the following doesn't work either :(
way[aeroway=runway][ref =~ /^([0-9]-[ ]?[0-9])$/] { throwError: tr("Runway reference - designators should be in increasing order"); assertMatch: "way aeroway=runway ref=1- 2"; }
comment:9 by , 21 months ago
Try "way aeroway=runway ref=\"1- 2\"";
for your assert. That way, it understands the space is part of the tag value.
comment:10 by , 21 months ago
Replying to Famlam:
Try
"way aeroway=runway ref=\"1- 2\"";
for your assert. That way, it understands the space is part of the tag value.
Thanks, that's what I was looking for.
Replying to gaben:
I'd like to filter by valid values first, so I need spaces. Unfortunately the following doesn't work either :(
way[aeroway=runway][ref =~ /^([0-9]-[ ]?[0-9])$/] { throwError: tr("Runway reference - designators should be in increasing order"); assertMatch: "way aeroway=runway ref=1- 2"; }
I have tested the expression in JOSM search and it works. Was it only a problem with the white space in the value in the assert?
comment:11 by , 21 months ago
Yay, thanks! Now the assertions working fine.
Replying to skyper:
Maybe, it is better to split the rule as the wrong separator and the wrong order (bigger designator in front) might work with an auto-fix if the rest is ok.
I'm not so familiar with MapCSS, how can I auto correct a value with MapCSS, e.g.
ref=15-33
toref=15/33
orref=18 /36
toref=18/36
?
I already wrote the Java validator, just in case :)
comment:12 by , 21 months ago
Looks like MapCSSTagChecker could benefit from more detailed descriptions. Looking through existing rules (trunk/resources/data/validator/), especially numeric.mapcss in your case, might help.
Basically, I comes down to overwriting the tag with fixAdd:
using eval expressions. Be aware of the java docs for MapCSS functions and regular expressions.
For the two easy examples the replace
function should work, e.g.:
fixAdd: concat("ref=", replace(replace(tag("ref"), "-", "/")), " ", "");
follow-up: 15 comment:14 by , 21 months ago
Those rules look monstrous, nice :D
Maybe in the final release version please comment out the asserts of the first check (with add this line to pass tests... I think it's a bug
) or it'll spam my console output continuously :).
p.s.: it seems it's unnecessary to call eval(...)
, it also works without
comment:15 by , 21 months ago
Replying to Famlam:
Those rules look monstrous, nice :D
They are the least understandable "code" I ever wrote, I'm proud of them :D
Maybe in the final release version please comment out the asserts of the first check (with
add this line to pass tests... I think it's a bug
) or it'll spam my console output continuously :).
I'm currently trying to figure out why. It seems the throwError
and assertMatch
goes hand in hand. Without throwError
the assertMatch
is not working.
p.s.: it seems it's unnecessary to call
eval(...)
, it also works without
Thanks, I'll check it.
comment:16 by , 20 months ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Hey there!
The new runway rule has been created and is currently being processed. It's available among the rules in the Rules/Runways section.
If you have any feedback or ideas for improvement, please let me know :)
An external rule may be a better fit, as the current OSM planet has only ~2000 problematic ways (~3% error rate).