Navigation
Turn-by-turn navigation
You can add a turn-by-turn navigation to your app using the ready-to-use interface components and the NavigationManager class.
To do that, first add a NavigationView and a DefaultNavigationControls to your MapView.
<ru.dgis.sdk.map.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ru.dgis.sdk.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ru.dgis.sdk.navigation.DefaultNavigationControls
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</ru.dgis.sdk.navigation.NavigationView>
</ru.dgis.sdk.map.MapView>
Then, add a My location marker to the map and create a NavigationManager object.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sdkContext = DGis.initialize(applicationContext, apiKeys)
// Register the geolocation source
locationProvider = ManagerLocationSource(applicationContext)
registerPlatformLocationSource(sdkContext, locationProvider)
setContentView(R.layout.activity_navigation)
findViewById<MapView>(R.id.mapView).apply { mapView ->
lifecycle.addObserver(mapView)
mapView.getMapAsync { map ->
// Add a marker for the current location
map.addSource(
MyLocationMapObjectSource(
sdkContext,
MyLocationDirectionBehaviour.FOLLOW_SATELLITE_HEADING,
createSmoothMyLocationController()
)
)
}
}
// Create a NavigationManager object
navigationManager = NavigationManager(sdkContext)
findViewById<NavigationView>(R.id.navigationView).apply {
// Attach the created NavigationManager object to the NavigationView
navigationManager = this@NavigationActivity.navigationManager
}
// Start navigation in a free-drive mode
navigationManager.start()
}
You can start navigation in one of three modes: free-drive, turn-by-turn, and the simulated navigation mode.
Additional navigation settings can be changed using the properties of the NavigationManager object.
Free-drive mode
In free-drive mode, no route will be displayed on the map, but the user will still be informed about speed limits, traffic cameras, incidents, and road closures.
To start navigation in this mode, call the start()
method without arguments.
navigationManager.start()
Turn-by-turn mode
In turn-by-turn mode, a route will be displayed on the map and the user will receive navigation instructions as they move along the route.
To start navigation in this mode, call the start()
method and specify a RouteBuildOptions object - arrival coordinates and route settings.
val routeBuildOptions = RouteBuildOptions(
finishPoint = RouteSearchPoint(
coordinates = GeoPoint(latitude = 55.752425, longitude = 37.613983)
),
routeSearchOptions = CarRouteSearchOptions(
avoidTollRoads = true,
avoidUnpavedRoads = false,
avoidFerry = false,
routeSearchType = RouteSearchType.JAM
)
)
navigationManager.start(routeBuildOptions)
Additionally, when calling the start()
method, you can specify a TrafficRoute object - a complete route object for navigation (see Building a route). In this case, NavigationManager will use the specified route instead of building a new one.
navigationManager.start(routeBuildOptions, trafficRoute)
Simulated navigation
In this mode, NavigationManager will not track the current location of the device. Instead, it will simulate a movement along the specified route.
This mode is useful for debugging.
To use this mode, call the startSimulation()
method and specify a RouteBuildOptions object (route settings) and a TrafficRoute object (the route itself).
You can change the speed of the simulated movement using the SimulationSettings.speed property (specified in meters per second).
navigationManager.simulationSettings.speed = 30 / 3.6
navigationManager.startSimulation(routeBuildOptions, trafficRoute)
To stop the simulation, call the stop()
method.
navigationManager.stop()
Traffic display
To display traffic on the map, add a TrafficSource data source.
val trafficSource = TrafficSource(sdkContext)
map.addSource(trafficSource)
Custom geolocation source
You can use your own geolocation source within the SDK. To do this, first implement the LocationSource interface.
public class CustomLocationSource: LocationSource {
override fun activate(listener: LocationChangeListener?) {
// Geolocation source has been activated
}
override fun deactivate() {
// Geolocation source has been deactivated
}
override fun setDesiredAccuracy(accuracy: DesiredAccuracy?) {
// Change of required accuracy level has been requested
}
}
Then, register the created source in the SDK using the registerPlatformLocationSource() function.
val customSource = CustomLocationSource()
registerPlatformLocationSource(sdkContext, customSource)
The entry point of the interface is the activate()
function. When the SDK requires a geolocation, it will call this function passing a LocationChangeListener object. After that, to report the current geolocation, you need to pass an array of Location objects (ordered from oldest to newest) to the onLocationChanged() method.
val location = Location(...)
val newLocations = arrayOf(location)
listener.onLocationChanged(newLocations)
To notify of a change in source availability, use the onAvailabilityChanged() method.
Optionally, you can add additional logic to handle different levels of geolocation accuracy. The required accuracy is passed to the setDesiredAccuracy()
function as a DesiredAccuracy object.
When the geolocation source is no longer needed, the SDK will call the deactivate()
function.