Geovisualization Developer's Guide

Spatial Layer

H.datalens.SpatialLayer presents geometrical features such as polygons and polylines on the map using data-driven styles. Styles can be parameterized with data rows, the zoom level and the interactive state.

The following image shows a visualization of buildings:

Figure 1. Visualization of buildings using a spatial layer

To render geometry features on the map with data-driven styles, you first need to define a dataProvider and a spatialProvider. The data provider (an instance of H.datalens.Provider) loads data from query results or from a static JSON object, while the spatial provider (an instance of H.datalens.SpatialTileProvider) loads a layer containing geometries.

You then need to specify two callbacks to connect the data with the geometries: rowToSpatialId must return the spatial ID for a given data row, and featureToSpatialId must return the spatial ID for a given geometry feature:

var layer = new H.datalens.SpatialLayer(
  dataProvider,
  spatialProvider,
  {
    rowToSpatialId: (row) => {
      return row.building_id;
    },
    featureToSpatialId: (feature) => {
      return feature.properties.id_ori;
    }
  }
);

The following diagram summarizes the spatial layer data flow:

Figure 2. Spatial layer data flow

Styles of geometry features can be specified based on the row data, the zoom level, and the interactive state by using the rowToStyle callback:

rowToStyle: (row, zoom, state) => {
  return {
    fillColor: scale(row.pixel_value_log)
  };
}

You can also use the defaultStyle callback to specify default styles when there is no data for a particular geometry feature:

defaultStyle: (zoom, state) => {
  return {
    fillColor:'#0E141E',
    lineJoin: 'round',
    lineCap: 'round',
    strokeColor: 'rgba(160, 163, 167, 1)',
    lineWidth: 1
  };
}

Finally, you add the layer to the map as follows:

map.addLayer(layer);

Several other options can be passed to the SpatialLayer during initialization:

  • dataToRows defines how the input data is split by rows. You can specify this callback to define client-side aggregation and filtering. By default it represents each row as an object where property names correspond to data column names.
  • opacity can be used to set the layer's transparency.

To add interactivity to the SpatialLayer, you can add an event listener to the map:

map.addEventListener('tap', (e) => {
  var feature = e.target.getFeature();
  var row = e.target.getData();
  layer.updateSpatialStyle(e.target, 'tapped');
});

In the event listener, you can use layer.updateSpatialStyle() to change the state of the geometry feature (automatically set to the event target), which in turn redraws the geometry feature using the new style. You can retrieve the data row associated with the event target by calling e.target.getData(). You can also retrieve the geometry feature (including its properties) by calling e.target.getFeature().