Bring back vector render mode for vector tile layers

This commit is contained in:
Andreas Hocevar
2019-11-18 07:49:24 +01:00
parent 3f8164250c
commit cf6cd09f58
9 changed files with 116 additions and 31 deletions

View File

@@ -5,7 +5,11 @@ shortdesc: Select features from vector tiles.
docs: >
<p>
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.
By changing the action type to "Multi Select" you can select multiple features at a time. With "Single Sslect on hover",
features will be higlighted when the pointer is above them.
</p><p>
The selection layer is configured with `renderMode: 'vector'` for better performance on frequent redraws,
i.e. when 'Single select on hover' is selected.
</p>
tags: "vector tiles, selection"
---
@@ -15,5 +19,6 @@ tags: "vector tiles, selection"
<select id="type" class="form-control">
<option value="singleselect" selected>Single Select</option>
<option value="multiselect">Multi Select</option>
<option value="singleselect-hover">Single Select on hover</option>
</select>
</form>

View File

@@ -8,6 +8,25 @@ import {Fill, Stroke, Style} from '../src/ol/style.js';
// lookup for selection objects
let selection = {};
const country = new Style({
stroke: new Stroke({
color: 'gray',
width: 1
}),
fill: new Fill({
color: 'rgba(20,20,20,0.9)'
})
});
const selectedCountry = new Style({
stroke: new Stroke({
color: 'rgba(200,20,20,0.8)',
width: 2
}),
fill: new Fill({
color: 'rgba(200,20,20,0.4)'
})
});
const vtLayer = new VectorTileLayer({
declutter: true,
source: new VectorTileSource({
@@ -18,18 +37,7 @@ const vtLayer = new VectorTileLayer({
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) {
const 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)'
})
});
}
style: country
});
const map = new Map({
@@ -39,18 +47,34 @@ const map = new Map({
target: 'map',
view: new View({
center: [0, 0],
zoom: 2
zoom: 2,
multiWorld: true
})
});
// Selection
const selectionLayer = new VectorTileLayer({
map: map,
renderMode: 'vector',
source: vtLayer.getSource(),
style: function(feature) {
if (feature.getId() in selection) {
return selectedCountry;
}
}
});
const selectElement = document.getElementById('type');
map.on('click', function(event) {
map.on(['click', 'pointermove'], function(event) {
if (selectElement.value === 'singleselect-hover' && event.type !== 'pointermove' ||
selectElement.value !== 'singleselect-hover' && event.type === 'pointermove') {
return;
}
vtLayer.getFeatures(event.pixel).then(function(features) {
if (!features.length) {
selection = {};
// force redraw of layer style
vtLayer.setStyle(vtLayer.getStyle());
selectionLayer.changed();
return;
}
const feature = features[0];
@@ -59,14 +83,12 @@ map.on('click', function(event) {
}
const fid = feature.getId();
if (selectElement.value === 'singleselect') {
if (selectElement.value.startsWith('singleselect')) {
selection = {};
}
// add selected feature to lookup
selection[fid] = feature;
// force redraw of layer style
vtLayer.setStyle(vtLayer.getStyle());
selectionLayer.changed();
});
});