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

# Route line

The Navigation SDK allows you to display route lines on a map, which is an integral component used in turn-by-turn navigation applications.

The interfaces described in this guide provide abstractions to prepare the navigation data and visualize it on a Mapbox Map.

## Use the route line UI component

The route line UI component consists of two main classes:

-   The [`MapboxRouteLineApi`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.api/-mapbox-route-line-api/) has methods for creating and modifying the route line and producing data describing the view related mutations.
-   The [`MapboxRouteLineView`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.api/-mapbox-route-line-view/) handles consuming the data produced by the `MapboxRouteLineApi` and rendering the results on the map.

By default, the route line UI component displays the route as a solid blue line with a darker blue outline.

![A screen shot showing the default style of the route line component.](https://docs.mapbox.com/android/assets/ideal-img/navigation-examples-show-camera-transitions.67c76b6.480.png)

### Instantiate the route line API

Instantiate the `MapboxRouteLineApi` and `MapboxRouteLineView` classes in your `Activity` or `Fragment`.

```kotlin
val routeLineApiOptions = MapboxRouteLineApiOptions.Builder().build()
val routeLineApi = MapboxRouteLineApi(routeLineApiOptions)

val routeLineViewOptions = MapboxRouteLineViewOptions.Builder(context).build()
val routeLineView = MapboxRouteLineView(routeLineViewOptions)
```

Draw a route line by passing a `NavigationRoute` instance to the `MapboxRouteLineApi` and rendering the result with the `MapboxRouteLineView`. Read more about requesting a `NavigationRoute` in the [Route generation](https://docs.mapbox.com/android/navigation/guides/turn-by-turn-navigation/build-the-route/) guide.

A recommended way to draw route lines is by registering a `RoutesObserver` with `MapboxNavigation`:

```kotlin
private val routesObserver = object : RoutesObserver {
    override fun onRoutesChanged(result: RoutesUpdatedResult) {
        /*
        obtain metadata to enhance visualization of alternative routes
        and hide parts that overlap with the primary route
        */
        val alternativesMetadata = mapboxNavigation.getAlternativeMetadataFor(
            result.navigationRoutes
        )
        routeLineApi.setNavigationRoutes(
            result.navigationRoutes,
            alternativesMetadata,
        ) { value ->
            routeLineView.renderRouteDrawData(mapStyle, value)
        }
    }
}
```

This approach ensures that whenever routes get updated the new information will be reflected on the route lines. This includes change in selected primary route, re-drawing routes after a reroute event, refreshes to update congestion information, or removal of invalid alternatives after the fork is passed.

> **Note: Use alternatives metadata**
> 
> Whenever updating the routes, make sure that you're providing the alternative metadata to enhance visualization of alternative routes and hide parts that overlap with the primary route.

Be sure to always unregister observers in `onStop()` or `onDestroy()`.

Also don't forget to cancel any potential in-flight `MapboxRouteLineApi` requests and `MapboxRouteLineView` background tasks:

```kotlin
override fun onDestroy() {
    super.onDestroy()
    routeLineApi.cancel()
    routeLineView.cancel()
}
```

### Request routes with the right data

When requesting a route using `MapboxNavigation` there are some options that are necessary if you want to display traffic congestion on the route line. You can use [`RouteOptions.builder().applyDefaultNavigationOptions()`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/base/com.mapbox.navigation.base.extensions/apply-default-navigation-options.html), which will use the `PROFILE_DRIVING_TRAFFIC` profile and the required annotations.

If you are using custom route options, be sure to use the `PROFILE_DRIVING_TRAFFIC` profile and include at least `ANNOTATION_CONGESTION_NUMERIC` and `ANNOTATION_DISTANCE` in the `annotationsList`. If any of these options are absent, there will not be enough data in the directions response to display traffic congestion on the route line.

```kotlin
val routeOptions = RouteOptions.builder()
	.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
	.annotationsList(
	    listOf(
	        DirectionsCriteria.ANNOTATION_CONGESTION_NUMERIC,
	        DirectionsCriteria.ANNOTATION_DISTANCE
	    )
	)
	.coordinates(listOf(origin, destination))
	.build()
	
mapboxNavigation.requestRoutes(routeOptions, callback)
```

To display alternative route lines, include the `alternatives(true)` route option.

```kotlin
val routeOptions = RouteOptions.builder()
	.alternatives(true)
	.coordinates(listOf(origin, destination))
	.build()
	
mapboxNavigation.requestRoutes(routeOptions, callback)
```

### Handle progress along the route

When progress along the route changes, the `MapboxRouteLineApi` must be updated with the latest information to correctly render active route leg or already traveled route part.

Register a [`RouteProgressObserver`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/navigation/com.mapbox.navigation.core.trip.session/-route-progress-observer/) with `MapboxNavigation` to keep the route line updated.

```kotlin
private val routeProgressObserver = RouteProgressObserver { routeProgress ->
	routeLineApi.updateWithRouteProgress(routeProgress) { result ->
		routeLineView.renderRouteLineUpdate(mapStyle, result)
	}
}
```

Always be sure to unregister observers in `onStop()` or `onDestroy()`.

## Customize the route line

### Differentiate the traveled route part

To visually differentiate the part of the route that has already been traveled from the route ahead, use the route line API's vanishing route line feature. Enabling this feature will make the section of the route line the behind the user's current location transparent by default, or you can configure a custom color.

Enable this feature using the [`MapboxRouteLineApiOptions`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-api-options/). The color can be configured with [`RouteLineColorResources.routeLineTraveledColor`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-route-line-color-resources/-builder/route-line-traveled-color.html).

```kotlin
val routeLineApiOptions = MapboxRouteLineApiOptions.Builder()
    .vanishingRouteLineEnabled(true)
    .build()
```

Then, register an `OnIndicatorPositionChangedListener` with the map location component to pass information about the current location of the user indicator on the map to the route line. This information is used to calculate the part of the route line that needs to be updated.

```kotlin
mapView.location.addOnIndicatorPositionChangedListener(onPositionChangedListener)
```

```kotlin
private val onPositionChangedListener = OnIndicatorPositionChangedListener { point ->
	val result = routeLineApi.updateTraveledRouteLine(point)
	routeLineView.renderRouteLineUpdate(mapStyle, result)
}
```

Always be sure to unregister observers in `onStop()` or `onDestroy()`.

> **Note: Requirements for the traveled route line visualization**
> 
> To change the appearance of the traveled route part, the setting needs to be enabled in `MapboxRouteLineApiOptions` but also data from both the `OnIndicatorPositionChangedListener` and `RouteProgressObserver` (see [Handle route updates](https://docs.mapbox.com/android/navigation/guides/ui-components/route-line/#handle-progress-along-the-route)) needs to be provided.

### Position the route line relative to map layers

The map on which you are displaying your route line contains many individual layers (for example, roads, buildings, labels, and more). The route line UI component consists of multiple layers that are added to the map.

By default, the route line is placed on top of all the other layers in the map. This rarely the most optimal position for a route line because it may appear on top of road labels and other labels on the map.

You can specify the route line layers' vertical position within all map layers using the [`routeLineBelowLayerId`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-options/-builder/route-line-below-layer-id.html) parameter of `MapboxRouteLineViewOptions`. The route line layers will be placed *below* the [layer with the ID](https://docs.mapbox.com/help/glossary/layer/) indicated in the `routeLineBelowLayerId` option.

```kotlin
val routeLineViewOptions = MapboxRouteLineViewOptions.Builder()
	.routeLineBelowLayerId("road-label")
	.build()
```

> **Note: Which layer ID should I use?**
> 
> For navigation-related Mapbox map styles, you can use a `routeLineBelowLayerId` value of `"road-label"`, but this layer is not present in all map styles. If you are using a custom map style or another Mapbox-designed style, you can find the layer IDs that exist in the style by opening the style in Mapbox Studio or printing the style JSON to the console. For more information see [Finding layer ids](https://docs.mapbox.com/help/glossary/layer/#finding-layer-ids).

> **Note (warning): Compatibility with Mapbox Standard Style**
> 
> When the route line component is used with the [Mapbox Standard Style](https://docs.mapbox.com/map-styles/standard/), the layers are added to the `MIDDLE` slot. Support for selecting the slot to which the route line should be inserted will be introduced in future releases.

### Change the style of the route line

The [`MapboxRouteLineViewOptions`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-options/) class offers several options for customizing the style of the route line.

#### Color

You can customize the route line colors by providing [`RouteLineColorResources`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-route-line-color-resources/) to the `MapboxRouteLineViewOptions.Builder` class.

```kotlin
val customColorResources = RouteLineColorResources.Builder()
    .routeDefaultColor(Color.parseColor("#FFCC00"))
    // ... etc
    .build()

val routeLineViewOptions = MapboxRouteLineViewOptions.Builder(this)
    .routeLineColorResources(customColorResources)
    .build()
```

#### Scale

A route line consists of multiple layers on the map. The lowest layer is called the casing layer. Above the casing layer is the main route line layer. And the top layer is a traffic line layer. By default, the casing layer has the greatest width giving the appearance of a border around the route line and traffic line.

The scaling behavior of these lines is determined by the `Expression` class from the Maps SDK. With the `RouteLineResources.Builder` you can customize the scaling expressions rather than using the defaults. See the [Maps SDK documentation](https://docs.mapbox.com/android/maps/guides/) for more information on creating expressions.

```kotlin
val scaleExpressions = RouteLineScaleExpressions.Builder()
    .routeCasingLineScaleExpression(customCasingExpression)
    .routeLineScaleExpression(customRouteLineExpression)
    .routeTrafficLineScaleExpression(customTrafficLineExpression)
    .build()

val routeLineViewOptions = MapboxRouteLineViewOptions.Builder(this)
    .scaleExpressions(scaleExpressions)
    .build()
```

#### Dash pattern

You can render the route line as a dashed (dotted) line, and customize it using [`LineLayersConfigs`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-line-layers-configs/) via `MapboxRouteLineViewOptions.lineLayersConfigs`.

Use [`LineDashConfig`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-line-dash-config/) to specify the dash length and gap length, in line-width units. Omit it (or pass `null`) to render a solid line.

```kotlin
val lineConfig = LineConfig.Builder()
    .lineDashConfig(
        LineDashConfig.Builder()
            .dashLength(0.001)
            .dashGap(1.8)
            .build(),
    )
    .lineCap(LineCap.ROUND)
    .lineJoin(LineJoin.ROUND)
    .build()

val routeLineViewOptions = MapboxRouteLineViewOptions.Builder(context)
    .lineLayersConfigs(LineLayersConfigs.Builder().lineConfig(lineConfig).build())
    .build()
```

To only see the dashed line pattern, you also need to hide the casing layer. See [Control route line layer visibility](#control-route-line-layer-visibility).

### Style inactive route legs

It's common to use routes with [multiple waypoints](https://docs.mapbox.com/android/navigation/guides/turn-by-turn-navigation/route-progress/#levels-of-route-progress). For better route visibility, you may want the route line to visually differentiate between the active route leg and inactive route legs.

When this feature is enabled and properly configured, the inactive route legs will appear a different color (or transparency) than the active route leg, making it clearer to the driver where the route is taking them. As the driver transitions from one route leg to another, the route leg colors will change to differentiate the active route leg from the inactive route legs. This feature only works on routes with multiple waypoints.

Enable this feature by setting the [`MapboxRouteLineApiOptions.styleInactiveRouteLegsIndependently`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-api-options/-builder/style-inactive-route-legs-independently.html) option to `true`.

```kotlin
val routeLineApiOptions = MapboxRouteLineApiOptions.Builder()
    .styleInactiveRouteLegsIndependently(true)
    .build()
```

Set the colors used for inactive route legs using one of the options in the [`RouteLineColorResources`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-route-line-color-resources/) class. There are multiple options to style inactive route legs. For example, you can use [`inActiveRouteLegsColor`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-route-line-color-resources/-builder/in-active-route-legs-color.html) to set the default color of inactive route legs. Additionally, there are options to style congestion levels, restricted roads, or closures on inactive route legs.

```kotlin
val customColorResources = RouteLineColorResources.Builder()
    .inActiveRouteLegsColor(Color.parseColor("#FFCC00"))
    .build()
```

> **Note: Requirements for styling inactive legs**
> 
> To change the appearance of the inactive legs, the setting needs to be enabled in `MapboxRouteLineApiOptions` but also data from the `RouteProgressObserver` (see [Handle route updates](https://docs.mapbox.com/android/navigation/guides/ui-components/route-line/#handle-progress-along-the-route)) needs to be provided.

### Display restricted road sections

The `MapboxRouteLineViewOptions` class includes an option to display roads or sections of roads designated as restricted. When you set this option to true, the route line will display a dashed line.

```kotlin
val routeLineViewOptions = MapboxRouteLineViewOptions.Builder(context)
   .displayRestrictedRoadSections(true)
   .build()
```

Further customization of the restricted road dashed line is available in the `MapboxRouteLineViewOptions` class. The available options are [`restrictedRoadDashArray`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-options/-builder/restricted-road-dash-array.html), [`restrictedRoadOpacity`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-options/-builder/restricted-road-opacity.html) and [`restrictedRoadLineWidth`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-options/-builder/restricted-road-line-width.html). These options are used when creating the layer that contains the restricted line and correspond to the dash line layer options of the Maps SDK. See the [Maps SDK line layer documentation](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.extension.style.layers.generated/-line-layer/#com.mapbox.maps.extension.style.layers.generated/LineLayer/lineDasharray/#/PointingToDeclaration/) for further explanation of these options.

You can configure the color of the dashed line representing restricted roads using the `RouteLineColorResources` class to set the [`restrictedRoadColor`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-route-line-color-resources/-builder/restricted-road-color.html) and [`alternativeRouteRestrictedRoadColor`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-route-line-color-resources/-builder/alternative-route-restricted-road-color.html) options.

```kotlin
val customColorResources = RouteLineColorResources.Builder()
    .restrictedRoadColor(Color.parseColor("#FFCC00"))
    .alternativeRouteRestrictedRoadColor(Color.parseColor("#FFCC00"))
    .build()
```

### Display soft gradient for traffic

Traffic congestion is represented on the route line by different colors. By default there is an abrupt transition from one color to the next. The `MapboxRouteLineViewOptions` class includes an option to display a gradient transition between the colors instead.

There is also an option to influence the length of the gradient transition. A higher value will result in a gradient over a longer length. A smaller value will result in a gradient that is shorter in length. In general, the [`softGradientTransition`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-dynamic-options-builder/soft-gradient-transition.html) option should be a value between 5.0 and 75.0.

```kotlin
val routeLineViewOptions = MapboxRouteLineViewOptions.Builder(context)
    .displaySoftGradientForTraffic(true)
    .softGradientTransition(30.0)
    .build()
```

### Update style at runtime

The route line UI component allows for changing a subset of `MapboxRouteLineViewOptions` at runtime without recreating `MapboxRouteLineView` or `MapboxRouteLineApi`. The specific options that can be changed dynamically are defined in the [`MapboxRouteLineViewDynamicOptionsBuilder`](https://docs.mapbox.com/android/navigation/api/coreframework/3.30.0-rc.1/ui-maps/com.mapbox.navigation.ui.maps.route.line.model/-mapbox-route-line-view-dynamic-options-builder/) class.

```kotlin
routeLineView.updateDynamicOptions(style) {
    routeLineColorResources(newColors)
    // ...
}
routeLineApi.getRouteDrawData {
    routeLineView.renderRouteDrawData(style, it)
}
```

## Control route line layer visibility

`MapboxRouteLineView` exposes methods to show or hide individual layers that make up the route line, without having to redraw or recreate the route line.

For example, to hide the traffic congestion line while keeping the rest of the route line visible:

```kotlin
routeLineView.hideTraffic(style)
// ...
routeLineView.showTraffic(style)
```