Route replay
Testing and previewing the navigation experience is an important part of building with the Navigation SDK. You might want to investigate how turn-by-turn navigation performed during test rides as you develop, test, and demo your work. This page references how to go back in time and replay real rides using the Navigation SDK.
Implement replay
The Navigation SDK's replay framework is comprised of two core classes:
MapboxReplayer
handles shifting historical event timestamps into real-time events.ReplayEventBase
is an interface for anything with a time unit. The time basis can be months in the past, in the future, or starting at0.0
.
There are also several helper classes you can use to create and listen to replay events:
ReplayHistoryMapper
converts history files into replay events.ReplayLocationEngine
extends the Android system'sLocationEngine
class. It observes theReplayEventUpdateLocation
and passes the location toMapboxNavigation
.ReplayRouteMapper
converts aDirectionsResponse
into replay events.ReplayProgressObserver
observes Mapbox navigation and simulates route progress.
Record and use history files
Record a history file
To record a trip as a history file:
- Start recording by calling
MapboxNavigation.toggleHistory(true)
. - At the end of the recording, call
MapboxNavigation.retrieveHistory
. - Save the history string.
Retrieve history files
There are two ways to retrieve a recorded history file to be used on a device:
- Store the JSON file in a directory and read the file. The Navigation SDK test app's
ReplayHistoryActivity
example uses this approach. The file is stored in the app's assets folder. - Host history files somewhere in a cloud-based backend database (for example Firebase, Amazon Web Services, or GitHub Pages).
Replay history data
After you've retrieved the history file, you can replay the history data using MapboxReplayer
:
- Map the history string to replay events using
ReplayHistoryMapper
. - Push the events into the
MapboxReplayer.pushEvents(..)
. - Substitute your
LocationEngine
with aReplayLocationEngine
. - Call
MapboxReplayer.play()
. - When done call
MapboxReplayer.finish()
to stop and clean up the replayer.
Replay history using real data by reading a history string from a file and replaying it with the Navigation SDK.
Create custom events
You can create custom events and play them on their own or play them through history files.
Replay custom events
You can replay any event you want, for example a map gesture event or zooming in and out of the map, to test on its own (without a history file). The Navigation SDK's ReplayRouteMapper
class creates location events from the DirectionsResponse
.
ReplayEventBase
is a base interface event that can be implemented with any event you want to test. Then, send them to the MapboxReplayer
via MapboxReplayer.pushEvents()
. The MapboxReplayer
has a seekTo()
method functions to move the player to timestamp that you want to play.
Set up a custom event that implements ReplayEventBase
:
private data class ReplayEventInitialRoute(
override val eventTimestamp: Double,
val coordinates: List<LatLng>
) : ReplayEventBase
Then set up the MapboxReplayer
and ReplayHistoryMapper
classes:
val mapboxReplayer = MapboxReplayer()
val replayHistoryMapper = ReplayHistoryMapper(customEventMappper, logger)
Create a ReplayHistoryLocationEngine
object and give it to MapboxNavigation
when you build a MapboxNavigation
object. This way, MapboxNavigation
will use the Location
objects:
mapboxNavigation = MapboxNavigation(
locationEngine = ReplayLocationEngine(mapboxReplayer)
)
Get history events:
val replayEvents = replayHistoryMapper.mapToReplayEvents(rideHistoryExampleJsonString)
Give custom events to the MapboxReplayer
:
mapboxReplayer.pushEvents(replayEvents)
Start replaying the events:
playReplay.setOnClickListener {
mapboxReplayer.play(context)
}
Replay custom events from history files
Navigation history files have several predefined events, which can be retrieved with the MapboxNavigation
class:
val historyString = mapboxNavigation.retrieveHistory()
Custom events can also be created and added to the history file:
mapboxNavigation.addHistoryEvent(eventTypeString, eventJsonProperties)
You must create a custom class that implements the Navigation SDK's CustomEventMapper
interface to replay the history file's custom events.
private class ReplayCustomEventMapper : CustomEventMapper {
override fun map(eventType: String, event: LinkedTreeMap<*, *>): ReplayEventBase? {
return when (eventType) {
"initial_route" -> {
val properties = event["properties"] as LinkedTreeMap<*, *>
val routeOptions = properties["routeOptions"] as LinkedTreeMap<*, *>
val coordinates = routeOptions["coordinates"] as List<List<Double>>
val coordinatesLatLng = coordinates.map { LatLng(it[1], it[0]) }
ReplayEventInitialRoute(
eventTimestamp = event["event_timestamp"] as Double,
coordinates = coordinatesLatLng
)
}
else -> null
}
}
}