原文链接及内容

运行界面

单击渲染的矢量切片要素并在地图上高亮显示。单击一个空白点(如海洋区域)以重置选择。点击下拉框将操作类型更改为“多选”,此时可以一次选择多个要素。点击下拉框并选择使用“Single Select on hover(悬停时单选)”选项,当鼠标指针悬停于要素上方时,要素将高亮显示。

选择图层配置有renderMode:'vector',以便在频繁重绘时(即选择“Single Select on hover(悬停时单选)”下拉框选项时)获得更好的性能。

main.js代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import MVT from 'ol/format/MVT.js';
import Map from 'ol/Map.js';
import VectorTileLayer from 'ol/layer/VectorTile.js';
import VectorTileSource from 'ol/source/VectorTile.js';
import View from 'ol/View.js';
import {Fill, Stroke, Style} from '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({
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: country,
});

const map = new Map({
layers: [vtLayer],
target: 'map',
view: new View({
center: [0, 0],
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', '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 = {};
selectionLayer.changed();
return;
}
const feature = features[0];
if (!feature) {
return;
}
const fid = feature.getId();

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

selectionLayer.changed();
});
});

界面布局文件index.html代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vector Tile Selection</title>
<link rel="stylesheet" href="node_modules/ol/ol.css">
<style>
.map {
width: 100%;
height: 400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<form>
<label for="type">Action type &nbsp;</label>
<select id="type">
<option value="singleselect" selected>Single Select</option>
<option value="multiselect">Multi Select</option>
<option value="singleselect-hover">Single Select on hover</option>
</select>
</form>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="https://cdn.jsdelivr.net/npm/elm-pep@1.0.6/dist/elm-pep.js"></script>
<script type="module" src="main.js"></script>
</body>
</html>