Modify

Opened 2 years ago

Closed 2 years 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

Change History (17)

comment:1 by gaben, 2 years ago

Component: Core validatorExternal rule
Owner: changed from team to gaben

An external rule may be a better fit, as the current OSM planet has only ~2000 problematic ways (~3% error rate).

comment:2 by gaben, 2 years 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";
}
Last edited 2 years ago by gaben (previous) (diff)

comment:3 by skyper, 2 years 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 gaben, 2 years 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.)

comment:5 by skyper, 2 years 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 gaben, 2 years 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 skyper, 2 years 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.

Last edited 2 years ago by skyper (previous) (diff)

comment:8 by gaben, 2 years 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 Famlam, 2 years ago

Try "way aeroway=runway ref=\"1- 2\""; for your assert. That way, it understands the space is part of the tag value.

Last edited 2 years ago by Famlam (previous) (diff)

in reply to:  8 comment:10 by skyper, 2 years 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?

in reply to:  5 comment:11 by gaben, 2 years 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 to ref=15/33 or
  • ref=18 /36 to ref=18/36?

I already wrote the Java validator, just in case :)

comment:12 by skyper, 2 years 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"), "-", "/")), " ", "");
Last edited 2 years ago by gaben (previous) (diff)

by gaben, 2 years ago

Attachment: runway.validator.mapcss added

result

comment:13 by gaben, 2 years ago

I plan to add the uploaded rule to the Rules, probably next week.

comment:14 by Famlam, 2 years 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

Last edited 2 years ago by Famlam (previous) (diff)

in reply to:  14 comment:15 by gaben, 2 years 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 gaben, 2 years ago

Resolution: fixed
Status: newclosed

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 :)

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.