Engines
Explore the fundamentals of working with HERE SDK engines, including their integration with or without a map view, initialization options, and efficient management of the map cache.
How to work with engines
The HERE SDK contains several modules - or engines as we call them - to execute specific tasks such as calculating a route with the RoutingEngine or requesting search results via the SearchEngine. There are many more engines you can use with the HERE SDK and you can read more about them in the dedicated chapters below. However, most engines share common concepts that makes it easier to use them. For example:
- All engines execute their tasks asynchronously and receive their results on the main thread.
- All engines share similar interfaces, callbacks and error handling.
- It is possible to start multiple instances of an engine in parallel.
- An online connection is required.
Below you can find an overview of the most common engines in the HERE SDK:
SearchEngine: Includes all functionality to search for places, suggestions and locations including geocoding and reverse geocoding.OfflineSearchEngine(only available for Navigate): The offline version of search that makes request locally using already downloaded map data.RoutingEngine/TransitRoutingEngine: Allows to calculate routes including various options and transport types.OfflineRoutingEngine(only available for Navigate): The offline version that calculates a route using already downloaded map data.LocationEngine(only available for Navigate): An advanced HERE positioning solution.ConsentEngine(only available for Navigate): A supportive engine that helps to aggregate the user's consent before using, for example, theLocationEngine.Navigator/VisualNavigator(only available for Navigate): Although not having 'engine' in its name, these classes act as an engine and control all functionality around turn-by-turn navigation.DynamicRoutingEngine(only available for Navigate): An engine that periodically searches for shorter or faster routes based on the current traffic situation. This can be useful during guidance to notify drivers on route alternatives.TrafficEngine: An engine that allows to search for traffic incidents.MapDownloader/MapUpdater/RoutePrefetcher(only available for Navigate): These classes perform downloads or updates of map data and mark a vital part of any application that supports an offline mode.VenueEngine(only available for Navigate): Specialized engines to support the integration of private venues into your apps.SDKNativeEngine: Is required to setup credentials programmatically and allows a few other advanced settings.MapView: A view to visualize map data. Not really an engine, but listed here for completeness.
Note that all HERE SDK engines, except for the SDKNativeEngine, can operate independently from each other and require HERE credentials to request data.
NoteThe HERE SDK does not verify credentials at instantiation time. This only happens once a feature is used that requires authentication. In case of a failure, you will get a dedicated error message. For example, the
SearchEnginewill reply with aSearchError.authenticationFailederror. Other engines provide similar error codes.Not all credentials will work for all features. If the credentials are invalid, the logs contain
[ERROR]messages with a text similar toFailed to get the authentication token: Authentication failed, error code: 1. This indicates that the credentials are not accepted when using a service. If you want to ensure that your credentials are set up correctly, use a feature with a specialized engine and check if the engine replies with an error value.
Any engine can be created using a parameterless constructor. Example:
try {
_searchEngine = SearchEngine();
} on InstantiationException {
// Handle exception.
}Using this default constructor requires that the HERE SDK is already initialized and that a shared instance of the SDKNativeEngine was set either directly by calling SDKNativeEngine.sharedInstance = sdkNativeEngine or implicitly by calling SDKNativeEngine.makeSharedInstance(options).
For rare use case scenarios, you can use an overloaded constructor that takes an individually created instance of the SDKNativeEngine - as shown in the below section.
Use Engines with or without a Map View
Engines do not need a map view to operate. Therefore it is possible to run an engine on its own, without any map view added to your application. This way, you can build an app solely around a specific engine. With or without a map view - the procedure to create a new engine is exactly the same. Just make sure to initialize the HERE SDK beforehand.
Initialization options
The HERE SDK can be initialized with various options that can be set either directly for the SDKNativeEngine or when initializing the engine with SDKOptions.
None of the options are persisted - unless otherwise notes in the API Reference: this means, whenever you initialize the HERE SDK again, the previous options have to be set again if you want to keep them.
The same applies to options you can set for the various feature engines or when using a feature such as the RoutingEngine to calculate a Route with, for example, RoutingOptions.
Since HERE SDK 4.12.1.0, the HERE SDK itself needs to be initialized manually. To learn more, see Integrate the HERE SDK.
- If your app immediately wants to show a map view after app start, then for most use cases it's sufficient to follow the Integrate the HERE SDK guide. However:
- If your app needs to show a map view at a later point in time or if you want to delay initialization, then it is also possible to initialize the HERE SDK at a later point in time.
These are the steps to initialize the HERE SDK:
- Call
SdkContext.init(IsolateOrigin.main). Note that this does not yet init the HERE SDK. - Initialize the HERE SDK by creating
SDKOptionsand use them to create a newSDKNativeEngine.
Make sure to call SdkContext.init(IsolateOrigin.main) once, since it initializes the Isolate and sets up other resources that are need to initialize the HERE SDK. If you have different isolates, it must be initialized for each of those isolates threads with a different init parameter. Usually, it is enough to call init() in the main() function in your main.dart file. Note that, for example, during a hot restart all existing isolates are destroyed and the HERE SDK runs SdkContext.init(IsolateOrigin.main) again. However, in such a case you would still need to call init() again if you want to launch a new custom isolate in which the HERE SDK should run.
The creation of the SDKNativeEngine and other engines such as the SearchEngine happens synchronously in a negligible amount of time.
You can initialize the HERE SDK in two ways:
- Create a shared instance of the
SDKNativeEnginewithSDKNativeEngine.makeSharedInstance(options). - Create individual instances of the
SDKNativeEngineviaSDKNativeEngine(options).
By calling SDKNativeEngine.makeSharedInstance(options) you create a shared instance of the SDKNativeEngine that can be used by the HERE SDK. This singleton approach allows easy creation of engines such as the SearchEngine, because you can use the default constructor (SearchEngine()) that requires no parameters. Internally, the SearchEngine will use the shared instance of the SDKNativeEngine you have created at initialization time. Therefore, when you re-initialize the HERE SDK, also all engines that have been created using the parameterless constructor, need to be created again.
NoteIn case of re-initialization, also a
MapViewinstance needs to be initialized again by calling itsonCreate(..)method. The state of aMapViewbecomes invalid, when theSDKNativeEngineis disposed. CallmapView.isValid()to determine if theMapViewis initialized correctly.
Alternatively, for rare use cases, you can set an individual SDKNativeEngine instance for each of the feature engines:
SearchEngine searchEngine = SearchEngine(sdkNativeEngine);In general, it should not be necessary to initialize the SDKNativeEngine multiple times. Only one shared instance can be set at a time, which happens implicitly when calling SDKNativeEngine.makeSharedInstance(options). Alternatively, you can use the available constructor to create an instance of the SDKNativeEngine directly: if you create multiple instances individually, then no shared instance is set - and each feature engine needs to be created with an instance of a SDKNativeEngine as constructor parameter - like shown above. This way you can use feature engines such as the SearchEngine or the RoutingEngine with different instances of the SDKNativeEngine that can hold different SDKOptions.
Note that any individual instance can be set explicitly as shared instance by calling SDKNativeEngine.sharedInstance = sdkNativeEngine. Attention: in this case, make sure to dispose() any previous instance by calling await SDKNativeEngine.sharedInstance?.dispose(). Note that this is not necessary when creating a global instance by calling SDKNativeEngine.makeSharedInstance(options) - for convenience, this call internally disposes any previously shared instance.
NoteFor most use cases it is not recommended to create multiple instances: in case of doubt, we recommend to initialize the HERE SDK only via
SDKNativeEngine.makeSharedInstance(options)as shown in the Integrate the HERE SDK guide. It is possible to use this initialization method each time the HERE SDK is needed and to dispose theSDKNativeEnginethereafter: for example, for each widget. However, for most cases it can be more efficient if the HERE SDK is initialized only once during the lifetime of an application.
Multiple SDKNativeEngine instances can’t have the same access key ID and the cache path is ensured to be unique per access key ID. If a second instance is created with an access key ID that is already in use, then an InstantiationException is thrown: as a rule of thumb, when you need multiple instances, you also need a distinct set of credentials for each.
NoteThe access key ID part of your credentials is tied to the cache path. When credentials are changed at runtime, it may look like that the previous cache is gone, but it still exists and it is not cleared automatically after disposing the
SDKNativeEngineor after setting new credentials. Since new credentials have been set, the cache path has just been changed. For example, when the previous credentials are restored, the previous cache can be used again.
More information on the cache can be found below.
Initialization and Android permissions
Usually, it is good practice to initialize the HERE SDK not before all permissions have been granted.
The HERE SDK for Flutter automatically merges all required permissions to the AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
NoteThese permissions are not sensitive and are immediately granted upon installation by the system - they are always needed, as the HERE SDK needs to have a working internet connection. It is not a requirement to handle these permissions and there are no HERE SDK specific requirements on how to handle permissions.
However, be aware that a user can deny any permission after installation via the device's app settings. You can use a native convenience class to notify the user upon app launch like shown here for native Android. Note that Flutter itself does not provide any mechanism to handle permissions - and the accompanying Flutter example apps do not utilize any specific Android permission handling. If no internet connection is available, most HERE SDK services will indicate this with an appropriate error message.
Note (only applicable for Navigate)For some HERE SDK features, like HERE Positioning, you need additional permissions. See the dedicated Find your Location section how to handle them.
Work with the map cache
To better support online and offline use cases, the HERE SDK supports caching of downloaded vector map data. This happens in the background. While interacting with the map, prefetching or using navigation with or without a map view, the data is stored locally on the device and can be accessed even when the device loses connection or operates in an offline mode.
NoteThe HERE SDK stores arbitrary data as part of map tiles. Therefore, even without displaying a map view, the map cache will be utilized. For instance, during navigation, all necessary data is stored in the map cache within map tiles. However, it's important to note that not all licenses support features such as prefetching and navigation.
The integrated map caching mechanism supports the standard vector based map schemes - satellite images and other raster tiles are also cached, but in a different cache that is not configurable.
Please note that the amount of cached data is limited and will be overwritten with new map data while using the map. In most cases, this is sufficient to give the user the impression of a faster start-up time - as no additional data must be downloaded when you start an app again at the same location as before.
When the cache is full, a least recently used LRU strategy is applied.
Change path and cache size
- An absolute cache path and maximum size can be specified when manually initializing the HERE SDK using
SDKOptions. Check the Engines section for more details. - Via
SDKOptionsyou can specify the desiredcacheSizeInBytesto define the upper bound of the cache in bytes. Make sure to query the available disk space on the device with the available platform APIs.
There can be a separate cache defined for customer raster layers.
This is how you can clear the map cache:
SDKCache.fromSdkEngine(SDKNativeEngine.sharedInstance).clearAppCache((error) {
if (error != null) {
// ...
}
});Note that disposing the SDKNativeEngine.sharedInstance does not clear the cache.
By setting an empty string as cache path, you keep the default cache path - which is also accessible via SDKNativeEngine.sharedInstance?.options.cachePath:
// Specify credentials programmatically and keep default cache path by setting an empty string.
SDKOptions sdkOptions = SDKOptions.withAccessKeySecretAndCachePath("YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET", "");Work with map cache in Navigate
NoteSince turn-by-turn navigation requires caching, a valid cache path is mandatory when creating a
SDKNativeEngine.
You can update the map cache to a newer map version - independently of offline maps. By calling mapUpdater.performMapUpdate() the map cache will be updated to a newer version (if available) - even if never any Region was installed. If offline maps are available, then they will be updated together with the map cache, like before. If offline maps are installed later after the cache has been updated, the same map version will be used. It is not possible to use different versions for the map cache and offline maps.
In order to get the latest map data while panning the map view, you can check if an update is available and then install it. If no offline Region maps are installed, this takes only a few seconds. The MapVersionHandle indicates the currently used map version.
NoteIf you do a fresh install of an application, then not necessarily the latest map version is used. Usually, each HERE SDK release is shipped with a specific map version. However, when you are using a (custom)
CatalogConfiguration, then it is possible to specify the map version that should be used right after installation of an app, for example, by specifying the latest map version in theDesiredCatalog.
More information on the map version, the cache and offline maps can be found in the Offline Maps section.
NoteVia
SDKOptionsyou can also specify a time when the cache should expire. If you set the time to 0, then this will prevent an app to store data into the cache. If no offline regions have been installed, then - when the device has lost connectivity - no map is visible until the device gets online again. Note that this will not enable you to always see the latest and greatest map data: for this, you would still need to check if a map update is available.
Questions and answers around the map cache
Navigate
-
What is a map tile? Map tiles are stored in the map cache. A map tile contains data relevant for search and routing, as well as vector data for the visual representation. It is stored in the Optimized Client Map (OCM) format. Map tiles are available for different zoom levels. A map tile may contain different data, depending on the zoom level.
-
How long are map tiles cached? Map tiles are only evicted when the cache is full - there is no staleness of old tiles and no automatic deletion of old tiles based on time. Note that this does not apply for satellite images (see below).
-
What is the eviction policy of the cache? The HERE SDK uses a LRU (least recently used tile) logic to evict the tiles when the map cache becomes full. There is no sophisticated logic to evict, for example, tiles that are farther away from the current location - as it is not foreseeable which areas of the world the user might visit next. However, the map cache is not session-specific, its data from the last time the device was used, that is from the last power cycle, is still there the next time the app is used. Note that the cache is specific per app, not per device.
-
What is the impact of missing data in the map cache? Usually, the map cache is never assumed to be complete and there can be always tiles missing for a surrounding area. This is because map tiles get loaded only on demand while they are rendered. When there are tiles missing from the map cache then, for example, the
OfflineSearchEnginewill not find POIs or road names that are part of the missing tiles and the HERE Rendering Engine cannot render such data. Also, theOfflineRoutingEnginemight fail - unless it finds a route around the missing tiles.
Explore
-
What is a map tile? Map tiles are stored in the map cache. A map tile contains data relevant for search and routing, as well as vector data for the visual representation. Map tiles are available for different zoom levels. A map tile may contain different data, depending on the zoom level.
-
How long are map tiles cached? Map tiles cannot be used after one day and will be evicted. New images are downloaded earliest after one day based on a LRU strategy.
Explore and Navigates
-
What is the eviction policy of the cache? The HERE SDK uses a LRU (least recently used tile) logic to evict the tiles after one day. The map cache is not session-specific, its data from the last time the device was used, that is from the last power cycle, is still there the next time the app is used. Note that the cache is specific per app, not per device.
-
What is the size of the map cache? The size of the map cache can be changed by the application. Use at least 256 MB (default). Values above 512 MB or 1 GB are recommended. For turn-by-turn navigation (which is available e.g. for the
Navigate), map tiles of zoom level 14 are needed, which equals a circle of roughly 2 km. However, this can vary a bit from location to location. -
Is any previously cached map tile searchable offline? Yes, it's always searchable with the
OfflineSearchEngine. However, sometimes not every map tile contains the same search results for every zoom level. Note that theOfflineSearchEngineis not available for every license. -
Is only one map tile cached at a time? Yes, only one tile at a time may be added unless its location is on the edge of two tiles. Depending on the zoom level, rendering of the map view will require several tiles - this is not happening automatically and only when the zoom level changes.
-
Are satellite images cached? Yes. When the satellite map scheme is set, the corresponding imagery is also cached, but satellite images cannot be used after one day and will be evicted. New images are downloaded earliest after one day based on a LRU strategy.
-
Is there always a "base map" available, such as a globe view? The HERE SDK downloads automatically the world tiles, that is the top most zoom level tiles for the globe. This means that there is always a map available for the globe with a very limited amount of information for rendering purposes. The shapes of countries and continents are visible and capitols are shown with text labels.
-
Is the cache auto-cleared? No, a full cache is only cleared based on a LRU strategy (see above). If tiles have not been fully downloaded due to a connectivity interruption, these tiles are preserved and the download continues when connectivity resumes.
-
If connectivity is available, will a whole route be cached in advance? No, this is not happening automatically. However, you can use the
RoutePrefetcherto download map data into the cache along the route corridor. Look into the turn-by-turn navigation section for more details. Note that theRoutePrefetcheris not available for every license.
Updated yesterday