PTNA - Public Transport Network Analysis

Static Analysis for OpenStreetMap


Motivation

First discussions (german) started at a Munich OSM pub meeting in February 2017.

The whole discussion was triggered by unintentional deletion of bus relations in the Munich area (but new relations were created). As a result, many links on the München/Transportation (german) page were out of date. However, one must also say that the site was not well maintained in the past, in part, was not known at all. The quality and timeliness of the site seems to be a general problem.

Problem: the quality of the page München/Transportation (german) leaves room for improvement:

  • Completeness:
    • we do not know if we have listed all existing bus lines of the MVV on the page
    • we do not know if we have mapped artifacts, e.g. bus lines that have already been reset or renumbered
    • suburban trains, subways and trams are manageable in number, there is a chance that we are complete
  • PTv2:
  • Correctness:
    • we do not know if the lines switched to PTv2 are consistent and sorted
    • i.e. whether the ways are captured correctly, in the correct order, without gaps, without extensions and at roundabouts
    • whether the "stop" and "platform" members are captured completely and in the correct order
  • Uniformity:
    • we do not know if all relations with their tags are complete and correct
    • i.e. with existing, correct and possibly uniform "network", "operator", public_transport: version, name, ref, from, to (and via), ...
  • Clarity:
    • we do not have a page that shows us all that, but most of all the problems with it
  • Automation:
    • we have no possibility to automatically create such a summary page (weekly, ...)

Causes there are many:

  • Completeness:
    • where should we get the information from? We may receive a list from the MVV (CSV, ...)
  • PTv2:
    • some lines have neither "version" 1 nor 2 as tag: forgotten, ignorance of existence ...
  • Correctness:
    • This is a tedious work that has to be started again and again, because relations are quickly (unintentionally) "filled" with gaps, ...
  • Uniformity:
  • Clarity:
    • Parts of the page are already clearer, how could a clearer page look like (layout?)
  • Automation:
    • there is nothing

A non-representative view of Berlin, Hamburg and Aachen shows that other cities have the same problem.


Overview

Lorem ipsum dolor sit amet, consectetur adipisici elit, …


The Web-site

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

The Analysis

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

  • Name
  • City/Region
  • Network
  • Results
  • Last Changes
  • Discussion
  • Lines

Statistics

Statistics ... Lorem ipsum dolor sit amet, consectetur adipisici elit, …


Lines belonging to the 'network'

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Important: Consider the Copyright © and origin of the data!

Note: The list will be published under the GPL 3 license.


The Analysis

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Description of the expected line

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Important: Consider the Copyright © and origin of the data!

Note: The list will be published under the GPL 3 license.

Example: Lines of the Münchner Verkehrs- und Tarifverbund in OSM Wiki

Downloading Data from OSM

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Definition of the search area

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Seletion of relevant routes, ways and nodes

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Output of data

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Definition of Analysis Options

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Analysis of Date

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Date of Data

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Münchner Verkehrs- und Tarifverbund

Overview overPT Lines ...

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Münchner Verkehrs- und Tarifverbund

Not assigned lines

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Verkehrsverbund Mittelsachsen

Other PT Lines

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Regionalverkehr Oberbayern

PT Lines w/o 'ref'

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Verkehrsverbund Ems-Jade

More Relations

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Verkehrsverbund Rhein-Sieg (VRS)

Details for 'network'-Values

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Considered 'network' values

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Verkehrsverbund Mittelsachsen (VMS)

Not considered 'network' values

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Example: Verkehrsverbund Mittelsachsen (VMS)

Checks

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Used Schema

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: OSM Wiki

Deviations

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: OSM Wiki

Specials

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: OSM Wiki

Approach

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: OSM Wiki

Analysis options

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Option Default Value Description Image
allow-coach OFF Allow 'route_master' = 'coach' und 'route' = 'coach' (although they are inofficial).
check-access OFF Ways are used which cannot be used explicitly or implicitly ('construction', 'access', ...) and where 'bus' = 'yes', 'bus' = 'designated', 'bus' = 'official', 'psv' =' yes', ... is not set. This applies to 'barrier' = '...' as well.
check-bus-stop OFF 'highway' = 'bus_stop' can be set on nodes only, not on ways or areas.
check-gtfs OFF Check 'gtfs:*' tags for validity, ...
check-name OFF Check of 'name' = '...ref: from => to' respectively 'name' ='...ref: from => via => ... => to'.
check-name-relaxed OFF More relaxed check of 'name' ='...: A => B', where 'A' must be part of 'from' and 'B' must be part of 'to'.
check-osm-separator OFF Check the value of 'network', ... whether the separator is actually the semicolon ';' (w/o Blanks).
check-platform OFF Missing 'bus' = 'yes', 'tram' = 'yes' or 'share_taxi' = 'yes' on 'public_transport' = 'platform'.
check-roundabouts OFF Check whether roundabouts are used partially (segments only) or completely (while not being segmented).
check-route-ref OFF Check whether the tag 'route_ref' on the stops of a route includes the value of 'ref' of the route (provided 'route_ref' exists).
Check also whether the tag 'ref' on the stops of a route accidentially includes the value of 'ref' of the route.
Check also for tags 'bus_lines', 'bus_routes', 'lines', 'routes' on the stops of a route. Those should be replaced by the tag 'route_ref'.
check-sequence OFF Check sequence of ways, are there any gaps?
check-stop-position OFF Missing 'bus' = 'yes', 'tram' = 'yes' or 'share_taxi' = 'yes' on 'public_transport' = 'stop_position'.
check-version OFF Check of 'public_transport:version' = '...' on Route-Master and Route.
check-way-type OFF Check whether the used way types are appropriate for the vehicle type ('train' using 'railway' = 'rail', 'tram' using 'railway' = 'tram', 'bus' using 'highway' = '...', ...).
coloured-sketchline OFF SketchLine considers the value of 'colour' = '...' of Route-Master or Route.
expect-network-long OFF The value of 'network' = '...' is expected in long form (see: network-long-regex).
expect-network-long-as The value of 'network' = '...' is expected in long form, as shown here.
expect-network-long-for The value of 'network' = '...' is expected in long form instead of the short form shown here.
expect-network-short OFF The value of 'network' = '...' is expected in short form (see: network-short-regex).
expect-network-short-as The value of 'network' = '...' is expected in short form, as shown here.
expect-network-short-for The value of 'network' = '...' is expected in short form instead of the long form shown here.
gtfs-feed Take this value as GTFS feed for option 'link-gtfs' if the relation does not provide the tags 'gtfs:feed', 'operator:guid' or 'network:guid'.
language en Defines the language for the output.
max-error Limits the number of identical error and note messages for a relation.
multiple-ref-type-entries analyze allow|analyze|no
Defines how to react if the combination of "ref;type" (e.g. "N8;bus") appears more than once in the route data. PTNA expects that there are separate routes with identical 'ref' and 'type' in different cities/villages and that those can be distinguished by also checking 'operator', 'to' and 'from'.
allow: allow further occurances of this entry, do not analyze 'operator', 'from' and 'to'
analyze: find out whether 'operator', 'from' and 'to' of the CSV data match the tags of the relation
no: ignore any further occurances of this entry, do not analyze 'operator', 'from' and 'to'.
network-long-regex The value of 'network' = '...' of the Route-Master and Route relations must match this regular expression as 'long' form or can be empty (unset).
network-short-regex The value of 'network' = '...' of the Route-Master and Route relations must match this regular expression as 'short' form or can be empty (unset).
no-additional-navigation OFF
operator-regex The value of 'operator' = '...' of the Route-Master and Route relations must match this regular expression or can be empty (unset).
or-separator |
positive-notes OFF Also show 'network:short' = '...', 'network:guid' = '...' and other tags and values.
ptv1-compatibility no allow|no|show
'highway' = 'bus_stop' on a point beside the road is treated as 'public_transport' = 'platform' if 'role' = 'platform'.
allow: silently assume compatibility with legacy bus-stops (aka: PTv1)
no: no compatibility with legacy bus-stops (aka: PTv1)
show: assume and show compatibility with legacy bus-stops (aka: PTv1).
ref-separator /
relaxed-begin-end-for Relaxed check of begin and end of routes regarding stop positions (i.e. for 'train', 'tram', 'light_rail').
separator ;
show-gtfs OFF Similar to option '--positive-notes': show values of 'gtfs*' tags in the 'Notes' column.
strict-network OFF Do not consider Route-Master and Route relations with empty 'network'.
strict-operator OFF Do not consider Route-Master and Route relations with empty 'operator'.

Messages

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

