Simple osm routing engine.
Simple routing engine for OpenStreetMaps with easy to customize profiles/weight-functions.
- Python 3.6.1 or newer
pip install routor
The CLI offers multiple commands, use
routor --help to find out more.
Downloads a compatible map from OSM, eg.
routor download "Bristol, England" ./bristol.graphml
routor download -n junction -n traffic_signals -e surface -e lanes "Bristol, England" "Somerset, England" ./bristol_somerset.graphml
By default, each downloaded map is enhanced with
street_count- how many physical segments are connected to a node
bearing- angle of each edge
speed_kph- free-flow travel speed based on
maxspeed, fallback is set to
30kph (see osmnx for more information)
travel_time- Travel time based on
If you provide a Google API (using --api-key), the following additional attributes are available:
elevation- elevation above sea level
grade_abs- grade of an endge
Determine the optimal route between two points using the given weight function and print the route as
routor route -- ./bristol.graphml "51.47967237816338,-2.6174926757812496" "51.45422084861252,-2.564105987548828" "routor.weights.length"
The configuration is either read from a
.env file or the environment.
Before you are able to run the server, you have to set the variables mentioned in routor/api/config.py.
Run the API
The api is served using uvicorn. To start the server run
You can also use the engine as a library. To calculate a route from A to B you can do
from pathlib import Path from routor.engine import Engine from routor import models, weights ... map_path = Path(...) engine = Engine(map_path) origin = models.Location(latitude=51.47967237816338, longitude=-2.6174926757812496) destination = models.Location(latitude=51.45422084861252, longitude=-2.564105987548828) route = engine.route(origin, destination, weight_func=weights.length, travel_time_func=weights.travel_time) # shortest distance
Calculates the shortest path from A to B, only the length of an edge is taken into account.
Calculates the fastest route based on travel time.
routor implements a simple plugin mechanism.
Simply create a new module with the prefix
routor_, make it available (install it,
sys.path hack or similar) and it will be automatically discovered and loaded.
Depending on how you structure your module/plugin, you have to do the registration of the additional functionality in either
Register a new weight function
Existing weight functions are defined in routor/weights.py and can be taken as reference. To register a new function in your plugin, you have to implement something similar to
# __init__.py from typing import Optional from routor.weights import register from routor import models def my_weight_func(prev_edge: Optional[models.Edge], edge: models.Edge) -> float: ... return ... register(my_weight_func, "weight_func")
Additionally, pdbpp and better-exceptions are installed to provide a better debugging experience.
better-exceptions you have to run
export BETTER_EXCEPTIONS=1 in your current session/terminal.
Clone this repository and run
poetry install poetry run pre-commit install
to create a virtual enviroment containing all dependencies. Afterwards, You can run the test suite using
poetry run pytest
This repository follows the Conventional Commits style.
in the root of this repository.
Release history Release notifications | RSS feed
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.