Search:
Login
Preferences
Help/Guide
About Trac
Register
Forgot your password?
Wiki
Timeline
Changelog
Browse Source
View Tickets
New Ticket
Roadmap
Builds
Sonar
Search
Context Navigation
+1
Start Page
Index
History
Editing Rules/PublicTransportGtfs
Adjust edit area height:
8
12
16
20
24
28
32
36
40
Edit side-by-side
= Public Transport GTFS These rules add additional checks for public transportation tagging. One major part are tags in use with [osmwiki:General_Transit_Feed_Specification GTFS] and [https://ptna.openstreetmap.de/ PTNA]. See [wikitr:/Presets/PublicTransportGtfs Public Transport GTFS preset] for a corresponding preset. == Help needed Please, feel free to: * enhance and update the preset * translate at [https://translations.launchpad.net/josm/trunk/ Launchpad] * create a nice icon. * write me an [osmwww:message/new/skyper email] == Notes * Really beta so far and under development. Expect false positives and lots of changes. * The tagging schema is still under heavy development and therefore the rules might change quite often. == Supported Tags So far checks in the categories `Missing tags`, `Conflicting tags` and `Value syntax` for the following tags exists. * [osmwiki:Key:colour colour] * [osmwiki:Key:duration duration] * [osmwiki:Key:fee fee] * [osmwiki:Key:from from] * [osmwiki:Proposed_features/Key:gtfs:feed gtfs:feed] * [osmwiki:Proposed_features/Key:gtfs:name gtfs:name] ''(no page, yet)'' * [osmwiki:Proposed_features/Key:gtfs:route_id gtfs:route_id] * [osmwiki:Proposed_features/Key:gtfs:shape_id gtfs:shape_id] * [osmwiki:Proposed_features/Key:gtfs:trip_id gtfs:trip_id] ''(no page, yet)'' * [osmwiki:Proposed_features/Key:gtfs:trip_id:sample gtfs:trip_id:sample] ''(no page, yet)'' * [osmwiki:Proposed_features/Key:gtfs:source_date gtfs:source_date] ''(no page, yet)'' * [osmwiki:Key:gtfs:stop_id gtfs:stop_id] * [osmwiki:Key:interval interval] * [osmwiki:Key:local_ref local_ref] * [osmwiki:Key:network network network] * [osmwiki:Key:network:guid network:guid] * [osmwiki:Key:network:short network:short] * [osmwiki:Key:opening_hours opening_hours] * [osmwiki:Key:operator operator] * [osmwiki:Proposed_features/Key:operator:guid operator:guid] * [osmwiki:Key:operator:short operator:short] * [osmwiki:Tag:railway=stop railway=stop] * [osmwiki:Key:ref ref] * [osmwiki:Key:ref:IFOPT ref:IFOPT] * [osmwiki:Key:source source] * [osmwiki:Key:to to] * [osmwiki:Key:website website] == Rules source code == #SourceCode {{{ #!rule meta { title: "Public Transport GTFS"; link: "https://josm.openstreetmap.de/wiki/Rules/PublicTransportGtfs"; description: "Special rules for Public transportation supporting GTFS and tags for PTNA. "; author: "skyper"; version: "0.0.[[revision]]_[[date]]"; } /* Class */ *[type=route_master][route_master =~ /^(bus|share_taxi|trolleybus|train|tram|light_rail|subway|monorail|ferry)$/] { set PtRouteMaster; } *[type=route][route =~ /^(bus|share_taxi|trolleybus|train|tram|light_rail|subway|monorail|ferry)$/] { set PtRoute; } /* Rule */ /* {0.tag} without {1.key} (error level) */ /* route_master and route relations, ToDo ferry on ways */ /* {0.tag} without {1.key} (warning level) */ /* stop_position, platform */ *[public_transport][public_transport =~ /^(platform|stop_position)$/][!local_ref], *[public_transport][public_transport =~ /^(platform|stop_position)$/][!network] { throwWarning: tr("`{0}` without `{1}*`.", "{0.tag}", "{2.tag}"); group: tr("Public Transport: missing tag"); assertMatch: "node public_transport=stop_position"; assertNoMatch: "node public_transport=stop_position local_ref=2"; assertMatch: "way public_transport=platform"; assertNoMatch: "way public_transport=platform network=blabla"; } /* stop_area */ /* route_master and route relations, ToDo ferry on ways */ relation.PtRouteMaster[type=route_master][!colour], relation.PtRouteMaster[type=route_master][!fee], relation.PtRouteMaster[type=route_master][!gtfs:name], relation.PtRouteMaster[type=route_master][!gtfs:route_id], relation.PtRouteMaster[type=route_master][!gtfs:source_date], relation.PtRouteMaster[type=route_master][!network], relation.PtRouteMaster[type=route_master][!network:short], relation.PtRouteMaster[type=route_master][!operator], relation.PtRouteMaster[type=route_master][!operator:short], relation.PtRouteMaster[type=route_master][!ref], relation.PtRouteMaster[type=route_master][!source], relation.PtRouteMaster[type=route_master][!website], relation.PtRoute[type=route][!colour], relation.PtRoute[type=route][!duration]["public_transport:version"=2], relation.PtRoute[type=route][!interval]["public_transport:version"=2], relation.PtRoute[type=route][!fee], relation.PtRoute[type=route][!from]["public_transport:version"=2], relation.PtRoute[type=route][!to]["public_transport:version"=2], relation.PtRoute[type=route][!gtfs:name]["public_transport:version"=1], relation.PtRoute[type=route][!gtfs:route_id], relation.PtRoute[type=route][!gtfs:source_date], relation.PtRoute[type=route][!network], relation.PtRoute[type=route][!network:short], relation.PtRoute[type=route][!opening_hours], relation.PtRoute[type=route][!operator], relation.PtRoute[type=route][!operator:short], relation.PtRoute[type=route][!ref], relation.PtRoute[type=route][!source], relation.PtRoute[type=route][!website] { throwWarning: tr("Public transport {0} relation without `{1}*`.", "{1.value}", "{2.tag}"); group: tr("Public Transport: missing tag"); assertMatch: "relation type=route route=train"; assertMatch: "relation type=route_master route_master=bus"; assertNoMatch: "relation type=route route=train network:short=MVV"; assertNoMatch: "relation type=route_master route_master=bus colour=green"; } /* {0.tag} without {1.key} or {2.key} (warning level) */ /* stop_position, platform */ *[public_transport][public_transport =~ /^(platform|stop_area|stop_position)$/][!ref:IFOPT][!gtfs:stop_id] { throwWarning: tr("`{0}` without `{1}*` or `{2}*`.", "{0.tag}", "{2.tag}", "{3.tag}"); group: tr("Public Transport: missing tag"); assertMatch: "node public_transport=stop_position train=yes railway=halt"; assertNoMatch: "node public_transport=stop_position train=yes railway=stop ref:IFOPT=ch:06666:4"; } /* {0.tag} without {1.key}, {2.key} or {3.key} (warning level) */ /* stop_position, platform */ /* stop_area */ /* route_master and route relations, ToDo ferry on ways */ relation.PtRouteMaster[gtfs:route_id][!gtfs:feed][!network:guid][!operator:guid], relation.PtRoute["public_transport:version"=2][!gtfs:shape_id][!gtfs:trip_id][!gtfs:trip_id:sample], relation.PtRoute[gtfs:route_id][!gtfs:feed][!network:guid][!operator:guid], relation.PtRoute[gtfs:shape_id][!gtfs:feed][!network:guid][!operator:guid], relation.PtRoute[gtfs:trip_id][!gtfs:feed][!network:guid][!operator:guid], relation.PtRoute[gtfs:trip_id:sample][!gtfs:feed][!network:guid][!operator:guid] { throwWarning: tr("Public transport relation with `{0}` but none of `{1}*`, `{2}*` or `{3}*`.", "{1.tag}", "{2.tag}", "{3.tag}", "{4.tag}"); group: tr("Public Transport: missing tag"); assertMatch: "relation type=route_master route_master=train gtfs:route_id=0-7-242-19j-1"; assertMatch: "relation type=route route=bus gtfs:shape_id=0-7-242-19j-1.26.R"; assertNoMatch: "relation type=route_master route_master=train gtfs:route_id=0-7-242-19j-1 network:guid=DE-BY-MVV"; assertNoMatch: "relation type=route_master route=bus colour=green"; } /* {0.tag} and {1.tag} without {2.key}, {3.key} or {4.key} (warning level) */ /* stop_position, platform */ node[public_transport][public_transport=stop_position][train=yes][railway!=stop], *[public_transport][public_transport =~ /^(platform|stop_position)$/][train=yes][!ref] { throwWarning: tr("`{0}` with `{1}` but without `{2}`.", "{0.tag}", "{2.tag}", "{3.tag}"); group: tr("Public Transport: missing tag"); assertMatch: "node public_transport=stop_position train=yes railway=halt"; assertNoMatch: "node public_transport=stop_position train=yes railway=stop ref=2"; } /* {0.tag} and {1.tag} without {2.key} (warning level) */ /* platform */ *[public_transport=platform][highway=bus_stop][bus!=yes][share_taxi!=yes][trolleybus=yes] { throwWarning: tr("`{0}` with `{1}` but none of `{2}*`, `{3}*` or `{4}*`.", "{0.tag}", "{1.tag}", "{2.tag}", "{3.tag}", "{4.tag}"); group: tr("Public Transport GTFS: missing tag"); assertMatch: "node public_transport=platrom highway=bus_stop"; assertNoMatch: "node public_transport=platrom highway=bus_stop bus=yes"; } /* value syntax */ /* FIXME: Get proper syntax as regex displayed. /* ref:IFOPT, gtfs:stop_id, route/shape/trip_id */ *[gtfs:route_id][gtfs:route_id !~ /^[0-9]{1,2}-[1-9][0-9]{0,2}(-[A-Z])?-j[1-9][0-9j]-[1-9][0-9]?$/], *[gtfs:shape_id][gtfs:shape_id !~ /^[0-9]{1,2}-[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]\.[0-9]{1,2}-[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]\.[0-9]{1,2}-[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.", "{0.value}", "{0.key}"); /* throwError: tr("Value `{0}` for `{1}=*` does not match value syntax `{2}`.", "{0.value}", "{0.key}", "{1.value}"); */ group: tr("Public Transport GTFS: value syntax"); 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=1108.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"; } /* ---------------- * conflicting tags */ /* route_id, shape_id, trip_id */ *[gtfs:trip_id][gtfs:trip_id:sample][!(tag("gtfs:trip_id") == tag("gtfs:trip_id:sample"))] { throwError: tr("`{1}` and `{0}` are not equal.", "{0.tag}", "{1.tag}"); group: tr("Public Transport GTFS: conflicting tags"); } *[gtfs:shape_id][gtfs:trip_id][!(tag("gtfs:shape_id") == get(regexp_match("^[1-9][0-9]{0,3}\\.T[023A]\\.(.+)$", tag("gtfs:trip_id")), 1))], *[gtfs:shape_id][gtfs:trip_id:sample][!(tag("gtfs:shape_id") == get(regexp_match("^[1-9][0-9]{0,3}\\.T[023A]\\.(.+)$", tag("gtfs:trip_id:sample")), 1))], *[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: conflicting tags"); 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"; } /* route_id parent */ /* Does not work */ /* relation.PtRouteMaster[gtfs:route_id] > * { * set ChildMasterRoute_id; * } */ relation[type=route_master][gtfs:route_id] > relation { set ChildMasterRoute_id; } /* FIXME: How to display the key-value of the parent? */ relation.ChildMasterRoute_id[gtfs:shape_id][parent_tag("gtfs:route_id")][!gtfs:route_id][!(parent_tag("gtfs:route_id") == replace(tag("gtfs:shape_id"), "\\.\\d+\\.[HR]$", ""))], relation.ChildMasterRoute_id[gtfs:trip_id][parent_tag("gtfs:route_id")][!gtfs:route_id][!gtfs:shape_id][!(parent_tag("gtfs:route_id") == get(regexp_match("^\\d+\\.T[023A]\\.(.+)\\.\\d+\\.[HR]$", tag("gtfs:trip_id")), 1))], relation.ChildMasterRoute_id[gtfs:trip_id:sample][parent_tag("gtfs:route_id")][!gtfs:route_id][!gtfs:shape_id][!(parent_tag("gtfs:route_id") == get(regexp_match("^\\d+\\.T[023A]\\.(.+)\\.\\d+\\.[HR]$", tag("gtfs:trip_id:sample")), 1))], relation.ChildMasterRoute_id[gtfs:route_id][parent_tag("gtfs:route_id")][!(parent_tag("gtfs:route_id") == tag("gtfs:route_id"))] { throwWarning: tr("`{0}` conflicts with `gtfs:route_id=*` of the `route_master` relation.", "{1.tag}"); /* throwWarning: tr("`{0}` differs to `route_id={1}` of the `route_master` relation.", "{1.tag}", "{2.value}"); */ group: tr("Public Transport GTFS: conflicting tags"); } }}}
Note:
See
WikiFormatting
and
TracWiki
for help on editing wiki content.
Change information
Your email or username:
E-mail address and name can be saved in the
Preferences
Comment about this change (optional):
Note:
See
TracWiki
for help on using the wiki.