Maps API for JavaScript Developer's Guide

Screen Overlays

HERE Maps API for JavaScript provides a way to overlay map with the user-defined animation or display data that requires WebGL context for rendering.

The API provides two layer types to facilitate the above mentioned use cases.
  • H.map.layer.DomLayer provides a DOM container that is used to place DOM elements according to the user-defined logic.
  • H.map.layer.CanvasLayer provides a requested (WebGL or CanvasContext2D) to draw on.

Both CanvasLayer and DomLayer use the user provided renderCallnack in order to implement the rendering logic. The callback recieves the requested canvas context or the DOM container and a set of rendering parameters describing the current state of the visible part of the map. The return value of the callback defines if map's rendering engine must schedule next frame or the layer finished rendering and the engine should stop.

Showing 2D canvas overlay on the map.

The example below uses H.map.layer.CanvasLayer with the 2D context to animate the approximate path of the International Space Station. The code:

  1. Defines rendering callback function that contains the drawing logic.
  2. Creates the instance of H.map.layer.CanvasLayer with the default options.
  3. Adds the created layer to the map. Layer's rendering callback is called each frame with the cleared context.
/**
 * Assuming that "map" with the satellite base layer
 * was already initialized.
 */
 var PHI = 0.9005,
  omega = 4.1214,
  t = 0,
  tick = 0,
  x = 0,
  lastZoom = NaN;

/**
 * The render callback is passed to the canvas layer
 * and invoked every rander frame.
 */
function renderCallback(ctx, renderParams) {
  var zoom = renderParams.zoom,
  projection = renderParams.projection,
  screenCenter = renderParams.screenCenter,
  radius = Math.pow(2, (projection.exp + zoom)) / (2 * Math.PI),
  y,
  pX,
  pY;

  if (isNaN(lastZoom)) {
  lastZoom = zoom;
  }

  ctx.strokeStyle = 'yellow';

  // calculate x,y pixel coordinates of the ISS for the given tick
  if (zoom !== lastZoom) {
  x = tick * Math.pow(2, zoom);
  }
  x += Math.pow(2, zoom);
  y = radius * Math.sin(omega * t + PHI);

  
  // shift calculated position rekative to the pixel projection
  // and the screen center
  pX = x - projection.x + screenCenter.x; 
  pY = y + (projection.w / 2) - projection.y + screenCenter.y;

  // draw crosshair at the given position
  ctx.moveTo(pX - 10, pY - 10);
  ctx.lineTo(pX + 10, pY + 10);
  ctx.moveTo(pX + 10, pY - 10);
  ctx.lineTo(pX - 10, pY + 10);
  ctx.stroke();

  lastZoom = zoom;

  tick += 1;
  t += 0.007;
  if (tick > 256) {
  tick = 0;
  x = 0;
  }

  // animate continuously
  return H.map.render.RenderState.ACTIVE;
}

var canvasLayer = new H.map.layer.CanvasLayer(renderCallback)

map.addLayer(canvasLayer);

The image below shows the observable result of this code on the map.