Map Matching
Map Matching service, you can match coordinates, such as GPS locations, to roads and paths that have been mapped in OpenStreetMap. By doing this, you can turn a path into a route with narrative instructions and also get the attribute values from that matched line.
Map Matching API (/map-matching/
)
The /map-matching
API is used to match noisy GPS traces onto the road network, reconstructing the most probable route.
Example Request
GET /map-matching/?token=YOUR_API_TOKEN
{
"shape": [
{ "lat": 39.983841, "lon": -76.735741, "type": "break" },
{ "lat": 39.983704, "lon": -76.735298, "type": "via" },
{ "lat": 39.983578, "lon": -76.734848, "type": "via" },
{ "lat": 39.983551, "lon": -76.734253, "type": "break" },
{ "lat": 39.983555, "lon": -76.734116, "type": "via" },
{ "lat": 39.983589, "lon": -76.733315, "type": "via" },
{ "lat": 39.983719, "lon": -76.732445, "type": "via" },
{ "lat": 39.983818, "lon": -76.731712, "type": "via" },
{ "lat": 39.983776, "lon": -76.731506, "type": "via" },
{ "lat": 39.983696, "lon": -76.731369, "type": "break" }
],
"costing": "auto",
"shape_match": "map_snap"
}
Parameter | Location | Required | Description |
---|---|---|---|
token | Query Param | ✅ Yes | API authentication token. Required, otherwise request will fail with 401 Token required . |
shape | Body JSON | ✅ Yes | Array of GPS coordinates with at least 2 points. Each point must have lat , lon , and a type (break or via ). |
costing | Body JSON | ✅ Yes | Travel mode. Options: auto , pedestrian , bicycle , bus ,motor_scooter . |
shape_match | Body JSON | ❌ No | Controls the map matching behavior. Common values: map_snap (default) Options: walk_or_snap , map_snap , edge_walk |
Shape Match Options details
shape_match
is an optional string input parameter. It allows some control of the matching algorithm based on the type of input.
shape_match type | Description |
---|---|
edge_walk | Indicates an edge walking algorithm can be used. This algorithm requires nearly exact shape matching, so it should only be used when the shape is from a prior Valhalla route. |
map_snap | Indicates that a map-matching algorithm should be used because the input shape might not closely match Valhalla edges. This algorithm is more expensive. |
walk_or_snap | Also the default option. This will try edge walking and if this does not succeed, it will fall back and use map matching. |
Attribute filters (trace_attributes only)
The trace_attributes action allows you to apply filters to include or exclude specific attribute filter keys in your response. These filters are optional and can be added to the action string inside of the filters object.
// Edge filter Keys
edge.names
edge.length # can also set source/target_percent_along
edge.speed
edge.speeds_faded
edge.speeds_non_faded
edge.road_class
edge.begin_heading
edge.end_heading
edge.begin_shape_index
edge.end_shape_index
edge.traversability
edge.use
edge.toll
edge.unpaved
edge.tunnel
edge.bridge
edge.roundabout
edge.internal_intersection
edge.drive_on_right
edge.surface
edge.sign.exit_number
edge.sign.exit_branch
edge.sign.exit_toward
edge.sign.exit_name
edge.travel_mode
edge.vehicle_type
edge.pedestrian_type
edge.bicycle_type
edge.transit_type
edge.id
edge.indoor
edge.way_id
edge.weighted_grade
edge.max_upward_grade
edge.max_downward_grade
edge.mean_elevation
edge.lane_count
edge.cycle_lane
edge.bicycle_network
edge.sac_scale
edge.shoulder
edge.sidewalk
edge.density
edge.speed_limit
edge.truck_speed
edge.truck_route
edge.country_crossing
edge.forward
edge.traffic_signal
// Node filter keys
node.intersecting_edge.begin_heading
node.intersecting_edge.from_edge_name_consistency
node.intersecting_edge.to_edge_name_consistency
node.intersecting_edge.driveability
node.intersecting_edge.cyclability
node.intersecting_edge.walkability
node.intersecting_edge.use
node.intersecting_edge.road_class
node.intersecting_edge.lane_count
node.elapsed_time
node.admin_index
node.type
node.traffic_signal
node.fork
node.time_zone
// Other filter keys
osm_changeset
shape
admin.country_code
admin.country_text
admin.state_code
admin.state_text
matched.point
matched.type
matched.edge_index
matched.begin_route_discontinuity
matched.end_route_discontinuity
matched.distance_along_edge
matched.distance_from_trace_point
Edge items include:
Item | Description |
---|---|
names | List of names |
source | The start of an edge's matched percentage of its length (0, range if edge was fully matched; end of an edge's matched percentage of its length (0, range if edge was fully matched); we set value to percentage of its length in units specified (default is kilometers). If percentage is unavailable, we set value to -1. |
target | The end of an edge's matched percentage of its length (0, range if edge was fully matched); we set value to percentage of its length in units specified (default is kilometers). If percentage is unavailable, we set value to -1. |
length | The retrieved edge's length in the units specified (default is kilometers). If unavailable, we represent the partially matched length, otherwise full length percent. |
speed | Edge's specified speed. The default is kilometers per hour. |
from.type | Describes how the shape was assigned to the edge. Either it’s inferred from road class (default value) or set by the user. |
speed.faded | Contains all speed values that are faded in the current time (if available). The current value fades with the flow rates when they are available. |
speed.non_faded | Contains all flow rates when speed is available that the edge is not the units specified (default flow rates are in kilometers per hour). All flows are available when speed is available. |
road_class | Road class value. |
begin.heading | The direction at the beginning of the edge. The units are degrees from north in a clockwise direction. |
end.heading | The direction at the end of the edge. The units are degrees from north in a clockwise direction. |
begin_shape_index | Index of the list of shape points for the start of the edge. |
end_shape_index | Index of the list of shape points for the end of the edge. |
traversability | Traversability value, if available. |
use | Use value. |
toll | Toll value. |
unpaved | Unpaved value. |
tunnel | Tunnel value. |
bridge | Bridge value. |
roundabout | Roundabout value. |
internal_intersection | Internal intersection value. |
drive_on_right | Drive on right value. |
surface | Surface value. |
sign.exit_number | Sign exit number value. |
sign.exit_branch | Sign exit branch value. |
sign.exit_toward | Sign exit toward value. |
sign.exit_name | Sign exit name value. |
travel_mode | Travel mode value. |
vehicle_type | Vehicle type value. |
pedestrian_type | Pedestrian type value. |
bicycle_type | Bicycle type value. |
transit_type | Transit type value. |
id | ID value. |
indoor | Indoor value. |
way_id | Way ID value. |
weighted_grade | Weighted grade value. |
max_upward_grade | Maximum upward grade value. |
max_downward_grade | Maximum downward grade value. |
mean_elevation | Mean elevation value. |
lane_count | Lane count value. |
cycle_lane | Cycle lane value. |
bicycle_network | Bicycle network value. |
sac_scale | SAC scale value. |
shoulder | Shoulder value. |
sidewalk | Sidewalk value. |
density | Density value. |
speed_limit | Speed limit value. |
truck_speed | Truck speed value. |
truck_route | Truck route value. |
country_crossing | Country crossing value. |
forward | Forward value. |
traffic_signal | Traffic signal value. |
Outputs of trace_attributes
The trace_attributes
results contains a list of edges and, optionally, the following items: osm_changeset
, list of admins
, shape
, matched_points
, and units
.
Result item | Description |
---|---|
edges | List of edges associated with input shape. See the list of edge items for details. |
osm_changeset | Identifier of the OpenStreetMap base data version. |
admins | List of the administrative codes and names. See the list of admin items for details. |
shape | The encoded polyline of the matched path. |
matched_points | List of match results when using the map_snap shape match algorithm. There is a one-to-one correspondence with the input set of latitude, longitude coordinates and this list of match results. See the list of matched point items for details. |
units | The specified units with the request, in either kilometers or miles. |
warnings | A warnings array. This array may contain descriptive text about notices of deprecated request parameters, clamped values etc. |
trace_attributes with shape parameter
{
"shape": [
{ "lat": 39.983841, "lon": -76.735741, "type": "break" },
{ "lat": 39.983704, "lon": -76.735298, "type": "via" },
{ "lat": 39.983578, "lon": -76.734848, "type": "via" },
{ "lat": 39.983551, "lon": -76.734253, "type": "break" },
{ "lat": 39.983555, "lon": -76.734116, "type": "via" },
{ "lat": 39.983589, "lon": -76.733315, "type": "via" },
{ "lat": 39.983719, "lon": -76.732445, "type": "via" },
{ "lat": 39.983818, "lon": -76.731712, "type": "via" },
{ "lat": 39.983776, "lon": -76.731506, "type": "via" },
{ "lat": 39.983696, "lon": -76.731369, "type": "break" }
],
"costing": "motor_scooter",
"shape_match": "walk_or_snap",
"filters": {
"attributes": [
"edge.names",
"edge.id",
"edge.weighted_grade",
"edge.speed"
],
"action": "include"
}
}
trace_attributes with encoded polyline parameter
{"shape":[{"lat":39.983841,"lon":-76.735741,"type":"break"},{"lat":39.983704,"lon":-76.735298,"type":"via"},{"lat":39.983578,"lon":-76.734848,"type":"via"},{"lat":39.983551,"lon":-76.734253,"type":"break"},{"lat":39.983555,"lon":-76.734116,"type":"via"},{"lat":39.983589,"lon":-76.733315,"type":"via"},{"lat":39.983719,"lon":-76.732445,"type":"via"},{"lat":39.983818,"lon":-76.731712,"type":"via"},{"lat":39.983776,"lon":-76.731506,"type":"via"},{"lat":39.983696,"lon":-76.731369,"type":"break"}],"encoded_polyline":"_grbgAh~{nhF?lBAzBFvBHxBEtBKdB?fB@dBZdBb@hBh@jBb@x@\\|@x@pB\\x@v@hBl@nBPbCXtBn@|@z@ZbAEbAa@~@q@z@QhA]pAUpAVhAPlAWtASpAAdA[dASdAQhAIlARjANnAZhAf@n@`A?lB^nCRbA\\xB`@vBf@tBTbCFbARzBZvBThBRnBNrBP`CHbCF`CNdCb@vBX`ARlAJfADhA@dAFdAP`AR`Ah@hBd@bBl@rBV|B?vB]tBCvBBhAF`CFnBXtAVxAVpAVtAb@|AZ`Bd@~BJfA@fAHdADhADhABjAGzAInAAjAB|BNbCR|BTjBZtB`@lBh@lB\\|Bl@rBXtBN`Al@g@t@?nAA~AKvACvAAlAMdAU`Ac@hAShAI`AJ`AIdAi@bAu@|@k@p@]p@a@bAc@z@g@~@Ot@Bz@f@X`BFtBXdCLbAf@zBh@fBb@xAb@nATjAKjAW`BI|AEpAHjAPdAAfAGdAFjAv@p@XlAVnA?~A?jAInAPtAVxAXnAf@tBDpBJpBXhBJfBDpAZ|Ax@pAz@h@~@lA|@bAnAd@hAj@tAR~AKxAc@xAShA]hAIdAAjA]~A[v@BhB?dBSv@Ct@CvAI~@Oz@Pv@dAz@lAj@~A^`B^|AXvAVpAXdBh@~Ap@fCh@hB\\zBN`Aj@xBFdA@jALbAPbAJdAHdAJbAHbAHfAJhALbA\\lBTvBAdC@bC@jCKjASbC?`CM`CDpB\\xAj@tB\\fA\\bAVfAJdAJbAXz@L|BO`AOdCDdA@~B\\z@l@v@l@v@l@r@j@t@b@x@b@r@z@jBVfCJdAJdANbCPfCF|BRhBS~BS`AYbAe@~BQdA","shape_match":"map_snap","costing":"pedestrian","directions_options":{"units":"miles"}}
trace_attributes with include attribute filter
{
"shape":[{"lat":39.983841,"lon":-76.735741},{"lat":39.983704,"lon":-76.735298},{"lat":39.983578,"lon":-76.734848},{"lat":39.983551,"lon":-76.734253},{"lat":39.983555,"lon":-76.734116},{"lat":39.983589,"lon":-76.733315},{"lat":39.983719,"lon":-76.732445},{"lat":39.983818,"lon":-76.731712},{"lat":39.983776,"lon":-76.731506},{"lat":39.983696,"lon":-76.731369}],"costing":"auto","shape_match":"walk_or_snap","filters":{"attributes":["edge.names","edge.id", "edge.weighted_grade","edge.speed"],"action":"include"}
}
trace_attributes with exclude attribute filter
{"shape":[{"lat":39.983841,"lon":-76.735741},{"lat":39.983704,"lon":-76.735298},{"lat":39.983578,"lon":-76.734848},{"lat":39.983551,"lon":-76.734253},{"lat":39.983555,"lon":-76.734116},{"lat":39.983589,"lon":-76.733315},{"lat":39.983719,"lon":-76.732445},{"lat":39.983818,"lon":-76.731712},{"lat":39.983776,"lon":-76.731506},{"lat":39.983696,"lon":-76.731369}],"costing":"auto","shape_match":"walk_or_snap","filters":{"attributes":["edge.names","edge.begin_shape_index","edge.end_shape_index","shape"],"action":"exclude"}}