Custom routes

In some cases, you may want your user to navigate along a route that doesn't match the Mapbox Directions API route's structure, while still using the Mapbox Navigation SDK. Mapbox Java SDK's Map Matching API wrapper is an appropriate tool for turning your custom route into a route that the Navigation SDK can process.

Map match to generate a route

Map matching is the art of taking coordinates and aligning them along a road network. After providing coordinates to the Java SDK's MapboxMapMatching.builder(), the Java SDK makes the request to the Mapbox Map Matching API, and then the API returns a route that can be used in the Navigation SDK for Android.

Note

Map matching to create a route is only possible for the initial route. Making a Map Matching API call while in turn-by-turn navigation isn't possible because the Navigation SDK's internal logic checks whether the device has gone off the intended route. If so, it automatically requests a new route from the Mapbox Directions API. This off-route requesting would clash with making another Map Matching API call as the device is moving.

To get started with creating a map matched DirectionsRoute, first install the Java SDK's services module into your project.

Navigation UI SDK

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

override fun allowRerouteFrom(offRoutePoint: Point): Boolean {

  // Fetch new route with MapboxMapMatching

  // Create new options with map matching response route
  val options = NavigationViewOptions.builder()
    .directionsRoute(mapMatchingDirectionsRoute)
    .build()
  navigationView.startNavigation(options)

  // Ignore internal routing, allowing MapboxMapMatching call
  return false
}

Your MapboxMapMatching request will need a List of Point geometry objects that represent the custom route you want to match with the road network.

val singlePoint = Point.fromLngLat()

Create a MapboxMapMatching request:

val mapboxMapMatchingRequest = MapboxMapMatching.builder()
    .accessToken(getString(R.string.mapbox_access_token))
    .coordinates(customRoutePointList)
    .steps(true)
    .voiceInstructions(true)
    .bannerInstructions(true)
    .profile(DirectionsCriteria.PROFILE_DRIVING)
    .build()

If successful, the response will have a matched route. Convert this route to a DirectionsRoute and give it to the already-instantiated MapboxNavigation object:

mapboxMapMatchingRequest.enqueueCall(object : Callback<MapMatchingResponse> {
    override fun onResponse(call: Call<MapMatchingResponse>, response: Response<MapMatchingResponse>) {
        if (response.isSuccessful) {
            response.body()?.matchings()?.let { matchingList ->
                matchingList[0].toDirectionRoute().apply {
                    mapboxNavigation?.setRoutes(listOf(this))
                }
            }

        }
    }

    override fun onFailure(call: Call<MapMatchingResponse>, throwable: Throwable) {

    }
})
example
Map matching

See how to use the Java SDK's Map Matching API wrapper to match points to the world's road and path network.

Was this page helpful?