# 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 `refreshRoute()`. * The `refreshRoute()` 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 a `TrafficOnRoute` object. It contains detailed information on the current traffic flow and incidents per `TrafficOnSection`. `TrafficOnSection` contains granular traffic information per span provided as a list of `TrafficOnSpan` objects. Note that both methods do not change the route distance and geometry. #### Note (only for Navigate) > Alternatively, you can use the `DynamicRoutingEngine` to 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 the `DynamicRoutingEngine`, refer to the [Navigation](navigation-optimization.md#find-better-routes) 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: ```java public void updateTrafficOnRoute(Route route) { // Since traffic is being calculated for the entire route, lastTraveledSectionIndex and traveledDistanceOnLastSectionInMeters are set to 0. int lastTraveledSectionIndex = 0; int traveledDistanceOnLastSectionInMeters = 0; routingEngine.calculateTrafficOnRoute(route, lastTraveledSectionIndex, traveledDistanceOnLastSectionInMeters, new CalculateTrafficOnRouteCallback() { @Override public void onTrafficOnRouteCalculated(@Nullable RoutingError routingError, @Nullable TrafficOnRoute trafficOnRoute) { if (routingError != null) { Log.d(TAG, "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: ```java private void showUpdatedETA(TrafficOnRoute trafficOnRoute) { for (TrafficOnSection section : trafficOnRoute.trafficSections) { List spans = section.trafficSpans; long updatedETAInSeconds = spans.stream() .mapToLong(span -> span.duration.getSeconds()) .sum(); long updatedTrafficDelayInSeconds = spans.stream() .mapToLong(span -> span.trafficDelay.getSeconds()) .sum(); String updatedETAString = String.format("Updated ETA %s\nUpdated traffic delay %s", timeUtils.formatTime(updatedETAInSeconds), timeUtils.formatTime(updatedTrafficDelayInSeconds)); showDialog("Updated traffic", updatedETAString); } } ``` > #### Note > > Traffic 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 [Real-time versus predictive traffic data sources](traffic.md#real---time-versus-predictive-traffic-data-sources). ## Update traffic during turn-by-turn navigation (only for HERE SDK 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 (only for HERE SDK for Navigate). ```java public void updateTrafficOnRoute(RouteProgress routeProgress, VisualNavigator visualNavigator) { Route currentRoute = visualNavigator.getRoute(); if (currentRoute == null) { // Should never happen. return; } // Below, we use 10 minutes. A common range is between 5 and 15 minutes. long trafficUpdateIntervalInMilliseconds = 10 * 60000; // 10 minutes. long now = System.currentTimeMillis(); if ((now - lastTrafficUpdateInMilliseconds) < trafficUpdateIntervalInMilliseconds) { return; } // Store the current time when we update trafficOnRoute. lastTrafficUpdateInMilliseconds = now; List sectionProgressList = routeProgress.sectionProgress; SectionProgress lastSectionProgress = sectionProgressList.get(sectionProgressList.size() - 1); int traveledDistanceOnLastSectionInMeters = currentRoute.getLengthInMeters() - lastSectionProgress.remainingDistanceInMeters; int lastTraveledSectionIndex = routeProgress.routeMatchedLocation.sectionIndex; routingEngine.calculateTrafficOnRoute(currentRoute, lastTraveledSectionIndex, traveledDistanceOnLastSectionInMeters, new CalculateTrafficOnRouteCallback() { @Override public void onTrafficOnRouteCalculated(@Nullable RoutingError routingError, @Nullable TrafficOnRoute trafficOnRoute) { if (routingError != null) { Log.d(TAG, "CalculateTrafficOnRoute error: " + routingError.name()); return; } // Sets traffic data for the current route, affecting RouteProgress duration in SectionProgress, // while preserving route distance and geometry. visualNavigator.setTrafficOnRoute(trafficOnRoute); Log.d(TAG, "Updated traffic on route."); } }); } ``` > #### Note > > 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](routing.md#get-eta-and-traffic-information).