Use custom map catalogs
The HERE SDK can be configured to consume custom map catalogs. This allows to use the HERE SDK with customized map data. For example, those can include your custom road networks or points of interest.
Similar to standard map catalogs, custom map data can be used by HERE SDK in both online and offline modes.
The creation of custom map catalogs - for example, with your custom road geometry or POIs - requires HERE support and an additional agreement with HERE. Please contact your HERE representative for more details.
Once this step is completed, you can use the below code examples to load and use your custom map data in your application.
Customize map data with the CatalogConfiguration
By default, the HERE SDK uses map data that is compiled into a specialized map format. This data is downloaded into the map cache on-the-fly - or it can be downloaded in advance with offline maps. The HERE SDK (Navigate) uses the OCM map catalog format.
A map catalog is identified through its Here Resource Name (HRN). By default, the HERE SDK contains the OCM catalog with the HRN: "hrn:here:data::olp-here:ocm". Every catalog is a collection of layers that contain map objects with geometry and attributions. A layer's content is cut into tiles, for efficient search, map display, routing, map matching, driver warnings and other data. The core map content is divided into regional maps, but can always be used as a single, global map. Other content is delivered in dedicated - mostly worldwide - maps.
This data can be customized together with HERE and then made accessible via a custom catalog. Once the catalog is ready, you can access it by specifying the HRN value and scope. More information on the HRN catalog identifier and setting a scope can be found here.
On top, you may also want to adapt certain HERE online services such as routing and search to match the data of the offline maps data. In this case, HERE can help to setup a custom backend that hosts the adapted HERE services just for your company. Such a custom backend can be specified via Map[EngineBaseURL, EngineOptions]. As a result, all requests made using classes like SearchEngine will use the specified backend.
NoteSetting custom backends via self-hosting is optional and only required when you want to use services such as custom routing or custom search online.
- When custom OCM data is installed on a device via
MapDownloaderor fully cached, then features like custom routing viaOfflineRoutingEngineare fully supported offline without the need for self-hosting of custom backends.- For online use a custom backend URL needs to be specified for the service (see below): Only with a custom backend you can create custom routes online with the
RoutingEngine. Same for other services like online search viaSearchEngine.
When a custom catalog is available on the HERE platform you can load and use your map data with a custom CatalogConfiguration. A CatalogConfiguration along with optional custom backend URLs needs to be specified via SDKOptions each time the HERE SDK is initialized - as the setting is not persisted.
The below code snippet shows how to do this:
func initializeHERESDKWithCustomCatalogConfiguration() {
// Note: Each catalog configuration may require special credentials.
// For tips on how to secure setting credentials from code, please check our Developer Guide.
let accessKeyID = "SET_YOUR_ACCESS_KEY"
let accessKeySecret = "SET_YOUR_ACCESS_KEY_SECRECT"
let authenticationMode = AuthenticationMode.withKeySecret(accessKeyId: accessKeyID, accessKeySecret: accessKeySecret)
var options = SDKOptions(authenticationMode: authenticationMode)
options.catalogConfigurations = getCustomCatalogConfiguration()
// Optionally, specify a custom routing backend that matches the custom OCM map for use with the (online) RoutingEngine.
options.customEngineOptions = getCustomBackends()
do {
try SDKNativeEngine.makeSharedInstance(options: options)
} catch let e as InstantiationErrorCode {
fatalError("Initialization of HERE SDK failed: \(e.localizedDescription)")
} catch let error {
fatalError("Initialization of HERE SDK failed: \(error.localizedDescription)")
}
SDKNativeEngine.sharedInstance?.setAccessScope(scope: getCustomCatalogScope())
print("Activated custom OCM catalog.")
}
func getCustomCatalogConfiguration() -> [CatalogConfiguration] {
var catalogConfigurations = [CatalogConfiguration]()
// We want to start with the latest catalog version.
let ignoreCachedData = true
let versionHint = CatalogVersionHint.latest(ignoreCachedData: ignoreCachedData)
let customHRN = "hrn:here:data::olp-namespace:your-company-ocm"
let customOCMCatalog = DesiredCatalog(hrn: customHRN, version: versionHint)
catalogConfigurations.append(CatalogConfiguration(catalog: customOCMCatalog))
// Optionally, set a patch HRN to enable incremental map updates.
return catalogConfigurations
}
// Note that self-hosting is optional.
func getCustomBackends() -> [EngineBaseURL: EngineOptions] {
var engineOptions = EngineOptions()
engineOptions.customBaseUrl = "https://your-company.router.hereapi.com"
return [.routingEngine: engineOptions]
}
private func getCustomCatalogScope() -> String {
return "hrn:here:authorization::olp-here:project/your-company-hsdk";
}
Initially, you need to specify a catalog version you want to start with. The DesiredCatalog provides a way to identify a catalog on the HERE platform. A developer can also specify the HERE Resource Name (HRN) for the catalog along with a CatalogVersionHint for the desired version. Once set up, you can use regular map updates via MapUpdater (not available for all licenses). This catalog version will then appear as part of the MapVersionHandle.
Make sure to set optionally catalogConfiguration.patchHrn = "hrn:here:data::olp-namespace:__your-patch-hrn-123__" when you want to enable incremental map updates for the custom OCM map. Use the appropriate patch HRN value for your project. Usually, incremental map updates are enabled by default, but when a CatalogConfiguration is set, then this behaves differently: setting the patchHrn to null will disable incremental map updates and for a CatalogConfiguration that is newly created, this is the default state.
More information on custom map data can be found in the HERE Map Attributes API which allows to access all HERE map data as well as the private map data of a customer.
Self-hosted services
With customEngineOptions (see above), it is possible to self-host services for the HERE SDK, for example, you can mirror the backend for HERE services on your own servers and access them by setting a URL via Map[EngineBaseURL, EngineOptions].
The access to your own backend is fully customizable with configurable endpoints including authentication and proxy support (see here).
This step is only needed when you want to ensure that you can use the online feature engines of the HERE SDK. For example, if you want to insert a custom POI layer, you can search this customized map data already with the OfflineSearchEngine. Alternatively, you can also use the MyPlaces API to insert your data at runtime - or handle your requests in-app with your own REST code and your own (remote) databases or servers. On the other hand, if you want to make use of, for example, the SearchEngine, then you should consider the effort of self-hosting, because then each online request needs to be handled on your self-hosted backend. However, the most common use case for self-hosting is to have full control over the accessed servers that respond to the requests that the HERE SDK will initiate.
Note that this requires quite some effort and it is recommended to get in touch with the HERE SDK support team to discuss your setup and possible alternatives.
NoteDespite hosting selected HERE online services on your own backends, it is also possible to host custom OCM map catalogs on your backends (on-premise). Self-hosted maps may help when you need to move all HERE services to your own network behind a firewall. This requires to use a DS Proxy (see below). Please talk to your HERE representative about the details for such an option.
Set a DS proxy
By default, the data service proxy, in short dsProxy, is set to "https://direct.data.api.platform.here.com/direct/v1", which will be used as a prefix for HERE platform requests. When a custom catalog should be used, then the HERE SDK will internally do a lookup request to find out the corresponding URL to access a catalog. In order to bypass this extra request, we recommend to set the URL upfront when initializing the HERE SDK.
For example, a valid dsProxy for a custom catalog may look like this: "https://data.api.platform.yourcompany.com/direct/v1".
Set the custom proxy via Map[EngineBaseURL, EngineOptions], then pass it as customEngineOptions to SDKOptions when initializing the HERE SDK.
In addition, for self-hosted backends and/or self-hosted maps (on-premise) an authentication token needs to be acquired manually by calling Authentication.authenticate(…). Before initializing the HERE SDK, set the token via AuthenticationMode.withToken(…).
NoteThe
dsProxyis not a network proxy setting: it only specifies the URL to access a catalog. If you do not want to load a custom catalog configuration (see above), you can ignore this setting.
Use custom catalogs together with Japan
Once your credentials are enabled by the HERE team for Japan, you can set the Japan map HRN string "hrn:here:data::olp-here:ocm-japan" to a DesiredCatalog instance. Then create a new CatalogConfiguration and pass it to sdkOptions.catalogConfigurations like already shown above.
Note that the below instructions are only relevant when you are using custom catalogs. If you do not use custom catalogs, you only need enabled credentials to see the enriched Japan map.
A Japan catalog can be set on it's own or together with a default map which is covering the whole world. By default, this is OCM, identified by this HRN value: "hrn:here:data::olp-here:ocm". Replace this with the custom HRN of your catalog. Below you can see how to use a Japan catalog together with a whole-world catalog.
func getDefaultCatalogConfigurationWithJapan() -> [CatalogConfiguration] {
var catalogConfigurations = [CatalogConfiguration]()
// We want to start with the latest catalog version.
let ignoreCachedData = true
let versionHint = CatalogVersionHint.latest(ignoreCachedData: ignoreCachedData)
// An OCM catalog is required, typically, use your own catalog HRN here.
let defaultOCMHRN = "hrn:here:data::olp-here:ocm"
let defaultOCMCatalog = DesiredCatalog(hrn: defaultOCMHRN, version: versionHint)
let defaultCatalogConfiguration = CatalogConfiguration(catalog: defaultOCMCatalog)
catalogConfigurations.append(defaultCatalogConfiguration)
// Specify a rich Japan map, requires special HERE credentials.
// If the credentials are not enabled for access, the map falls back to the Japan base map.
let japanOCMHRN = "hrn:here:data::olp-here:ocm-japan"
let japanOCMCatalog = DesiredCatalog(hrn: japanOCMHRN, version: versionHint)
let japanCatalogConfiguration = CatalogConfiguration(catalog: japanOCMCatalog)
catalogConfigurations.append(japanCatalogConfiguration)
// Optionally, set a patch HRN to enable incremental map updates.
return catalogConfigurations
}
Make sure to set optionally catalogConfiguration.patchHrn = "hrn:here:data::olp-here:ocm-japan-patch" when you want to enable incremental map updates for the Japan map. Usually, incremental map updates are enabled by default, but when a CatalogConfiguration is set, then - for now - this behaves differently: Setting the
patchHrn to nil will disable incremental map updates and for a CatalogConfiguration that is newly created, this is the default state.
For convenience, you can also get the default configuration like this:
var catalogConfigurations = [CatalogConfiguration]()
// By calling getDefault() you will automatically get the latest version
// at the time when the HERE SDK was built.
let defaultConfiguration = CatalogConfiguration.getDefault(catalogType: CatalogType.optimizedClientMap)
catalogConfigurations.append(defaultConfiguration)
// Specify a rich Japan map, requires special HERE credentials.
// Note: If the credentials are not enabled for access, the map falls back to the Japan base map.
let japanConfiguration = CatalogConfiguration.getDefault(catalogType: CatalogType.optimizedClientMapJapan)
catalogConfigurations.append(japanConfiguration)
You can also retrieve the details of a default catalog like shown below:
let catalogJapan = CatalogConfiguration.getDefault(catalogType: CatalogType.optimizedClientMapJapan)
let catalogIdentifier = catalogJapan.catalog.id
print("Japan HRN: \(String(describing: catalogIdentifier.hrn))")
print("Japan version: \(String(describing: catalogIdentifier.version))")
Updated 10 hours ago