The Data Inspector Library provides example applications designed to help you understand the different use cases. There are two ways to access the examples:
Follow this link to access the examples hosted on the HERE platform. You can start investigating Data Inspector capabilities right away, without any installations. The only thing you need is to log into the platform.
Follow the steps described in the Install Example Apps chapter to install and run the examples locally. Once installed, open the examples at http://localhost:5000/.
Each example runs in the Data Inspector application window (represented by the DataInspector class) and explains a single feature of a certain Data Inspector Library component or a combination of various features.
Figure 1. Data Inspector Library Examples
Click the Details button to view a detailed example description.
To view the source code of an example, click the Source code button.
To download a ZIP archive with the sources of all example applications, click the Download examples button.
Examples List
This chapter describes all the examples that the Data Inspector Library contains, including their source code (click to expand):
This example showcases how an embedded application can control the DataInspector from outside.
It is possible to change the catalog's HERE Resource Name (HRN), layer, layer version, as well as zoom level and map view location based on user input or URL parameters.
In this example, an input form is provided where you can enter the HRN, layer, version, latitude, longitude, and zoom level values in order to change the state of the DataInspector.
For this purpose, DataInspector provides these public methods:
setState: Sets a new state for the DataInspector and reloads with a new HRN, layer, and layer version.
focusMapCameraAt: Centers the camera at the specified coordinates and sets the desired zoom level.
Also, you can get the state of the DataInspector and maintain it in the URL parameters when you move around, or specify a new HRN, version, or layer, for example:
/*
* Copyright (C) 2018-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ GeoCoordinates }from"@here/harp-geoutils";import{ MapViewEventNames }from"@here/harp-mapview";import{ VersionedLayer, PlatformDataProvider }from"@here/interactive-datasource-protocol";import{
DataInspector,
I18n,
PanelDisplayMode,
WidgetAbstract
}from"@here/interactive-mapview-ui";import{ Action, History, createBrowserHistory, Update }from"history";import{
geoCenter,
useToken,
locale,
showLanguageSelector,
enableExtendedCoverage,
layerBrowserAppDataLayer,
layerBrowserAppHostHrn,
lookupServiceEnvironment,
hideURL
}from"../config";import{ bearerTokenProvider }from"./common";/**
* This example showcases how embedded application can control the data inspector from outside.
*
* It is possible to change the catalog HRN, layer, and layer version, as well as
* zoom level and location of the map view based on user input or URL parameters.
*
* In this example the input form provided where user can input HRN, Layer, Version, Latitude,
* Longitude and Level in order to change the state of the data inspector.
*
* For this purpose the `DataInspector` provides public methods such as:
* `setState` - Sets new state for a component and reloads with new HRN, layer and layer version.
* `focusMapCameraAt` - Centers the camera at the specified coordinates and sets desired zoom level.
*
* Also, it allows to get state of the data inspector and maintain it in the URL parameters
* when user moves around or gives new HRN/version/layer:
* ?hrn=hrn:here:data::olp-here:rib-2&layer=topology-geometry&location=52.4956004,13.3553675&zoomLevel=10
*//**
* Interface for parameters which controls the data inspector.
*/interfaceDataInspectorControlParams{/**
* A catalog HRN string for the data source.
*/
hrn:string;/**
* A layer name for the data source.
*/
layer:string;/**
* A version of the data source layer.
*/
version?:number;/**
* Map zoom level.
*/
zoomLevel?:number;/**
* Camera position.
*/
location?:{
latitude:number;
longitude:number;};}/** Available strategies to store/retrieve data from URL. */enum BrowserHistoryStrategy {/** Custom strategy. */
Custom,/** Build in into DataInspector strategy. */
DataInspector,/** Data will not be stored/retrieved from URL. Used to avoid URL parameters conflict. */
None
}/**
* Class which implements functionality of controlling the data inspector.
*/classLayerBrowserApplication{/** An instance of [[DataInspector]] UI widget. */private m_dataInspector: DataInspector;/**
* Parameters which controls the data inspector.
* Catalog HRN and layer already set by default. Can be changed to any other supported
* catalog/layer.
*/private m_controlParams: DataInspectorControlParams ={
hrn: layerBrowserAppHostHrn,
layer: layerBrowserAppDataLayer
};/**
* An object which lets easily manage browser history.
*/private m_browserHistory: History |undefined;/**
* One of PUSH, REPLACE, or POP depending on how the URL was set.
*/private m_browserAction = Action.Push;/**
* Constructor initializes browser history, control parameters, data inspector, listeners and
* user input form.
*
* @param browserHistoryStrategy Defines which strategy will be used to store/retrieve data
* from URL.
* @default BrowserHistoryStrategy.Custom.
*/constructor(browserHistoryStrategy = BrowserHistoryStrategy.Custom){if(browserHistoryStrategy === BrowserHistoryStrategy.Custom){this.m_browserHistory =createBrowserHistory();this.m_browserHistory.listen(this.browserHistoryHandler.bind(this));}// Fetch control parameter from URL before creating data inspector instance in order to// initialize with defined in URL parameters.this.fetchControlParams();// Set browser title.this.setBrowserTitle();// Create data inspector.this.m_dataInspector =newDataInspector({
mapView:{
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"},
defaultZoomLevel:this.m_controlParams.zoomLevel,...(this.m_controlParams.location
?{ geoCenter:this.m_controlParams.location }:{ geoCenter })},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
logMessages:true,
lookupServiceEnvironment,
pageUrlParams:{
enabled: browserHistoryStrategy === BrowserHistoryStrategy.DataInspector
}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSources:[{
hrn:this.m_controlParams.hrn,
layer:this.m_controlParams.layer,
catalogVersion:this.m_controlParams.version
}],
enableCoverage:true,
enableExtendedCoverage,
enableFiltering:true,
enableInfoPanel:true});// Open control panel to pay attention of the user on authorization form in case if not// logged in.if(this.m_dataInspector.toolBar !==undefined&&this.m_dataInspector.authForm !==undefined&&this.m_dataInspector.authForm.isDisabled ===false){const leftPanelBtn =this.m_dataInspector.toolBar.getLeftPanelBtn();if(leftPanelBtn){
leftPanelBtn.switchOn();}}// Add listeners after data inspector created.this.addDataInspectorStateListeners();// During update of the data inspector event listeners destroyed, so it requires to add// listeners again.this.m_dataInspector.addEventListener(
WidgetAbstract.EVENT_AFTER_UPDATE,this.addDataInspectorStateListeners.bind(this));// Adds submit handler for user input form.this.initializeUserInputForm();}/**
* Changes state of the data inspector when navigating
* by browser buttons ("Back", "Forward") without page reload.
*
* @param location The current location.
* @param action The current navigation action (PUSH, REPLACE, or POP).
*/privatebrowserHistoryHandler(update: Update):void{this.m_browserAction = update.action;this.fetchControlParams();// Update browser title.this.setBrowserTitle();// Change state of the data inspector only on actions caused by// browser buttons ("Back", "Forward").if(update.action !== Action.Pop){return;}this.changeState(this.m_controlParams.hrn,this.m_controlParams.layer,this.m_controlParams.version,this.m_controlParams.location !==undefined?this.m_controlParams.location.latitude
:undefined,this.m_controlParams.location !==undefined?this.m_controlParams.location.longitude
:undefined,this.m_controlParams.zoomLevel
);}/**
* Adds listeners of events which changes state of the data inspector
* in order to represent actual parameter values in URL.
*/privateaddDataInspectorStateListeners():void{if(this.m_browserHistory ===undefined||this.m_dataInspector.mapView ===undefined){return;}// Covers `zoomLevel`, `location.latitude` and `location.longitude`.this.m_dataInspector.mapView.addEventListener(MapViewEventNames.MovementFinished,()=>{// Don't change URL in case of `window.history.back()` or `window.history.forward()`// since it already changed.if(this.m_browserAction === Action.Pop){this.m_browserAction = Action.Push;return;}if(this.m_dataInspector.mapView ===undefined){return;}this.pushToHistory({...this.m_controlParams,
zoomLevel:this.m_dataInspector.mapView.zoomLevel,
location:{
latitude:this.m_dataInspector.mapView.geoCenter.latitude,
longitude:this.m_dataInspector.mapView.geoCenter.longitude,}});});// Covers `version`.this.m_dataInspector.mapView.addEventListener(MapViewEventNames.DataSourceConnect,async(event)=>{const dataSource =this.m_dataInspector.interactiveDataSource;if(
dataSource ===undefined||(event asany).dataSourceName !== dataSource.name
){return;}const dataProvider = dataSource.dataProvider()as PlatformDataProvider;if(dataProvider !==undefined){const layer = dataProvider.layer;if(layer instanceofVersionedLayer){
layer.addEventListener(
VersionedLayer.ON_VERSION_CHANGE,(event:any)=>{this.pushToHistory({...this.m_controlParams,
version: event.catalogVersion
});});}}});}/**
* Fetch data inspector control parameters from page URL.
*/privatefetchControlParams():void{if(this.m_browserHistory ===undefined){return;}const searchParams =newURLSearchParams(location.search);const urlHrn = searchParams.get("hrn");if(urlHrn !==null){this.m_controlParams.hrn = urlHrn;}const urlLayer = searchParams.get("layer");if(urlLayer !==null){this.m_controlParams.layer = urlLayer;}const urlVersion = searchParams.get("version");if(urlVersion !==null){const version = Number.parseInt(urlVersion,undefined);this.m_controlParams.version =!Number.isNaN(version)? version :undefined;}else{// If `version` parameter not present in URL it should be latest version.this.m_controlParams.version =undefined;}const urlZoomLevel = searchParams.get("zoomLevel");if(urlZoomLevel !==null){const zoomLevel = Number.parseInt(urlZoomLevel,undefined);this.m_controlParams.zoomLevel =!Number.isNaN(zoomLevel)? zoomLevel :undefined;}const urlLocation = searchParams.get("location");if(urlLocation !==null){const coordinates = urlLocation.split(",");if(coordinates.length ===2){const latitude = Number.parseFloat(coordinates[0]);const longitude = Number.parseFloat(coordinates[1]);if(!isNaN(latitude)&&!isNaN(longitude)){this.m_controlParams.location ={
latitude,
longitude
};}}}}/**
* Updates page URL to represent state of the data inspector.
* This method manipulates the browser history by pushing new URL into history which
* allows to navigate through different states of data inspector without page reload.
*
* @param controlParams Parameters which controls the data inspector.
*/privatepushToHistory(controlParams: DataInspectorControlParams):void{if(this.m_browserHistory ===undefined){return;}const searchParams:string[]=[];
searchParams.push("showLanguageSelector="+ showLanguageSelector);if(controlParams.hrn !==undefined){
searchParams.push("hrn="+ controlParams.hrn);}if(controlParams.layer !==undefined){
searchParams.push("layer="+ controlParams.layer);}if(controlParams.version !==undefined){
searchParams.push("version="+ controlParams.version);}if(
controlParams.location !==undefined&&
controlParams.location.latitude !==undefined&&
controlParams.location.longitude !==undefined){const location =Number(controlParams.location.latitude).toFixed(5)+","+Number(controlParams.location.longitude).toFixed(5);
searchParams.push("location="+ location);}if(controlParams.zoomLevel !==undefined){
searchParams.push("zoomLevel="+ Math.floor(controlParams.zoomLevel));}const search ="?"+ searchParams.join("&");if(this.addOptionalParameters(search)===this.addOptionalParameters(this.m_browserHistory.location.search)){if(search ===this.m_browserHistory.location.search){// Don't add to history if URL the same as current one.return;}else{// Replace latest URL in the history in case if it's just extended with optional// parameter(s) (e.g. &zoomLevel=10 added).this.m_browserHistory.replace({
pathname:this.m_browserHistory.location.pathname,
search:this.addOptionalParameters(search)});}}else{// Add new URL to the history.this.m_browserHistory.push({
pathname:this.m_browserHistory.location.pathname,
search
});}}/**
* Adds optional parameters to search query in order to be able to compare all configuration
* parameters.
* @param search URL search query
*/privateaddOptionalParameters(search:string):string{// Optional parameters.const params =newMap();
params.set("hrn",this.m_controlParams.hrn);
params.set("layer",this.m_controlParams.layer);if(this.m_dataInspector.mapView){
params.set("location",Number(this.m_dataInspector.mapView.geoCenter.latitude).toFixed(5)+","+Number(this.m_dataInspector.mapView.geoCenter.longitude).toFixed(5));
params.set("zoomLevel", Math.floor(this.m_dataInspector.mapView.zoomLevel).toString());}// Extend/replace optional parameters with actual values from URL.
search.substr(1).split("&").forEach(param =>{const paramPair = param.split("=");if(paramPair.length ===2){
params.set(paramPair[0], paramPair[1].toString());}});// Get final search query with all parameters.const fullSearch =[];for(const entry of params.entries()){
fullSearch.push(entry.join("="));}return"?"+ fullSearch.join("&");}/**
* Adds submit handler of user input form where user can change some parameters to control data
* inspector from outside.
*/privateinitializeUserInputForm():void{const form = document.getElementById("userInputForm")as HTMLFormElement;if(form ===null){return;}const formFields = form.elements;(formFields.namedItem("userHrn")as HTMLInputElement).placeholder =
I18n.translate("olpdi.examples.control-di.hrn");(formFields.namedItem("userLayer")as HTMLInputElement).placeholder =
I18n.translate("olpdi.examples.control-di.layer");(formFields.namedItem("userVersion")as HTMLInputElement).placeholder =
I18n.translate("olpdi.examples.control-di.version");(formFields.namedItem("userLatitude")as HTMLInputElement).placeholder =
I18n.translate("olpdi.examples.control-di.latitude");(formFields.namedItem("userLongitude")as HTMLInputElement).placeholder =
I18n.translate("olpdi.examples.control-di.longitude");(formFields.namedItem("userZoomLevel")as HTMLInputElement).placeholder =
I18n.translate("olpdi.examples.control-di.zoom-level");(formFields.namedItem("submitBtn")as HTMLInputElement).value =
I18n.translate("olpdi.examples.control-di.change");//hide `See URL` button in case examples hosted from a portalif(hideURL !==true){// Since olp-examples shows each example in iframe, it is not possible to// track the URL, so the link was added which opens example in new tab to demonstrate URL.const viewURL = document.createElement("a");
viewURL.href ="#";
viewURL.textContent = I18n.translate("olpdi.examples.control-di.view-url");
viewURL.setAttribute("target","_blank");
viewURL.classList.add("userInputFormLink");(document.getElementById("submitContainer")as HTMLElement).appendChild(viewURL);}
form.onsubmit =this.userInputFormHandler.bind(this);this.populateUserInputForm(form);}/**
* Populate form fields with default configurations.
* @param form From object.
*/privatepopulateUserInputForm(form: HTMLFormElement):void{const config =this.m_dataInspector.getConfig();if(config ===undefined){return;}const formFields = form.elements;if(config.interactiveDataSource !==undefined){(formFields.namedItem("userHrn")as HTMLInputElement).value =
config.interactiveDataSource.hrn !==undefined? config.interactiveDataSource.hrn.toString():"";(formFields.namedItem("userLayer")as HTMLInputElement).value =
config.interactiveDataSource.layer !==undefined? config.interactiveDataSource.layer.toString():"";(formFields.namedItem("userVersion")as HTMLInputElement).value =
config.interactiveDataSource.catalogVersion !==undefined? config.interactiveDataSource.catalogVersion.toString():"";}const geoCenter = config.mapView.geoCenter || config.mapView.defaultGeoCenter;(formFields.namedItem("userLatitude")as HTMLInputElement).value =
geoCenter.latitude.toFixed(5);(formFields.namedItem("userLongitude")as HTMLInputElement).value =
geoCenter.longitude.toFixed(5);(formFields.namedItem("userZoomLevel")as HTMLInputElement).value =
config.mapView.defaultZoomLevel.toString();}/**
* Gathers user input, changes data inspector state and updates URL.
*/privateuserInputFormHandler(event: Event):boolean{const formData =newFormData(event.target as HTMLFormElement);// Data source.const hrn = formData.get("userHrn")asstring||this.m_controlParams.hrn;const layer = formData.get("userLayer")asstring||this.m_controlParams.layer;let version:number|undefined= Number.parseInt(
formData.get("userVersion")asstring,undefined);
version =!isNaN(version)? version :undefined;// Camera position.let latitude:number|undefined= Number.parseFloat(
formData.get("userLatitude")asstring);
latitude =!isNaN(latitude)? latitude :undefined;let longitude:number|undefined= Number.parseFloat(
formData.get("userLongitude")asstring);
longitude =!isNaN(longitude)? longitude :undefined;const location = latitude !==undefined&& longitude !==undefined?{
latitude,
longitude
}:undefined;const zoomLevel:number|undefined= Number.parseInt(
formData.get("userZoomLevel")asstring,undefined)||undefined;this.changeState(hrn, layer, version, latitude, longitude, zoomLevel);this.pushToHistory({
hrn,
layer,
version,
zoomLevel,
location
});// Prevent default submit behavior.returnfalse;}/**
* Changes state of data inspector (data source and position of camera).
* @param hrn Catalog HRN.
* @param layer Catalog layer.
* @param version Layer version.
* @param latitude Latitude.
* @param longitude Longitude.
* @param zoomLevel Zoom level.
*/privatechangeState(
hrn:string,
layer:string,
version?:number,
latitude?:number,
longitude?:number,
zoomLevel?:number):void{this.changeDataInspectorState(hrn, layer, version);const coordinates = latitude !==undefined&& longitude !==undefined?newGeoCoordinates(latitude, longitude):undefined;this.m_dataInspector.focusMapCameraAt(coordinates, zoomLevel);}/**
* Sets new state of the data inspector with changed HRN, layer and/or layer version.
* @param hrn Catalog HRN.
* @param layer Catalog layer.
* @param version Layer version.
*/privatechangeDataInspectorState(hrn:string, layer:string, version?:number):void{const config =this.m_dataInspector.getConfig();// Don't change state if hrn, layer or version wasn't changed.if(config !==undefined&& config.interactiveDataSource !==undefined&& config.interactiveDataSource.hrn === hrn
&& config.interactiveDataSource.layer === layer
&& config.interactiveDataSource.catalogVersion === version
){return;}const prevState =this.m_dataInspector.state;const controlPanel =this.m_dataInspector.controlPanel;const prevControlPanelDisplayMode =
controlPanel ? controlPanel.state.displayMode :undefined;this.m_dataInspector.setInteractiveDataSources([{
hrn,
layer,
catalogVersion: version
}]);if(controlPanel !==undefined){if(prevControlPanelDisplayMode === PanelDisplayMode.Expanded){
controlPanel.show();}else{
controlPanel.hide();}}}/**
* Sets browser title with HRN and layer.
*/privatesetBrowserTitle():void{
document.title =this.m_controlParams.hrn +"/"+this.m_controlParams.layer;}}// Run example application.newLayerBrowserApplication(BrowserHistoryStrategy.DataInspector);
Embed the Visualization in a TypeScript Application
This example creates an instance of DataInspector. It creates a mapView within an HTML element of fixed size and creates a GeoJSON data source connected to the Data API.
This example offers a minimum number of Data Inspector options. To show a single map, just remove the interactiveDataSource object from the DataInspector constructor.
Example Source Code
/*
* Copyright (C) 2018-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{ useToken, locale, showLanguageSelector, lookupServiceEnvironment, ribCartoLayer, ribHostHrn }from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"}},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
accessKeyForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{// this "interactiveDataSource" object can be commented to just show the map.
interactiveDataSource:{
hrn: ribHostHrn,
layer: ribCartoLayer
},
enableCoverage:true,
enableFiltering:true,
enableInfoPanel:true});
This example demonstrates how to create and use a simple server-side token provider. Rather than having a login that works on all accounts for demo purposes, the token provider generates login tokens based on your own credentials only. A client application can request and use these tokens for all its requests.
/*
* Copyright (C) 2018-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*//*
* This file shows the simple NodeJS back-end application that provides tokens to clients.
*
* Current example hands out tokens to anybody who has access, therefore an access to the the server
* should be additionally protected (e.g. some company specific login mechanism).
*/// Raw function, that is used to retrieve tokens.const requestToken =require("@here/olp-sdk-authentication").requestToken;// Initialize the server.const express =require("express");const app =express();// Get credentials from the file ./credentials.properties// snippet:token-provider-credentials.jsconst credentials =require("fs").readFileSync("./credentials.properties");const url =(/here\.token\.endpoint\.url\s*=\s*([\S]*)/g).exec(credentials)[1];const consumerKey =(/here\.access\.key\.id\s*=\s*([\S]*)/g).exec(credentials)[1];const secretKey =(/here\.access\.key\.secret\s*=\s*([\S]*)/g).exec(credentials)[1];const scope =((/here\.token\.scope\s*=\s*([\S]*)/g).exec(credentials)||[])[1];// end:token-provider-credentials.js// snippet:token-provider-app.js// Cached datalet tokenExpirationTime =newDate();let tokenInfo =null;// Add GET endpoint on this server, that will fetch the token from the token endpoint.// API format: /getToken?ttl={number}, where ttl is an optional parameter which defines the time to// live of a token in seconds.
app.get("/getToken",async(request, response)=>{try{if(newDate()>= tokenExpirationTime){
console.log('Request a new token...');
tokenInfo =awaitrequestToken({// Set the token endpoint
url,// Set the time to live of the token. If not defined, then 3600 sec will be used by default.expiresIn: request.query.ttl,// Pass credential data.
consumerKey,
secretKey,
scope
});
tokenExpirationTime =newDate(Date.now()+ tokenInfo.expiresIn *1000);
console.log(`The token expires on: ${tokenExpirationTime}`);}// Allow CORS. Optional, if token provider and client application will be hosted on different server
response.set("Access-Control-Allow-Origin","*");// Send back token to the requestor.
response.status(200).send(tokenInfo.accessToken);}catch(e){// For code brevity, we don't analyze error type and return HTTP 500 response.
console.error(`Error acquiring new token: ${e.message}`);
response.status(500).send(e.message);}});// end:token-provider-app.js// snippet:token-provider-listen.js// Define the server port.constPORT=3000;// Start the server.
app.listen(PORT,()=>{
console.log(`Token provider is listening port ${PORT}`);});// end:token-provider-listen.js
This example creates an instance of DataInspector. It creates a mapView within an HTML element of fixed size and creates a GeoJSON data source connected to the Data API.
This example demonstrates all the features of the Data Inspector, including the Stats panel. This panel shows a log with information about decoded tiles and an expanded panel with information about the decoded tile. For all possible configuration options for UI elements, see the source code of this example below.
Example Source Code
/*
* Copyright (C) 2018-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*//*
* This example shows all properties `DataInspector` can accept to customize visualization.
*
* Please visit API documentation to see the detailed description of all constructor arguments:
* https://developer.here.com/olp/documentation/data-inspector-library/api_reference_typedoc/classes/_here_interactive_mapview_ui.hostcomponent.html#constructor
*/import{ DataInspector, PanelDisplayMode }from"@here/interactive-mapview-ui";import{
useToken,
locale,
showLanguageSelector,
boundingBox,
enableExtendedCoverage,
geoCenter,
lookupServiceEnvironment,
omvHostHrn,
omvDataLayer,
ribHostHrn,
ribTopologyLayer
}from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
elementId:"my-host-component",// The property below sets custom auth token provider without authentication form.// getBearerToken: () => Promise.resolve("Your Token"),
mapView:{
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js",
count:2},
maxZoomLevel:15,
defaultZoomLevel:12,
geoCenter: geoCenter,// Please note that the "boundingBox" property will override the values of "geoCenter"// and "defaultZoomLevel" properties.
boundingBox,
enableTilt:false,
enableRotation:false},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
baseMap:{
hrn: omvHostHrn,
layer: omvDataLayer,// Catalog version for the base map.// version: -1;
styleSetName:"tilezen"//The name of the style set from the theme},
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
zoomLevel:true,
statusBar:true,
searchField:true,
decodedPanel:{
enabled:true,
initialState: PanelDisplayMode.Expanded,
width:400},
statsPanel:{
enabled:true,
initialState: PanelDisplayMode.Collapsed
},
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined,},
toolbar:{
enabled:true,
fullScreenButton:true,
languageSelector: showLanguageSelector
},
logMessages:true,
lookupServiceEnvironment,
pageUrlParams:{ enabled:true},
locales:["en-US","ja-JP","zh-CN","zz-ZZ"]},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSources:[{
hrn: ribHostHrn,
layer: ribTopologyLayer,
catalogVersion:0,
levelsWithData:[12],
externalRendererPluginName:"interactive_host_full.plugin.template",
preferRendererPlugin:false,
selectedPartitions:["23600040","23605525","23600039"]}],
enableCoverage:true,
enableExtendedCoverage,
enableInfoPanel:true,
enableFiltering:true});
This example demonstrates the easiest way to embed visualization in a single-page application written in pure HTML and JavaScript. This example uses the DataInspector class with all the default values. To run this example code, no compilation is required.
The leaflet / protobuf example demonstrates how you can use JavaScript to authenticate with the HERE platform and access Protobuf-encoded data in the Roads - Topology & Geometry layer from the HERE Map Conent catalog with the HERE Data SDK for TypeScript, how to retrieve a schema from the layer and use it to decode the data into GeoJSON, how to show the OMV Plus base map using the HARP plugin for Leaflet, and how to visualize the data on top of the base map. For more details, see Inspect HERE Platform Data with Leaflet.
This example demonstrates how you can access data from different layers with a custom GeoJSON rendering plugin. This app provides a sample plugin for the schema of the Places for HERE Essential Map layer in the HERE Map Content catalog that extracts data from the Places Metadata layer to show category names for places. The plugin contains inline comments to help you better understand how it works.
For more information on how to implement multi-layer data access from rendering plugins, see Rendering Functions.
Example Source Code
/*
* Copyright (C) 2020-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{ useToken, locale, showLanguageSelector, lookupServiceEnvironment, ribHostHrn }from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
defaultZoomLevel:11,
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"}},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSource:{
hrn: ribHostHrn,
layer:"here-places",
externalRendererPluginName:"renderer.plugin.here-places"},
enableCoverage:true});
This example demonstrates how you can use JavaScript in combination with the OpenLayers web-mapping library to visualize European country borders from the HERE GeoJSON Samples catalog. From the example source code, you can learn how to get access to the HERE platform with your user credentials and app API key, load the HERE OMV Plus basemap, customize basemap styling, fetch GeoJSON data from the platform catalog, and render this data atop the basemap.
This example demonstrates how to interact with the features of the Sensor Data Ingestion Interface (SDII) data source. You can highlight paths and road signs with the mouse pointer and filter out individual SDII messages.
Example Source Code
/*
* Copyright (C) 2018-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{
useToken,
locale,
showLanguageSelector,
omvDataLayer,
omvHostHrn,
sdiiHostHrn,
sdiiDataLayer,
lookupServiceEnvironment
}from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"},
defaultZoomLevel:12},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
baseMap:{
hrn: omvHostHrn,
layer: omvDataLayer
},
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSource:{
hrn: sdiiHostHrn,
layer: sdiiDataLayer
},
enableCoverage:true,
enableFiltering:true,
enableInfoPanel:true});
This example shows how you can use sdiiDataSource to animate road signs and paths.
Example Source Code
/*
* Copyright (C) 2018-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{
useToken,
locale,
showLanguageSelector,
omvDataLayer,
omvHostHrn,
sdiiHostHrn,
sdiiDataLayer,
lookupServiceEnvironment
}from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
theme:"../resources/normal.reduced.night.json",
decoder:{ url:"../decoder.bundle.js"},
defaultZoomLevel:12},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
baseMap:{
hrn: omvHostHrn,
layer: omvDataLayer
},
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSource:{
hrn: sdiiHostHrn,
layer: sdiiDataLayer,
animationEnabled:true},
enableCoverage:true,
enableFiltering:true,
enableInfoPanel:true});
/*
* Copyright (C) 2020-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{ useToken, locale, showLanguageSelector, sdiiDataLayer, sdiiHostHrn, lookupServiceEnvironment }from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
defaultZoomLevel:12,
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"}},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSource:{
hrn: sdiiHostHrn,
layer: sdiiDataLayer,
preferRendererPlugin:true,
externalRendererPluginName:"plugin-sdii"},
enableCoverage:true,
enableFiltering:true,
enableInfoPanel:true});
This example uses GeoJsonDataSource to obtain data from a catalog with GeoJSON data. It visualizes GeoJSON data from a single tile.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ MapViewEventNames }from"@here/harp-mapview";import{ GeoJsonDataSource }from"@here/olp-geojson-datasource";import{ useToken, geoJsonDataLayer, geoJsonDataTile, geoJsonHrn, lookupServiceEnvironment }from"../config";import{
addBaseMapCountryBorder,
bearerTokenProvider,
createBaseMapDataSource,
createTokenResolver,
initializeMapView,
setupTileSelection
}from"./common";import{ TileControlHandler }from"@here/interactive-mapview-ui";import{ MapControls }from"@here/harp-map-controls";import{
BaseMapDataProvider,
LookupEnvironment,
PlatformDataProvider
}from"@here/interactive-datasource-protocol";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;// For the full map initialization code see sdii/simple exampleconst mapView =initializeMapView(canvas);let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});const dataProvider =newPlatformDataProvider({
hrn: geoJsonHrn,
layer: geoJsonDataLayer,
getToken: getBearerToken,
environment: lookupServiceEnvironment
});// geoJSON Data sourceconst geoJsonDataSource =newGeoJsonDataSource({
dataProvider
});
mapView.addEventListener(MapViewEventNames.DataSourceConnect,(event:any)=>{if(event.dataSourceName === geoJsonDataSource.name){
geoJsonDataSource.selectTile(geoJsonDataTile);}});
mapView.addDataSource(geoJsonDataSource);const mapControls =newMapControls(mapView);
mapControls.zoomLevelDeltaOnDoubleClick =0;
mapControls.setZoomLevel(13);setupTileSelection(mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource));
This example visualizes the geometry of a hard-coded GeoJSON object without connecting to the Data API.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ MapViewEventNames }from"@here/harp-mapview";import{
BaseMapDataProvider,
InteractiveIntersectionAgent,
LookupEnvironment
}from"@here/interactive-datasource-protocol";import{ GeoJsonDataSource }from"@here/olp-geojson-datasource";import{
addBaseMapCountryBorder,
bearerTokenProvider,
createBaseMapDataSource,
createTokenResolver,
initializeMapView,
setupTileSelection
}from"./common";import{ TileControlHandler }from"@here/interactive-mapview-ui";import{ MapControls }from"@here/harp-map-controls";import{ useToken, geoJsonData, geoJsonMapCenter, lookupServiceEnvironment }from"../config";import{ GeoCoordinates }from"@here/harp-geoutils";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;// For the full map initialization code see sdii/simple exampleconst mapView =initializeMapView(canvas);
mapView.geoCenter =newGeoCoordinates(geoJsonMapCenter.latitude, geoJsonMapCenter.longitude);let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});// geoJSON Data sourceconst geoJsonDataSource =newGeoJsonDataSource({
intersectionAgent:newInteractiveIntersectionAgent(mapView)});
mapView.addDataSource(geoJsonDataSource);/**
* Show geoJSON data from other resource than DataStore
* (e.g. read from the file, direct geoJSON object).
*/
mapView.addEventListener(MapViewEventNames.DataSourceConnect,(event:any)=>{if(event.dataSourceName === geoJsonDataSource.name){
geoJsonDataSource.renderGeoJson(geoJsonData);}});const mapControls =newMapControls(mapView);
mapControls.zoomLevelDeltaOnDoubleClick =0;
mapControls.setZoomLevel(17);setupTileSelection(mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource));
This example visualizes speed limits using an external GeoJSON rendering plugin. The plugin uses SegmentAnchorGeometryDataProvider to retrieve road geometries and map speed limit data to them.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector, DataInspectorEventNames }from"@here/interactive-mapview-ui";import{ useToken, locale, showLanguageSelector, lookupServiceEnvironment, ribHostHrn, speedLimitTiles }from"../config";import{ bearerTokenProvider }from"./common";const dataInspector =newDataInspector({
mapView:{
defaultZoomLevel:11,
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"}},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSource:{
hrn: ribHostHrn,
layer:"navigation-attributes",
externalRendererPluginName:"renderer.plugin.template"},
enableCoverage:true});if(dataInspector.mapView ===undefined){thrownewError("MapView was not initialized.");}
dataInspector.addEventListener(
DataInspectorEventNames.DATA_INSPECTOR_IS_READY,()=> speedLimitTiles.forEach(tile => dataInspector.tileControlHandler.selectTile(tile,true)));
This example visualizes such custom GeoJSON feature properties as style.color, style.fill, style.width, properties.tooltip, as well as other MapBox styles.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ GeoCoordinates }from"@here/harp-geoutils";import{ MapViewEventNames }from"@here/harp-mapview";import{
BaseMapDataProvider,
InteractiveIntersectionAgent,
LookupEnvironment
}from"@here/interactive-datasource-protocol";import{ GeoJsonDataSource }from"@here/olp-geojson-datasource";import{
addBaseMapCountryBorder,
bearerTokenProvider,
createBaseMapDataSource,
createTokenResolver,
InformationPanel,
initializeMapView,
setupTileSelection
}from"./common";import{
useToken,
geoJsonProperties,
geoJsonPropertiesCenter,
lookupServiceEnvironment
}from"../config";import{ MapControls }from"@here/harp-map-controls";import{
GeoJsonInfoPanel,
I18n,
installInfoWidgets,
TileControlHandler
}from"@here/interactive-mapview-ui";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;// For the full map initialization code see sdii/simple exampleconst mapView =initializeMapView(canvas);
mapView.geoCenter =newGeoCoordinates(
geoJsonPropertiesCenter.latitude,
geoJsonPropertiesCenter.longitude
);// Create info panelconst infoPanelMsg = I18n.translate("olpdi.examples.geojson-properties.hint");newInformationPanel(infoPanelMsg);let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});// GeoJSON Data sourceconst geoJsonDataSource =newGeoJsonDataSource({
intersectionAgent:newInteractiveIntersectionAgent(mapView)});
mapView.addDataSource(geoJsonDataSource);installInfoWidgets(GeoJsonInfoPanel, geoJsonDataSource, document.body,"geojson-info-panel");// Show geoJSON data from other resource than DataStore// (e.g. read from the file, direct geoJSON object)
mapView.addEventListener(MapViewEventNames.DataSourceConnect,(event:any)=>{if(event.dataSourceName === geoJsonDataSource.name){
geoJsonDataSource.renderGeoJson(geoJsonProperties);}});const mapControls =newMapControls(mapView);
mapControls.zoomLevelDeltaOnDoubleClick =0;
mapControls.setZoomLevel(17);setupTileSelection(mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource));
This example automatically adjusts a map's zoom and position to fit a specific GeoJSON object. You can obtain the bounding box of the rendered GeoJSON object in the GeoJsonDataSource.EVENT_TILE_DECODED event. This example provides sample code to calculate the camera's position of the mapView allowing you to fit an object in the map view.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ GeoCoordinates }from"@here/harp-geoutils";import{ MapViewEventNames }from"@here/harp-mapview";import{
BaseMapDataProvider,
InteractiveIntersectionAgent,
LookupEnvironment
}from"@here/interactive-datasource-protocol";import{ GeoJsonDataSource, GeoJsonDataSourceEvent }from"@here/olp-geojson-datasource";import{
bearerTokenProvider,
createBaseMapDataSource,
initializeMapView,
setupTileSelection,
createTokenResolver,
addBaseMapCountryBorder
}from"./common";import{ TileBoundingBox, TileControlHandler }from"@here/interactive-mapview-ui";import{ MapControls }from"@here/harp-map-controls";import{ useToken, geoJsonData, lookupServiceEnvironment }from"../config";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;// For the full map initialization code see sdii/simple exampleconst mapView =initializeMapView(canvas);// Initially position map off desired location.
mapView.geoCenter =newGeoCoordinates(10,10);let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});// GeoJSON Data sourceconst geoJsonDataSource =newGeoJsonDataSource({
intersectionAgent:newInteractiveIntersectionAgent(mapView)});
mapView.addDataSource(geoJsonDataSource);/**
* Show geoJSON data from other resource than DataStore
* (e.g. read from the file, direct geoJSON object).
*/
mapView.addEventListener(MapViewEventNames.DataSourceConnect,(event:any)=>{if(event.dataSourceName === geoJsonDataSource.name){
geoJsonDataSource.renderGeoJson(geoJsonData);}});// Map centering by bounding box
geoJsonDataSource.addEventListener(
GeoJsonDataSource.EVENT_BEFORE_TILE_RENDERED,(event: GeoJsonDataSourceEvent)=>{const boundingBox = event.boundingBox;if(boundingBox ===undefined){return;}
TileBoundingBox.fitMapViewToWorldBoundingBox(mapView, boundingBox, mapControls,50);});const mapControls =newMapControls(mapView);setupTileSelection(mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource));
This example demonstrates how to couple the GeoJSON data source with the coverage data source to visualize those tiles that have data. GeoJsonDataSource obtains data from a catalog with GeoJSON data, and coverageDataSource is connected to the same catalog, so that they represent the same data.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ CoverageDataSource }from"@here/coverage-datasource";import{
PlatformDataProvider,
InteractiveIntersectionAgent,
LookupEnvironment,
BaseMapDataProvider
}from"@here/interactive-datasource-protocol";import{ GeoJsonDataSource }from"@here/olp-geojson-datasource";import{
useToken,
geoJsonDataLayer,
geoJsonHrn,
geoJsonLevelWithData,
lookupServiceEnvironment
}from"../config";import{
bearerTokenProvider,
InformationPanel,
createBaseMapDataSource,
createTokenResolver,
initializeMapView,
setupTileSelection,
addBaseMapCountryBorder
}from"./common";import{ I18n, TileControlHandler }from"@here/interactive-mapview-ui";import{ MapControls }from"@here/harp-map-controls";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;const mapView =initializeMapView(canvas);// Create info panelnewInformationPanel(I18n.translate("olpdi.examples.geojson-tilegrid.hint"));let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});const dataProvider =newPlatformDataProvider({
hrn: geoJsonHrn,
layer: geoJsonDataLayer,
getToken: getBearerToken,
environment: lookupServiceEnvironment
});// Tile gridconst coverageDataSource =newCoverageDataSource({
dataProvider,// The grid will be rendered for specified tiles level
levelsWithData:[geoJsonLevelWithData]});
mapView.addDataSource(coverageDataSource);// geoJSON Data sourceconst geoJsonDataSource =newGeoJsonDataSource({
dataProvider,
intersectionAgent:newInteractiveIntersectionAgent(mapView),
levelsWithData:[geoJsonLevelWithData]});
mapView.addDataSource(geoJsonDataSource);const mapControls =newMapControls(mapView);
mapControls.zoomLevelDeltaOnDoubleClick =0;
mapControls.setZoomLevel(12);setupTileSelection(
mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource, coverageDataSource));
This example demonstrates how to subscribe to various events of the GeoJsonDataSource. After the tiles have been loaded, you can see the events that are triggered by long-clicking any tile. It adds event listeners to the EVENT_TILE_GET, EVENT_TILE_DECODED, EVENT_BEFORE_TILE_DECODE, EVENT_TILE_SELECT, and EVENT_TILE_DESELECT events.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ CoverageDataSource }from"@here/coverage-datasource";import{
PlatformDataProvider,
InteractiveIntersectionAgent,
LookupEnvironment,
BaseMapDataProvider
}from"@here/interactive-datasource-protocol";import{ GeoJsonDataSource }from"@here/olp-geojson-datasource";import{
useToken,
geoJsonDataLayer,
geoJsonHrn,
geoJsonLevelWithData,
lookupServiceEnvironment,}from"../config";import{
bearerTokenProvider,
createBaseMapDataSource,
InformationPanel,
initializeMapView,
setupTileSelection,
createTokenResolver,
addBaseMapCountryBorder
}from"./common";import{ MapControls }from"@here/harp-map-controls";import{ I18n, TileControlHandler }from"@here/interactive-mapview-ui";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;// For the full map initialization code see sdii/simple exampleconst mapView =initializeMapView(canvas);// Create info panelconst infoPanelMsg = I18n.translate("olpdi.examples.geojson-events.hint")+``+ I18n.translate("olpdi.examples.geojson-events.events-list-title")+`:`;const infoPanel =newInformationPanel(infoPanelMsg,true);let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});const dataProvider =newPlatformDataProvider({
hrn: geoJsonHrn,
getToken: getBearerToken,
layer: geoJsonDataLayer,
environment: lookupServiceEnvironment
});// Tile gridconst coverageDataSource =newCoverageDataSource({
dataProvider,// The grid will be rendered for specified tiles level
levelsWithData:[geoJsonLevelWithData]});
mapView.addDataSource(coverageDataSource);// geoJSON Data sourceconst intersectionAgent =newInteractiveIntersectionAgent(mapView);const geoJsonDataSource =newGeoJsonDataSource({
dataProvider,
intersectionAgent,
levelsWithData:[geoJsonLevelWithData]});
mapView.addDataSource(geoJsonDataSource);// all events of GeoJsonDataSource
geoJsonDataSource.addEventListener(GeoJsonDataSource.EVENT_TILE_GET,()=>{
infoPanel.element.innerText += GeoJsonDataSource.EVENT_TILE_GET+"\n";});
geoJsonDataSource.addEventListener(GeoJsonDataSource.EVENT_TILE_DECODED,()=>{
infoPanel.element.innerText += GeoJsonDataSource.EVENT_TILE_DECODED+"\n";});
geoJsonDataSource.addEventListener(GeoJsonDataSource.EVENT_BEFORE_TILE_DECODE,()=>{
infoPanel.element.innerText += GeoJsonDataSource.EVENT_BEFORE_TILE_DECODE+"\n";});
geoJsonDataSource.addEventListener(GeoJsonDataSource.EVENT_BEFORE_TILE_RENDERED,()=>{
infoPanel.element.innerText += GeoJsonDataSource.EVENT_BEFORE_TILE_RENDERED+"\n";});
geoJsonDataSource.addEventListener(GeoJsonDataSource.EVENT_TILE_SELECT,()=>{
infoPanel.element.innerText += GeoJsonDataSource.EVENT_TILE_SELECT+"\n";});
geoJsonDataSource.addEventListener(GeoJsonDataSource.EVENT_TILE_DESELECT,()=>{
infoPanel.element.innerText += GeoJsonDataSource.EVENT_TILE_DESELECT+"\n";});const mapControls =newMapControls(mapView);
mapControls.setZoomLevel(12);setupTileSelection(
mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource, coverageDataSource));
This example shows how to load GeoJSON data from a versioned layer of a catalog.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ CoverageDataSource }from"@here/coverage-datasource";import{
PlatformDataProvider,
InteractiveIntersectionAgent,
LookupEnvironment,
BaseMapDataProvider
}from"@here/interactive-datasource-protocol";import{ GeoJsonDataSource }from"@here/olp-geojson-datasource";import{
useToken,
geoJsonContentTypeHrn,
geoJsonContentTypeLayerVersioned,
geoJsonContentTypeLevelWithData,
lookupServiceEnvironment
}from"../config";import{
addBaseMapCountryBorder,
bearerTokenProvider,
createBaseMapDataSource,
createTokenResolver,
InformationPanel,
initializeMapView,
setupTileSelection
}from"./common";import{ MapControls }from"@here/harp-map-controls";import{ I18n, TileControlHandler }from"@here/interactive-mapview-ui";const canvas = document.getElementById("mapCanvas")as HTMLCanvasElement;// For the full map initialization code see sdii/simple exampleconst mapView =initializeMapView(canvas);// Create info panelconst infoPanelMsg = I18n.translate("olpdi.examples.geojson-contenttype-versioned.hint");newInformationPanel(infoPanelMsg);let getBearerToken;if(useToken){
getBearerToken = bearerTokenProvider;}else{const tokenResolver =createTokenResolver(mapView);
getBearerToken = tokenResolver.getBearerToken.bind(tokenResolver)as()=>Promise;}// Base mapcreateBaseMapDataSource(getBearerToken).then(omvDataSource =>{
mapView.addDataSource(omvDataSource);if(lookupServiceEnvironment === LookupEnvironment.HERE_CN){addBaseMapCountryBorder(mapView, omvDataSource.dataProvider()as BaseMapDataProvider);}});const dataProvider =newPlatformDataProvider({
hrn: geoJsonContentTypeHrn,
getToken: getBearerToken,
layer: geoJsonContentTypeLayerVersioned,
environment: lookupServiceEnvironment
});// GeoJSON Data Sourceconst geoJsonDataSource =newGeoJsonDataSource({
dataProvider,
levelsWithData:[geoJsonContentTypeLevelWithData],
schemaProviderOptions:{
enabled:false},
intersectionAgent:newInteractiveIntersectionAgent(mapView)});
mapView.addDataSource(geoJsonDataSource);// Tile gridconst coverageDataSource =newCoverageDataSource({
dataProvider,// The grid will be rendered for specified tiles level
levelsWithData:[geoJsonContentTypeLevelWithData],
schemaProviderOptions:{
enabled:false}});
mapView.addDataSource(coverageDataSource);const mapControls =newMapControls(mapView);
mapControls.setZoomLevel(13);setupTileSelection(
mapView,newTileControlHandler(mapView, mapControls, geoJsonDataSource, coverageDataSource));
This example showcases how to create an instance of custom InteractiveDataSource and dynamically add it to a DataInspector instance. Custom SpeedLimitsDataSource visualizes speed limits from the HERE Map Content catalog. It retrieves the speed limits data from the HERE Map Content Navigation Attributes layer and visualizes it over the roads geometry from the HERE Map Content Road Topology layer. The speed limits data has no geometry information, so it is mapped to road segments from the Roads - Topology & Geometry layer.
Example Source Code
/*
* Copyright (C) 2017-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ SegmentAnchorGeometryDataProvider }from"@here/geometry-data-provider";import{
PlatformDataProvider,
InteractiveIntersectionAgent
}from"@here/interactive-datasource-protocol";import{
DataInspector,
DataInspectorEventNames,
InfoPanel,
installInfoWidgetsWhenDataSourceReady,
PanelDisplayMode
}from"@here/interactive-mapview-ui";import{
useToken,
locale,
showLanguageSelector,
omvDataLayer,
omvHostHrn,
lookupServiceEnvironment,
ribHrn,
ribTopologyLayer,
speedLimitTiles
}from"../config";import{ bearerTokenProvider }from"./common";import{ SpeedLimitsDataSource }from"./datasources/speedLimitsDataSource/SpeedLimitsDataSource";/**
* This example showcases dynamically creating and using a custom implementation of
* `InteractiveDataSource` - a datasource to visualize speed limits from RIB catalog.
*
* Because custom `SpeedLimitsDataSource` datasource is not determined by `DataInspector` by catalog
* HRN, it is added to an instance of `DataInspector` after it is initialized.
*/// Create an instance of `DataInspector`.const dataInspector =newDataInspector({
elementId:"may-host-component",
mapView:{
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"},
defaultZoomLevel:12,
enableTilt:false,},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
baseMap:{
hrn: omvHostHrn,
layer: omvDataLayer
},
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
zoomLevel:true,
statusBar:true,
searchField:true,
decodedPanel:{
enabled:true,
initialState: PanelDisplayMode.Expanded,
width:400},
statsPanel:{
enabled:true,
initialState: PanelDisplayMode.Collapsed
},
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
enabled:true,
fullScreenButton:true,
languageSelector: showLanguageSelector
},
logMessages:true,
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,undefined,true);let speedLimitsDataSource: SpeedLimitsDataSource |undefined;
dataInspector.addEventListener(
DataInspectorEventNames.DATA_INSPECTOR_IS_READY,async()=>{if(dataInspector.mapView ===undefined|| dataInspector.interactiveDataSource !==undefined){return;}//create data providerconst dataProvider =newPlatformDataProvider({
hrn: ribHrn,
layer:"navigation-attributes",
getToken: dataInspector.getConfig().getBearerToken!,
environment: lookupServiceEnvironment
});await dataProvider.connect();// Create an instance of `SegmentAnchorGeometryDataProvider`, necessary for `SpeedLimitsDataSource`.const geometryDataProvider =newSegmentAnchorGeometryDataProvider({
hrn: ribHrn,
layer: ribTopologyLayer,
getToken: dataInspector.getConfig().getBearerToken!,
environment: lookupServiceEnvironment
});await geometryDataProvider.connect();const selectedTiles = speedLimitsDataSource !==undefined?[...speedLimitsDataSource.selectedPartitions]:[speedLimitTiles[0]];// Create a sample speed limits datasource which uses `RoadSegmentsDataProvider`.
speedLimitsDataSource =newSpeedLimitsDataSource({
dataProvider,
geometryDataProvider
});
speedLimitsDataSource.isSelected =true;// An instance of `InteractiveIntersectionAgent` is needed to detect speed limit items under mouse// pointer.const intersectionAgent =newInteractiveIntersectionAgent(dataInspector.mapView);
speedLimitsDataSource.setUpIntersectionAgent(intersectionAgent);if(dataInspector.controlPanel !==undefined){installInfoWidgetsWhenDataSourceReady(
InfoPanel,
speedLimitsDataSource,
dataInspector.controlPanel.container,"info-panel");}await dataInspector.setInteractiveDataSources([speedLimitsDataSource]);// Select speed limit tiles.for(const tile of selectedTiles){
dataInspector.tileControlHandler.selectTile(tile.toString(),true);}});
This example demonstrates how you can use the Data Inspector tool to explore object store layers, in a similar manner as you would with your typical file browser.
Example Source Code
/*
* Copyright (C) 2021-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{
useToken,
locale,
showLanguageSelector,
lookupServiceEnvironment,
objectStoreCatalogHrn,
objectStoreLayer
}from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
defaultZoomLevel:11,
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"}},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSources:[{
hrn: objectStoreCatalogHrn,
layer: objectStoreLayer,}],
enableCoverage:true});
This example demonstrates how you can use the Data Inspector to explore interactive map layers on the HERE platform. Interactive map layers do not require loading data by clicking tiles, data is retrieved automatically as the map is panned or zoomed. Depending on data density and current zoom level, some data features can be omitted from results. Zoom in to see more detailed results.
Example Source Code
/*
* Copyright (C) 2021-2023 HERE Global B.V. and its affiliate(s). All rights reserved.
*
* This software and other materials contain proprietary information controlled by HERE and are
* protected by applicable copyright legislation. Any use and utilization of this software and other
* materials and disclosure to any third parties is conditional upon having a separate agreement
* with HERE for the access, use, utilization or disclosure of this software. In the absence of such
* agreement, the use of the software is not allowed.
*/import{ DataInspector }from"@here/interactive-mapview-ui";import{
useToken,
locale,
showLanguageSelector,
lookupServiceEnvironment,
interactiveMapCatalogHrn,
interactiveMapLayer
}from"../config";import{ bearerTokenProvider }from"./common";newDataInspector({
mapView:{
defaultZoomLevel:11,
theme:"../resources/normal.reduced.night.json",
decoder:{
url:"../decoder.bundle.js"}},
monacoEditorWorkersBasePath:"../monaco-editor",
translationsBasePath:"../resources/i18n/",
streamSaverBasePath:"../resources/mitm/",
defaultLocale: locale ||undefined,
getBearerToken: useToken ? bearerTokenProvider :undefined,
widgets:{
authForm:!useToken ?{
tokenForm:false,
accessKeyForm:true,
localAuthForm:true}:undefined},
toolbar:{
languageSelector: showLanguageSelector
},
lookupServiceEnvironment,
pageUrlParams:{ enabled:true}},
document.getElementById("map-here")as HTMLElement,{
interactiveDataSources:[{
hrn: interactiveMapCatalogHrn,
layer: interactiveMapLayer,}],
enableCoverage:true});