> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/ja/navigation/v2/llms.txt)

# Route generation

Before a user can begin turn-by-turn navigation with your application, you must provide the Navigation SDK with a route. You can generate a route from the [Mapbox Directions API](https://docs.mapbox.com/api/navigation/#directions) using the Navigation SDK by providing both an *origin* and a *destination* `Point` object. There are several ways you can customize the returned route and how it is displayed in your application including:

-   Adding stops (or *waypoints*) between the origin and destination.
-   Making sure the route begins in the direction in which the driver is already traveling to prevent needing a u-turn.
-   Specifying the side of the road to approach when arriving at the destination or at stops along the route.

If you need complete route customization, you can provide a custom already-generated route that is not from the Mapbox Directions API, then transform it into the correct format to be used with the Navigation SDK using the **Mapbox Java SDK's Map Matching wrapper**. For instructions on this process, see the [Use a custom route](#use-a-custom-route) section.

> **Note**
> 
> If you provide both a `DirectionsRoute` and a pair of coordinates (origin and destination), only the `DirectionsRoute` will be used.

## Request a route

The Navigation SDK uses routes generated by the [Mapbox Directions API](https://docs.mapbox.com/api/navigation/#directions). After you've created [a `MapboxNavigation` object](https://docs.mapbox.com/android/ja/navigation/v2/guides/get-started/initialization/), you can use its [`requestRoutes()`](https://docs.mapbox.com/android/navigation/v2/api/2.22.2/libnavigation-core/com.mapbox.navigation.core/-mapbox-navigation/request-routes.html) method to request routes from the Mapbox Directions API.

The method requires a built `RouteOptions` object as defined in the **Mapbox Java SDK's Directions wrapper**. The `RouteOptions` class has convenient methods for setting the various route parameters. You can find full descriptions of each parameter in the [Directions API documentation](https://docs.mapbox.com/api/navigation/directions/#retrieve-directions).

You can use the Java SDK's `RouteOptions.builder` class to create a `RouteOptions` class as you create a new route request. There are many methods that can be used to customize your request, two of which are required:

-   `coordinatesList()`
    -   `origin`: [a `Point` object](https://docs.mapbox.com/android/ja/java/guides/geojson/#geometries)
    -   `destination`: [a `Point` object](https://docs.mapbox.com/android/ja/java/guides/geojson/#geometries)
-   `applyDefaultNavigationOptions()`: if you don't want to customize other options, explicitly use the defaults

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
        .applyDefaultNavigationOptions()
		.coordinatesList(listOf(originPoint, destinationPoint))
		.build()
)
```

The `origin` and `destination` are `Point` coordinates that need to be in a single list of `Point`s. The `origin` should be the first `Point` in the list and the `destination` should be the last `Point`. If there are any other `Point`s in the list between the `origin` and `destination`, these `Point`s are considered [waypoints](#include-waypoint-stops).

> **Related content (example): [Fetch routes between an origin and destination](https://docs.mapbox.com/android/ja/navigation/v2/examples/fetch-a-route/)**
> 
> Fetch routes by specifying two coordinates in `RouteOptions` and passing those options to `MapboxNavigation`'s `requestRoutes` method.

### Include waypoint stops

If your navigation experience involves several stops along the way to the final destination, you can add up to 25 coordinates (including the origin and destination) to the `RouteOptions` builder. The coordinates are treated as stops between the origin and destination `Points` in the order that you add them (the first waypoint `Point` is the first stop along the route):

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
        .applyDefaultNavigationOptions()
		.coordinatesList(listOf(originPoint, firstWaypoint, secondWaypoint, thirdWaypoint, destinationPoint))
		.build()
)
```

### Request a route in a specific direction

The Navigation SDK can make a Directions API request that takes into account the direction the device is facing. The returned route will be ideal for the device's particular *bearing*.

**Device location**: In the adjacent diagram, the blue dot with white stroke is the device location.

**Bearing**: The bearing tells you the direction that a device is facing. It is an angle clockwise from true north between 0 and 359. For example, if the device is facing north, the bearing will be 0°, and if the device is facing due east, the bearing will be 90°. In the adjacent diagram, the pink arrow is the direction that the device is facing (which is due west or 270°).

**Tolerance**: Tolerance is the range of degrees by which a route can deviate from the bearing angle and still be recommended. The semi-transparent blue area illustrates tolerance. In this example tolerance is 90° (45° in either direction from the bearing angle).

The `RouteOptions.builder()`'s `bearingsList()` method is a list of `Bearing` objects where each specifies angle clockwise from true north between 0 and 359 and tolerance, which is the range of degrees by which the angle can deviate (recommended value is 45 or 90).

If the `bearingsList()` method is used, the list of `Bearing` objects must be the same length as the list of `Point`s passed through the `coordinates()` method. But you can skip a coordinate and show its position in the `Bearing` list with the `null` value.

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
        .applyDefaultNavigationOptions()
		.coordinatesList(listOf(originPoint, destinationPoint))
		.bearingsList(
            listOf(
                Bearing.builder()
                    .angle(originLocation.bearing.toDouble())
                    .degrees(45.0)
                    .build(),
                null
            )
        )
		.build()
)
```

### Specify a side of the road to approach

You can state from which side of the road to approach a waypoint by adding [`approaches`](https://docs.mapbox.com/android/java/api/libjava-services/7.10.1/com/mapbox/api/directions/v5/MapboxDirections.Builder.html#approaches-java.util.List-) to the `RouteOptions` builder. There are three options found in the `DirectionsCriteria` class:

-   `"unrestricted"` (default): the route can approach waypoints from either side of the road. Use `DirectionsCriteria.APPROACH_UNRESTRICTED`.
-   `"curb"`: Return the route in a way that, upon arrival, the waypoint is located on the side corresponding to the `driving_side` of the region where the route is situated. Use `DirectionsCriteria.APPROACH_CURB`.
-   `null`: if no option is specified, it is translated internally to `""`, which has the same result as setting an approach to `"unrestricted"`. Use `null`.

If provided, the list of approaches must be the same length as the list of coordinates (including the `origin` and the `destination`) and in that particular order (`origin`, waypoints, `destination`).

If a re-route occurs and `approaches` were used to fetch the first `DirectionsRoute`, the new route fetched will take the same `approaches` criteria into account.

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
        .applyDefaultNavigationOptions()
		.coordinatesList(listOf(originPoint, firstWaypoint, secondWaypoint, thirdWaypoint, destinationPoint))
		.approachesList(listOf(DirectionsCriteria.APPROACH_UNRESTRICTED,
		DirectionsCriteria.APPROACH_UNRESTRICTED, DirectionsCriteria.APPROACH_CURB, null, DirectionsCriteria.APPROACH_CURB))
		.build()
)
```

### Add silent waypoints

Unlike [other waypoints](#include-waypoint-stops) that are treated as a stops between [route's legs](https://docs.mapbox.com/android/ja/navigation/v2/guides/turn-by-turn-navigation/route-progress/#levels-of-route-progress), silent waypoints will influence the route so the user passes through the waypoint without specifically mentioning it in maneuver instructions.

By default all coordinates specified in the `coordinatesList` are waypoints. If you want to specify that one or more coordinates in the list should be treated as silent waypoints, use `RouteOption.Builder`'s `waypointIndicesList` method. List the index of each coordinate (as it is in `coordinatesList`) that should be treated as a waypoint and omit the index of coordinates that should be treated as *silent* waypoints.

For example, if you want a route that passes through the `originPoint`, `silentWaypoint`, and `destinationPoint`, but you don't want the driver to *stop* at the middle coordinate, then specify `listOf(0, 2)` as `waypointIndicesList`.

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
		.applyDefaultNavigationOptions()
		.coordinatesList(listOf(originPoint, silentWaypoint, destinationPoint))
		.waypointIndicesList(listOf(0, 2))
		.build(),
	callback
)
```

The Navigation SDK will build a route through all three coordinates but the `silentWaypoint` won't be mentioned anywhere.

### Assign names to waypoints

You can assign a name to any waypoint using `RouteOption.Builder`'s `waypointNamesList` method. Waypoint names are used in the [maneuver UI component](https://docs.mapbox.com/android/ja/navigation/v2/guides/ui-components/maneuver/) and [voice instructions](https://docs.mapbox.com/android/ja/navigation/v2/guides/ui-components/voice/).

The example below shows how to generate a route that begins at an `originPoint` and stops at `"Gas station"` and then `"Work"`.

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
		.applyDefaultNavigationOptions()
		.coordinatesList(listOf(originPoint, gasStationWaypoint, workWayPoint))
		.waypointNamesList(listOf("", "Gas station", "Work"))
		.build(),
	callback
)
```

> **Note: Do not assign names to silent waypoints**
> 
> You can only set names for waypoints that will be treated as stops. You can't set names for silent waypoints. Be careful mixing `waypointIndicesList` and `waypointNamesList`.

### Check the status of a route request

The Navigation SDK's `mapboxNavigation.requestRoutes()` method requires two parameters: a `RouteOptions` object and a [`NavigationRouterCallback`](https://docs.mapbox.com/android/navigation/v2/api/2.22.2/libnavigation-base/com.mapbox.navigation.base.route/-navigation-router-callback/) interface object. The Navigation SDK's `NavigationRouterCallback` interface provides methods, which inform you about the status of a route request.

```kotlin
private val routesReqCallback = object : NavigationRouterCallback {

    override fun onRoutesReady(
        routes: List<NavigationRoute>,
        routerOrigin: RouterOrigin
    ) {
        mapboxNavigation.setNavigationRoutes(routes)
    }

    override fun onCanceled(routeOptions: RouteOptions, routerOrigin: RouterOrigin) {
    }

    override fun onFailure(reasons: List<RouterFailure>, routeOptions: RouteOptions) {
    }
}
```

Add the `NavigationRouterCallback` object to the `mapboxNavigation.requestRoutes()` method:

```kotlin
mapboxNavigation.requestRoutes(
	RouteOptions.builder()
		.applyDefaultParams()
		.coordinatesList(listOf(originPoint, destinationPoint))
		.build(),

		routesReqCallback
)
```

### Route request/response models

The request/response models provide 2 types of API: Static and Dynamic. Static is used for stable features of Mapbox Directions API, Dynamic for unlisted, experimental, or Developer Preview features.

#### Static API

This is the type of interaction that's presented above - accessing/setting stable properties via plain Java getters/builders for every stable property from Directions API's response models.

Here is an example accessing `duration` property from the [route object](https://docs.mapbox.com/api/navigation/directions/#route-object):

```kotlin
directionsRoute.duration()
```

You can use builders to create and update models. Every model has an associated builder. The builder can be created by calling a static `builder()` method on a model's class or by calling `toBuilder()` on a model's instance. See an example of `RouteOptions` creation via the builder:

```
RouteOptions.builder()
	.applyDefaultNavigationOptions()
	.applyLanguageAndVoiceUnitOptions(this)
	.coordinatesList(listOf(origin, destination))
	.build()
```

#### Dynamic API

To reference Directions API features that are either unlisted, experimental, or in a Developer Preview phase, you can use `DirectionsJsonObject#getUnrecognizedProperty`.

For example, if Directions API [route object](https://docs.mapbox.com/api/navigation/directions/#route-object) had a `duration_experimental` property marked as a preview, you would be able to access it like in the example below:

```kotlin
directionsRoute.getUnrecognizedProperty("duration_experimental")
```

`DirectionsJsonObject#getUnrecognizedProperty` returns a `JsonElement`. You can extract and cast the value based on the documented type.

For example, if `duration_experimental` from the previous example had a type `number` in documentation, you would be able to convert it to `double`.

```kotlin
directionsRoute.getUnrecognizedProperty("duration_experimental")?.asDouble
```

Read [gson's documentation](https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.6/com.google.gson/com/google/gson/JsonElement.html) to learn how to access data from a `JsonElement`.

You can't set unrecognized properties to models. The only exception is `RouteOptions` that is used to create Directions API request.

Use `RouteOptions.Builder#unrecognizedProperties` if you want to add an unlisted, experimental, or preview parameter to a request:

```kotlin
RouteOptions.builder()
    .applyLanguageAndVoiceUnitOptions(this)
	.coordinatesList(listOf(origin, destination))
    .unrecognizedProperties(mapOf(
        "experimentalParameterName" to "experimentalParameterValue"
    ))
    .build()
```

## Set an active route for navigation

Once you have a reference to available routes, you can set a primary route that will be used for navigation by calling `MapboxNavigation#setNavigationRoutes()`.

```kotlin
private val routesReqCallback = object : NavigationRouterCallback {
    override fun onRoutesReady(
        routes: List<NavigationRoute>,
        routerOrigin: RouterOrigin
    ) {
        mapboxNavigation.setNavigationRoutes(routes)
    }

    override fun onCanceled(routeOptions: RouteOptions, routerOrigin: RouterOrigin) {
    }

    override fun onFailure(reasons: List<RouterFailure>, routeOptions: RouteOptions) {
    }
}
```

If the list is not empty, the route at index 0 is valid, and the trip session is started, then the SDK enters an `Active Guidance` state and `RouteProgress` updates will be available.

> **Note: Trip session state**
> 
> Read more about navigation session management in the Types of navigation section of the [Initialize the SDK](https://docs.mapbox.com/android/ja/navigation/v2/guides/get-started/initialization/) guide.

## Style a route

Use the Navigation SDK to design an application that provides a unique experience for your users or fits your brand. The Navigation SDK offers a wide range of options for customizing the look of your application including navigation instructions, route lines, and map style.

### Day and night mode

### Summary bottom sheet

### Navigation view

## Listen for route changes

Use the Navigation SDK's [`RoutesObserver`](https://docs.mapbox.com/android/navigation/v2/api/2.22.2/libnavigation-core/com.mapbox.navigation.core.directions.session/-routes-observer/) interface if you want to know when the routes list has changed.

This observer will be called with a new list of routes when:

-   Routes were changed with `MapboxNavigation.setNavigationRoutes`
-   Routes annotations were refreshed (for example, a congestion annotation that provides information about the live traffic along the route)
-   A driver went off route and a reroute was executed

The `RoutesObserver` is the source of truth for route updates. You should use it for all route-related actions (like updating UI elements or drawing a route on a map).

The route at index 0 in this list is always considered the primary route, while the rest are potential alternative routes. You can get the current list of routes with `getNavigationRoutes()`:

```kotlin
val currentRoutes = mapboxNavigation.getNavigationRoutes()
```

```kotlin
private val routesObserver = object : RoutesObserver {
	override fun onRoutesChanged(routes: List<DirectionsRoute>) {

	}
}
```

Register the `RoutesObserver` interface with [your already-instantiated `MapboxNavigation` object](https://docs.mapbox.com/android/ja/navigation/v2/guides/get-started/initialization/).

```kotlin
mapboxNavigation.registerRoutesObserver(routesObserver)
```

Don't forget to unregister the `RoutesObserver` interface:

```kotlin
override fun onStop() {
	super.onStop()
	mapView.onStop()
	mapboxNavigation.unregisterRoutesObserver(routeProgressObserver)
}
```

## Use a custom route

In some cases, you may want your user to navigate along a route that doesn't match the [Mapbox Directions API](https://docs.mapbox.com/api/navigation/#directions) route's structure while still using the Mapbox Navigation SDK. The [Mapbox Java SDK's Map Matching wrapper](https://docs.mapbox.com/android/ja/java/guides/services/map-matching/) 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()`](https://docs.mapbox.com/android/java/api/libjava-services/7.10.1/com/mapbox/api/matching/v5/MapboxMapMatching.Builder.html), 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.

To get started with creating a map matched `DirectionsRoute`, first [install the Java SDK's `services` module into your project](https://docs.mapbox.com/android/ja/java/guides/install).

Your `MapboxMapMatching` request will need a `List` of [`Point` geometry objects](https://docs.mapbox.com/android/ja/java/guides/geojson/#geometries) that represent the custom route you want to match with the road network.

```kotlin
val singlePoint = Point.fromLngLat()
```

Create a `MapboxMapMatching` request:

```kotlin
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](https://docs.mapbox.com/android/ja/navigation/v2/guides/get-started/initialization/):

```kotlin
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().toNavigationRoute(
                    RouterOrigin.Custom()
                ).apply {
                    mapboxNavigation?.setNavigationRoutes(listOf(this))
                }
	        }

	    }
	}

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

	}
})
```

When using `MapboxMapMatching` with the Navigation SDK, you need to make a few changes to your setup to make sure re-routes are successful. A custom `RerouteController` must be added to your `MapboxNavigation` or rerouting needs to be disabled entirely. Otherwise, Navigation SDK would try to request a new route directly from [Mapbox Directions API](https://docs.mapbox.com/api/navigation/#directions).