Electronic horizon
Mapbox Electronic Horizon is a feature of the Mapbox Navigation SDK that surfaces map data along the probable path (or paths) of a vehicle within the road network to anticipate conditions beyond the physical "visible" horizon. The data provided by the electronic horizon enables capabilities like adaptive cruise control, proactive driver alerts for upcoming congestion, speed change and dangerous curves, and available alternative paths. Mapbox Electronic Horizon is designed for Advanced Driver Assistance Systems (ADAS) for in-vehicle deployment, but it can also be used in mobile iOS applications.
The Mapbox Electronic Horizon feature of the Mapbox Navigation SDK is in public beta and is subject to changes, including its pricing. Use of the feature is subject to the beta product restrictions in the Mapbox Terms of Service.
Mapbox reserves the right to end any free tier or free evaluation offers at any time and requires customers to place an order to purchase the Mapbox Electronic Horizon feature, regardless of the level of use of the feature.
Turn-by-turn and free-drive navigation
The Mapbox Navigation SDK allows users to navigate in two different modes: turn-by-turn and free-drive navigation. The electronic horizon feature works in both modes.
-
During turn-by-turn navigation (also called active navigation), the user-selected route and its metadata are used as the path for the electronic horizon.
-
During free-drive navigation (also called passive navigation), the electronic horizon will determine the most probable path from the vehicle's current location.
For both turn-by-turn and free-drive navigation, the electronic horizon and its metadata are exposed via the same interface in the Navigation SDK as described below.
Configuring electronic horizon detection
Initialize an ElectronicHorizonConfig
object to configure electronic horizon detection. Then set it to CoreConfig.electronicHorizonConfig
to start electronic horizon updates.
var coreConfig = CoreConfig()
coreConfig.electronicHorizonConfig = ElectronicHorizonConfig(
length: 500,
expansionLevel: 1,
branchLength: 50,
minTimeDeltaBetweenUpdates: nil
)
return MapboxNavigationProvider(coreConfig: coreConfig)
To begin receiving electronic horizon updates, set up observers of electronic horizon–related events and start the updates by calling startUpdatingEHorizon()
.
let electronicHorizonController = mapboxNavigationProvider.electronicHorizon()
electronicHorizonController.startUpdatingEHorizon()
Electronic horizon notifications are only fired when the trip session is started and external resources, navigation tiles, are downloaded, so notifications might not fire right away.
Direct calls to the electronic horizon
RoadMatching
object provides three objects:
roadObjectStore
: Provides methods to get the current road object, get upcoming road objects, and add or remove custom road objects.roadGraph
: Provides methods to get the shape and metadata for aRoadGraph.Edge
.roadObjectMatcher
: It offers techniques for matching custom objects to the road graph and obtaining aRoadObject
. To receive matching results, set theRoadObjectMatcherDelegate
.
Most probable path
Mapbox Electronic Horizon represents the road network ahead of the user as a tree of edges. For example, an edge may represent a road segment between two intersections or between the two ends of a bridge. An edge may traverse multiple road objects, and a road object may be associated with multiple edges. Each intersection has outlet edges, representing a connecting road segment with a calculated probability that the user will transition to it.
Based on the device's location and user-selected route (if applicable), Mapbox Electronic Horizon determines the most likely path a user may take and provides a most probable path (MPP). The MPP contains data in a tree-like structure where edges have a level
attribute equal to 0
and side-branches have a level
attribute equal to 1
or higher based on their position relative to the current edge.
In most cases, the electronic horizon will return one MPP, but if two or more alternatives at an intersection have a similar probability (a difference less or equal to 5%), the electronic horizon might return several MPP paths. You can choose the MPP with a slightly higher probability or, if you have additional information about the road conditions, you can suggest which MPP the user should choose.
Observing position events
To find out when the electronic horizon or MPP changes due to a user location update, subscribe to eHorizonEvents
notifications.
electronicHorizonController.eHorizonEvents
.compactMap { $0.event as? EHorizonStatus.Events.PositionUpdated }
.sink { [weak self] event in
self?.handle(positionUpdatedEvent: event)
}.store(in: &subscriptions)
The EHorizonStatus.Events.PositionUpdated
contains the electronic horizon edge structure in startingEdge
and the user’s position in the routing graph in position
.
startingEdge
is set to an RoadGraph.Edge
object, which is a starting point in a tree of edges that you can traverse recursively to explore the routing graph in the vicinity of the user.
Get more details about an edge
To get more details about an edge, such as its name and shape, get the active RoadGraph
object from the RoadMatching.roadGraph
, then pass the edge’s identifier
into the RoadGraph
object’s methods.
Demonstrates how to use electronic horizon to predict the user's most probable path and show upcoming intersections.
Road objects
Road objects represent routing-related landmarks within the routing graph, such as traffic incidents, tunnel entrances, and border crossings.
Observing road object notifications
To find out when the user enters or exits the geofence associated with a road object, observe the EHorizonStatus.Events.RoadObjectEntered
and EHorizonStatus.Events.RoadObjectExited
events, respectively.
func startUpdatingRoadObjects() {
electronicHorizonController.eHorizonEvents
.compactMap {
switch $0.event {
case let event as EHorizonStatus.Events.RoadObjectEntered:
return event.roadObjectId
case let event as EHorizonStatus.Events.RoadObjectExited:
return event.roadObjectId
default:
return nil
}
}
.sink { [weak self] roadObjectId in
self?.handleEnterOrExit(roadObjectId: roadObjectId)
}.store(in: &subscriptions)
electronicHorizonController.startUpdatingEHorizon()
}
Get more details about a road object
To get more details about a road object, such as its location and type, get the active RoadObjectsStore
object from the RoadMatching.roadObjectStore
, then pass the road object identifier
into the RoadObjectsStore
object’s methods.
Adding custom road objects
The SDK allows you to add user-defined user objects. Follow the steps to support custom road objects in your app:
- Match the geometry to the road graph:
let matcher = mapboxNavigation.electronicHorizon().roadMatching.roadObjectMatcher
matcher.delegate = self
matcher.match(polygon: polygon, identifier: "custom-road-object-id")
- Wait until the matching is successful and add the received
RoadObject
to theRoadObjectStore
.
extension ViewController: RoadObjectMatcherDelegate {
func roadObjectMatcher(_ matcher: RoadObjectMatcher, didMatch roadObject: RoadObject) {
guard roadObject.isUserDefined else { return }
let store = mapboxNavigation.electronicHorizon().roadMatching.roadObjectStore
store.addUserDefinedRoadObject(roadObject)
}
//...
}
- Do not forget to remove the custom road objects from the store when they are no longer needed.
roadObjectStore.removeUserDefinedRoadObject(identifier: "custom-road-object-id") // Removes a specific custom road object
roadObjectStore.removeAllUserDefinedRoadObjects() // Removes all custom objects
After these steps, you will receive the EH updates for added user-defined objects.
Demonstrates how to add user-defined road objects and subscribe to distance updates.