This is a prototype of a routing engine for railways based on a forked version of the GraphHopper routing engine and OpenStreetMap data.
Following features are currently supported:
railway=railway_crossing
)The configured vehicle profiles can:
Missing features:
This project includes a web frontend which is a fork of the original GraphHopper web frontend.
This project uses Maven (for the Java code) and NodeJS for the web frontend for building.
npm
has to be installed.
git submodule init
git submodule update
mvn clean install
JUnit 5 is used for unit tests.
You can configure OpenRailRouting by editing its GraphHopper configuration (YAML file). Please refer to config.yml for details.
Each route request has to specify a profile. The available profiles are determined by the configuration when the graph is imported. Each profile consists of
name
: name of the profileturn_costs
: turn costs
vehicle_types
: vehicle types used for vehicle-specific turn restrictions. Available values: train
, light_rail
, tram
, subway
u_turn_costs
: time penality in seconds for reversingcustom_model_files
: list of files that define the profile. The files are searched in src/main/resources/com/graphhopper/custom_profiles
.You can add an additional directory to the custom models search path by:
graphhopper:
custom_models.directory: path/to/your/custom_models_directory
If you have your own separate custom models directory, you do not have to recompile OpenRailRouting after every change of the models.
Please refer to the GraphHopper documentation about custom models for a detailed explanation how custom models work. The following contains a few notes about differences between GraphHopper and OpenRailRouting.
In addition to the encoded values supported by GraphHopper, OpenRailRouting can encoded the following encoded values per edge:
voltage
: decimal (precision: 100 Volt), missing values are encoded as 0.0
frequency
: decimal (precision: 2.5 Hz), missing values are encoded as 0.0
electrified
: enum (UNSET
, NO
, OTHER
, CONTACT_LINE
, RAIL
)gauge
: integer, missing values are encoded as 0.0
railway_class
: enum for the value of the OSM railway=*
tag: RAIL
, LIGHT_RAIL
, TRAM
, SUBWAY
, NARROW_GAUGE
, FUNICULAR
railway_service
: enum for the value of the OSM service=*
tag: NONE
, SIDING
, YARD
, SPUR
, CROSSOVER
preferred_direction
: boolean value, true if the requested direction matches the preferred direction of operation of the trackIn order to make use of these encoded values, you have to set them in the GraphHopper configuration using:
graphhopper:
graph.encoded_values: gauge,voltage,electrified,frequency,road_environment,max_speed,rail_access,rail_average_speed,railway_class,railway_service
If an edge has multiple gauges, voltages, freuqencies or types of electrification (e.g. multi-gauge tracks or tracks), the edge is duplicated during import. As author of a custom model, you don't need to take this into account.
OpenRailRouting provides a few basic profiles where you can combine and built upon:
all_tracks.json
accepts any track.rail.json
routes on any railway=rail
tramtrain.json
routes on railway=rail/light_rail/tram
gauge_1435.json
limits accessible tracks to those with gauge=1435
or missing gauge.15kv-ac_750v-dc.json
limits accessible tracks to those with 15 kV 16.7 Hz AC, 750 V DC or missing information about power systems. Tracks with electrified=no/rail
will be assumed as inaccessible.Don't forget that clients can submit their own profiles at runtime if they use POST requests.
To run the routing engine, execute
java -Xmx2500m -Xms50m \
-Ddw.graphhopper.datareader.file=$OSMFILE \
-jar target/railway_routing-0.0.1-SNAPSHOT.jar ACTION [ARGUMENTS] CONFIG_FILE [OPTARG]
The tool currently supports three different actions (ACTION
above):
import
to import the graph (graph will be stored at the subdirectory graph-cache/
)serve
to listen to HTTP requests for the API and the web interface on the port specified in a YAML configuration file (see
config.yml
as an example). If no data has been imported, an import of the routing graph will happen first.match
do map matching. This command needs additional arguments called OPTARG
above.Arguments:
--input
, -i
: Path to input file (.osm.pbf format)--output
, -o
: Path to output directory where the graph should be written toRequired settings to be given either as Java system properties (-Dgraphhopper.datareader.file=PATH
or in the YAML file):
graphhopper.datareader.file=$PATH
: path to OSM filegraphhopper.graph.location=./graph-cache
: directory where the graph should be written to
(default: ./graph-cache
)Required settings to be given either as Java system properties (-Ddw.KEY=VALUE
or in the configuration file):
dw.graphhopper.datareader.file=$PATH
: path to OSM filedw.graphhopper.graph.location=./graph-cache
: directory where the graph should be read from
(default: ./graph-cache
)dw.server.applicationConnector.port=$PORT
: port to be opened by JettyRequired settings to be given either as Java system properties (-Ddw.KEY=VALUE
or in the configuration file):
dw.graphhopper.datareader.file=$PATH
: path to OSM filedw.graphhopper.graph.location=./graph-cache
: directory where the graph should be read from
(default: ./graph-cache
)Following arguments have to be provided (not as Java system variables). You can retrieve this list
by calling
java -jar target/railway_routing-0.0.1-SNAPSHOT-jar-with-dependencies.jar match config.yml
--gpx-location=$PATTERN
is required. This can be either a single GPX file or a wildcard pattern
like /path/to/dir/mytracks/*.gpx
. The resulting routes will be written as GPX files to same
directory but .res.gpx
will be appended to their file names. Wildcard patterns need to be
enclosed with quotes (--gpx-location="path/to/files/*.gpx"
) to prevent your shell expanding
the pattern.-V VEHICLE
, --vehicle=$VEHICLE
: routing profile to be used.Optional command line arguments:
-a NUMBER
, --gps-accuracy=NUMBER
: GPS accuracy in metres (default: 40)--max_nodes=NUMBER
: maximum number of nodes to visit between two trackpoints (default: 10,000)See LICENSE.txt
See THIRD_PARTY.md for a list of all third-party code in this repository
Development of this project has been supported by Geofabrik and SNCF.