# 六.失量图层
# 1.矢量层命中检测
查看代码详情
<template>
<div>
<div ref="map" class="map"></div>
<div id="info"> </div>
</div>
</template>
<script>
export default {
mounted() {
let {
format: { GeoJSON },
Map,
View,
layer: { Vector: VectorLayer },
source: { Vector: VectorSource },
style: { Fill, Stroke, Style },
} = ol;
const style = new Style({
fill: new Fill({
color: "#eeeeee",
}),
});
const vectorLayer = new VectorLayer({
background: "#1a2b39",
source: new VectorSource({
url: "https://openlayers.org/data/vector/ecoregions.json",
format: new GeoJSON(),
}),
style: function (feature) {
const color = feature.get("COLOR_NNH") || "#eeeeee";
style.getFill().setColor(color);
return style;
},
});
const map = new Map({
layers: [vectorLayer],
target: this.$refs.map,
view: new View({
center: [12579156, 3274244],
zoom: 1,
}),
});
const highlightStyle = new Style({
stroke: new Stroke({
color: "rgba(255, 255, 255, 0.7)",
width: 2,
}),
});
const featureOverlay = new VectorLayer({
source: new VectorSource(),
map: map,
style: highlightStyle,
});
let highlight;
const displayFeatureInfo = function (pixel) {
vectorLayer.getFeatures(pixel).then(function (features) {
const feature = features.length ? features[0] : undefined;
const info = document.getElementById("info");
if (features.length) {
info.innerHTML =
feature.get("ECO_NAME") + ": " + feature.get("NNH_NAME");
} else {
info.innerHTML = " ";
}
if (feature !== highlight) {
if (highlight) {
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}
});
};
map.on("pointermove", function (evt) {
if (evt.dragging) {
return;
}
const pixel = map.getEventPixel(evt.originalEvent);
displayFeatureInfo(pixel);
});
map.on("click", function (evt) {
displayFeatureInfo(evt.pixel);
});
},
};
</script>
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
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
# 2.矢量瓦片信息
查看代码详情
<template>
<div ref="map" class="map">
<pre id="info" />
</div>
</template>
<script>
export default {
mounted() {
let {
format: { MVT },
Map,
View,
layer: { Vector: VectorLayer, VectorTile: VectorTileLayer },
source: { Vector: VectorSource, VectorTile: VectorTileSource },
} = ol
const map = new Map({
target: this.$refs.map,
view: new View({
center: [12579156, 3274244],
zoom: 2,
}),
layers: [
new VectorTileLayer({
source: new VectorTileSource({
format: new MVT(),
url: "https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf",
}),
}),
],
})
map.on("pointermove", showInfo)
const info = document.getElementById("info")
function showInfo(event) {
const features = map.getFeaturesAtPixel(event.pixel)
if (features.length == 0) {
info.innerText = ""
info.style.opacity = 0
return
}
const properties = features[0].getProperties()
info.innerText = JSON.stringify(properties, null, 2)
info.style.opacity = 1
}
},
}
</script>
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
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
# 3.矢量瓦片选择
查看代码详情
<template>
<div>
<div ref="map" class="map"></div>
<form class="form-inline">
<label for="type">Action type </label>
<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>
</div>
</template>
<script>
export default {
mounted() {
let {
format: { MVT },
Map,
View,
layer: { Tile: TileLayer, VectorTile: VectorTileLayer },
source: { VectorTile: VectorTileSource },
style: { Fill, Stroke, Style },
} = ol;
// 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: this.$refs.map,
view: new View({
center: [12579156, 3274244],
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.indexOf("singleselect") === 0) {
selection = {};
}
// add selected feature to lookup
selection[fid] = feature;
selectionLayer.changed();
});
});
},
};
</script>
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# 4.从 Mapbox 样式对象创建的矢量瓦片
查看代码详情
<template>
<div ref="map" class="map"></div>
</template>
<script>
export default {
mounted() {
let {
control: { FullScreen },
} = ol
// import olms from 'ol-mapbox-style';
olms(
"map",
"https://api.maptiler.com/maps/topo/style.json?key=Get your own API key at https://www.maptiler.com/cloud/"
).then(function (map) {
map.addControl(new FullScreen())
})
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 5.EPSG:4326 中的矢量瓦片
查看代码详情
<template>
<div ref="map" class="map" style="background:none;"></div>
</template>
<script>
export default {
mounted() {
let {
format: { MVT },
View,
source: { VectorTile: VectorTileSource },
tilegrid: { TileGrid },
} = ol
const maxResolution = 360 / 512
defaultResolutions.length = 14
for (let i = 0; i < 14; ++i) {
defaultResolutions[i] = maxResolution / Math.pow(2, i + 1)
}
olms(
"map",
"https://api.maptiler.com/maps/basic-4326/style.json?key=" +
mapkeys.maptiler
).then(function (map) {
// Custom tile grid for the EPSG:4326 projection
const tileGrid = new TileGrid({
extent: [-180, -90, 180, 90],
tileSize: 512,
resolutions: defaultResolutions,
})
const mapboxStyle = map.get("mapbox-style")
// Replace the source with a EPSG:4326 projection source for each vector tile layer
map.getLayers().forEach(function (layer) {
const mapboxSource = layer.get("mapbox-source")
if (
mapboxSource &&
mapboxStyle.sources[mapboxSource].type === "vector"
) {
const source = layer.getSource()
layer.setSource(
new VectorTileSource({
format: new MVT(),
projection: "EPSG:4326",
urls: source.getUrls(),
tileGrid: tileGrid,
})
)
}
})
// Configure the map with a view with EPSG:4326 projection
map.setView(
new View({
projection: "EPSG:4326",
zoom: mapboxStyle.zoom,
center: mapboxStyle.center,
})
)
})
},
}
</script>
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
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