Small utility that uses OSRM to compute pairwise travel times and distances between a list of coordinates.
This repository contains a small C++ program (CMake-based) that:
- Loads a list of coordinates (or samples them inside a small Belgium area if none provided).
- Boots an OSRM engine (using a prebuilt
.osrmdataset) and queries pairwise routes. - Produces two CSV outputs: travel_distances and travel_times, plus (optionally) a coordinates file.
- Contains a
DockerImage/Dockerfilethat builds an image with the runtime and creates an/app/resultsfolder inside the container.
include/OSRMParameters.h— structosrm_paramscontaining configuration, coordinates storage, and helpers for loading/sampling/saving coordinates.src/OSRM_Engine.cpp— the main OSRM logic: sampling (if used), starting the OSRM engine, calculating pairwise matrices (distance/time), writing CSVs.src/main.cpp— CLI entrypoint: parses arguments, loads or samples coordinates, starts the engine and runs calculations.DockerImage/Dockerfile— Dockerfile to build a container with system dependencies and compile the app.
The program expects a simple whitespace-separated text file where each line contains one coordinate pair. Use the format:
<longitude> <latitude>
Example:
4.3517 50.8466
3.7038 51.0370
Note: internally coordinates are used as (longitude, latitude) to match how the OSRM types are constructed in the code.
By default outputs are written to the results/ directory (created automatically by the repository and Dockerfile):
results/travel_distances.csv— CSV matrix of distances (meters). Row = from-index, column = to-index.results/travel_times.csv— CSV matrix of travel times (seconds). Same indexing as distances.results/coordinates.txt— when sampling is used, the sampled coordinates written aslongitude latitudeper line.
You can run the full Docker workflow with run.sh:
./run.sh -r belgium -c ./results/coordinates.txtIf run.sh is not executable yet, either run:
chmod +x run.sh
./run.sh -r belgium -c ./results/coordinates.txtor invoke it with Bash:
bash ./run.sh -r belgium -c ./results/coordinates.txtWhat run.sh does:
- Resolves an OSM PBF source from either:
-r <region>(Geofabrik Europe URL), or-u <direct_pbf_url>.
- Downloads and caches the file as
OSM/region.osm.pbf(usingOSM/.last_regionas a marker). - Copies your coordinates file to
results/coordinates.txtwhen-cis provided. - Builds Docker image
app/osrmonly if it does not already exist (or when--force-buildis set). - Runs the container and writes outputs to
results/on your host.
Common examples:
# Region shortcut + explicit coordinates
./run.sh -r belgium -c ./results/coordinates.txt
# Direct URL
./run.sh -u https://download.geofabrik.de/europe/belgium-latest.osm.pbf -c ./results/coordinates.txt
# Sampling mode (no coordinates file)
./run.sh -r belgium
# Rebuild image even if already present
./run.sh -r belgium --force-buildNotes:
- First run can take several minutes because the Docker image is built and data may be downloaded.
- Later runs are usually much faster because image layers and region data are cached.
- Rebuilds can be slow again when using
--force-build, changing region/PBF source, or after Docker cache cleanup. - Prerequisites: Docker (daemon running), curl, and enough disk space for Docker layers plus OSM data.
./run.shandbash ./run.share equivalent; use whichever you prefer.- If you change region or PBF source and already have an existing image, use
--force-buildto ensure the image is rebuilt with the new dataset. - Progress appears in terminal logs (
Downloading,Building docker image,Running container). - Outputs are written to
results/travel_distances.csvandresults/travel_times.csv.
The DockerImage/Dockerfile bundles dependencies and builds both OSRM and this application.
If you want to run Docker manually (without run.sh):
- Make sure Docker is installed.
- Place your coordinates file in
DockerImage/results/coordinates.txt(optional; omit for sampling). - Download a region file from Geofabrik, rename it to
region.osm.pbf, and place it inDockerImage/OSM/. - From
DockerImage/, run:
docker build . -t app/osrm
docker run -v $(pwd)/results:/app/results app/osrmThis writes CSV outputs to your local results folder.
Note: this Docker image uses the car profile by default (other common profiles are bicycle and foot).
Prerequisites
- CMake
- A C++17-capable compiler (g++/clang)
- An OSRM dataset (.osrm files) for the region you want to query (e.g. Belgium), these are the processed osm.pbf files by the OSRM engine
Build
mkdir -p build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel 8Run
# Provide an OSRM dataset and optional coordinates file
./build/osrm --osrm-path /full/path/to/region.osrm --coordinates-path /full/path/to/coords.txt
# If you omit --coordinates-path the program samples 100 points inside a small central-Belgium bounding area
./build/osrm --osrm-path /full/path/to/region.osrmNotes:
- If
--coordinates-pathis provided, the program uses the file you pass. If omitted, it randomly samples locations inside Belgium (small central polygon) and writes the sampled coordinates toresults/coordinates.txt. - After the run you should find the CSV matrices in
results/.
You may have noticed a crash during program exit referencing libtbbmalloc or libtbb on some macOS setups. This is a destructor-order issue that occurs in certain environments when TBB static destructors run during process teardown.
Workarounds the code includes:
- The program performs an explicit cleanup: it resets the OSRM engine pointer and frees allocated matrices before exit. This helps reduce the chance of TBB-related crashes.
- If you still see a crash on teardown, the code uses
std::_Exit(0)after cleanup to avoid running the remaining C++ static destructors. This is a pragmatic workaround (it skips any further C++ destructors) — acceptable here because the program explicitly releases its OSRM/TBB resources first.
If you prefer to debug the destructor-order issue instead of using std::_Exit, try running under a debugger or removing the early exit and instrumenting static destructors to discover which object triggers TBB access during teardown.