Changes between Version 38 and Version 39 of Rules/PublicTransportGtfs
- Timestamp:
- 2022-02-08T13:39:46+01:00 (4 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Rules/PublicTransportGtfs
v38 v39 63 63 */ 64 64 65 relation[type=route_master][route_master =~ / ^(bus|coach|share_taxi|trolleybus|train|light_rail|subway|tram|monorail|funicular|ferry|aerialway|school_bus|walking_bus)$/] {65 relation[type=route_master][route_master =~ /bus|coach|share_taxi|trolleybus|train|light_rail|subway|tram|monorail|funicular|ferry|aerialway|school_bus|walking_bus/] { 66 66 set PtRouteMaster; 67 67 } 68 68 /* Note: Only relations, routes on way are not supported */ 69 relation[type=route ][route =~ / ^(bus|coach|share_taxi|trolleybus|train|light_rail|subway|tram|monorail|funicular|ferry|aerialway|school_bus|walking_bus)$/] {69 relation[type=route ][route =~ /bus|coach|share_taxi|trolleybus|train|light_rail|subway|tram|monorail|funicular|ferry|aerialway|school_bus|walking_bus/] { 70 70 set PtRoute; 71 71 } … … 75 75 } 76 76 77 *[bus!=yes][coach!=yes][share_taxi!=yes][trolleybus!=yes][train!=yes][light_rail!=yes][subway!=yes][tram!=yes][monorail!=yes][funicular!=yes][ferry!=yes][!aerialway] { 77 *[/bus|coach|share_taxi|trolleybus|train|light_rail|subway|tram|monorail|funicular|ferry/ =~ /yes|no/][!aerialway] { 78 set PtVehicle; 79 } 80 81 *[/bus|coach|share_taxi|trolleybus|train|light_rail|subway|tram|monorail|funicular|ferry/ !~ /yes/][!aerialway] { 78 82 set noPtVehicle; 79 83 } 80 84 81 *[public_transport =~ / ^(platform|stop_area|stop_position)$/] {85 *[public_transport =~ /platform|stop_area|stop_position/] { 82 86 set PtStop; 83 87 } … … 100 104 101 105 /* stop_area, stop_position, platform */ 102 *[public_transport =~ / ^(platform|stop_position)$/][public_transport][!local_ref],106 *[public_transport =~ /platform|stop_position/][public_transport][!local_ref], 103 107 *.PtStop[public_transport][!network] { 104 108 throwWarning: tr("`{0}` without `{1}*`.", "{1.tag}", "{2.tag}"); … … 156 160 assertNoMatch: "relation type=route route=train"; 157 161 assertNoMatch: "relation type=route_master route_master=bus"; 158 159 162 } 160 163 … … 200 203 /* ToDo: Check against parent relation vehicle type */ 201 204 /* ToDo: Extend to check for parent relation value and offer fix */ 202 /* *[public_transport =~ / ^(platform|stop_position)$/][highway!=bus_stop][public_transport].noPtVehicle { */205 /* *[public_transport =~ /platform|stop_position/][highway!=bus_stop][public_transport].noPtVehicle { */ 203 206 /* needs check the other way around as access tags are problematic with ways */ 204 node[public_transport=stop_position] [highway!=bus_stop].noPtVehicle {207 node[public_transport=stop_position].noPtVehicle { 205 208 throwWarning: tr("`{0}` without serving vehicle type specified.", "{0.tag}"); 206 209 group: tr("Public Transport GTFS: missing tag"); 207 210 assertMatch: "node public_transport=stop_position"; 208 211 assertNoMatch: "node public_transport=stop_position bus=yes"; 209 assertNoMatch: "node public_transport=stop_position highway=bus_stop"; 210 } 211 212 /* {0.tag} without any (info level) */ 212 } 213 213 214 214 /* platform */ 215 /* node[public_transport=platform][highway!=bus_stop].noPtVehicle { 216 throwInfo: tr("`{0}` without serving vehicle type specified.", "{0.tag}"); 217 group: tr("Public Transport GTFS: missing tag"); 218 assertMatch: "node public_transport=platform"; 219 assertNoMatch: "node public_transport=platform bus=yes"; 220 assertNoMatch: "node public_transport=platform highway=bus_stop"; 221 } */ 215 /* access tags are only useful on stop_position */ 216 area[public_transport=platform][highway].PtVehicle { 217 throwWarning: tr("`Problematic access tag on {0} together with {1}. Only stop positions need it, according to the wiki.", "{0.tag}", "{1.tag}"); 218 group: tr("Public Transport GTFS: suspicious tag combination"); 219 assertMatch: "way public_transport=platform highway=platform bus=yes"; 220 assertNoMatch: "way public_transport=platform bus=yes"; 221 } 222 area[public_transport=platform][!highway].PtVehicle { 223 throwWarning: tr("`Access tag on {0}. Only stop positions need it, according to the wiki.", "{0.tag}"); 224 group: tr("Public Transport GTFS: suspicious tag combination"); 225 assertMatch: "way public_transport=platform bus=yes"; 226 assertNoMatch: "way public_transport=platform"; 227 } 228 229 /* {0.tag} with any (info level) */ 230 231 /* platform */ 232 /* access tags are only useful on stop_position */ 233 node[public_transport=platform].PtVehicle { 234 throwOther: tr("`Serving vehicle type specified on {0}. Only stop positions need it, according to the wiki.", "{0.tag}"); 235 group: tr("Public Transport GTFS: suspicious tag combination"); 236 assertMatch: "node public_transport=platform bus=yes"; 237 assertNoMatch: "node public_transport=platform"; 238 } 222 239 223 240 /* {0.tag} and {1.tag} without {2.key} (warning level) */ 224 241 225 242 /* stop_position, platform */ 226 node[public_transport=stop_position][train=yes][railway!=stop][public_transport], 227 *[public_transport =~ /^(platform|stop_position)$/][train=yes][!ref][public_transport] { 228 throwWarning: tr("`{0}` with `{1}` but without `{2}`.", "{3.tag}", "{1.tag}", "{2.tag}"); 243 node[public_transport=stop_position][train=yes][railway!=stop], 244 node[public_transport=stop_position][train=yes][!ref], 245 *[public_transport=platform][railway=platform][!ref] { 246 throwWarning: tr("`{0}` with `{1}` but without `{2}`.", "{0.tag}", "{1.tag}", "{2.tag}"); 229 247 group: tr("Public Transport GTFS: missing tag"); 230 248 assertMatch: "node public_transport=stop_position train=yes railway=halt"; … … 235 253 236 254 /* platform */ 237 *[highway=bus_stop][public_transport =~ /^(platform|stop_position)$/][bus!=yes][share_taxi!=yes][trolleybus!=yes][public_transport] { 255 /*[highway=bus_stop][public_transport =~ /^(platform|stop_position)$/][bus!=yes][share_taxi!=yes][trolleybus!=yes][public_transport] { 238 256 throwWarning: tr("`{0}` with `{1}` but none of `{2}*`, `{3}*` or `{4}*`.", "{5.tag}", "{0.tag}", "{2.tag}", "{3.tag}", "{4.tag}"); 239 257 group: tr("Public Transport GTFS: missing tag"); 240 258 assertMatch: "node public_transport=platform highway=bus_stop"; 241 259 assertNoMatch: "node public_transport=platform highway=bus_stop bus=yes"; 242 } 260 } */ 243 261 244 262 /* One of many {0.key} but no {1.key} */ 245 263 246 264 /* gtfs:release_date */ 247 *[/(^gtfs: |:gtfs|^ref:IFOPT)/][!gtfs:release_date] {265 *[/(^gtfs:.+|.+:gtfs|^ref:IFOPT)$/][!gtfs:release_date] { 248 266 throwWarning: tr("GTFS tag without `{0}*`.", "{1.tag}"); 249 267 group: tr("Public Transport GTFS: missing tag"); … … 252 270 assertMatch: "node ref:IFOPT=1"; 253 271 assertNoMatch: "node ref:IFOPT=1 gtfs:release_date=2019"; 254 } 272 } 255 273 256 274 /* ----------------------- 257 * value syntax 275 * value syntax 258 276 */ 259 277 260 278 /* route_id, shape_id, trip_id */ 261 /* FIXME: Split checks per feed instead of one global regex. 279 /* FIXME: Split checks per feed instead of one global regex. */ 262 280 /* FIXME: Get proper syntax as regex displayed. */ 263 281 *[gtfs:route_id ][gtfs:route_id !~ /^[0-9]{1,2}-[A-Z]?[0-9]{1,3}[A-Z]?(-[0-9A-Z])?-[js]?[1-9][0-9j]a?-[0-9]+(;[ ]?[0-9]{1,2}-[A-Z]?[0-9]{1,3}[A-Z]?(-[0-9A-Z])?-[js]?[1-9][0-9j]a?-[0-9]+)*$/], … … 293 311 *[network:guid ][network:guid !~ /^(([A-Z]{2}-){2}[a-zA-Z]{2}.*|[A-Z]{2}-Flixbus|BO-C-Cochabamba|(CH|LU)-[a-zA-Z]{3,}|CO-BOY-[A-Z].+|ES-AR-Z-[A-Z].+|FR-IDF-(r|[a-zA-Z]{3,}.*)|MG-T-Antananarivo)$/], 294 312 *[operator:guid][operator:guid !~ /^(([A-Z]{2}-){2}[a-zA-Z]{2}.*|[A-Z]{2}-Flixbus|BO-C-Cochabamba|(CH|LU)-[a-zA-Z]{3,}|CO-BOY-[A-Z].+|ES-AR-Z-[A-Z].+|FR-IDF-(r|[a-zA-Z]{3,}.*)|MG-T-Antananarivo)$/], 295 *[gtfs:release_date][gtfs:release_date !~ /^20(1[ 7-9]|2[0-2])-(0[1-9]|1[0-2])-(3[01]|[12][0-9]|0[1-9])$/] {313 *[gtfs:release_date][gtfs:release_date !~ /^20(1[89]|2[0-2])-(0[1-9]|1[0-2])-(3[01]|[12][0-9]|0[1-9])$/] { 296 314 throwError: tr("Value `{0}` for `{1}=*` does not match value syntax.", "{0.value}", "{0.key}"); 297 315 /* throwError: tr("Value `{0}` for `{1}=*` does not match value syntax `{2}`.", "{0.value}", "{0.key}", "{1.value}"); */ … … 352 370 353 371 /* short ref:IFOPT */ 354 node[public_transport=stop_position][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/],355 node[public_transport=stop_position][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/],356 node[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/],357 node[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/],358 way[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){3}$/],359 way[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){3}$/],372 node[public_transport=stop_position][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/], 373 node[public_transport=stop_position][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/], 374 node[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/], 375 node[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/], 376 way[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){3}$/], 377 way[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){3}$/], 360 378 relation[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){3}$/], 361 379 relation[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){3}$/] { … … 368 386 assertNoMatch: "relation public_transport=platform ref:IFOPT=de:09162:1179:30"; 369 387 } 370 way[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/],371 way[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/],388 way[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/], 389 way[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/], 372 390 relation[public_transport=platform ][ref:IFOPT ]!.ErrorSyntaxIFOPT[ref:IFOPT !~ /^.+(:.+){4}$/], 373 391 relation[public_transport=platform ][gtfs:stop_id]!.ErrorSyntaxIFOPT[gtfs:stop_id !~ /^.+(:.+){4}$/], … … 413 431 /* Permanet links to PTNA GTFS */ 414 432 /* *[JOSM_search("ptna.openstreetmap.de/gtfs")][!JOSM_search("^.*network=([a-zA-Z]+[-]){2,}\\d{4}(-\\d\\d){2}.*$")] { */ 415 *[url =~ / ^.*ptna\.openstreetmap\.de\/gtfs.+$/][url !~ /^.*(network=([a-zA-Z]+[-]){2,}|release_date=)\d{4}(-\d\d){2}.*$/],416 *[website =~ / ^.*ptna\.openstreetmap\.de\/gtfs.+$/][website !~ /^.*(network=([a-zA-Z]+[-]){2,}|release_date=)\d{4}(-\d\d){2}.*$/],417 *[source =~ / ^.*ptna\.openstreetmap\.de\/gtfs.+$/][source !~ /^.*(network=([a-zA-Z]+[-]){2,}|release_date=)\d{4}(-\d\d){2}.*$/] {433 *[url =~ /.*ptna\.openstreetmap\.de\/gtfs.+/][url !~ /.*(network=([a-zA-Z]+[-]){2,}|release_date=)\d{4}(-\d\d){2}.*/], 434 *[website =~ /.*ptna\.openstreetmap\.de\/gtfs.+/][website !~ /.*(network=([a-zA-Z]+[-]){2,}|release_date=)\d{4}(-\d\d){2}.*/], 435 *[source =~ /.*ptna\.openstreetmap\.de\/gtfs.+/][source !~ /.*(network=([a-zA-Z]+[-]){2,}|release_date=)\d{4}(-\d\d){2}.*/] { 418 436 throwWarning: tr("Relative GTFS url in `{0}=*`. Add `{1}` behind the feed or network value.", "{0.key}", "&release_date=*"); 419 437 assertMatch: "node source=\"https://ptna.openstreetmap.de/gtfs/19\""; … … 427 445 428 446 /* ref:IFOPT, gtfs:stop_id, local_ref */ 429 /* *[public_transport][public_transport =~ / ^(platform|stop_position)$/][!(tag("local_ref") == get(regexp_match("^(.+:){4}([A-Z]+[ ]?)?([1-9][0-9]{0,2}[A-Z]?)", tag("ref:IFOPT")), 3))][local_ref][ref:IFOPT], */430 /* *[public_transport][public_transport =~ / ^(platform|stop_position)$/][!(tag("local_ref") == get(regexp_match("^(.+:){4}([A-Z]+[ ]?)?([1-9][0-9]{0,2}[A-Z]?)", tag("gtfs:stop_id")), 3))][local_ref][ref:IFOPT] { */431 *[local_ref][ref:IFOPT]!.ErrorSyntaxIFOPT[public_transport =~ / ^(platform|stop_position)$/][!(tag("local_ref") == get(regexp_match("^(.+:){4}(.+)", tag("ref:IFOPT")), 2))],432 *[local_ref][ref:IFOPT]!.ErrorSyntaxIFOPT[public_transport =~ / ^(platform|stop_position)$/][!(tag("local_ref") == get(regexp_match("^(.+:){4}(.+)", tag("gtfs:stop_id")), 2))] {447 /* *[public_transport][public_transport =~ /platform|stop_position/][!(tag("local_ref") == get(regexp_match("^(.+:){4}([A-Z]+[ ]?)?([1-9][0-9]{0,2}[A-Z]?)", tag("ref:IFOPT")), 3))][local_ref][ref:IFOPT], */ 448 /* *[public_transport][public_transport =~ /platform|stop_position)][!(tag("local_ref") == get(regexp_match("^(.+:){4}([A-Z]+[ ]?)?([1-9][0-9]{0,2}[A-Z]?)", tag("gtfs:stop_id")), 3))][local_ref][ref:IFOPT] { */ 449 *[local_ref][ref:IFOPT]!.ErrorSyntaxIFOPT[public_transport =~ /platform|stop_position/][!(tag("local_ref") == get(regexp_match("^(.+:){4}(.+)", tag("ref:IFOPT")), 2))], 450 *[local_ref][ref:IFOPT]!.ErrorSyntaxIFOPT[public_transport =~ /platform|stop_position/][!(tag("local_ref") == get(regexp_match("^(.+:){4}(.+)", tag("gtfs:stop_id")), 2))] { 433 451 throwWarning: tr("`{0}` conflicts with `{1}`.", "{0.tag}", "{1.tag}"); 434 452 group: tr("Public Transport GTFS: conflicting tags"); … … 454 472 *[gtfs:shape_id][gtfs:trip_id ]!.MultipleID!.GtfsIdSyntax[!(tag("gtfs:shape_id") == get(regexp_match("^[1-9][0-9]{0,3}\\.T[023A]\\.(.+)$", tag("gtfs:trip_id")), 1))], 455 473 *[gtfs:shape_id][gtfs:trip_id:sample]!.MultipleID!.GtfsIdSyntax[!(tag("gtfs:shape_id") == get(regexp_match("^[1-9][0-9]{0,3}\\.T[023A]\\.(.+)$", tag("gtfs:trip_id:sample")), 1))] { 456 throwError: tr("`{1}` is not a substring of `{0}`.", "{0.tag}", "{1.tag}"); 474 throwError: tr("`{1}` is not a substring of `{0}`.", "{0.tag}", "{1.tag}"); 457 475 group: tr("Public Transport GTFS: conflicting tags"); 458 476 assertMatch: "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=7-352-j1j-1.17.H";
