Map Matching with Navigation

In some cases, you may want to have the user stick to a very specific route that doesn't fit into the scope covered by the Mapbox Directions API. For example, a company would like to use its own custom truck routing API, but also allow people to navigate on it with the Mapbox Navigation SDK for Android. The Mapbox Map Matching API is an appropriate fit for this situation.

Map Matching is the art of taking coordinates and aligning them along a road network. In the truck example above, a truck routing API would deliver coordinates to the device, the coordinates would be passed to the Mapbox Map Matching API, and then the API would return a route that can be used in the Navigation SDK for Android.

Here is an example of converting a MapboxMapMatching response into a DirectionsRoute:

.enqueueCall(new Callback<MapMatchingResponse>() {
public void onResponse(Call<MapMatchingResponse> call, Response<MapMatchingResponse> response) {
if (response.isSuccessful()) {
DirectionsRoute route = response.body().matchings().get(0).toDirectionRoute();
public void onFailure(Call<MapMatchingResponse> call, Throwable throwable) {

There are several rules you must adhere to when using the Map Matching API with the Navigation SDK for Android:

Map Matching with MapboxNavigation

In the libandroid-navigation module of the Navigation SDK for Android, MapboxMapMatching requests will replace your NavigationRoute requests.

To start navigation initially or to restart navigation after an off-route event has been fired, you can make a map matching request and then convert the MapMatchingMatching response to a DirectionsRoute with MapMatchingMatching#toDirectionRoute.

navigation.addOffRouteListener(new OffRouteListener() {
public void userOffRoute(Location location) {
// Make the Map Matching request here
// Call MapboxNavigation#startNavigation with successful response

Map Matching with NavigationView

When using MapboxMapMatching with the NavigationView, you need to make a few changes to your setup to ensure re-routes are successful. A RouteListener must be added to your NavigationViewOptionsand you must return false in the allowRerouteFrom callback. This will ensure that the NavigationViewdoes not make a Directions API request. Instead, it will wait for the new DirectionsRoute provided by your map matching response.

public boolean allowRerouteFrom(Point offRoutePoint) {
// Fetch new route with MapboxMapMatching
// Create new options with map matching response route
NavigationViewOptions options = NavigationViewOptions.builder()
// Ignore internal routing, allowing MapboxMapMatching call
return false;