Message Type Option Description How to fix it Image
'%s' = '%s' includes the separator value ';' (semi-colon) with sourrounding blank Notes
'%s' = '%s': ',' (comma) as separator value should be replaced by ';' (semi-colon) without blank Notes
'colour' has unknown value '%s'. Add '#' as first character. Errors
'colour' has unknown value '%s'. Choose one of the 140 well defined HTML/CSS colour names or the HTML Hex colour codes '#...' or '#......'. Errors
'colour' of Route does not fit to 'colour' of Route-Master: %s Errors
'colour' of Route is not set but 'colour' of Route-Master is set: %s Errors
'colour' of Route is set but 'colour' of Route-Master is not set: %s Errors
'name' is not set Errors
'network' = '%s' of Route does not fit to 'network' = '%s' of Route-Master: %s Errors
'network' = '%s' of Route is a part of 'network' = '%s' of Route-Master: %s Notes
'network' = '%s' should be long form Notes
'network' = '%s' should be short form Notes
'network' is not set Errors
'network:long' is long form Notes
'network:long' matches long form Notes
'operator' = '%s' of Route does not fit to 'operator' = '%s' of Route-Master: %s Errors
'public_transport:version' is neither '1' nor '2' Errors
'public_transport:version' is not set Notes
'public_transport:version' is not set to '2' Errors
'ref' is not set Errors
'route' = '%s' of Route does not fit to 'route_master' = '%s' of Route-Master: %s Errors
'route' tag is not set: %s Errors
'type' = '%s' is not 'route': %s Errors
'type' tag is not set: %s Errors
Error in input data: insufficient data for nodes Errors This Route relation has been included into the input data as a side-effect, the member ways and member nodes of this Route have not been included.
Error in input data: insufficient data for ways Errors This Route relation has been included into the input data as a side-effect, the member ways and member nodes of this Route have not been included.
Missing route for ref='%s' and route='%s' Errors This route is expected as '%s' ('bus', 'tram', ...) according to CSV data, but does not exist in the given data set (see also section: "Overpass API Query").
Multiple Routes but 'public_transport:version' is not set to '2' Errors
Multiple Routes but no Route-Master Errors
Multiple Routes but this Route is not a member of any Route-Master Errors
PTv2 route: '%s' is not part of 'name' (derived from '%s' = '%s') Notes check-name
PTv2 route: 'from' is not set Notes check-name
PTv2 route: 'name' has more than one '=>' but 'via' is not set Notes check-name
PTv2 route: 'name' has no via-parts but 'via' is set Notes
PTv2 route: 'name' includes deprecated '<=>' Notes check-name
PTv2 route: 'name' includes deprecated '==>' Notes check-name
PTv2 route: 'name' of Route is identical to 'name' of other Route(s), consider setting an appropriate 'via' value and include that into 'name' Notes check-name
PTv2 route: 'name' should (at least) be of the form '... ref ...: from => to' Notes check-name
PTv2 route: 'name' should be similar to the form '... ref ...: from => to' Notes check-name-relaxed
PTv2 route: 'public_transport' = 'platform' is part of way Errors
PTv2 route: 'public_transport' = 'stop_position' is not part of way Errors
PTv2 route: 'ref' is not part of 'name' Notes check-name
PTv2 route: 'role' = '%s' and %s: consider setting 'public_transport' = 'platform' Errors ptv1-compatibility=show
PTv2 route: 'role' = '%s' and %s: consider setting 'public_transport' = 'stop_position' Errors ptv1-compatibility=show
PTv2 route: 'role' = '%s' but 'public_transport' is not set Errors
PTv2 route: 'to' is not set Notes check-name
PTv2 route: 'via' is set: %d. via-part ('%s') of 'name' is not equal to %d. via-value = '%s' Notes check-name
PTv2 route: 'via' is set: %d. via-part ('%s') of 'name' is not part of %d. via-value = '%s' Notes check-name-relaxed
PTv2 route: consider removing the first way of the route from the relation, it is a way before the first stop position: %s Errors check-sequence
PTv2 route: consider removing the last way of the route from the relation, it is a way after the last stop position: %s Errors check-sequence
PTv2 route: empty 'role' Errors
PTv2 route: first node of oneway way has 'role' = 'stop_exit_only' Errors check-sequence
PTv2 route: first node of way has 'role' = 'stop_exit_only'. Is the route sorted in reverse order? Errors check-sequence
PTv2 route: first node of way is not a stop position of this route: %s Errors check-sequence
PTv2 route: first node of way is not the first stop position of this route: %s versus %s Errors check-sequence
PTv2 route: first stop position on first way is not the first stop position of this route: %s versus %s Errors check-sequence
PTv2 route: first way is a oneway road and ends in a 'stop_position' of this route and there is no exit. Is the route sorted in reverse order? Errors check-sequence
PTv2 route: from-part ('%s') of 'name' is not equal to 'from' = '%s' Notes check-name
PTv2 route: from-part ('%s') of 'name' is not part of 'from' = '%s' Notes check-name-relaxed
PTv2 route: has a gap, consists of %d segments. Gap appears at way Errors check-sequence
PTv2 route: has a gap, consists of %d segments. Gap appears at wayPTv2 route: has a gap, consists of %d segments. Gap appears at way
PTv2 route: includes %d entire roundabout but uses only segments Notes check-sequence
check-roundabout
PTv2 route: incorrect order of 'stop_position', 'platform' and 'way' (stop/platform after way) Errors
PTv2 route: incorrect order of 'stop_position', 'platform' and 'way' (stop/platform after way)PTv2 route: incorrect order of 'stop_position', 'platform' and 'way' (stop/platform after way)
PTv2 route: last node of oneway way has 'role' = 'stop_entry_only' Errors check-sequence
PTv2 route: last node of way has 'role' = 'stop_entry_only'. Is the route sorted in reverse order? Errors check-sequence
PTv2 route: last node of way is not a stop position of this route: %s Errors check-sequence
PTv2 route: last node of way is not the last stop position of this route: %s versus %s Errors check-sequence
PTv2 route: last stop position on last way is not the last stop position of this route: %s versus %s Errors check-sequence
PTv2 route: mismatch between 'role' = '%s' and 'public_transport' = '%s' Errors
PTv2 route: missing '%s' = 'yes' on 'public_transport' = 'stop_position' Errors
PTv2 route: roundabout appears twice, following itself Errors check-sequence
PTv2 route: roundabout appears twice, following itselfPTv2 route: roundabout appears twice, following itself
PTv2 route: there are less via-parts in 'name' (%d) than in 'via' (%d) Notes check-name
PTv2 route: there are more via-parts in 'name' (%d) than in 'via' (%d) Notes check-name
PTv2 route: there are no 'public_transport' = 'stop_position' and no 'public_transport' = 'platform' Errors
PTv2 route: there is no 'public_transport' = 'platform' Notes
PTv2 route: there is no 'public_transport' = 'stop_position' Notes
PTv2 route: there is no stop position of this route on the first way: %s Errors check-sequence
PTv2 route: there is no stop position of this route on the last way: %s Errors check-sequence
PTv2 route: there is only one 'public_transport' = 'platform' Errors
PTv2 route: there is only one 'public_transport' = 'stop_position' Errors
PTv2 route: to-part ('%s') of 'name' is not equal to 'to' = '%s' Notes check-name
PTv2 route: to-part ('%s') of 'name' is not part of 'to' = '%s' Notes check-name-relaxed
PTv2 route: using motorway_link way without entering a motorway way Errors check-motorway-link The vehicle uses a motorway entrance or exit without using a motorway/trunk road immediately after or before it. This may indicate incorrect tagging of the 'highway' = 'motorway_link'. But it can also point to a wrong route, e.g. if it was created automatically by a routing SW. There still seems to be Routing-SW that prefers to use a short stretch of highway enrance to turn around after 20 m and route back to the previous route instead of taking the direct route (because a traffic light influences the result?).
Precondition: the route is without gap(s).
PTv2 route: using oneway way in wrong direction Errors check-sequence
PTv2 route: using oneway way in wrong directionPTv2 route: using oneway way in wrong direction
PTv2 route: using wrong way type (%s) Errors
PTv2 route: wrong 'role' = '%s' Errors
Route does not exist in the given data set: %s Errors
Route exists in the given data set but 'ref' tag is not set: %s Errors The Route is member of this Route-Master, but has no 'ref' tag (%s = ID of the route). See section: "Public Transport Lines without 'ref'" of the analysis.
Route has 'network' = '%s' value which is considered as not relevant: %s Notes
Route has 'network' = '%s' value which is part of 'network' = '%s' of Route-Master: %s Notes
Route has 'operator' = '%s' value which is considered as not relevant: %s Errors
Route has 'route' = '%s' value which is considered as not relevant: %s Errors
Route has different 'network' = '%s' than Route-Master 'network' = '%s': %s Errors
Route has different 'operator' = '%s' than Route-Master 'operator' = '%s': %s Errors
Route has different 'ref' = '%s' than Route-Master 'ref' = '%s' - this should be avoided: %s Notes This is currently deactivated.
Route has different 'route' = '%s' than Route-Master 'route_master' = '%s': %s Errors
Route has not matching 'ref' = '%s': %s Errors
Route is not member of Route-Master: %s Errors
Route might be listed with 'ref' = '%s' in a different section or in section 'Not clearly assigned routes' of this analysis: %s Errors
Route with Relation(s) Errors
Route with only 1 Node Errors
Route with only 1 Way Errors
Route without Node(s) Errors
Route without Way(s) Errors
Route-Master exists in the given data set but 'ref' tag is not set: %s Errors
Route-Master has less Routes than actually match (%d versus %d) in the given data set Errors This Route-Master has less route relations than listed here (Route(s) not listed in the Route-Master?).
Route-Master has more Routes than actually match (%d versus %d) in the given data set Errors This route master has more route relations than listed here (route without or with other 'ref'/'route'/'network' tag?).
Route-Master has not matching 'ref' = '%s': %s Errors
Route-Master might be listed with 'ref' = '%s' in a different section or in section 'Not clearly assigned routes' of this analysis: %s Errors
Route-Master might be listed with unknown 'ref' in section 'Public Transport Lines without 'ref'' of this analysis: %s Errors
Route-Master with Node(s) Errors The Route-Master relation contains stops or train/bus stops.
Route-Master with Relation(s) unequal to 'route' Errors The Route-Master relation contains relation(s) that are not of type 'route'.
Route-Master with Way(s) Errors The Route-Master relation contains streets/railways/trains/bus stops/...
Route-Master without Route(s) Errors The Route-Master relation does not contain a Route relation (should not happen with the used Overpass API query, see: 'The overpass API query does not return').
Route-Type is not set. Line %s of Routes-Data. Contents of line: '%s' Errors
Route-Type is not supported: '%s'. Line %s of Routes-Data. Contents of line: '%s' Errors
Route: '%s' = '%s' of stop should be deleted, 'route_ref' = '%s' exists Notes check-route-ref
Route: '%s' = '%s' of stop should be replaced by 'route_ref' = '%s' Notes check-route-ref
Route: 'highway' = 'bus_stop' is set on way. Allowed on nodes only! Errors check-bus-stop
Route: 'ref' = '%s' of stop should represent the reference of the stop, but includes the 'ref' = '%s' of this route %s Notes check-route-ref
Route: 'route_ref' = '%s' of stop does not include 'ref' = '%s' value of this route%s Errors check-route-ref
Route: 'route_ref' = '%s' of stop includes the separator value ';' (semi-colon) with sourrounding blank Notes check-route-ref
Route: 'route_ref' = '%s' of stop: ',' (comma) as separator value should be replaced by ';' (semi-colon) without blank Notes check-route-ref
Route: incorrect access restriction (%s) to way. Consider tagging as '%s'='no' and '%s'='yes' Errors check-access The access restriction does not comply with the map features. Please consult the OSM Wiki: https://wiki.openstreetmap.org/wiki/Map_Features#Restrictions
Route: restricted access (%s) to way without 'psv'='yes', '%s'='yes', '%s'='designated', or ... Errors check-access
Route: restricted access at barrier (%s) without 'psv'='yes', '%s'='yes', '%s'='designated', or ... Errors check-access
Route: suspicious %s along with 'highway' unequal to 'construction' on way Notes check-access The key 'construction' is set and the key 'highway' is not set to 'construction'. Construction works on ways are usually mapped as the combination of 'higway' = 'construction' and 'construction' = 'xxx', where 'xxx' is the former value of the 'highway' key. When the construction works are finished, the key 'highway' is set to its former or a different value while the key 'construction' gets delete. Sometimes, deleting the key 'construction' is not carried out, which leaves an artifact and can be seen as an error.
Example: 'construction' = 'primary' and 'highway' = 'primary' instead of 'highway' = 'construction'.
Check whether the construction works are finished or not. If yes, delete the key 'construction'. If no, check for an appropriate value of the key 'highway'.
Route: unclear access (%s) to way Notes check-access A conditional access is mapped to a way. PTNA will not analyze the value of the tag.
Example: 'psv:conditional' = 'yes @ (Mo-Fr 05:00-22:00)'.
Please evaluate the value manually and decide whether a fix is needed or not.
Skipping further analysis ... Errors This error is related to: 'Error in input data: insufficient data for nodes' and 'Error in input data: insufficient data for ways'. Further analysis of this Route relation does not make sense without the data for ways and nodes.
The tag 'line' (='%s') is reserved for 'power' = 'line' related tagging. For public transport 'route_master' and 'route' are used. Notes
There is more than one Route-Master Errors Route-Master: There is more than one Route-Master for this line = 'ref' (different 'network'-tags?).
Route: There is more than one Route Master for this line = 'ref' plus the parent Route Master of this route.
This Route is direct member of more than one Route-Master: %s Errors This Route has more than one parent Route-Master (%s = list of Route-Masters).
This Route is not a member of any Route-Master Errors

The Code

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

ptna

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: ptna auf GitHub

ptna-networks

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: ptna-networks auf GitHub

ptna-www

Lorem ipsum dolor sit amet, consectetur adipisici elit, …

See: ptna-www auf GitHub