Opened 4 years ago
Last modified 4 years ago
#19504 new enhancement
Better documentation of mapcss validator rules syntax
Reported by: | skyper | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Wiki content | Version: | |
Keywords: | mapcss validator rules | Cc: |
Description
Currently, there is no page for the validator rules mapcss syntax. Everything is documented at MapCSSImplementation. This leads to problems, as some specific validator parts like throwError
is not explained at all and any complex example for validator rules is missing. Additionally, it is not clear which part is valid for rules at all and the context is spread across the big page.
Could we somehow update the situation, please, like explicitly mentioning validator one the relevant parts and adding examples for both, styles and rules, could enhance the situation.
E.g.
- I miss a concrete example with
regexp_match
andthrowWarning
using parts of it of the message. - Why are expressions not handled within
throwWarning
and how to nicely get the values of tags which appear in a negative regexpression?
Thanks a lot.
Attachments (0)
Change History (8)
comment:1 by , 4 years ago
follow-up: 3 comment:2 by , 4 years ago
Replying to skyper:
how to nicely get the values of tags which appear in a negative regexpression?
like this?
way[highway][highway!~/^(primary|secondary)$/] { throwWarning: tr("highway not primary or secondary but {0}", "{0.value}"); }
follow-up: 4 comment:3 by , 4 years ago
Replying to Klumbumbus:
The validator specific parts are at wiki:/Help/Validator/MapCSSTagChecker
Oh, I oversaw the second link, did separate them mean-while. Still there is no indication on wiki:/Help/Styles/MapCSSImplementation about what is working in rules (under certain conditions) and what is exclusively for styles.
Replying to Klumbumbus:
Replying to skyper:
how to nicely get the values of tags which appear in a negative reg-expression?
like this?
way[highway][highway!~/^(primary|secondary)$/] { throwWarning: tr("highway not primary or secondary but {0}", "{0.value}"); }
Yeah, thanks, figured that out already. Do not remember exactly, what I had in mind. It was a negative regex including key-value combinations, so I had a list of tags to check which where not present in the selectors.
I have a new problem with a positive regex. How to better format a list:
way[highway][/^.*;lanes$/][!lanes] { throwWarning: tr("{0} with {1} but without {2}", "{0.key}", "{1.key}", "{2.key}"); }
Operators within the definition are not evaluated neither works:
-lanesTags: "join_list(", ", tagregex("^.*:lanes$"))";
I want to get the list of keys or even all tags with key ending :lanes
.
I also tried "Eval Expressions" but I did not figure out how to use regexp_match
and get the job done.
Does subsetting in rules work?
*[type=route_master][route_master =~ /^(bus|share_taxi|trolleybus|train|tram|light_rail|subway|monorail|ferry)$/] { set PtRouteMaster } *[!network].PtRouteMaster, *[!operator].PtRouteMaster { throwWarning: tr("Public transport relation without {0}", "{0.key}"); }
comment:4 by , 4 years ago
Replying to skyper:
…
Does subsetting in rules work?
*[type=route_master][route_master =~ /^(bus|share_taxi|trolleybus|train|tram|light_rail|subway|monorail|ferry)$/] { set PtRouteMaster } *[!network].PtRouteMaster, *[!operator].PtRouteMaster { throwWarning: tr("Public transport relation without {0}", "{0.key}"); }
This works see e.g. source:/trunk/resources/data/validator/highway.mapcss
comment:5 by , 4 years ago
How do I get the used negative regex displayed in the warning?
Following does not work and I get:
SEVERE: Unable to replace argument ^[1-9][0-9]?-[1-9][0-9]{0,2}(-[A-Z])?-j[1-9][0-9j]-[1-9][0-9]?\.[1-9][0-9]?\.[HR]$ in Value `7-342-j1J-1.19` for `gtfs:shape_id: Illegal group reference: group index is missing: java.lang.IllegalArgumentException: Illegal group reference: group index is missing
/* value syntax */ /* ref:IFOPT, gtfs:stop_id, route/shape/trip_id */ *[gtfs:route_id][gtfs:route_id !~ /^[1-9][0-9]?-[1-9][0-9]{0,2}(-[A-Z])?-j[1-9][0-9j]-[1-9][0-9]?$/], *[gtfs:shape_id][gtfs:shape_id !~ /^[1-9][0-9]?-[1-9][0-9]{0,2}(-[A-Z])?-j[1-9][0-9j]-[1-9][0-9]?\.[1-9][0-9]?\.[HR]$/], *[gtfs:trip_id][gtfs:trip_id !~ /^[1-9][0-9]{0,3}\.T[023A]\.[1-9][0-9]?-[1-9][0-9]{0,2}(-[A-Z])?-j[1-9][0-9j]-[1-9][0-9]?\.[1-9][0-9]?\.[HR]$/], *[gtfs:trip_id:sample][gtfs:trip_id:sample !~ /^[1-9][0-9]{0,3}\.T[023A]\.[1-9][0-9]?-[1-9][0-9]{0,2}(-[A-Z])?-j[1-9][0-9j]-[1-9][0-9]?\.[1-9][0-9]?\.[HR]$/], *[gtfs:feed][gtfs:feed !~ /^(([A-Z]{2}-){2}[a-zA-Z]{2}.*|DE-SPNV|DE-S-und-U-Bahnen|DK-Alle)$/], *[network:guid][network:guid !~ /^([A-Z]{2}-){2}[a-zA-Z]{2}.*$/], *[operator:guid][operator:guid !~ /^([A-Z]{2}-){2}[a-zA-Z]{2}.*$/], *[gtfs:source_date][gtfs:source_date !~ /^20(1[7-9]|20)-(0[1-9]|1[0-2])-(3[01]|[12][0-9]|0[1-9])$/], *[ref:IFOPT][ref:IFOPT !~ /^[a-z]{2}:[0-9]{5}:[1-9][0-9]{0,4}(:[0-9]{1,2}(:[1-9][0-9]?)?)?$/], *[gtfs:stop_id][gtfs:stop_id !~ /^[a-z]{2}:[0-9]{4,5}:[1-9][0-9]{0,4}(:[0-9]{1,2}(:[1-9][0-9]?)?)?$/] { throwError: tr("Value `{0}` for `{1}=*` does not match value syntax `{2}`", "{0.value}", "{0.key}", "{1.value}"); group: tr("Public Transport GTFS"); assertMatch: "relation gtfs:route_id=7-342-j1j-1.H"; assertNoMatch: "relation gtfs:route_id=7-342-j1j-1"; assertNoMatch: "relation gtfs:route_id=90-742-B-j20-1"; assertNoMatch: "relation gtfs:route_id=10-11-I-j20-1"; assertMatch: "relation gtfs:shape_id=11-4-I-j20-1.23."; assertNoMatch: "relation gtfs:shape_id=11-4-I-j20-1.23.H"; assertNoMatch: "relation gtfs:shape_id=7-342-j1j-1.51.R"; assertMatch: "relation gtfs:trip_id=108.T2.11-4-I-j20-1.10."; assertNoMatch: "relation gtfs:trip_id=1108.T2.11-4-I-j20-1.10.H"; assertNoMatch: "relation gtfs:trip_id=29.T0.7-342-j1j-1.50.H"; assertNoMatch: "relation gtfs:trip_id=2.TA.90-742-B-j20-1.4.R"; assertMatch: "relation gtfs:feed=DE-SH.NAH"; assertNoMatch: "relation gtfs:feed=df-SL-saarVV"; assertNoMatch: "relation gtfs:feed=DE-SH-NAH.SH"; assertNoMatch: "relation gtfs:feed=DE-BY-VVM-Mittelschwaben"; assertNoMatch: "relation gtfs:feed=DE-SL-saarVV"; assertMatch: "relation gtfs:source_date=2016-09-30"; assertMatch: "relation gtfs:source_date=2020-9-3"; assertMatch: "relation gtfs:source_date=2016-09-30"; assertNoMatch: "relation gtfs:source_date=2020-09-30"; assertMatch: "node ref:IFOPT=+1"; assertMatch: "node ref:IFOPT=aa:aa:09"; assertMatch: "node ref:IFOPT=ch:3001:64883"; assertNoMatch: "node ref:IFOPT=ch:23001:64883"; assertNoMatch: "node ref:IFOPT=de:08315:6504:0:14"; assertNoMatch: "node ref:IFOPT=ch:23005:6"; assertNoMatch: "node gtfs:stop_id=ch:3001:64883"; }
follow-up: 7 comment:6 by , 4 years ago
Damn no word about handling of dots .
as string in regexp_match
. Needs two backslash \\
:
*[gtfs:route_id][gtfs:shape_id]["gtfs:route_id" != get(regexp_match("^(.+)\\.[1-9][0-9]?\\.[HR]$", tag("gtfs:shape_id")), 1)] {
comment:7 by , 4 years ago
Replying to skyper:
Damn no word about handling of dots
.
as string inregexp_match
. Needs two backslash\\
:
*[gtfs:route_id][gtfs:shape_id]["gtfs:route_id" != get(regexp_match("^(.+)\\.[1-9][0-9]?\\.[HR]$", tag("gtfs:shape_id")), 1)] {
Does not work and the assertMatch
does not warn. Below seems to work though:
/* conflicting tags */ /* route_id, shape_id, trip_id */ *[gtfs:route_id][gtfs:shape_id][!(tag("gtfs:route_id") == get(regexp_match("^(.+)\\.[1-9][0-9]?\\.[HR]$", tag("gtfs:shape_id"), "d"), 1))], *[gtfs:route_id][gtfs:trip_id][!(tag("gtfs:route_id") == get(regexp_match("^[1-9][0-9]{0,3}\\.T[023A]\\.(.+)\\.[1-9][0-9]?\\.[HR]$", tag("gtfs:trip_id")), 1))], *[gtfs:route_id][gtfs:trip_id:sample][!(tag("gtfs:route_id") == get(regexp_match("^[1-9][0-9]{0,3}\\.T[023A]\\.(.+)\\.[1-9][0-9]?\\.[HR]$", tag("gtfs:trip_id:sample")), 1))] { throwError: tr("`{1}` is not a substring of `{0}`", "{0.tag}", "{1.tag}"); group: tr("Public Transport GTFS"); assertMatch: "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=7-342-j1j-1"; assertMatch: "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=7-352-j1j-1.17.H"; assertMatch: "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=T7-342-j1j-1.17.H"; assertNoMatch: "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=7-342-j1j-1.17.H"; assertMatch: "relation gtfs:route_id=11-4-I-j20-1 gtfs:trip_id=1108.T2.11-4-I-j20-1.10."; assertMatch: "relation gtfs:route_id=11-4-I-j20-1 gtfs:trip_id=1108.T2.11-5-I-j20-1.10.H"; assertMatch: "relation gtfs:route_id=11-4-I-j20-1 gtfs:trip_id=1108.TB2.11-5-I-j20-1.10.H"; assertNoMatch: "relation gtfs:route_id=11-4-I-j20-1 gtfs:trip_id=1108.T2.11-4-I-j20-1.10.H"; }
comment:8 by , 4 years ago
I have more questions, see #16977.
skyper (comment 7):
Replying to GerdP:
…
It seems that these rules in addresses.mapcss are matched although there is no way in the dataset:
way[addr:interpolation=odd] > node[addr:housenumber][get(split(".", tag("addr:housenumber")/2), 1)=0] { throwWarning: tr("Even housenumber in odd address interpolation."); } way[addr:interpolation=even] > node[addr:housenumber][get(split(".", tag("addr:housenumber")/2), 1)=5] { throwWarning: tr("Odd housenumber in even address interpolation."); }It seems that the selector works in the wrong way?
How about:
way[addr:interpolation =~ /^(even|odd)$/] > node ( set ChildAddrInterpol;} node[addr:housenumber]get(split(".", tag("addr:housenumber")/2), 1)=0].ChildAddrInterpol { throwWarning: tr("Even housenumber in odd address interpolation."); } node[addr:housenumber][get(split(".", tag("addr:housenumber")/2), 1)=5].ChildAddrInterpol { throwWarning: tr("Odd housenumber in even address interpolation."); }Does the order of selectors matter? From which side is evaluated?
Maybe even below will work, which will only look for parent tag:
node[addr:housenumber][parent_tag("addr:interpolation") == odd][get(split(".", tag("addr:housenumber")/2), 1)=0] { throwWarning: tr("Even housenumber in odd address interpolation."); } node[addr:housenumber][parent_tag("addr:interpolation") == even][get(split(".", tag("addr:housenumber")/2), 1)=5] { throwWarning: tr("Odd housenumber in even address interpolation."); }
At least for performance, it would be good to know in which order the selectors are evaluated and if it is useful to add a child/parent selector as class at the end or at the beginning. Can anyone tell me something about it?
The validator specific parts are at wiki:/Help/Validator/MapCSSTagChecker