Interact with VectorTile features

The nice thing about vector tiles is that we can interact with features, because we have the data on the client. One thing to note though is that vector tiles are optimized for rendering. This means that features only contain attributes that are needed for filtering and rendering, and that geometries are optimized for the rendered resolution and clipped near the tile boundary.

For this exercise, we're going to draw a box around the features at the pointer's location when hovering over them.

Adding a vector layer for displaying bounding boxes

We will be drawing the bounding boxes of the hovered features on a separate layer. The following imports are needed, and we add them next to the other imports in main.js:

import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import {Stroke, Style} from 'ol/style';

Next, we can create a source for the layer, the layer, and assign it to the map:

const source = new VectorSource();
new VectorLayer({
  map: map,
  source: source,
  style: new Style({
    stroke: new Stroke({
      color: 'red',
      width: 4,
    }),
  }),
});

Interacting with the map

Now it is time to add a pointermove listener to the map, which gets all the features at the pointer location and adds their bounding boxes to the layer. We need two additional imports for that:

import Feature from 'ol/Feature';
import {fromExtent} from 'ol/geom/Polygon';

Finally we can add the code that clears the current contents of the source and adds the bounding boxes for the features at the pointer location as new content:

map.on('pointermove', function (event) {
  source.clear();
  map.forEachFeatureAtPixel(
    event.pixel,
    function (feature) {
      const geometry = feature.getGeometry();
      source.addFeature(new Feature(fromExtent(geometry.getExtent())));
    },
    {
      hitTolerance: 2,
    }
  );
});

Now when hovering over the map, the result should look like this:

Hovering over the map
Hovering over the map

results matching ""

    No results matching ""