Skip to content
Amir's Blog
Go back

A Practical Guide to Map-Matching with Valhalla Map Matching API

Edit page

Map matching solves a fundamental problem with GPS data; Raw GPS data from vehicles or phones is inherently noisy. It zigzags through buildings, jumps across intersections, and disappears in tunnels. For any serious traffic analysis, emission modeling, or routing application, this raw data is unreliable. The solution is map-matching: the process of snapping a sequence of coordinates to the most likely path on a real-world road network.

To see the difference before and after map matching of a gps track, check out this interactive map showing a recording of my actual bike commute from the subway station to work. The raw, messy GPS track is in blue, and the clean, map-matched route is in red.

Move the interactive maps with your mouse and see how fuzzy raw points are snapped to road segment after map matching!

Before: Raw GPX Track

After: Map-Matched Route

In this guide, we’ll build a powerful, offline map-matching server using Valhalla and then use the tools in the MapMatching project to process trips and visualize the results.

By the end of this tutorial, you will:

All the code is in the MapMatching GitHub Repository.

You can also try a live map matching demo with a small GPX file right now at mapmatch.streamlit.app!


Part 1: Prerequisites for Map Matching- Gathering Your Tools 🛠️

Before we start, you’ll need two things.

1. Docker

This is the highly recommended way to run Valhalla. It avoids complex dependency issues and ensures a clean, isolated environment. If you don’t have it, install it now.

2. OpenStreetMap (OSM) Data

Valhalla builds its road network graph from OSM data. This data comes in a compressed .osm.pbf file format. We’ll use a regional extract for this tutorial.

  1. Go to Geofabrik.de.
  2. Navigate to Europe -> Germany -> Hessen. (Or your region of choice)
  3. Download the hessen-latest.osm.pbf file.

Part 2: The Setup - Getting Everything Ready 🚀

This process involves getting the code, launching the Valhalla server, and setting up the Python environment.

Step 1: Get the Code

First, clone the MapMatching repository and navigate into the directory.

git clone https://github.com/amirbabaei97/MapMatching.git
cd MapMatching

Step 2: Launch Valhalla with Docker

Create a folder named custom_files inside the project directory and place your downloaded hessen-latest.osm.pbf file into it. Then, run the following command in your terminal:

docker run -dt --name valhalla -p 8002:8002 -v $PWD/custom_files:/custom_files ghcr.io/valhalla/valhalla-scripted:latest

This command downloads the official Valhalla image and starts it. On its first run, it will automatically find your .pbf file and build the routing tiles. This can take 5-15 minutes. You can watch the progress with docker logs -f valhalla.

To verify it’s working, open http://localhost:8002/status in your browser. You should see a JSON response confirming the service is running.

Step 3: Set up the Python Environment

Now, let’s prepare the Python tools.

# 1. Create and activate a virtual environment
python3 -m venv .map_matching
source .map_matching/bin/activate

# 2. Install the required libraries
pip install -r requirements.txt

# 3. Create your configuration file
cp .env.sample .env

The .env file holds all the settings for the scripts, like the Valhalla URL and file paths. The default settings should work perfectly with the Docker setup above.


Part 3: Run the Batch Processor ⚙️

The repository includes a powerful script, map_matching.py, that finds all GPX files in the input folder, processes them in parallel, and saves the results.

To run it, simply execute:

python map_matching.py

The script will:


Part 4: Cherry on top - The Interactive Dashboard 📊

This is where you get to see the magic. The project includes an interactive web dashboard built with Streamlit that lets you upload a trip and instantly see the before-and-after comparison.

You can also try a live map matching demo with a small GPX file right now at mapmatch.streamlit.app!

Launch the dashboard with this command:

streamlit run dashboard/app.py

Your browser will open a new tab with the application. Here, you can:


Conclusion & Next Steps

You now have a complete, local map matching pipeline. With the map_matching.py script and the Streamlit dashboard, you can process large datasets for research and immediately visualize the results for analysis and presentation.

Map Matching results

Side-by-side maps of a random sample of 50,000 trips from a large-scale FCD provider (a) a spaghetti plot of raw FCD trajectories and (b) a heat map of map-matched FCD volume on the road network

Questions?

If you have any questions or feedback, feel free to reach out at [email protected].


Edit page
Share this post:

Previous Post
In search of the right tomato - openpomo.com, a FOSS implementation for yet another Pomodoro app
Next Post
Estimating Traffic Speeds from GPS Trajectories: Leveraging Apache Spark for Floating Car Data (FCD) Analysis