Update traffic information
Keep your routes up-to-date with the latest traffic conditions. This section explains how to refresh traffic data on existing routes and how to leverage dynamic routing during navigation to find better alternatives when traffic changes.
Update traffic on route
Traffic information for a route can be refreshed by invoking either calculateTrafficOnRoute() or refreshRouteWithRouteHandleAndRefreshRouteParameters().
- The
refreshRouteWithRouteHandleAndRefreshRouteParameters()method can be used when updates to the starting point or route metadata are required. - In scenarios where only traffic information needs to be updated, the
calculateTrafficOnRoute()method can be utilized to provide aTrafficOnRouteobject. It contains detailed information on the current traffic flow and incidents perTrafficOnSection.TrafficOnSectioncontains granular traffic information per span provided as a list ofTrafficOnSpanobjects.
Note that both methods do not change the route distance and geometry.
Note (only applicable for Navigate)
Alternatively, you can use the
DynamicRoutingEngineto find improved routes during navigation. These routes are optimized based on the current traffic flow. As a result, they may also include new route geometry to bypass heavy traffic. For more details about theDynamicRoutingEngine, refer to the Navigation section.
Update traffic during route preview using TrafficOnRoute
The routingEngine.calculateTrafficOnRoute(..) method updates traffic on a specific section or an entire route after it has been created. It allows to calculated this during navigation or in a route preview context.
It does this by recalculating traffic from the last traveled route section, using its index and an offset (in meters) from the last visited position. In a route preview context you can set lastTraveledSectionIndex traveledDistanceOnLastSectionInMeters to 0 in order to update traffic for the entire route.
Here's how the method can be utilized in screens primarily designed for route previews:
void updateTrafficOnRoute(here.Route route) {
// Since traffic is being calculated for the entire route,
// lastTraveledSectionIndex and traveledDistanceOnLastSectionInMeters are set to 0.
int lastTraveledSectionIndex = 0;
int traveledDistanceOnLastSectionInMeters = 0;
// Note: calculateTrafficOnRoute requires a route with routeHandle.
// Enable it by setting routeOptions.enableRouteHandle to true when creating the route.
_routingEngine.calculateTrafficOnRoute(
route,
lastTraveledSectionIndex,
traveledDistanceOnLastSectionInMeters,
(RoutingError? routingError, TrafficOnRoute? trafficOnRoute) {
if (routingError != null) {
print("CalculateTrafficOnRoute error: ${routingError.name}");
} else {
showUpdatedETA(trafficOnRoute!);
}
},
);
}The updated ETA from TrafficOnRoute is available through TrafficOnSpan. Each TrafficOnSpan provides traffic information along the route. The following method can be used to extract the updated ETA:
void showUpdatedETA(TrafficOnRoute trafficOnRoute) {
for (var section in trafficOnRoute.trafficSections) {
List<TrafficOnSpan> spans = section.trafficSpans;
int updatedETAInSeconds = spans.fold(0, (sum, span) => sum + span.duration.inSeconds);
int updatedTrafficDelayInSeconds = spans.fold(0, (sum, span) => sum + span.trafficDelay.inSeconds);
String updatedETAString = "Updated travel duration ${_timeUtils.formatTime(updatedETAInSeconds)}\n"
"Updated traffic delay ${_timeUtils.formatTime(updatedTrafficDelayInSeconds)}";
_showDialog("Updated traffic", updatedETAString);
}
}
NoteTraffic updates use predictive models to forecast conditions along your route, which may differ from real-time traffic shown on map layers. For details on these differences, see Traffic.
Update traffic during turn-by-turn navigation (only available for Navigate)
During turn-by-turn navigation, it is recommended to calculate a dedicated TrafficOnRoute object by calling calculateTrafficOnRoute(). Since the traffic situation can change frequently while being on a trip, an application should repeat this call periodically.
The example implementation provided below ensures that traffic updates are performed at an configurable interval.
Upon completion of calculateTrafficOnRoute(), the VisualNavigator can be updated with the new TrafficOnRoute object, which adjusts the information on the duration provided by the RouteProgress object.
void updateTrafficOnRoute(RouteProgress routeProgress) {
Route? currentRoute = _visualNavigator.route;
if (currentRoute == null) {
// Should never happen.
return;
}
// Below, we use 10 minutes. A common range is between 5 and 15 minutes.
const int trafficUpdateIntervalInMilliseconds = 10 * 60000; // 10 minutes.
int now = DateTime.now().millisecondsSinceEpoch;
if ((now - lastTrafficUpdateInMilliseconds) < trafficUpdateIntervalInMilliseconds) {
return;
}
// Store the current time when we update trafficOnRoute.
lastTrafficUpdateInMilliseconds = now;
List<SectionProgress> sectionProgressList = routeProgress.sectionProgress;
SectionProgress lastSectionProgress = sectionProgressList.last;
int traveledDistanceOnLastSectionInMeters =
currentRoute.lengthInMeters - lastSectionProgress.remainingDistanceInMeters;
int lastTraveledSectionIndex = routeProgress.routeMatchedLocation.sectionIndex;
_routeCalculator.calculateTrafficOnRoute(
currentRoute,
lastTraveledSectionIndex,
traveledDistanceOnLastSectionInMeters,
(RoutingError? routingError, TrafficOnRoute? trafficOnRoute) {
if (routingError != null) {
print("CalculateTrafficOnRoute error: ${routingError.name}");
return;
}
// Sets traffic data for the current route, affecting RouteProgress duration in SectionProgress,
// while preserving route distance and geometry.
_visualNavigator.trafficOnRoute = trafficOnRoute;
print("Updated traffic on route.");
},
);
}
Note (only applicable for Navigate)This code initiates periodic calls to the HERE Routing backend. Depending on your contract, each call may be charged separately. It is the application's responsibility to decide how and how often this code should be executed.
The visualNavigator.setTrafficOnRoute() method does not take effect immediately. Instead, the updated travel duration (ETA) is reflected in the next RouteProgress event. For details on extracting the ETA from a RouteProgress event, see the ETA section.
Updated yesterday