Geovisualization Developer's Guide

Quickstart - Advanced

Introduction

This quickstart will show you how to create a visualization by uploading a sample datasource to your account on the Geovisualization backend and using it in a project that processes data with the Geovisualization REST API and its query language, and then uses the Geovisualization JavaScript API to plot data-driven markers on a map.

Figure 1. Earthquake Visualization

The example plots earthquake events on a map. The events are represented with symbols, called "proportional markers", whose size, color and opacity vary according to the magnitude and depth of each earthquake. The marker's size indicates the magnitude of the earthquake, and its color indicates the depth of the earthquake epicenter.

Get a HERE Account

To access Geovisualization, go to https://account.here.com/sign-up and sign up for a HERE account

Get a HERE Plan

When you have an account, register for a 90-day Free Trial plan on the HERE website: https://developer.here.com/plans.

Generate App ID and App Code

On the project page for the newly created plan, click the blue Generate App ID and App Code button under the JavaScript/REST heading to generate the App ID and App Code you will need for Geovisualization.

Upload a Dataset

Sign into our Data Manager with the credentials you created above, download the sample earthquake dataset from http://js.cit.datalens.api.here.com/datasets/starter_pack/Earthquakes_7day.csv, click the blue circular + button and select the downloaded CSV file to upload it.

Behind the scenes the Data Manager creates a new dataset for you and then uploads the data into the new dataset, representing two API endpoints, creating a dataset and uploading data to the dataset.

Make a note of the ID beneath the new dataset as you will need it in the following tutorial steps.

Authenticating with the Geovisualization REST API

To use the Geovisualization REST API you will need an authentication token that will allow you to fetch and process data.
Note:

Postman is a Chrome plugin and desktop application that helps you interact with APIs and see the output. We use it throughout our documentation to illustrate making requests. Other similar tools are available, but we recommend Postman so you can better follow our examples.

Get an Access Token

To get an authentication token, send your HERE account credentials as a POST request to the Geovisualization REST API including the email address and password associated with your HERE account in a JSON object and your app_id and app_code as URL parameters.

Note: You can also use the sign_in endpoint in the 01. User Authentication folder of our Postman collection.

The response will include a value called access_token. Copy this token as you will add it to the Authorization parameter in future API requests.

https://datalens.api.here.com/v1/sign_in?app_id={YOUR_APP_ID}&app_code={YOUR_APP_CODE}
      
    {
    "email": "{your email address}",
    "password": "{your password}"
    }
Note: A token is valid for one hour.

The Refresh Token

The response also includes a refresh_token. After the access token has expired, you can send the refresh token to the backend to receive a new pair of access and refresh tokens. You do this with a POST to the following endpoint, including your original access and refresh tokens in the request body:

https://datalens.api.here.com/v1/sign_in/refresh?app_id={YOUR_APP_ID}&app_code={YOUR_APP_CODE}
    
    {
    "access_token": "{expired access token string}",
    "refresh_token": "{corresponding refresh token string}"
    }
The response will include two new values for access_token and refresh_token.
Note: Find out more about getting credentials and what interactions authenticated and unauthenticated users can make in the Getting Authentication Credentials topic.

Querying your Data

Queries on datasets fetch, aggregate, transform and filter the data to prepare it for visualizations. Geovisualization provides a specially designed query language, which uses JSON syntax to define the actions to perform on the data. The Geovisualization query language operates on your data in a similar way to SQL.

A query is associated with a specified dataset in the query definition. The query receives its own ID after it has been sent to the backend with the Geovisualization REST API and stored in your account.

A query typically includes the following information:

  • The ID of the dataset associated with the query, whose data the query will process
  • Instructions on how the columns of the dataset will be selected
  • Instructions on how the selected data will be filtered, transformed and sorted, where required
  • Geospacial transformations that project the data from map coordinates to screen coordinates

Map Tiling

For the query on the earthquake dataset, you need to select the data you want to visualize on the map. In this example, you will select the location, magnitude and depth for each earthquake event.

