Map Matching API
The Map Matching API lets you match geographical coordinates, such as GPS tracks, to the existing road network.
You can choose between various transportation modes, including cars, buses, delivery trucks, bicycles, and walking.
The API returns the reconstructed route geometry as well as details about the road segments that make up a route, including speed limit, road surface, and more. This makes it an excellent choice for route visualization and analysis.
Authentication and API key
To use the Map Marching API, you'll need a Geoapify API key. You can register and get an API Key.
We'll never ask for money before you're ready. Try us for FREE and upgrade to a paid plan when the needs of your project increase. For more information on our plans, visit the Pricing page.
How to get Geoapify API key
- Register on Geoapify MyProjects page
- Create a new project.
- Go to the API Keys section. One API key is generated automatically. You can generate multiple API keys per project if required.
- Optionally, you can protect the API key by listing allowed IP addresses, HTTP referrers, origins, and CORS.
- Choose "Map Matching API" and an API key to generate a URL and programming code.
- Press the "Try" button to execute the API call and get the result object example.
API reference
The Map Matching API works via POST request that allows sending up to 1000 of location points in the request body.
API URL
POST https://api.geoapify.com/v1/mapmatching
HEADERS 'Content-Type: application/json'
Request parameters
Name | Description |
---|---|
apiKey | Your Geoapify API key |
Request body parameters
Name | Description |
---|---|
waypoints | Array of waypoints |
waypoints.location | Location represented as an array of coordinates: [longitude, latitude] |
waypoints.timestamp | Optional field. ISO formatted timestamp. Helps to calculate effective speed and filter incorrect waypoints. |
waypoints.bearing | Optional field. Number [0, 360] . Helps to determine speed more accurately. |
mode | Transportation or travel mode. Possible values: "drive", "walk", "bicycle" |
Below is an example of the API call:
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:45.000Z",
"location":[
10.6950319,
47.567783
]
},
...
]
}
}
Response Object
The response contains a GeoJSON FeatureCollection object with the "MultiLineString" type feature, which represents the route. The FeatureCollection object properties contain detailed route legs, steps, and matched points.
By default, the API response FeatureCollection contains only one feature so that you can address it as the first element of the collection, for example, result.feature[0]
. Here is the structure of the feature properties object:
Name | Description |
---|---|
distance | Distance in meters for the whole route |
time | Time in seconds for the whole route |
mode | Requested transportation or travel mode |
waypoints | An array of MatchedWaypoint |
legs | An array of RouteLeg. Each leg represents separate parts of the route. |
MatchedWaypoint
Contains information about an original waypoint and matched location.
Name | Description |
---|---|
original_index | Original index of the waypoint in request |
location | Matched location. An array of the coordinates: [lon, lat] |
original_location | Original location. An array of the coordinates: [lon, lat] |
match_type | Matched type. Possible values: matched , unmatched , interpolated |
match_distance | Distance in meters between matched and original locations |
leg_index | Leg index, the waypoint belongs to |
step_index | Step point, the waypoint belongs to |
RouteLeg
Contains information about a route between 2 locations.
Name | Description |
---|---|
distance | Length of the route in meters |
time | Time in seconds for the route |
steps | An array of LegStep. Steps of the route |
LegStep
Contains information about a step or segment of a RouteLeg:
Name | Description |
---|---|
name | Route step name. Usually a street name |
road_class | Road class. Possible values: unclassified , motorway , trunk , primary , secondary , tertiary , unclassified , residential , service_other |
surface | Type of surface. Possible values: paved_smooth , paved , paved_rough , compacted , dirt , gravel , path , impassable |
traversability | Traversability of the road segment. Possible values: forward , backward , both |
speed | Actual (calculated) speed |
speed_limit | Speed limit for the road segment |
lane_count | Number of lanes |
toll | Indicates whether the step is a part of a toll route |
tunnel | Indicates whether the step is a part of a tunnel |
bridge | Indicates whether the step is a part of a bridge |
time | Time in seconds required to pass the road segment |
distance | Length of the route segment in meters |
begin_bearing | Starting bearing |
end_bearing | Final bearing |
from_index | An index of the starting point for the segment in the corresponding feature coordinates array |
to_index | An index of the end point for the segment in the corresponding feature coordinates array |
osm_way_id | OpenStreetMap way id. You can get additional route parameters from the OSM database by using the id parameter. Note that the OpenStreetMap ID is not static and may be changed in the future. |
Here is an example of the response object:
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"properties":{
"distance":4609,
"time":324,
"legs":[
{
"time":324,
"distance":4609,
"steps":[
{
"speed":40,
"speed_limit":50,
"surface":"paved_smooth",
"lane_count":1,
"road_class":"unclassified",
"from_index":0,
"to_index":1,
"name":"Morisse",
"traversability":"both",
"time":1,
"distance":9,
"begin_bearing":25,
"end_bearing":25
},
...
]
}
],
"mode":"drive",
"waypoints":[
{
"original_index":0,
"location":[ 10.694686, 47.567033 ],
"original_location":[ 10.694703, 47.567028 ],
"match_type":"matched",
"match_distance":1.369,
"leg_index":0,
"step_index":0
},
...
]
},
"geometry":{
"type":"MultiLineString",
"coordinates":[...]
}
Code samples
Get route steps
By default, the resulting Map Matching Feature geometry contains the whole route. However, sometimes it's required to split the route info the steps and points between them. Here is an example of how this can be done.
We used Turf library to operate with GeoJSON objects. You can install the library by running npm install @turf/helpers
.
import {
FeatureCollection,
multiPoint,
lineString,
point,
featureCollection,
Feature,
LineString,
Point,
MultiLineString,
} from "@turf/helpers";
// mapMatchingData => the FeatureCollection object returned by Map Matching API
function splitMapMatchingResultIntoSteps(mapMatchingData: FeatureCollection) {
const legSteps: Feature<LineString, any>[] = [];
const pointsBetweenSteps: Feature<Point, any>[] = [];
if (!mapMatchingData.features?.length) {
return null;
}
mapMatchingData.features[0].properties.legs.forEach((leg, index) => {
const points: number[][] = (mapMatchingData.features[0]
.geometry as MultiLineString).coordinates[index];
leg.steps.forEach((step, index) => {
const stepCoords: number[][] = points.slice(
step.from_index,
step.to_index + 1
);
legSteps.push(lineString(stepCoords, step));
if (index > 0) {
pointsBetweenSteps.push(point(points[step.from_index]));
}
});
});
return {
steps: legSteps,
points: pointsBetweenSteps
}
}
Pricing
We use credits to calculate the cost of an API call. Credits are a unified unit that keeps our pricing policy straightforward and simple.
We offer four different Pricing Plans depending on usage amounts. First, you can sign up for our Free plan, which gives you 3,000 credits per day. Once your usage exceeds this amount, you can upgrade to a more advanced plan.
The pricing model for the Map Matching API is as follows:
Rule | Description | Example |
---|---|---|
100 waypoint = 1 credit | Every 100 matched waypoints costs 1 credit | 567 waypoints cost 6 credits |