Retrieving horizon data
Navigation SDK for Android is only available upon request. Contact us to get started.
Virtual Horizon acts as a digital assistant, extending the driver’s location context beyond their immediate view. It can be used by UI components to improve the driving experience, for example, by informing the driver of what is ahead. This information includes details about upcoming traffic events, vehicle restrictions, and more.
While navigating, you can use Virtual Horizon to retrieve detailed information about the horizon ahead of the vehicle, along the possible trajectories of the vehicle across the road network. The HorizonEngine
delivers this information as a combination of a HorizonPosition
and a HorizonSnapshot
.
The SDK provides horizon data for various elements, including:
StreetElement
- Information about a street, such as name.SpeedLimitElement
- Information about speed limits.GeneralRoadPropertiesElement
- Information about the road ahead, such as number of lanes, functional road class and driving side.CountryInformationElement
- Information about the country ahead, including country code, speed limit unit and regional speed limits.VehicleRestrictionElement
- Information about vehicle-specific restrictions ahead, such as maximum height allowed and restricted vehicle types.DangerousGoodsRestrictionElement
- Information about dangerous good restrictions ahead, including ADR tunnel restrictions and hazardous load restrictions.
This guide focuses on demonstrating how to utilize the HorizonEngine
for extracting specific speed-related data, including the current speed limit, the distance to the next speed limit, and the value of the upcoming speed limit. These insights allow you to create navigation applications that not only guide users accurately but also enhance their road experience by keeping them well-informed.
For more in-depth information, refer to the HorizonEngine
API reference.
Configuring the horizon engine
Incorporating horizon data into your navigation application requires the following steps:
- Define your horizon data preferences by specifying
HorizonOptions
, which the SDK uses to configure theHorizonEngine
. - Add a
HorizonUpdatedListener
to receive data based on your chosenHorizonOptions
. - Start navigation with or without a route, using the
OnlineTomTomNavigationFactory
to obtain aTomTomNavigation
object. TheHorizonEngine
is automatically created during initialization of theTomTomNavigation
object.
Specifying horizon options
First, define the set of HorizonOptions
. To indicate that you are interested in SpeedLimitElement
horizon elements, specify SpeedLimitElementType
in the list of element types of interest.
1private val horizonOptions =2 HorizonOptions(3 elementTypes = listOf(SpeedLimitElementType),4 mainPathSearchOptions =5 MainPathSearchOptions(6 searchDistancePolicy =7 ExplicitDistancePolicy(8 searchDistance =9 PathSearchDistance(10 maxHorizonLength = Distance.kilometers(1),11 ),12 ),13 ),14 )
Starting navigation
Then, start navigation with a route as described in the Starting navigation guide.
But, instead of adding a listener for route progress updates, make sure you add a HorizonUpdatedListener
to listen to horizon updates for the horizon options you defined.
1fun startNavigation() {2 val tomTomNavigation = OnlineTomTomNavigationFactory.create(navigationConfiguration)3 tomTomNavigation.addHorizonUpdatedListener(horizonOptions, horizonUpdatedListener)45 val routePlan = RoutePlan(route, routePlanningOptions)6 val navigationOptions = NavigationOptions(routePlan)7 tomTomNavigation.start(navigationOptions)8}
Retrieving horizon data
With navigation started, you can listen to horizon updates and retrieve horizon data.
1private val horizonUpdatedListener =2 object : HorizonUpdatedListener {3 private var horizonSnapshot: HorizonSnapshot? = null45 override fun onPositionUpdated(6 options: HorizonOptions,7 position: HorizonPosition,8 ) {9 horizonSnapshot?.let { snapshot ->10 position.takeIf { it.isOnRoad }?.let { position ->11 snapshot.displayCurrentSpeedLimit(position)12 snapshot.displayNextSpeedLimit(position)13 }14 }15 }1617 override fun onSnapshotUpdated(18 options: HorizonOptions,19 snapshot: HorizonSnapshot,20 ) {21 horizonSnapshot = snapshot22 }2324 override fun onHorizonReset(options: HorizonOptions) {25 // do nothing26 }27 }
Once you have retrieved the data, you can use it to extract the value of the current speed limit.
1private fun HorizonSnapshot.displayCurrentSpeedLimit(position: HorizonPosition) {2 mainPath()?.getElements(SpeedLimitElementType)3 ?.firstOrNull { element -> element.startOffset < position.offset && element.endOffset >= position.offset }4 ?.let { element -> (element as SpeedLimitElement).speedLimit }5 ?.also { speedLimit ->6 when (speedLimit.type) {7 SpeedLimit.Type.Limited -> Log.v(TAG, "Speed limit value: " + speedLimit.speed)8 SpeedLimit.Type.Unlimited -> Log.v(TAG, "Unlimited speed")9 }10 }11}
You can also extract the distance to the next speed limit and the value of the next speed limit.
1private fun HorizonSnapshot.displayNextSpeedLimit(position: HorizonPosition) {2 mainPath()?.getElements(SpeedLimitElementType)3 ?.firstOrNull { element -> element.startOffset >= position.offset }4 ?.let { element ->5 Log.v(TAG, "Distance to the next speed limit: " + distanceTo(element, position))6 (element as SpeedLimitElement).speedLimit7 }8 ?.also { speedLimit ->9 when (speedLimit.type) {10 SpeedLimit.Type.Limited -> Log.v(TAG, "Next speed limit value: " + speedLimit.speed)11 SpeedLimit.Type.Unlimited -> Log.v(TAG, "Next, unlimited speed")12 }13 }14}
Next steps
Now that you know how to retrieve horizon data, here are the recommendations on what to explore next: