Skip to main content

Route arrow

The Navigation SDK allows you to display an arrow on a map that illustrates the next maneuver as a user navigates along a route. This is a common UI component used in turn-by-turn navigation applications.

Use the route maneuver arrow UI component

The route maneuver arrow UI component consists of two main classes:

By default the route maneuver arrow will be displayed as a white arrow on top of the route line (if it exists) or on top of all features in the map. It will be visible for the maneuver that is next based on the device location.

Instantiate the route maneuver arrow API

Instantiate the MapboxRouteArrowApi and MapboxRouteArrowView classes in your Activity or Fragment.

val routeArrow = MapboxRouteArrowApi()
val routeArrowOptions = RouteArrowOptions.Builder(context).build()
val routeArrowView = MapboxRouteArrowView(routeArrowOptions)

To show the next maneuver arrow, register a RouteProgressObserver with MapboxNavigation. When a RouteProgress object is received, call the MapboxRouteArrowApi and pass the result of the arrow calculation to the render method of MapboxRouteArrowView.

private val routeProgressObserver = object : RouteProgressObserver {
override fun onRouteProgressChanged(routeProgress: RouteProgress) {
val updatedManeuverArrow = routeArrow.addUpcomingManeuverArrow(routeProgress)
routeArrowView.renderManeuverUpdate(mapStyle, updatedManeuverArrow)
}
}

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

Customize the route maneuver arrow

There are several ways to customize the route maneuver arrow UI component using RouteArrowOptions.

Position the route arrow 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 maneuver arrow UI component consists of layers that are added to the map.

Position the route arrow relative to map layers
You can read more about the default position of route line layers relative to other map layers and options for cusomtization in the Route line guide.

By default, the maneuver arrow will be placed on top of all the other layers in the map. This is not always the most optimal position for a route arrow because it may appear on top of road labels and other labels on the map. You can specify the route arrow layers' position within all map layers using the aboveLayerId parameter of the RouteArrowOptions. When the maneuver arrow layers are created they will be placed above the layer specified by the aboveLayerId option.

We recommend RouteLayerConstants.TOP_LEVEL_ROUTE_LINE_LAYER_ID as a good starting point which will place the route arrows right above the route line.

val routeArrowOptions = RouteArrowOptions.Builder(this)
.withAboveLayerId(RouteLayerConstants.TOP_LEVEL_ROUTE_LINE_LAYER_ID)
.build()
Compatibility with Mapbox Standard Style
When the route arrow component is used with the Mapbox Standard Style, the layers are added to the MIDDLE slot. Support for selecting the slot to which the route arrows should be inserted will be introduced in future releases.

Add custom arrows

The Navigation SDK supports displaying multiple arrows on the map. An arrow is defined by a collection of at least two Point objects. The arrowhead is placed at the last point in the collection and the direction of the arrowhead is determined by calculating the bearing of the last two points in the collection.

Arrows can be added to and removed from the map before and during navigation. While the next maneuver arrow is managed by the MapboxRouteArrowApi class, it is up to you to manage any other arrows you add to the map.

To add a custom arrow, create an arrow using ManeuverArrow and add it to the view.

val myArrow = ManeuverArrow(
listOf(
Point.fromLngLat(-122.432034, 37.775755),
Point.fromLngLat(-122.431229, 37.775865),
Point.fromLngLat(-122.431293, 37.776255)
)
)

val result = mapboxArrowApi.addArrow(myArrow)
routeArrowView.render(style, result)

To remove an arrow you've added before:

val result = mapboxArrowApi.removeArrow(myArrow)
routeArrowView.render(style, result)
Was this page helpful?