Continuous replanning
The Navigation SDK for iOS is only available upon request. Contact us to get started.
Introduction
Every trip takes time, and the situation on the road is constantly changing, so routes can become stale even while you’re driving. Continuous replanning provides users with the most up-to-date route path. This can be a new path, for example, if traffic conditions mean that it will be faster or if a road blockage appears on the original route. It can also be the same path with updated delay information, if a change in the traffic changes the Estimated Time of Arrival (ETA).
The Continuous Replanning component performs a route refresh by checking for better route alternatives in the background, then applying them based on how the component is configured. The component is fully customizable, so you can configure the definition of a better route, the mode for applying a new route, and the interval time between replans.
Configuration
Modes and options
Route replanning mode
There are three replanning modes:
- Automatic - Replan proposals are applied automatically. A replanning notification is sent via
NavigationRouteObserver::func didReplanRoute(replannedRoute: Route, reason: RouteReplanningReason)
. - Manual - replans are proposed within
NavigationRouteObserver::func didProposeRoutePlan(routePlan: RoutePlan, reason: RouteReplanningReason)
. - Unreachable only - the active route is automatically replaced with a better proposal if it contains a blockage or the current route is unreachable due to insufficient battery charge.
The default mode is Automatic.
Route replanning options
The following options can be used to configure TomTomRouteReplanningEngine
:
- routeReplanInterval - The time interval between replannings.
- minimalTrafficDelay - The minimum traffic delay time required for an alternative route to be used.
- minimalTimeDifference - The minimum time difference required for an alternative route to be used.
- routeReplanningPolicy - Determines how continuous replanning works.
Route replanning policy
ContinuousReplanningPolicy
specifies how continuous replanning works.
It has two possible values:
- Refresh only - the continuous replanning component only refreshes the route along the existing path.
- Find better - the continuous replanning component searches for better routes. It only refreshes if no better routes are found.
The default mode is refresh only.
Enabling/Disabling continuous replanning
BetterProposalAcceptanceMode
is specified using NavigationConfiguration
.
1let navigationConfiguration = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 betterProposalAcceptanceMode: .automatic6)7let navigation = Navigation(configuration: navigationConfiguration)
1let navigationConfiguration = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 betterProposalAcceptanceMode: .manual6)78let navigation = Navigation(configuration: navigationConfiguration)
1let navigationConfiguration = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 betterProposalAcceptanceMode: .unreachableOnly6)78let navigation = Navigation(configuration: navigationConfiguration)
Specifying the route replanning policy
To configure the replanning policy, you must create a TomTomRouteReplanningEngine
by passing RouteReplanningEngineOptions
with preferred ContinuousReplanningPolicy
.
1let routeReplanningEngineOptions = RouteReplanningEngineOptions(2 routeReplanInterval: Measurement.tt.minutes(5),3 minimalTrafficDelay: Measurement.tt.minutes(10),4 minimalTimeDifference: Measurement.tt.minutes(5),5 routeReplanningPolicy: .findBetter6)7let routeReplanningEngine = TomTomRouteReplanningEngine(options: routeReplanningEngineOptions)89let navigationConfiguration = NavigationConfiguration(10 apiKey: Keys.navigation,11 locationProvider: locationEngine,12 routeReplanner: routeReplanner,13 routeReplanningEngine: routeReplanningEngine14)1516let navigation = Navigation(configuration: navigationConfiguration)
Providing a custom Better Route Selector
TomTomRouteReplanningEngine can accept a custom RouteProposalSelector for advanced customization of the better route selection process. To use a custom RouteProposalSelector
, pass a class conforming to RouteProposalSelector
as an init parameter.
1let routeProposalSelector = CustomRouteProposalSelector()23let routeReplanningEngine = TomTomRouteReplanningEngine(4 options: routeReplanningEngineOptions,5 routeProposalSelector: routeProposalSelector6)78let navigationConfiguration = NavigationConfiguration(9 apiKey: Keys.navigation,10 locationProvider: locationEngine,11 routeReplanner: routeReplanner,12 routeReplanningEngine: routeReplanningEngine13)1415let navigation = Navigation(configuration: navigationConfiguration)
Working with manual replanning mode
To use manual replanning mode, specify the BetterProposalAcceptanceMode
as .manual
and set up a NavigationRouteObserver::func didProposeRoutePlan(routePlan: RoutePlan, reason: RouteReplanningReason)
callback.
1let routeReplanningEngineOptions = RouteReplanningEngineOptions(2 routeReplanInterval: Measurement.tt.minutes(5),3 minimalTrafficDelay: Measurement.tt.minutes(10),4 minimalTimeDifference: Measurement.tt.minutes(5),5 routeReplanningPolicy: .findBetter6)7let routeReplanningEngine = TomTomRouteReplanningEngine(options: routeReplanningEngineOptions)89let navigationConfiguration = NavigationConfiguration(10 apiKey: Keys.navigation,11 locationProvider: locationEngine,12 routeReplanner: routeReplanner,13 routeReplanningEngine: routeReplanningEngine,14 betterProposalAcceptanceMode: .manual15)1617let navigation = Navigation(configuration: navigationConfiguration)18navigation.addRouteObserver(self)
1func didProposeRoutePlan(routePlan: RoutePlan, reason: RouteReplanningReason) {2 /* YOUR CODE GOES HERE */3}
Incremental guidance computation
If the guidanceProgressOffset
of the route is less than the length
in the route summary
, the route needs to be updated. Instead of calling the planRoute
method, the replanning engine can call the advanceGuidanceProgress
method. This adds more instructions and corresponding lane guidance to the route and increases the guidanceProgressOffset
of the route.
Route deviation
Introduction
The Navigation
module detects when the user has diverged from the navigated route. Route Deviation is a specific case of the more general Continuous Replanning feature, but with its own wide range of possibilities for customization. You can configure the definition of a deviation (not tracking a route) with a custom RouteTrackingEngine
or specify how route deviation will work with a separate ReplanningRetryPolicy
for deviations. Whenever a deviation is detected, the notification is sent via NavigationRouteObserver::func didDeviateFromRoute(currentRoute: Route, location: GeoLocation)
. The location
provided by the callback is the location where the deviation from the route was detected. The currentRoute
parameter is the Route
from which the user deviated.
1func didDeviateFromRoute(currentRoute: Route, location: GeoLocation) {2 /* YOUR CODE GOES HERE */3}
Configuration
Modes and options
Deviation replanning mode
There are two replanning modes for deviation:
- Automatic - Replan proposals are applied automatically. A replanning notification is sent via
NavigationRouteObserver::func didReplanRoute(replannedRoute: Route, reason: RouteReplanningReason)
withRouteReplanningReason.deviation
. - None - No replanning occurs.
The default mode is Automatic.
Route tracking engine
Deviation is not tracking a route. To configure the route tracking engine, create a custom engine that implements the RouteTrackingEngine
protocol and set this engine using NavigationConfiguration
.
1let navigationConfigurationNone = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 routeTrackingEngine: customEngine6)
Enabling/Disabling route deviation
DeviationReplanningMode
is specified using NavigationConfiguration
.
1let navigationConfiguration = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 deviationReplanningMode: .automatic6)
Route Deviation can be disabled by specifying DeviationReplanningMode
as .none
.
1let navigationConfigurationNone = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 deviationReplanningMode: .none6)
Specifying the route deviation retry policy
To configure the replanning retry policy, you need to create a custom class which implements the ReplanningRetryPolicy
protocol.
1let navigationConfigurationNone = NavigationConfiguration(2 apiKey: Keys.navigation,3 locationProvider: locationEngine,4 routeReplanner: routeReplanner,5 routeDeviationReplanningRetryPolicy: customRetryPolicy6)
Next steps
Since you have learned about continuous replanning and route deviation, here are recommendations for the next steps: