Manage data and OTA costs
This guide provides strategies to reduce the size of the HERE SDK and enhance its runtime performance by minimizing the amount of data that needs to be loaded or processed.
Configure OCM layers to minimize data load
Setting a layer configuration involves specifying a list of feature items. Only the features in this list will be enabled; all others will be disabled. To disable a single feature, ensure all other desired features are included in the list, or they will be automatically disabled as well.
Several features of the HERE SDK are stored in the OCM map data format (Optimized Client Maps).
Utilizing the LayerConfiguration, you can control:
- The amount of map data loaded into the cache during online panning of the
MapView. - The volume of data downloaded when adding a new
Regionfor offline use.
For instance, if turn-by-turn navigation is not utilized within an application, the corresponding feature configuration NAVIGATION can be omitted. This adjustment results in less data being downloaded into the cache while panning the MapView. Moreover, the size of the data downloaded when adding a new Region will be considerably reduced.
As of now, the below features can be specified. The table also shows which features are enabled, by default:
| Feature | Enabled | Description |
|---|---|---|
detailRendering |
Yes | Additional rendering details like buildings. Only used for the MapView. When not set, the data will be excluded when downloading offline regions or prefetching areas that contain such data. However, during online usage such data may still be downloaded into the cache and shown. |
navigation |
Yes | Map data that is used for map matching during navigation. When not set, navigation may not work properly when being used online or offline. |
offlineSearch |
Yes | Map data that is used to search. When not set, the OfflineSearchEngine may not work properly when being used. |
offlineSearchGlobal |
No | Offers improved map data for offline search with better performance and memory footprint. Extends the search range and allows searching for places beyond the search center. It is recommended to disable offlineSearch when using this feature to avoid downloading unnecessary layers. Curently, only installed regions are supported. Cached or prefetched map data is not yet supported. |
offlineRouting |
Yes | Map data that is used to calculate routes. When not set, the OfflineRoutingEngine may not work properly when being used. |
truck |
Yes | Map data that is used to calculate truck routes. When not set, the OfflineRoutingEngine may not work properly when being used to calculate truck routes. It is also used for map matching during truck navigation. When not set, truck navigation may not work properly when being used offline. Online truck navigation will still work when the device has an online connection. |
landmarks3d |
Yes | Map data that is used to render textured 3D landmarks. When not set, the data will be excluded when downloading offline regions or prefetching areas that contain such data. When the LANDMARKS layer is set to be visible for a MapScene, 3D landmarks will still be visible during online usage. |
junctionView3x4, junctionView16x9 |
No | 3D visuals for complex junctions. This asset data can be used to show SVG images during guidance. If enabled, downloaded regions will include junction view images to be used with the corresponding JunctionViewWarning event. This could be useful to download the assets before starting a trip. If not enabled, the required data will be downloaded when needed. Each image can occupy up to 15 MB. Note that future releases of the HERE SDK will optimize the size by reducing the level of realism. By default, the layer is not enabled. |
junctionSign3x4, junctionSign4x3, junctionSign3x5, junctionSign5x3, junctionSign16x9 |
No | Signpost visuals. This asset data can be used to show SVG images during guidance. If enabled, downloaded regions will include junction view images to be used with the corresponding SignpostWarning event. If not enabled, the required data will be downloaded when needed. Each image can occupy up to 300 KB. If not enabled, the required data will be downloaded when needed. By default, the layer is not enabled. |
rendering |
Yes | A basic set of rendering features such as Carto POIs. As a base layer, this feature cannot be disabled. |
rdsTraffic |
No | Map data that provides traffic broadcast functionality using RDS-TMC format. It should be used when there is no internet connection, so that the routing module can utilize traffic data coming over the radio channel to create routes with the OfflineRoutingEngine. |
ev |
No | Offline map data for EV charging stations. |
truckServiceAttributes |
No | Enables truck related attributes to be returned by OfflineSearchEngine. |
fuelStationAttributes |
No | Enables fuel attributes to be returned by OfflineSearchEngine. |
offlineBusRouting |
No | Map data that is used to calculate bus routes. When not set, the OfflineRoutingEngine may not be able to calculate routes with BusOptions. |
terrain |
No | Map data that is used to represent topographical data. |
Note that each of the listed features relates to one or more OCM layer groups. The names of the OCM layer groups can be seen per feature in the API Reference. However, for most use cases knowing the related OCM layer name is not relevant.
In addition, there are two layers, ADAS and EHORIZON (Electronic Horizon), that are currently not relevant for use with the HERE SDK and can be ignored for now. By default, they are already disabled.
Configure OCM layers to minimize data load
Setting a LayerConfiguration involves specifying a list of Feature items via SDKOptions.layerConfiguration. Only the features in this list will be enabled; all others will be disabled. If the intention is to disable a single feature, ensure all other desired features are included in the list, or they will be automatically disabled as well.
For example, if the feature list contains navigation and TRUCK, then it enables only navigation and truck features and disables all others.
Only the LayerConfiguration that was set globally when a Region was first downloaded or cached is used. To update the LayerConfiguration for an already downloaded region, either delete and re-download the region or initialize the MapUpdater again and call mapUpdater.updateCatalog(..).
If a feature is disabled, required data for that feature will not occupy space in the cache or as part of a Region download. That feature cannot be used offline. Sometimes an error may occur - for example, when trying to use the OfflineSearchEngine although OFFLINE_SEARCH has been disabled. Find more details below.
NoteEngines like the
SearchEngineor theRoutingEnginewill never make use of cached or downloaded map data. Only theOfflineSearchEngineandOfflineRoutingEnginewill use such data if the related features have not been disabled. For example, if you are sure that your app fully operates online, it is safe to disable the offline search feature. However, if you want to ensure that an app can also search for POIs when there is a temporary connection loss, you may want to switch to theOfflineSearchEnginewhen such a loss is detected - and therefore, you should not disable the related feature.
As listed above, for some disabled features, a device may still download corresponding data when a device has online connectivity and the feature is needed. For example, when the landmarks3d feature is disabled, but the corresponding MapScene layer is enabled, then the device will still download the needed textures to render a 3D landmark when it becomes visible in the MapView viewport.
For all listed features from above - except for offlineSearch and offlineRouting, the HERE SDK will first check if the needed data is available in the cache. If not found there, it will look if there is a downloaded Region for offline use. If not found, the HERE SDK will try to download the needed data over the air. For offlineSearch and offlineRouting the behavior will be the same, but no data will be requested over the air.
Set a LayerConfiguration
At first, specify the desired layer configuration:
var features: [LayerConfiguration.Feature] = []
// With this layer configuration we enable only the listed layers.
// All the other layers including the default layers will be disabled.
features = [.detailRendering, .rendering, .offlineSearch]
Set the created layerConfiguration object to SDKOptions and initialize the HERE SDK as usual.
options.layerConfiguration = LayerConfiguration(enabledFeatures: features)
// Now use this SDKOptions for initializing a new SDKNativeEngine instance.
Update the layer configuration
Layer configurations can be updated any time by setting new SDKOptions to create a new instance of a SDKNativeEngine.
Call mapUpdater.retrieveCatalogsUpdateInfo(..) to query the list of all catalogs that have newer versions available. This will apply a new LayerConfiguration which will overwrite the previous one. Now, from the list of all catalogs use each CatalogUpdateInfo to perform a map update via mapUpdater.updateCatalog(catalogUpdateInfo, CatalogUpdateProgressListener()). When you are using a MapView, then you also need to reinitialize all engines including the SdkNativeEngine and the MapView.
NoteWhen calling
mapUpdater.updateCatalog(..)and no regions have been downloaded, this method will update only the map cache. If no updates are available, theMapUpdateProgressListener.onComplete()callback will be invoked immediately with aMapLoaderError. The map data cache adheres to the LRU (Least Recently Used) eviction policy, so any updates will exclusively apply to newly downloaded data and not retroactively to existing cached data. For immediate cache invalidation, users can manually clear the cache. Otherwise, stale cache data may still be accessed by the HERE SDK, for example, when using theOfflineSearchEngine.
To apply a changed LayerConfiguration it is recommended to use the same code you use to check for map updates. Just make sure to perform the code on a new MapUpdater instance. An example implementation of checkForMapUpdates() can be found in the map update guide.
Note that it is the developer's responsibility to decide when to perform the update. The async update process, also called "normalization", may take time depending on how many regions have been installed. The HERE SDK does not decide or notify when such an update can be made. It is not necessary to call this, when the feature configuration has not been changed by a developer.
Update the layer configuration when using a MapView
To enable or disable a layer configuration at runtime when showing a MapView, calling mapUpdater.updateCatalog(..) alone is not sufficient. All engines, including SdkNativeEngine and MapView, must be reinitialized. Below we show an example of the steps.
- Start with reinitialization of the HERE SDK and set a new layer configuration.
let authenticationMode = AuthenticationMode.withKeySecret(accessKeyId: accessKeyID, accessKeySecret: accessKeySecret)
var options = SDKOptions(authenticationMode: authenticationMode)
options.layerConfiguration = LayerConfiguration(enabledFeatures: features)
do {
// Initialize the SDKNativeEngine
try SDKNativeEngine.makeSharedInstance(options: options)
} catch let engineInstantiationError {
showMessage("Failed to initialize the HERE SDK. Cause: \(engineInstantiationError.localizedDescription)")
return
}
// Reset the map view
self.mapViewObservable.resetMapView()
// Initialize MapDownloader
initMapDownloader(sdkNativeEngine: SDKNativeEngine.sharedInstance!)
// Reinitialize other necessary engines as required.
- Update the current
MapViewinstance to recreate the rendering surface that was invalidated by the invocation ofmakeSharedInstance().
To enable the re-creation of MapView, encapsulate it within a MapViewObservable. This object allows SwiftUI to observe the MapView.
Consequently, any changes made to the MapViewObservable will trigger the re-creation of the MapView along with its rendering surfaces.
class MapViewObservable : ObservableObject {
@Published var mapView: MapView?
init() {
self.mapView = MapView()
}
func configureMapView() {
self.mapView = self.mapView ?? MapView()
let camera = self.mapView!.camera
let distanceInMeters = MapMeasure(kind: .distanceInMeters, value: 1000 * 7)
camera.lookAt(point: GeoCoordinates(latitude: 52.530932, longitude: 13.384915),
zoom: distanceInMeters)
// Load the map scene using a map scheme to render the map with.
self.mapView!.mapScene.loadScene(mapScheme: MapScheme.normalDay, completion: onLoadScene)
}
// Completion handler for loadScene().
private func onLoadScene(mapError: MapError?) {
if let mapError = mapError {
print("Error: Map scene not loaded, \(String(describing: mapError))")
}
}
func resetMapView() {
self.mapView = nil
}
}
The MapViewObservable can be integrated with SwiftUI by leveraging a UIViewRepresentable wrapper. An implementation may look like below:
// The MapView provided by the HERE SDK conforms to a UIKit view, so it needs to be wrapped to conform
// to a SwiftUI view. The map view is created in the ContentView and bound here.
private struct WrappedMapView: UIViewRepresentable{
@ObservedObject var mapViewObservable: MapViewObservable
func makeUIView(context: Context) -> MapView {
if mapViewObservable.mapView == nil{
mapViewObservable.configureMapView()
}
return mapViewObservable.mapView!
}
func updateUIView(_ uiView: MapView, context: Context) {
// Updates will automatically apply due to observable properties
}
}
- Reinitialize the
MapUpdaterand use it to update the catalogs.
// ReCreate MapUpdater in background to not block the UI thread.
MapUpdater.fromEngineAsync(SDKNativeEngine.sharedInstance!) { mapUpdater in
self.mapUpdater = mapUpdater
// Perform the map update ...
}
To see a possible implementation of how to update a LayerConfiguration and perform map data updates, refer to the OfflineMaps example app on GitHub.
Implicit prefetch features for online use
In addition to layerConfiguration.enabledFeatures, you can also set layerConfiguration.implicitlyPrefetchedFeatures.
enabledFeatureswill enable all layers from the list when downloading regions for offline use.implicitlyPrefetchedFeatureswill enable all layers from the list when downloading map content into the map cache, for example, when panning theMapViewduring online use.
By default, the following features are enabled for implicit prefetching:
detailRenderingnavigationofflineSearchofflineRoutingrenderingtruck
To customize implicit prefetching, use the implicitlyPrefetchedFeatures field in LayerConfiguration.
var features: [LayerConfiguration.Feature] = [.detailRendering, .rendering, .offlineSearch]
options.layerConfiguration = LayerConfiguration(enabledFeatures: features)
options.layerConfiguration.implicitlyPrefetchedFeatures = features
When configuring LayerConfiguration, you can enable the same set of features for both online and offline use by assigning the same list of features to both enabledFeatures and implicitlyPrefetchedFeatures. This ensures consistency in feature availability regardless of whether the application is operating online or offline.
In order to disable implicitlyPrefetchedFeatures, assign an empty list to layerConfiguration.implicitlyPrefetchedFeatures. Disabling implicit prefetching for certain features reduces network consumption, but may limit offline capabilities. Cached map data already downloaded will not be removed immediately.
Here are some examples of how to configure implicitlyPrefetchedFeatures based on specific use cases:
-
If your primary goal is to minimize network usage during online operations, set an empty list to
layerConfiguration.implicitlyPrefetchedFeatures. This ensures only minimal required map data is downloaded while panning or interacting with theMapView. The trade-off is that less data in the cache will not allow you to use offline features, unless you have the needed regions installed. -
If your application requires offline routing, but you do not know which regions to download in advance, enable only the
offlineRoutingimplicit feature. This reduces the amount of downloaded data when panning the map in online mode, but you can still try to use theOfflineRoutingEngineon the cached data. Note that there is no guarantee that enough data has been cached. If you want to make sure to have enough data, it is recommended to install the needed regions. -
If your application requires offline routing while being radio-silent, enable only the
offlineRoutingimplicit feature as mentioned above and additionally set it as aPassThroughFeatureviaSDKNativeEngine.
Updated 10 hours ago