Skip to content

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

http
GET /map-matching/?token=YOUR_API_TOKEN
json
{
  "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"
}
ParameterLocationRequiredDescription
tokenQuery Param✅ YesAPI authentication token. Required, otherwise request will fail with 401 Token required.
shapeBody JSON✅ YesArray of GPS coordinates with at least 2 points. Each point must have lat, lon, and a type (break or via).
costingBody JSON✅ YesTravel mode. Options: auto, pedestrian, bicycle, bus,motor_scooter.
shape_matchBody JSON❌ NoControls 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 typeDescription
edge_walkIndicates 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_snapIndicates 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_snapAlso 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:

ItemDescription
namesList of names
sourceThe 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.
targetThe 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.
lengthThe retrieved edge's length in the units specified (default is kilometers). If unavailable, we represent the partially matched length, otherwise full length percent.
speedEdge's specified speed. The default is kilometers per hour.
from.typeDescribes how the shape was assigned to the edge. Either it’s inferred from road class (default value) or set by the user.
speed.fadedContains 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_fadedContains 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_classRoad class value.
begin.headingThe direction at the beginning of the edge. The units are degrees from north in a clockwise direction.
end.headingThe direction at the end of the edge. The units are degrees from north in a clockwise direction.
begin_shape_indexIndex of the list of shape points for the start of the edge.
end_shape_indexIndex of the list of shape points for the end of the edge.
traversabilityTraversability value, if available.
useUse value.
tollToll value.
unpavedUnpaved value.
tunnelTunnel value.
bridgeBridge value.
roundaboutRoundabout value.
internal_intersectionInternal intersection value.
drive_on_rightDrive on right value.
surfaceSurface value.
sign.exit_numberSign exit number value.
sign.exit_branchSign exit branch value.
sign.exit_towardSign exit toward value.
sign.exit_nameSign exit name value.
travel_modeTravel mode value.
vehicle_typeVehicle type value.
pedestrian_typePedestrian type value.
bicycle_typeBicycle type value.
transit_typeTransit type value.
idID value.
indoorIndoor value.
way_idWay ID value.
weighted_gradeWeighted grade value.
max_upward_gradeMaximum upward grade value.
max_downward_gradeMaximum downward grade value.
mean_elevationMean elevation value.
lane_countLane count value.
cycle_laneCycle lane value.
bicycle_networkBicycle network value.
sac_scaleSAC scale value.
shoulderShoulder value.
sidewalkSidewalk value.
densityDensity value.
speed_limitSpeed limit value.
truck_speedTruck speed value.
truck_routeTruck route value.
country_crossingCountry crossing value.
forwardForward value.
traffic_signalTraffic 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 itemDescription
edgesList of edges associated with input shape. See the list of edge items for details.
osm_changesetIdentifier of the OpenStreetMap base data version.
adminsList of the administrative codes and names. See the list of admin items for details.
shapeThe encoded polyline of the matched path.
matched_pointsList 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.
unitsThe specified units with the request, in either kilometers or miles.
warningsA warnings array. This array may contain descriptive text about notices of deprecated request parameters, clamped values etc.

trace_attributes with shape parameter

json
{
  "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

json
{"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

json
{
  "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

json
{"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"}}