Beta
Navigation SDK for iOS v2

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.

Active guidance and passive navigation

The Mapbox Navigation SDK allows users to navigate in two different modes: active guidance and passive navigation. The electronic horizon feature works in both modes.

  • During active turn-by-turn navigation, the user-selected route and its metadata are used as the path for the electronic horizon.

  • During passive navigation (also called free-drive mode), the electronic horizon will determine the most probable path from the vehicle's current location.

For both active guidance and passive navigation, the electronic horizon and its metadata are exposed via the same interface in the Navigation SDK as described below.

Configuring electronic horizon detection

Set the RouteController.electronicHorizonOptions or PassiveLocationDataSource.electronicHorizonOptions property to an ElectronicHorizonOptions object configure electronic horizon detection.

related
ElectronicHorizonOptions reference

Define the options for the ElectronicHorizon.

To begin receiving electronic horizons, set up a NavigationSession or PassiveLocationDataSource (such as through PassiveLocationManager) and observe electronic horizon–related notifications. To avoid wasting power, the notifications themselves contain only the most important data about the electronic horizon. If you need additional details about road objects or individual edges in the routing graph, use the RoadObjectsStore and RoadGraph classes, respectively.

Note

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.

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, each of which represents 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 there are two or more alternatives at an intersection that 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 notifications

To find out when the electronic horizon or MPP changes due to a user location update, observe electronicHorizonDidUpdatePosition notifications.

func startUpdatingPosition() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didUpdateElectronicHorizonPosition),
                                           name: .electronicHorizonDidUpdatePosition,
                                           object: nil)
}

The Notification.userInfo dictionary contains the electronic horizon edge structure in treeKey and the user’s position in the routing graph in positionKey.

@objc func didUpdateElectronicHorizonPosition(_ notification: Notification) {
    guard 
        let position = notification.userInfo?[ElectronicHorizon.NotificationUserInfoKey.positionKey] as? RoadGraph.Position,
        let horizon = notification.userInfo?[ElectronicHorizon.NotificationUserInfoKey.treeKey] as? ElectronicHorizon
    else { return }
}

treeKey is set to an ElectronicHorizon object, which contains a tree of Edge instances that you can traverse recursively to explore the routing graph in the vicinity of the user.

You can also unsubscribe from electronic horizon position notifications during the lifetime of an object.

func stopUpdatingPosition() {
    NotificationCenter.default.removeObserver(self, name: .electronicHorizonDidUpdatePosition, object: nil)
}
related
NotificationUserInfoKey reference

See all the keys in the user information dictionaries of various notifications posted by instances of RouteController or PassiveLocationDataSource.

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 RouteController.roadGraph or PassiveLocationDataSource.roadGraph, then pass the edge’s identifier into the RoadGraph object’s methods.

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 electronicHorizonDidEnterRoadObject and electronicHorizonDidExitRoadObject notifications, respectively.

func startUpdatingRoadObjects() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didEnterOrExitRoadObject),
                                           name: .electronicHorizonDidEnterRoadObject,
                                           object: nil)
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didEnterOrExitRoadObject),
                                           name: .electronicHorizonDidExitRoadObject,
                                           object: nil)
}

The Notification.userInfo dictionary contains the road object identifier in roadObjectIdentifierKey. didTransitionAtEndpointKey indicates whether the user transitioned to or from the road object at one of its endpoints or whether they did so somewhere along the road object.

@objc func didEnterOrExitRoadObject(_ notification: Notification) {
    guard 
        let identifier = notification.userInfo?[ElectronicHorizon.NotificationUserInfoKey.roadObjectIdentifierKey] as? RoadObjectIdentifier,
        let didTransitionAtEndpoint = (notification.userInfo?[ElectronicHorizon.NotificationUserInfoKey.didTransitionAtEndpointKey] as? NSNumber)?.boolValue
    else { return }
}

You can also unsubscribe from road object notifications during the lifetime of an object.

func stopUpdatingRoadObjects() {
    NotificationCenter.default.removeObserver(self, name: .electronicHorizonDidEnterRoadObject, object: nil)
    NotificationCenter.default.removeObserver(self, name: .electronicHorizonDidExitRoadObject, object: nil)
}

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 RouteController.roadObjectsStore or PassiveLocationDataSource.roadObjectsStore, then pass the road object identifier into the RoadObjectsStore object’s methods.