06 - Set Up an OSRM Server on Ubuntu 16
We will see in this post how to deploy your own OSRM service in case you want to use it on your own data or just to not be limited by the number requests with responses like:
{'message': 'Too Many Requests'}
.
Sources:
- https://www.digitalocean.com/community/tutorials/how-to-set-up-an-osrm-server-on-ubuntu-14-04
- https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM
- http://project-osrm.org/docs/v5.5.1/api/
OSRM features
- Nearest service - Snaps a coordinate to the street network and returns the nearest n matches.
- Route service - Finds the fastest route between coordinates in the supplied order.
- Table service - Computes the duration of the fastest route between all pairs of supplied coordinates.
- Match service - Map matching matches/snaps given GPS points to the road network in the most plausible way.
- Trip service - The trip plugin solves the Traveling Salesman Problem using a greedy heuristic (farthest-insertion algorithm). The returned path does not have to be the fastest path, as TSP is NP-hard it is only an approximation.
- Tile service - This service generates Mapbox Vector Tiles that can be viewed with a vector-tile capable slippy-map viewer.
You will need at least 2.5GB of RAM (in my case with 1GB OSRM build failed).
Upgrade all the packages
sudo apt-get update
Install dependencies
sudo apt-get install build-essential git cmake pkg-config \
libbz2-dev libxml2-dev libzip-dev libboost-all-dev \
lua5.2 liblua5.2-dev libtbb-dev
Create a dedicated directory and move into to keep everything tidy and clean
mkdir osrm
cd osrm
Get OSRM from the official GitHub repo
git clone https://github.com/Project-OSRM/osrm-backend.git
Compile and install OSRM binaries
cd osrm-backend
mkdir -p build
cd build
cmake ..
cmake --build .
sudo cmake --build . --target install
The map pre-processing is quite memory intensive. For this reason, OSRM uses a library called STXXL to map its internal operations on the hard disk. STXXL relies on a configuration file called .stxxl, which lives in the same directory where you are running your software, to determine how much space is dedicated to the STXXL data structures.
Configure STXXL with an .stxxl
file in your osrm
folder.
cd ~/osrm
vi .stxxl
Write in it
disk=/tmp/stxxl,10G,syscall
Save and close it.
Because the speed profile script might depend on some Lua functions defined in the profiles library, we also create a symbolic link to it in the same directory by running the following two commands.
ln -s osrm-backend/profiles/car.lua profile.lua
ln -s osrm-backend/profiles/lib
Get openstreetmap data
wget https://download.geofabrik.de/europe/france/ile-de-france-latest.osm.bz2
bzip2 -d ile-de-france-latest.osm.bz2
Pre-process the .osm
file with the car profile
osrm-extract ile-de-france-latest.osm -p ./osrm-backend/profiles/car.lua
Build the contraction hierarchy
osrm-contract ile-de-france-latest.osrm
To keep the osrm-routed process running after ending ssh session, use tmux
tmux
Start a routing engine HTTP server on port 5000 inside the tmux session
osrm-routed ile-de-france-latest.osrm
Leave/detach the tmux
session by typing Ctrl
+b
and then d
You have now a high performance routing engine up and running.
Get the estimated fastest route for a departure-destination pair of GPS points
Let’s take for example the following GPS points (departure’s longitude, departure’s latitude, departure’s longitude, departure’s latitude) :
2.25975,48.923557;2.262194,48.922554
To use the service with Python, you can do:
import json
import requests
from pprint import pprint
url = 'http://0.0.0.0:5000/route/v1/car/'
url += '2.25975,48.923557;2.262194,48.922554'
response = requests.get(url)
json_data = json.loads(response.text)
The service response should looks like:
pprint(json_data)
{
"code":"Ok",
"routes":[
{
"geometry":"gkriHmjxLpCkBBcILcBHB",
"legs":[
{
"steps":[
],
"distance":251.2,
"duration":34,
"summary":"",
"weight":34
}
],
"distance":251.2,
"duration":34,
"weight_name":"routability",
"weight":34
}
],
"waypoints":[
{
"hint":"rUAAgDMXC4AHAAAABQAAAAAAAAAmAAAAHvuhQA7XVUAAAAAAYpXVQQcAAAAFAAAAAAAAACYAAAA4BQAAInsiAKSD6gImeyIApYPqAgAArwmOS6TT",
"distance":0.313522,
"name":"Rue Victor Hugo",
"location":[
2.259746,
48.923556
]
},
{
"hint":"rBoNgK0aDYANAAAAAAAAAAAAAAAAAAAACWqrQAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAAA4BQAAeYUiAESA6gKyhCIAun_qAgAADwyOS6TT",
"distance":21.170758,
"name":"",
"location":[
2.262393,
48.922692
]
}
]
}
To retrieve the geometry:
json_data["routes"][0]["geometry"]
For our example you will get:
gkriHmjxLpCkBBcILcBHB
You can check this geometry with the Google Interactive Polyline Encoder Utility. Copy/Paste the geometry into the Encoded Polyline field and click on Decode polyline. In my case, I get the folowing polyline: