Edit

Vector Tile Selection

Select features from vector tiles.

Click a rendered vector-tile feature to highlight it on the map. Click on an empty spot (ocean) to reset the selection. By changing the action type to "Multi Select" you can select multiple features at a time.

index.html<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Vector Tile Selection</title>
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <style>
      .map {
        width: 100%;
        height:400px;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <form class="form-inline">
      <label>Action type &nbsp;</label>
      <select id="type" class="form-control">
        <option value="singleselect" selected>Single Select</option>
        <option value="multiselect">Multi Select</option>
      </select>
    </form>
    <script src="index.js"></script>
  </body>
</html>
index.jsimport 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import MVT from 'ol/format/MVT';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import {Fill, Stroke, Style} from 'ol/style';

// lookup for selection objects
var selection = {};

var vtLayer = new VectorTileLayer({
  declutter: true,
  source: new VectorTileSource({
    maxZoom: 15,
    format: new MVT({
      idProperty: 'iso_a3'
    }),
    url: 'https://ahocevar.com/geoserver/gwc/service/tms/1.0.0/' +
      'ne:ne_10m_admin_0_countries@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf'
  }),
  style: function(feature) {
    var selected = !!selection[feature.getId()];
    return new Style({
      stroke: new Stroke({
        color: selected ? 'rgba(200,20,20,0.8)' : 'gray',
        width: selected ? 2 : 1
      }),
      fill: new Fill({
        color: selected ? 'rgba(200,20,20,0.2)' : 'rgba(20,20,20,0.9)'
      })
    });
  }
});

var map = new Map({
  layers: [
    vtLayer
  ],
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 2
  })
});

var selectElement = document.getElementById('type');

map.on('click', function(event) {
  vtLayer.getFeatures(event.pixel).then(function(features) {
    if (!features.length) {
      selection = {};
      // force redraw of layer style
      vtLayer.setStyle(vtLayer.getStyle());
      return;
    }
    var feature = features[0];
    if (!feature) {
      return;
    }
    var fid = feature.getId();

    if (selectElement.value === 'singleselect') {
      selection = {};
    }
    // add selected feature to lookup
    selection[fid] = feature;

    // force redraw of layer style
    vtLayer.setStyle(vtLayer.getStyle());
  });

});
package.json{
  "name": "vector-tile-selection",
  "dependencies": {
    "ol": "6.1.1"
  },
  "devDependencies": {
    "parcel": "1.11.0"
  },
  "scripts": {
    "start": "parcel index.html",
    "build": "parcel build --experimental-scope-hoisting --public-url . index.html"
  }
}