Skip to content
This repository has been archived by the owner. It is now read-only.
Switch branches/tags

Map Matching based on GraphHopper

Build Status

Snaps GPX traces to the road using the GraphHopper routing engine.

Read more about the map matching problem at Wikipedia.

See the demo in action (black is GPS track, green is matched result):



Apache License 2.0


Our web forum is here.


Java 8 and Maven >=3.3 are required.


mvn package -DskipTests

Then you need to import an OSM map for the area you want to do map-matching on, e.g. the provided sample data:

java -jar matching-web/target/graphhopper-map-matching-web-3.0-SNAPSHOT.jar import map-data/leipzig_germany.osm.pbf

OpenStreetMap data in pbf or xml format are available from here.

The optional parameter --vehicle defines the routing profile like car, bike, motorcycle or foot. You can also provide a comma separated list. For all supported values see the variables in the FlagEncoderFactory of GraphHopper.

Before re-importing, you need to delete the graph-cache directory, which is created by the import.

Now you can match GPX traces against the map:

java -jar matching-web/target/graphhopper-map-matching-web-3.0-SNAPSHOT.jar match matching-web/src/test/resources/*.gpx

If you were using multiple vehicles for the import you can use --vehicle to select one of them, otherwise the first one will be used.

Web app

Start via:

java -jar matching-web/target/graphhopper-map-matching-web-3.0-SNAPSHOT.jar server config.yml

Access the simple UI via localhost:8989.

You can post GPX files and get back snapped results as GPX or as compatible GraphHopper JSON. An example curl request is:

curl -XPOST -H "Content-Type: application/gpx+xml" -d @matching-web/src/test/resources/test1.gpx "localhost:8989/match?vehicle=car&type=json"


Determine the bounding box of one or more GPX files:

java -jar matching-web/target/graphhopper-map-matching-web-3.0-SNAPSHOT.jar getbounds matching-web/src/test/resources/*.gpx

Java usage

Have a look at to see how the web service is implemented on top of library functions to get an idea how to use map matching in your own project.

Use this Maven dependency:



Note that the edge and node IDs from GraphHopper will change for different PBF files, like when updating the OSM data.


The map matching algorithm mainly follows the approach described in

Newson, Paul, and John Krumm. "Hidden Markov map matching through noise and sparseness." Proceedings of the 17th ACM SIGSPATIAL International Conference on Advances in Geographic Information Systems. ACM, 2009.

This algorithm works as follows. For each input GPS position, a number of map matching candidates within a certain radius around the GPS position is computed. The Viterbi algorithm as provided by the hmm-lib is then used to compute the most likely sequence of map matching candidates. Thereby, the distances between GPS positions and map matching candidates as well as the routing distances between consecutive map matching candidates are taken into account. The GraphHopper routing engine is used to find candidates and to compute routing distances.

Before GraphHopper 0.8, this faster but more heuristic approach was used.