You could define the query to select the data for all earthquakes in the dataset. To optimize performance, Geovisualization provides a way to select only the data required for the currently visible area on the map, referred to as the "current viewport". Geovisualization does this by a process called "tiling", which subdivides the whole map into a grid of tiles. A tile is identified by a column (x) and a row (y) and a zoom level (z). The query you define will call only the data that falls on the tiles visible in the current viewport.

In the browser, the visualization app is aware of which tiles comprise the current viewport. The Geovisualization JavaScript API executes the query for each tile, requesting all the data points per tile. The query takes each tile's x, y and z as parameters in the request to the backend, which reprojects each geographical point into pixel space to determine which data points fall into each tile. Finally, it returns the data point including the original geographical coordinates (not the pixel coordinates). Then, the JavaScript renders the data point on the map at the correct location.

Define the Query Code

Start with creating a query array:
{
  "query": {
    ...
  }
}
Inside the array, metrics is a list of strings representing the names of the columns in the dataset that you want to include in the query result:
...
"metrics": [
  "Lat",
  "Lon",
  "Magnitude",
  "Depth",
  "Region",
  "Datetime"
],
...
namespace is a list of variables you use to define the parameters required in the transformation of data points returned during tiling:
...   
"namespace": {
  "tz": {"source": [{"$input": "z"}]},
  "tx": {"source": [{"$input": "x"}]},
  "ty": {"source": [{"$input": "y"}]},
  "px": {
    "source": ["Lon", "tz"],
    "apply": [{
      "type": "transform",
      "fn": "lon_to_x"
    }]
  },
  "py": {
    "source": ["Lat", "tz"],
    "apply": [{
      "type": "transform",
      "fn": "lat_to_y"
    }]
  },
  "pixels": {"source": ["px","py"]}
},
...
filters contains a single filter that restricts the query to return only the data points that are visible within each tile:
...
"filters": [{
  "pixels": {
    "$pixel_within_tile": ["tx","ty"]
  }
}]
...
dataset indicates the ID of the dataset the query is executed on:
...
"dataset": "{DATASET_ID}"
...

Store the Query and Get the Query ID

Now that you have defined a query, you need to send it to the Geovisualization backend to store it in your account. Geovisualization registers the query and assigns it a query ID which you use to identify it in visualization apps.

To store a new query and get its ID, send a POST request to the Geovisualization backend including your access token in the Authorization field of the request header, the code of the query to store in the request body as raw JSON with a description and tags to help you find and classify your queries (Read more in the defining a query guide):

https://datalens.api.here.com/v1/queries?app_id={YOUR_APP_ID}&app_code={YOUR_APP_CODE}
    Authorization: Bearer {ACCESS_TOKEN}
      {
      "description": "Tutorial Earthquake Query",
      "tags": [
        "depths",
        "magnitudes",
        "earthquakes"
      ],
      "query": {
        "metrics": […],
        "namespace": {…},
        "filters": […],
        "dataset": "{DATASET_ID}"
      }
      }
Note: You can also use the queries endpoint in the 07. Query CRUD folder of our Postman collection.

The JSON response body provides some information about the query, such as its creation date and the number of rows in its dataset. It also includes a string called id, which represents the unique query ID:

"id": "4a91cf4a8cfe4e27956b2ea52259308e",

You need to reference this query ID in your JavaScript code that styles the visualization, for example:

queryId: '4a91cf4a8cfe4e27956b2ea52259308e';

You can also see the query ID associated with the dataset in the Data Manager.

Publish the Query

By default, queries are private and can only be executed using the authentication credentials of the user who created them. To make a visualization accessible to anyone, without requiring its creator's credentials, you need to publish the query.

To publish a query, send a POST request including in the request body the ID of the query to publish, and set the "visibility" property to "public" and you will receive a response body that confirms that the query has been published:

https://datalens.api.here.com/v1/publishing?app_id={YOUR_APP_ID}&app_code={YOUR_APP_CODE}   
      
{
  "queries": {
    "visibility": "public",
    "ids": ["{SPECIFY_QUERY_ID}"]
  }
}

