Changes between Version 8 and Version 9 of Rules/PublicTransportGtfs


Ignore:
Timestamp:
2020-07-17T16:55:16+02:00 (6 years ago)
Author:
skyper
Comment:

add more checks

Legend:

Unmodified
Added
Removed
Modified
  • Rules/PublicTransportGtfs

    v8 v9  
    1414
    1515== Supported Tags
    16 === Value syntax check
    17 * [osmwiki:Key:ref:IFOPT ref:IFOPT]
    18 * [osmwiki:Key:gtfs:stop_id gtfs:stop_id]
    19 * [osmwiki:Key:network:guid network:guid]
    20 * [osmwiki:Proposed_features/Key:operator:guid operator:guid]
     16So far checks in the categories `Missing tags`, `Conflicting tags` and `Value syntax` for the following tags exists.
     17
     18* [osmwiki:Key:colour colour]
     19* [osmwiki:Key:duration duration]
     20* [osmwiki:Key:fee fee]
     21* [osmwiki:Key:from from]
    2122* [osmwiki:Proposed_features/Key:gtfs:feed gtfs:feed]
     23* [osmwiki:Proposed_features/Key:gtfs:name gtfs:name] ''(no page, yet)''
    2224* [osmwiki:Proposed_features/Key:gtfs:route_id gtfs:route_id]
    2325* [osmwiki:Proposed_features/Key:gtfs:shape_id gtfs:shape_id]
     
    2527* [osmwiki:Proposed_features/Key:gtfs:trip_id:sample gtfs:trip_id:sample] ''(no page, yet)''
    2628* [osmwiki:Proposed_features/Key:gtfs:source_date gtfs:source_date] ''(no page, yet)''
     29* [osmwiki:Key:gtfs:stop_id gtfs:stop_id]
     30* [osmwiki:Key:interval interval]
     31* [osmwiki:Key:local_ref local_ref]
     32* [osmwiki:Key:network network network]
     33* [osmwiki:Key:network:guid network:guid]
     34* [osmwiki:Key:network:short network:short]
     35* [osmwiki:Key:opening_hours opening_hours]
     36* [osmwiki:Key:operator operator]
     37* [osmwiki:Proposed_features/Key:operator:guid operator:guid]
     38* [osmwiki:Key:operator:short operator:short]
     39* [osmwiki:Tag:railway=stop railway=stop]
     40* [osmwiki:Key:ref ref]
     41* [osmwiki:Key:ref:IFOPT ref:IFOPT]
     42* [osmwiki:Key:source source]
     43* [osmwiki:Key:to to]
     44* [osmwiki:Key:website website]
    2745
    2846== Rules source code == #SourceCode
     
    3553  author: "skyper";
    3654  version: "0.0.[[revision]]_[[date]]";
     55}
     56/*<?xml version="1.0" encoding="UTF-8"?>*/
     57/*
     58 *  Collection of rules for public transport tagging and GTFS and PTNA
     59 */
     60
     61/*  Class  */
     62
     63*[type=route_master][route_master =~ /^(bus|share_taxi|trolleybus|train|tram|light_rail|subway|monorail|ferry)$/] {
     64  set PtRouteMaster;
     65}
     66
     67*[type=route][route =~ /^(bus|share_taxi|trolleybus|train|tram|light_rail|subway|monorail|ferry)$/] {
     68  set PtRoute;
     69}
     70
     71
     72/*  Rule  */
     73/* {0.tag} without {1.key} (error level) */
     74
     75/* route_master and route relations, ToDo ferry on ways */
     76
     77/* {0.tag} without {1.key} (warning level) */
     78/* stop_position, platform */
     79*[public_transport][public_transport =~ /^(platform|stop_position)$/][!local_ref],
     80*[public_transport][public_transport =~ /^(platform|stop_position)$/][!network] {
     81  throwWarning: tr("`{0}` without `{1}*`.", "{0.tag}", "{2.tag}");
     82  group: tr("Public Transport: missing tag");
     83  assertMatch:   "node public_transport=stop_position";
     84  assertNoMatch: "node public_transport=stop_position local_ref=2";
     85  assertMatch:   "way public_transport=platform";
     86  assertNoMatch: "way public_transport=platform network=blabla";
     87}
     88
     89/* stop_area */
     90
     91/* route_master and route relations, ToDo ferry on ways */
     92relation.PtRouteMaster[type=route_master][!colour],
     93relation.PtRouteMaster[type=route_master][!fee],
     94relation.PtRouteMaster[type=route_master][!gtfs:name],
     95relation.PtRouteMaster[type=route_master][!gtfs:route_id],
     96relation.PtRouteMaster[type=route_master][!gtfs:source_date],
     97relation.PtRouteMaster[type=route_master][!network],
     98relation.PtRouteMaster[type=route_master][!network:short],
     99relation.PtRouteMaster[type=route_master][!operator],
     100relation.PtRouteMaster[type=route_master][!operator:short],
     101relation.PtRouteMaster[type=route_master][!ref],
     102relation.PtRouteMaster[type=route_master][!source],
     103relation.PtRouteMaster[type=route_master][!website],
     104relation.PtRoute[type=route][!colour],
     105relation.PtRoute[type=route][!duration]["public_transport:version"=2],
     106relation.PtRoute[type=route][!interval]["public_transport:version"=2],
     107relation.PtRoute[type=route][!fee],
     108relation.PtRoute[type=route][!from]["public_transport:version"=2],
     109relation.PtRoute[type=route][!to]["public_transport:version"=2],
     110relation.PtRoute[type=route][!gtfs:name]["public_transport:version"=1],
     111relation.PtRoute[type=route][!gtfs:route_id],
     112relation.PtRoute[type=route][!gtfs:source_date],
     113relation.PtRoute[type=route][!network],
     114relation.PtRoute[type=route][!network:short],
     115relation.PtRoute[type=route][!opening_hours],
     116relation.PtRoute[type=route][!operator],
     117relation.PtRoute[type=route][!operator:short],
     118relation.PtRoute[type=route][!ref],
     119relation.PtRoute[type=route][!source],
     120relation.PtRoute[type=route][!website] {
     121  throwWarning: tr("Public transport {0} relation without `{1}*`.", "{1.value}", "{2.tag}");
     122  group: tr("Public Transport: missing tag");
     123  assertMatch:   "relation type=route route=train";
     124  assertMatch:   "relation type=route_master route_master=bus";
     125  assertNoMatch: "relation type=route route=train network:short=MVV";
     126  assertNoMatch: "relation type=route_master route_master=bus colour=green";
     127}
     128
     129/* {0.tag} without {1.key} or {2.key} (warning level) */
     130/* stop_position, platform */
     131*[public_transport][public_transport =~ /^(platform|stop_area|stop_position)$/][!ref:IFOPT][!gtfs:stop_id] {
     132  throwWarning: tr("`{0}` without `{1}*` or `{2}*`.", "{0.tag}", "{2.tag}", "{3.tag}");
     133  group: tr("Public Transport: missing tag");
     134  assertMatch:   "node public_transport=stop_position train=yes railway=halt";
     135  assertNoMatch: "node public_transport=stop_position train=yes railway=stop ref:IFOPT=ch:06666:4";
     136}
     137
     138/* {0.tag} without {1.key}, {2.key} or {3.key} (warning level) */
     139/* stop_position, platform */
     140
     141/* stop_area */
     142
     143/* route_master and route relations, ToDo ferry on ways */
     144relation.PtRouteMaster[gtfs:route_id][!gtfs:feed][!network:guid][!operator:guid],
     145relation.PtRoute["public_transport:version"=2][!gtfs:shape_id][!gtfs:trip_id][!gtfs:trip_id:sample],
     146relation.PtRoute[gtfs:route_id][!gtfs:feed][!network:guid][!operator:guid],
     147relation.PtRoute[gtfs:shape_id][!gtfs:feed][!network:guid][!operator:guid],
     148relation.PtRoute[gtfs:trip_id][!gtfs:feed][!network:guid][!operator:guid],
     149relation.PtRoute[gtfs:trip_id:sample][!gtfs:feed][!network:guid][!operator:guid] {
     150  throwWarning: tr("Public transport relation with `{0}` but none of `{1}*`, `{2}*` or `{3}*`.", "{1.tag}", "{2.tag}", "{3.tag}", "{4.tag}");
     151  group: tr("Public Transport: missing tag");
     152  assertMatch:   "relation type=route_master route_master=train gtfs:route_id=0-7-242-19j-1";
     153  assertMatch:   "relation type=route route=bus gtfs:shape_id=0-7-242-19j-1.26.R";
     154  assertNoMatch: "relation type=route_master route_master=train gtfs:route_id=0-7-242-19j-1 network:guid=DE-BY-MVV";
     155  assertNoMatch: "relation type=route_master route=bus colour=green";
     156}
     157
     158/* {0.tag} and {1.tag} without {2.key}, {3.key} or {4.key} (warning level) */
     159/* stop_position, platform */
     160node[public_transport][public_transport=stop_position][train=yes][railway!=stop],
     161*[public_transport][public_transport =~ /^(platform|stop_position)$/][train=yes][!ref] {
     162  throwWarning: tr("`{0}` with `{1}` but without `{2}`.", "{0.tag}", "{2.tag}", "{3.tag}");
     163  group: tr("Public Transport: missing tag");
     164  assertMatch:   "node public_transport=stop_position train=yes railway=halt";
     165  assertNoMatch: "node public_transport=stop_position train=yes railway=stop ref=2";
     166}
     167
     168/* {0.tag} and {1.tag} without {2.key} (warning level) */
     169/* platform */
     170*[public_transport=platform][highway=bus_stop][bus!=yes][share_taxi!=yes][trolleybus=yes] {
     171  throwWarning: tr("`{0}` with `{1}` but none of `{2}*`, `{3}*` or `{4}*`.", "{0.tag}", "{1.tag}", "{2.tag}", "{3.tag}", "{4.tag}");
     172  group: tr("Public Transport GTFS: missing tag");
     173  assertMatch: "node public_transport=platrom highway=bus_stop";
     174  assertNoMatch: "node public_transport=platrom highway=bus_stop bus=yes";
    37175}
    38176
     
    51189*[ref:IFOPT][ref:IFOPT       !~ /^[a-z]{2}:[0-9]{5}:[1-9][0-9]{0,4}(:[0-9]{1,2}(:[1-9][0-9]?)?)?$/],
    52190*[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]?)?)?$/] {
    53 /*  throwError: tr("Value `{0}` for `{1}=*` does not match value syntax `{2}`", "{0.value}", "{0.key}", "{1.value}"); */
    54   throwError: tr("Value `{0}` for `{1}=*` does not match value syntax", "{0.value}", "{0.key}");
    55   group: tr("Public Transport GTFS");
    56   assertMatch: "relation gtfs:route_id=7-342-j1j-1.H";
     191  throwError: tr("Value `{0}` for `{1}=*` does not match value syntax.", "{0.value}", "{0.key}");
     192/*  throwError: tr("Value `{0}` for `{1}=*` does not match value syntax `{2}`.", "{0.value}", "{0.key}", "{1.value}"); */
     193  group: tr("Public Transport GTFS: value syntax");
     194  assertMatch:   "relation gtfs:route_id=7-342-j1j-1.H";
    57195  assertNoMatch: "relation gtfs:route_id=7-342-j1j-1";
    58196  assertNoMatch: "relation gtfs:route_id=90-742-B-j20-1";
    59197  assertNoMatch: "relation gtfs:route_id=10-11-I-j20-1";
    60   assertMatch: "relation gtfs:shape_id=11-4-I-j20-1.23.";
     198  assertMatch:   "relation gtfs:shape_id=11-4-I-j20-1.23.";
    61199  assertNoMatch: "relation gtfs:shape_id=11-4-I-j20-1.23.H";
    62200  assertNoMatch: "relation gtfs:shape_id=7-342-j1j-1.51.R";
    63   assertMatch: "relation gtfs:trip_id=1108.T2.11-4-I-j20-1.10.";
     201  assertMatch:   "relation gtfs:trip_id=1108.T2.11-4-I-j20-1.10.";
    64202  assertNoMatch: "relation gtfs:trip_id=1108.T2.11-4-I-j20-1.10.H";
    65203  assertNoMatch: "relation gtfs:trip_id=29.T0.7-342-j1j-1.50.H";
    66204  assertNoMatch: "relation gtfs:trip_id=2.TA.90-742-B-j20-1.4.R";
    67   assertMatch: "relation gtfs:feed=DE-SH.NAH";
     205  assertMatch:   "relation gtfs:feed=DE-SH.NAH";
    68206  assertNoMatch: "relation gtfs:feed=df-SL-saarVV";
    69207  assertNoMatch: "relation gtfs:feed=DE-SH-NAH.SH";
    70208  assertNoMatch: "relation gtfs:feed=DE-BY-VVM-Mittelschwaben";
    71209  assertNoMatch: "relation gtfs:feed=DE-SL-saarVV";
    72   assertMatch: "relation gtfs:source_date=2016-09-30";
    73   assertMatch: "relation gtfs:source_date=2020-9-3";
    74   assertMatch: "relation gtfs:source_date=2016-09-30";
     210  assertMatch:   "relation gtfs:source_date=2016-09-30";
     211  assertMatch:   "relation gtfs:source_date=2020-9-3";
     212  assertMatch:   "relation gtfs:source_date=2016-09-30";
    75213  assertNoMatch: "relation gtfs:source_date=2020-09-30";
    76   assertMatch: "node ref:IFOPT=+1";
    77   assertMatch: "node ref:IFOPT=aa:aa:09";
    78   assertMatch: "node ref:IFOPT=ch:3001:64883";
     214  assertMatch:   "node ref:IFOPT=+1";
     215  assertMatch:   "node ref:IFOPT=aa:aa:09";
     216  assertMatch:   "node ref:IFOPT=ch:3001:64883";
    79217  assertNoMatch: "node ref:IFOPT=ch:23001:64883";
    80218  assertNoMatch: "node ref:IFOPT=de:08315:6504:0:14";
     
    83221}
    84222
    85 
    86223/*  ----------------
    87224 *  conflicting tags
     
    89226
    90227/* route_id, shape_id, trip_id */
     228*[gtfs:trip_id][gtfs:trip_id:sample][!(tag("gtfs:trip_id") == tag("gtfs:trip_id:sample"))] {
     229throwError: tr("`{1}` and `{0}` are not equal.", "{0.tag}", "{1.tag}");
     230  group: tr("Public Transport GTFS: conflicting tags");
     231}
     232*[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))],
     233*[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))],
    91234*[gtfs:route_id][gtfs:shape_id][!(tag("gtfs:route_id") == get(regexp_match("^(.+)\\.[1-9][0-9]?\\.[HR]$", tag("gtfs:shape_id"), "d"), 1))],
    92235*[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))],
    93236*[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))] {
    94   throwError: tr("`{1}` is not a substring of `{0}`", "{0.tag}", "{1.tag}");
    95   group: tr("Public Transport GTFS");
     237  throwError: tr("`{1}` is not a substring of `{0}`.", "{0.tag}", "{1.tag}"); 
     238  group: tr("Public Transport GTFS: conflicting tags");
    96239  assertMatch:   "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=7-342-j1j-1";
    97240  assertMatch:   "relation gtfs:route_id=7-342-j1j-1 gtfs:shape_id=7-352-j1j-1.17.H";
     
    103246  assertNoMatch: "relation gtfs:route_id=11-4-I-j20-1 gtfs:trip_id=1108.T2.11-4-I-j20-1.10.H";
    104247}
     248
     249/* route_id parent */
     250
     251/* Does not work */
     252/* relation.PtRouteMaster[gtfs:route_id] > * {
     253 *   set ChildMasterRoute_id;
     254 * }
     255 */
     256
     257relation[type=route_master][gtfs:route_id] > relation {
     258  set ChildMasterRoute_id;
     259}
     260
     261/* FIXME: How to display the key-value of the parent? */
     262relation.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]$", ""))],
     263relation.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))],
     264relation.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))],
     265relation.ChildMasterRoute_id[gtfs:route_id][parent_tag("gtfs:route_id")][!(parent_tag("gtfs:route_id") == tag("gtfs:route_id"))] {
     266  throwWarning:  tr("`{0}` conflicts with `gtfs:route_id=*` of the `route_master` relation.", "{1.tag}");
     267/*  throwWarning:  tr("`{0}` differs to `route_id={1}` of the `route_master` relation.", "{1.tag}", "{2.value}"); */
     268  group: tr("Public Transport GTFS: conflicting tags");
     269}
    105270}}}