Optimizing Data Consumption Using HERE SDK Navigate

Key Strategies for Data Optimization

#### 1. Incremental Map Updates

Ensure incremental updates are enabled to limit data downloads to essential map changes. This reduces bandwidth usage significantly compared to downloading entire map bundles.

<br />// Get the shared SDKNativeEngine instanceSDKNativeEngine sdkNativeEngine = SDKNativeEngine.getSharedInstance();// Obtain the current CatalogConfigurationCatalogConfiguration currentCatalogConfiguration = sdkNativeEngine.getCatalogConfiguration();// Check if incremental updates are enabledif (currentCatalogConfiguration != null && currentCatalogConfiguration.patchHrn != null) { String patchHrn = currentCatalogConfiguration.patchHrn; System.out.println("Incremental updates are enabled with patch HRN: " + patchHrn);} else { System.out.println("Incremental updates are not enabled.");}<br />

####

Note:
Incremental map updates
are supported, by default: Instead of downloading an entire region, only the parts that have changed will be installed. This results in a faster update process and less downloaded data. If the patchHrn field of a CatalogConfiguration is null, then incremental updates will be disabled and the map data is downloaded still incrementally to some extent, but in larger bundles resulting in more bandwidth consumption. Usually, this is handled internally by the HERE SDK and developers do not need to create a CatalogConfiguration on their own. With incremental map updates for the 1st time usage, a user will have to download the full region(s). Any update after the 1st download can be done incremental. Note that the decision if a full download or only an incremental update is executed is done automatically by the HERE SDK.

#### 2. Optimizing Cache Size

The cache size plays a pivotal role in the performance of the SDK. By increasing the cache size, you can reduce the frequency of online data downloads.

<br />SDKOptions sdkOptions = new SDKOptions();sdkOptions.cacheSizeInBytes = 512 * 1024 * 1024; // 512 MBSDKNativeEngine.createInstance(context, sdkOptions);<br />

For more details, refer to the SDKOptions Documentation.

#### 3. Strategic Optimization of Map Features

The SDK offers the flexibility to define and enable only the features crucial for your application.

Enabling Specific LayerConfiguration Features(Suggested):

<br /> public List getFeaturesToEnable() { <br /> ArrayList features = new ArrayList<>(); <br /> <br /> features.add(LayerConfiguration.Feature.NAVIGATION); <br /> features.add(LayerConfiguration.Feature.DETAIL_RENDERING); <br /> features.add(LayerConfiguration.Feature.RENDERING); <br /> <br /> // Enable only if required by your application. <br /> features.add(LayerConfiguration.Feature.TRUCK); <br /> features.add(LayerConfiguration.Feature.OFFLINE_SEARCH); <br /> features.add(LayerConfiguration.Feature.OFFLINE_ROUTING); <br /> <br /> // Enable only the realistic view / junction sign aspect ratio used by the application. <br /> // Do not enable all aspect-ratio variants, as this increases data usage. <br /> <br /> // Example: for RealisticViewWarningOptions.aspectRatio = ASPECT_RATIO_3_X_4 <br /> features.add(LayerConfiguration.Feature.JUNCTION_VIEW_3X4); <br /> features.add(LayerConfiguration.Feature.JUNCTION_SIGN_3X4); <br /> <br /> // Example alternative: for RealisticViewWarningOptions.aspectRatio = ASPECT_RATIO_16_X_9 <br /> // Use these instead of the 3x4 variants above: <br /> // features.add(LayerConfiguration.Feature.JUNCTION_VIEW_16X9); <br /> // features.add(LayerConfiguration.Feature.JUNCTION_SIGN_16X9); <br /> <br /> return features; <br /> } <br /> LayerConfiguration layerConfiguration = new LayerConfiguration();layerConfiguration.enabledFeatures = getFeaturesToEnable();SDKOptions sdkOptions = new SDKOptions();sdkOptions.layerConfiguration = layerConfiguration;SDKNativeEngine.createInstance(context, sdkOptions);<br />

Note:Realistic view warnings are configured with a single aspect ratio through RealisticViewWarningOptions. Therefore, only the matching junction view and junction sign features should be enabled.

For example, if the application uses ASPECT_RATIO_3_X_4, enable the 3x4 junction view/sign features. If the application uses ASPECT_RATIO_16_X_9, enable the 16x9 features instead. Avoid enabling all variants such as 3x4, 4x3, 5x3 and 16x9 unless the application really needs them, because unused variants can increase offline map size, implicit prefetch size and network data consumption.
Disabling Specific Map Features:

<br /> public HashMap getMapFeaturesToEnable(){ HashMap map = new HashMap<>(); map.put(MapFeatures.TRAFFIC_FLOW, MapFeatureModes.TRAFFIC_FLOW_WITH_FREE_FLOW); map.put(MapFeatures.TRAFFIC_INCIDENTS, MapFeatureModes.TRAFFIC_INCIDENTS_ALL); map.put(MapFeatures.ROAD_EXIT_LABELS, MapFeatureModes.ROAD_EXIT_LABELS_ALL); return map;}public ArrayList getMapFeaturesToDisable(){ ArrayList features = new ArrayList<>(); features.add(MapFeatures.EXTRUDED_BUILDINGS); features.add(MapFeatures.BUILDING_FOOTPRINTS); features.add(MapFeatures.VEHICLE_RESTRICTIONS); features.add(MapFeatures.LANDMARKS); features.add(MapFeatures.TERRAIN); features.add(MapFeatures.CONGESTION_ZONES); features.add(MapFeatures.ENVIRONMENTAL_ZONES); features.add(MapFeatures.SHADOWS); features.add(MapFeatures.SAFETY_CAMERAS); return features;}public void updateMapViewFeatures(){ mapView.getMapScene().enableFeatures(getMapFeaturesToEnable()); mapView.getMapScene().disableFeatures(getMapFeaturesToDisable());}<br />

Refer to the HERE SDK Documentation on Map Features.

#### 4. Efficient Incremental Map Updates

Instead of downloading the entire map data with each update, only the differences (diff files) or changes needs to be downloaded. This approach significantly reduces bandwidth usage and improves update speed.


The patchHrn property of CatalogConfiguration plays a crucial role in this process. When this field is present, the data from the main catalog is merged with the data from the patch catalog.

<br />List catalogConfigurations = new ArrayList<>(); CatalogVersionHint versionHint = CatalogVersionHint.specific(OCM_VERSION); boolean ignoreCachedData = true; String defaultOCMHRN = "hrn:here:data::olp-here:ocm"; DesiredCatalog defaultOCMCatalog = new DesiredCatalog(defaultOCMHRN, versionHint); CatalogConfiguration catalogConfiguration = new CatalogConfiguration(defaultOCMCatalog); catalogConfiguration.patchHrn = "hrn:here:data::olp-here:ocm-patch" ; catalogConfigurations.add(new CatalogConfiguration(defaultOCMCatalog));<br />

Please note: Here SDK does not update the map on its own. Only through the call to this API. This means, when you configure the patchHRN, you still need to call this API for incremental map updates, with patchHRN set HERE SDK will download the map but with diff files only not the whole bundles.

#### 5. Disabling Incremental Map Updates on Cellular Networks

To prevent high data consumption, disable incremental map updates on cellular networks and enable them only on Wi-Fi.

Network Utility Class:

<br /> public class NetworkUtil { public static final int TYPE_WIFI = 1; public static final int TYPE_MOBILE = 2; public static final int TYPE_NOT_CONNECTED = 0; public static int getConnectivityStatus(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if (activeNetwork != null) { if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) return TYPE_WIFI; if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) return TYPE_MOBILE; } return TYPE_NOT_CONNECTED; }}`<br />
Use Network Utility to Check Network Status:

<br /> public void callMapUpdate() { int status = NetworkUtil.getConnectivityStatus(getApplicationContext()); if (status == NetworkUtil.TYPE_MOBILE) { Log.d("NetworkAvailable", "MOBILE"); Toast.makeText(getApplicationContext(), "Update Not allowed over cellular", Toast.LENGTH_LONG).show(); } else if (status == NetworkUtil.TYPE_WIFI) { Log.d("NetworkAvailable", "WIFI"); Toast.makeText(getApplicationContext(), "Starting Update over WiFi", Toast.LENGTH_SHORT).show(); upgradeOCMToVersion(); }}`<br />
Perform Map Update:

<br /> public void performMapUpdate(CatalogUpdateInfo catalogUpdateInfo) { currentMapUpdater.updateCatalog(catalogUpdateInfo, new CatalogUpdateProgressListener() { @Override public void onProgress(@NonNull RegionId regionId, int progress) { Toast.makeText(getApplicationContext(), "Region " + regionId.id + " Progress " + progress, Toast.LENGTH_LONG).show(); } @Override public void onComplete(@Nullable MapLoaderError mapLoaderError) { if (mapLoaderError == null) { Toast.makeText(getApplicationContext(), "Download Successful", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "Failed: " + mapLoaderError.name(), Toast.LENGTH_LONG).show(); } } });}<br />

#### 6. Addressing Persistent Bandwidth Issues with UsageStats API

The UsageStats class collects detailed statistics on the HERE SDK’s network usage. Enabling UsageStats will help pinpoint features contributing to high bandwidth usage.

Enable UsageStats:

<br /> SDKNativeEngine sdkNativeEngine = SDKNativeEngine.getSharedInstance();sdkNativeEngine.setUsageStatsEnabled(true);String tag = "USAGE"; List stats = SDKNativeEngine.getSharedInstance().getSdkUsageStats(); double totalConsumed =0.0; for( UsageStats usageStats: stats){ double total = 0; Log.d(tag," Feature Name "+ usageStats.feature); for (UsageStats.NetworkStats networkStats: usageStats.networkStats){ double consumed = ((double) networkStats.sentBytes+ (double) networkStats.receivedBytes)/1000000; total+=consumed; Log.d(tag," Method Name "+ networkStats.methodCall); Log.d(tag," Consumed "+ consumed +" MB"); } totalConsumed+=total; Log.d(tag," Feature "+ usageStats.feature+" Consumed "+total+ " MB "); } Log.d(tag," Total consumed Consumed "+totalConsumed+ " MB "); }<br />

Once enabled, your application will begin collecting comprehensive usage statistics for each feature. Please share that with us if you report issues.

For more information, refer to the HERE SDK UsageStats Documentation.

#### 7. Configuring Data Layers for Implicit Prefetch

With the 4.18.4 release, the HERE SDK includes the ability to configure data layers for implicit prefetch. By minimizing implicit prefetch, customers can reduce data consumption during navigation or rendering.

LayerConfiguration Fields:

enabledFeatures: Specifies feature configuration for enabling a list of features for map download.
implicitlyPrefetchedFeatures: Specifies the list of features enabled for implicit map prefetch. Implicit map prefetch will download map content for enabled features when showing a map in the MapView.
Constructors:

<br /> public LayerConfiguration(@NonNull List enabledFeatures)public LayerConfiguration()public LayerConfiguration(@NonNull List enabledFeatures, @NonNull List implicitlyPrefetchedFeatures)<br />
Example Usage:

<br /> public List getFeaturesToEnable(){ ArrayList features = new ArrayList<>(); features.add(LayerConfiguration.Feature.NAVIGATION); features.add(LayerConfiguration.Feature.DETAIL_RENDERING); features.add(LayerConfiguration.Feature.RENDERING); // Add more features as needed return features;}public List getImplicitlyPrefetchedFeatures() { <br /> ArrayList features = new ArrayList<>(); <br /> <br /> // Keep implicit prefetch minimal. <br /> features.add(LayerConfiguration.Feature.NAVIGATION); <br /> <br /> // Add realistic view / junction sign data only if it is required during navigation, <br /> // and only for the aspect ratio used by RealisticViewWarningOptions. <br /> <br /> // Example: for RealisticViewWarningOptions.aspectRatio = ASPECT_RATIO_3_X_4 <br /> // features.add(LayerConfiguration.Feature.JUNCTION_VIEW_3X4); <br /> // features.add(LayerConfiguration.Feature.JUNCTION_SIGN_3X4); <br /> <br /> // Example alternative: for RealisticViewWarningOptions.aspectRatio = ASPECT_RATIO_16_X_9 <br /> // features.add(LayerConfiguration.Feature.JUNCTION_VIEW_16X9); <br /> // features.add(LayerConfiguration.Feature.JUNCTION_SIGN_16X9); <br /> <br /> return features; <br /> }LayerConfiguration layerConfiguration = new LayerConfiguration( getFeaturesToEnable(), getImplicitlyPrefetchedFeatures());SDKOptions sdkOptions = new SDKOptions();sdkOptions.layerConfiguration = layerConfiguration;SDKNativeEngine.createInstance(context, sdkOptions);<br />

Refer to the documentation

Note:
Implicit prefetch should not include all realistic view or junction sign variants by default. Add only the feature data that the application needs and only for the configured aspect ratio. This helps reduce unnecessary background downloads while rendering or navigating.

#### 8. Refreshing Routes

The refreshRoute methods allow for updating several options of a previously calculated route on-the-fly.

Method 1: Asynchronously refreshes a route with a new starting point and specified options. Useful for on-the-fly updates without recalculating the entire route.

<br /> @NonNullpublic TaskHandle refreshRoute(@NonNull RouteHandle routeHandle, @NonNull Waypoint startingPoint, @NonNull RefreshRouteOptions refreshRouteOptions, @NonNull CalculateRouteCallback callback) { // Implementation here}<br />
Method 2: Similar to the first method, but with additional parameters to specify the last traveled section index and the traveled distance on the last section.

<br /> @NonNullpublic TaskHandle refreshRoute(@NonNull RouteHandle routeHandle, @Nullable Waypoint startingPoint, @Nullable java.lang.Integer lastTraveledSectionIndex, @Nullable java.lang.Integer traveledDistanceOnLastSectionInMeters, @NonNull RefreshRouteOptions refreshRouteOptions, @NonNull CalculateRouteCallback callback) { // Implementation here}<br />

For more information, refer to the HERE SDK RoutingEngine API.

Implementing these strategies will help optimize data consumption in applications using the HERE SDK, leading to more efficient and cost-effective operation, particularly over cellular networks. Adjust configurations as per your application's requirements to achieve the best results. Please download the sample project discussing above all practices.