Be sure to include your token in the Authorization field of the request header.

Note: You can also use the publishing endpoint in the 12. Publish Queries folder of our Postman collection.

Visualizing your Data

Next you define the HTML and JavaScript code for the visualization. The code will make one request to the Geovisualization REST API for each tile in the viewport, so that the app receives the geographical data points only for the visible tiles. With this data, you create a marker on the map for each data point, using data-driven styling (size, color and opacity) to represent each earthquake's magnitude and depth.
Note: For a full guide to visualizing your data, see Creating Visualizations.

Define the HTML Code

Create an index.html file and add the following HTML to set up the JavaScript, CSS and page structure you will need, also create a map.js file in the same directory to contain the JavaScript code you will need.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>The Geovisualization Example</title>
  <meta name="viewport" content="initial-scale=1.0, width=device-width" />
  <link rel="stylesheet" type="text/css" href="https://js.cit.api.here.com/v3/3.0/mapsjs-ui.css" />
  <link rel="stylesheet" type="text/css" href="./dist/ui.css">
  <link rel="stylesheet" type="text/css" href="./dist/index.css">
</head>
<body>
  <div class="dl-map"></div>    
    <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-core.js"></script>
  <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-service.js"></script>
  <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-ui.js"></script>
  <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
  <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-clustering.js"></script>
  <script type="text/javascript" src="https://js.cit.datalens.api.here.com/2.6.1/mapsjs-datalens.js"></script>  
  <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
  <script src="./map.js"></script>
</body>
</html>    
    

Define the JavaScript Code

This example will not show all the JavaScript code, only the parts most relevant to using Geovisualization. You can find the full JavaScript code here and if you are new to HERE, we recommend you read the Maps API for JavaScriptdocumentation.

Note: For the full JavaScript API reference, see JavaScript API.

First create an instance of a provider class (H.datalens.QueryTileProvider) to request the data for the tiles visible in the viewport. In its constructor, use an instance of a service class (H.datalens.Service) that defines the communication with the Geovisualization REST API. Finally, bind the query to the provider.

...
const service = platform.configure(new H.datalens.Service());

const provider = new H.datalens.QueryTileProvider(
  service,
  {
    queryId: query.id,
    tileParamNames: {x: 'x', y: 'y', z: 'z'}
  });
...

To draw the proportional markers, instantiate a map layer (H.datalens.ObjectLayer), then, create an SVG circle for each marker, with its style defined by the following functions:

  • The marker's size (size) is a function of the magnitude of the earthquake. The greater the magnitude of the earthquake, the larger the size of the marker.
  • The marker's color (fill) is a function of the depth of the earthquake epicenter. The deeper the epicenter, the darker the blue of the marker.
  • The marker's transparency (fillOpacity) is also a function of the earthquake's depth. The deeper the epicenter, the greater the transparency of the marker.

The following code illustrates the above:

...
const layer = new H.datalens.ObjectLayer(
  provider,
  {
    rowToMapObject: (row) => new H.map.Marker({
      lat: row.lat, lng: row.lon
  }),
  rowToStyle: (row, zoom) => {
    let size = magnitudeScale(row.magnitude) * zoom * window.devicePixelRatio;
    let icon = H.datalens.ObjectLayer.createIcon([
      'svg',
      {viewBox: [-size, -size, 2 * size + 2, 2 * size + 2]},
      ['path', {
        d: d3.arc()({
          startAngle: 0,
          endAngle: 360,
          outerRadius: size
        }),
        fill: depthScale(row.depth),
        fillOpacity: alphaScale(row.depth),
        stroke: 'rgba(227,232,235,0.5)',
        strokeWidth: 1.5 * pixelRatio
      }]
    ], {size: size});
    return {icon: icon};
  },
  dataDomains: {
  magnitude: magnitudeScale.ticks(10),
  depth: depthScale.ticks(10)
  }
});
...

Finally, to render the markers, add the layer to the map:

...
map.addLayer(layer);
Load index.html in your browser to see the final rendered visualization.