How to Snap a GPS Track to the Road Network
- API or service
- Map Matching API
- Task
- Ordered GPS measurements → matched road route
- Examples
- Difficulty
- Intermediate
- Time
- 10 min
Snap a GPS track to the road network
You have an ordered sequence of noisy GPS measurements from a completed or ongoing trip and need a road-aligned route. The Map Matching API associates those measurements with plausible road positions and returns matched route geometry and road steps.
Map matching preserves input order and follows the recorded track as closely as possible. It does not reorder points or optimize a new trip like the Routing API.
Task flow: ordered GPS measurements → Map Matching API → matched points, road-aligned geometry, and route details.
Submit a GPS track
POST up to 1000 ordered measurements. Each location uses [longitude, latitude] order; ISO timestamps help the matcher evaluate movement between samples.
POST https://api.geoapify.com/v1/mapmatching?apiKey=YOUR_API_KEY
Content-Type: application/json
{
"mode": "drive",
"waypoints": [
{
"timestamp": "2019-11-04T07:09:34.000Z",
"location": [10.694703, 47.567028]
},
{
"timestamp": "2019-11-04T07:09:57.000Z",
"location": [10.6952599, 47.5682759]
},
{
"timestamp": "2019-11-04T07:10:17.000Z",
"location": [10.6975647, 47.5691475]
},
{
"timestamp": "2019-11-04T07:10:49.000Z",
"location": [10.7004255, 47.5696526]
},
{
"timestamp": "2019-11-04T07:11:34.000Z",
"location": [10.7028073, 47.5688025]
},
{
"timestamp": "2019-11-04T07:11:55.000Z",
"location": [10.7059951, 47.5678558]
},
{
"timestamp": "2019-11-04T07:12:16.000Z",
"location": [10.7106272, 47.5658437]
},
{
"timestamp": "2019-11-04T07:12:47.000Z",
"location": [10.7175699, 47.5655232]
}
]
}
Choose the mode that produced the track. An optional bearing from 0 to 360 degrees can provide additional direction context for a measurement.
Read matched points
The response is a GeoJSON FeatureCollection. Its geometry is the reconstructed road route, while properties.waypoints relates each input measurement to its matched location.
Reduced response:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"distance": 2024,
"time": 138,
"waypoints": [
{
"original_index": 0,
"original_location": [10.694703, 47.567028],
"location": [10.694689, 47.56703],
"match_type": "matched",
"match_distance": 1.022797,
"leg_index": 0,
"step_index": 0
},
{
"original_index": 1,
"original_location": [10.6952599, 47.5682759],
"location": [10.695257, 47.568269],
"match_type": "matched",
"match_distance": 0.792993,
"leg_index": 0,
"step_index": 10
},
{
"original_index": 2,
"original_location": [10.6975647, 47.5691475],
"location": [10.697561, 47.569138],
"match_type": "matched",
"match_distance": 1.012806,
"leg_index": 0,
"step_index": 14
}
]
}
}
]
}
original_location preserves the measurement, while location is the road-matched position. match_distance is the distance between them in meters. Do not overwrite the original GPS data when storing matched results.
The route geometry is omitted from this reduced response. The complete feature contains a MultiLineString with 129 road-aligned coordinates for this request.
Handle match quality
Inspect every returned waypoint instead of assuming that all measurements matched successfully.
match_type |
Meaning for the application |
|---|---|
matched |
The measurement was associated with a road position. |
interpolated |
The position was inferred from surrounding matched measurements. |
merged |
A measurement was combined with a nearby measurement. |
unmatched |
No suitable road position was found. |
Use match_distance as a quality signal, but choose thresholds based on the device accuracy, sampling interval, road density, and product requirements. A larger value is not automatically wrong in tunnels, urban canyons, or sparse road networks.
For production tracks:
- keep measurements ordered and retain their original indexes;
- send timestamps and bearings when they are available and reliable;
- split tracks longer than 1000 measurements into manageable chronological chunks;
- detect large time or distance gaps before matching unrelated trip segments together;
- retain original and matched coordinates for auditing;
- handle an empty route or unmatched measurements without breaking visualization or analytics.