Modify

Opened 23 months ago

Last modified 22 months 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 and throwWarning 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 Changed 23 months ago by Klumbumbus

The validator specific parts are at wiki:/Help/Validator/MapCSSTagChecker

comment:2 in reply to:  description ; Changed 23 months ago by Klumbumbus

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}");
}

comment:3 in reply to:  2 ; Changed 23 months ago by skyper

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 in reply to:  3 Changed 23 months ago by skyper

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 Changed 23 months ago by skyper

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";
}
Last edited 23 months ago by skyper (previous) (diff)

comment:6 Changed 22 months ago by skyper

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 in reply to:  6 Changed 22 months ago by skyper

Replying to skyper:

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)]  {

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";
}
Last edited 22 months ago by skyper (previous) (diff)

comment:8 Changed 22 months ago by skyper

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?

Modify Ticket

Change Properties
Set your email in Preferences
Action
as new The owner will remain team.
as The resolution will be set.
to The owner will be changed from team to the specified user.
The owner will change to skyper
as duplicate The resolution will be set to duplicate.The specified ticket will be cross-referenced with this ticket
The owner will be changed from team to anonymous.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.