Map Tile API Developer's Guide

Extruded Buildings

This article shows example usage of matainfo tile for selecting or highlighting buildings.

User story

In order to make buildings on the map interactive (highlight upon selection, etc.) user obtains metadata information about an image, showing a map tile that includes an extruded building.

Original map tile

Given the following request:

https://2.base.maps.cit.api.here.com
/maptile/2.1/maptile/newest/normal.day/19/281707/171901/256/png8
?app_id={YOUR_APP_ID}
&app_code={YOUR_APP_CODE}

The response to the request delivers the following image:

Figure 1. Map tile with building

This tile contains a fragment of a building near the bottom left corner. When the user wants to find out more information about it they can use the following request:

Metainfo Tile Request Summary

The following list summarizes the elements required to create a request matching the user story and shows, in square brackets, how those elements are used in the example(s) below. Note that the request example also uses the authentication parameters.

Resource: maptile [maptile], see also (resource) type
URL variables: {map id} [newest], see also Requesting the Right Map Version
  {scheme} [normal.day], see also scheme
  {zoom}/{column}/{row} [19/281707/171901], see also The Mercator Projection
  {size} [256], see also size
  {format} [png8], see also format
Parameters: metadata [metaonly], see also metadata
  mgen [2], see also mgen

Metainfo Tile Request

The code block below demonstrates a complete request for a metadata map tile with extruded buildings:

https://2.base.maps.cit.api.here.com
/maptile/2.1/maptile/newest/normal.day/19/281707/171901/256/png8
?app_id={YOUR_APP_ID}
&app_code={YOUR_APP_CODE}
&metadata=metaonly
&mgen=2

Processing Metainfo Tile Response

The response to the request delivers the following Metainfo Tile as a JSON object:


{ "metadata" : {
"street labels":[  ],
"labels":[],
"city center labels":[],
"buildings":[ { "id": "1609441356716643099", "vertices": [ 37, 161.69, 18, 199.50, 0, 189.18, 0, 142.78 ], "polygons": [ [ 0, 1, 2, 3]], "outlines": [ [ 0, 1, 2 ], [ 3, 0 ]] } ],
"transit stops":[  ],
"POIs":[  ]
}
}

In the response, the building has 8 vertices that are ordered counterclockwise for inner polygon and clockwise for outer polygon. In this example there is only an outer polygon, so it is filled inside, all inner polygons will be filled outside.

The metadata also contains two arrays, "polygons" and "outlines", each containing arrays of indices that reference the given array of vertices. In our case, we have one polygon that has the vertex indices (0, 1, 2, 3), which represents the contour of our building fragment and two outlines that have also the vertex indices, in this case, (0, 1, 2) and (3, 0).

Using this information we can draw a polygon reflecting current building's shape, e.g. with HTML5 canvas:

<canvas id="building_canvas" width="256" height="256" style="border:1px solid #d3d3d3;" />
<script>
var building_canvas = document.getElementById('building-canvas');
building_canvas.getContext('2d').clearRect(0, 0, building_canvas.width, building_canvas.height);

var bcnt = map.custom.tile_meta.metadata.buildings.length;
var bld;
console.log('There are ' + bcnt.toString() + ' buildings on the tile')

var building_canvas = document.getElementById('building-canvas').getContext('2d');
building_canvas.fillStyle = '#FFE8E8';

building_canvas.strokeStyle="green";
building_canvas.lineWidth=1;

var vertices, mpolygons, moutlines;

for (var i=0; i<bcnt; i++) {
  bld = map.custom.tile_meta.metadata.buildings[i];
  vertices = bld.vertices;
  mpolygons = bld.polygons;
  moutlines = bld.outlines;

  // move to first point
  building_canvas.beginPath();

  for (var idx = 0; idx < mpolygons.length; idx++) {
    for ( var vidx = 0; vidx < mpolygons[idx].length; vidx++ ) {
      var index = 2*mpolygons[idx][vidx];
      point = vertices.slice(index, index+2);
      if ( vidx == 0 ) {
        building_canvas.moveTo(point[0], point[1]);
      }
      building_canvas.lineTo(point[0], point[1]);
    }
      }

      building_canvas.fill();

      building_canvas.beginPath();

      for (var idx = 0; idx < moutlines.length; idx++) {
    for ( var vidx = 0; vidx < moutlines[idx].length; vidx++ ) {
      var index = 2*moutlines[idx][vidx];
      point = vertices.slice(index, index+2);
      if ( vidx == 0 ) {
        building_canvas.moveTo(point[0], point[1]);
      }
      building_canvas.lineTo(point[0], point[1]);
    }
      }

      building_canvas.stroke();
      building_canvas.closePath();
}

</script>
Figure 2. Building shape reflected using metadata

In this example we only consider one part of the building. See also Combining Building Metainfo from Several Tiles.