Selfhost OpenRouteService API
After last weeks overpass api selfhost, this week it is selfhosting openrouteservice. They have a ready to modify docker-compose.yml and good documentation for Docker hosting. Maybe a bit too many options and too many choices for someone hosting this the first time.
As last week we will use a Hetzner VPS, I used the same CX32 with 4 cores, 8 GB memory and 80GB disk to start with (and later a CX42 for more memory). Again I used Debian 12 as operating system.
The 8GB of memory are not enough so we create a swapfile with additonal 8GB of memory:
Then I installed Docker Engine.
My modified docker-compose.yml is stripped of everything I don't need: removing car-routing and adding walking.
I downloaded baden-wuerttemberg-latest.osm.pdf
from Geofabrik and put it into a freshly created ors-docker/files/
folder.
--- services: ors-app: build: context: ./ container_name: ors-app ports: - "80:8082" # Expose the ORS API on port 80 - "9001:9001" image: openrouteservice/openrouteservice:v8.0.0 volumes: - ./ors-docker:/home/ors environment: REBUILD_GRAPHS: False CONTAINER_LOG_LEVEL: INFO XMS: 4g # start RAM assigned to java XMX: 10g # max RAM assigned to java. Rule of Thumb: <PBF-size> * <profiles> * 2 # Example: 1.5 GB pbf size, two profiles (car and foot-walking) # -> 1.5 * 2 * 2 = 6. Set xmx to be AT LEAST `-Xmx6g` ADDITIONAL_JAVA_OPTS: "" # further options you want to pass to the java command ors.engine.source_file: /home/ors/files/baden-wuerttemberg-latest.osm.pbf ors.engine.profiles.car.enabled: false ors.engine.profiles.walking.enabled: true
Then run everything with docker compose up
.
This took a while. Especially the elevation cache and graph building.
I later tried the pbf for the United States (10GB) which needed more memory (I used a bigger instance with 16Gb of memory and 16GB of swap, and it took more than 7 hours to preprocess.
When the preprocessing is finished, the status page (http://<IP-ADDRESS>/ors/v2/status
) for me looked like this:
{ "languages": [ "cs", "cs-cz", "de", "de-de", "en", "en-us", "eo", "eo-eo", "es", "es-es", "fr", "fr-fr", "gr", "gr-gr", "he", "he-il", "hu", "hu-hu", "id", "id-id", "it", "it-it", "ja", "ja-jp", "nb", "nb-no", "ne", "ne-np", "nl", "nl-nl", "pl", "pl-pl", "pt", "pt-pt", "ro", "ro-ro", "ru", "ru-ru", "tr", "tr-tr", "zh", "zh-cn" ], "engine": {"build_date": "2024-03-21T13:55:54Z", "version": "8.0.0"}, "profiles": { "profile 1": { "storages": { "HillIndex": {"gh_profile": "pedestrian_ors_fastest"}, "WayCategory": {"gh_profile": "pedestrian_ors_fastest"}, "WaySurfaceType": {"gh_profile": "pedestrian_ors_fastest"}, "TrailDifficulty": {"gh_profile": "pedestrian_ors_fastest"} }, "profiles": "foot-walking", "creation_date": "", "limits": { "maximum_distance": 100000, "maximum_waypoints": 50, "maximum_distance_dynamic_weights": 100000, "maximum_distance_avoid_areas": 100000 }}}, "services": ["routing", "isochrones", "matrix", "snap"] }
Same as last week an example for how to use the API.
I only needed the routing for a walking distance and duration estimation.
As example we will route from the Empire State building in New York to the center of Central Park.
The coordinates are: 40.748448,-73.985630
to 40.782773,-73.965363
(both lat,lon).
import httpx r = httpx.get( "http://<IP-ADDRESS>/ors/v2/directions/foot-walking", params={ # here it is lon,lat "start": "-73.985630,40.748448", "end": "-73.965363,40.782773", }, ) print(r.json()["features"][0]["properties"]["summary"])
This returns {'distance': 4421.3, 'duration': 3183.2}
, so 4.4 km and 53 minutes.
I compared this to Google Maps Routing and it is in the same ballpark.