原文链接及内容

运行界面

ol/proj模块中调用useGeographic函数使地图视图使用地理坐标(即使视图投影不是地理的)。

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
import {Feature, Map, Overlay, View} from 'ol/index.js';
import {OSM, Vector as VectorSource} from 'ol/source.js';
import {Point} from 'ol/geom.js';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js';
import {useGeographic} from 'ol/proj.js';

useGeographic();

const place = [-110, 45];

const point = new Point(place);

const map = new Map({
target: 'map',
view: new View({
center: place,
zoom: 8,
}),
layers: [
new TileLayer({
source: new OSM(),
}),
new VectorLayer({
source: new VectorSource({
features: [new Feature(point)],
}),
style: {
'circle-radius': 9,
'circle-fill-color': 'red',
},
}),
],
});

const element = document.getElementById('popup');

const popup = new Overlay({
element: element,
stopEvent: false,
});
map.addOverlay(popup);

function formatCoordinate(coordinate) {
return `
<table>
<tbody>
<tr><th>lon</th><td>${coordinate[0].toFixed(2)}</td></tr>
<tr><th>lat</th><td>${coordinate[1].toFixed(2)}</td></tr>
</tbody>
</table>`;
}

const info = document.getElementById('info');
map.on('moveend', function () {
const view = map.getView();
const center = view.getCenter();
info.innerHTML = formatCoordinate(center);
});

let popover;
map.on('click', function (event) {
if (popover) {
popover.dispose();
popover = undefined;
}
const feature = map.getFeaturesAtPixel(event.pixel)[0];
if (!feature) {
return;
}
const coordinate = feature.getGeometry().getCoordinates();
popup.setPosition([
coordinate[0] + Math.round(event.coordinate[0] / 360) * 360,
coordinate[1],
]);

popover = new bootstrap.Popover(element, {
container: element.parentElement,
content: formatCoordinate(coordinate),
html: true,
offset: [0, 20],
placement: 'top',
sanitize: false,
});
popover.show();
});

map.on('pointermove', function (event) {
const type = map.hasFeatureAtPixel(event.pixel) ? 'pointer' : 'inherit';
map.getViewport().style.cursor = type;
});

界面布局文件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
29
30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Geographic Coordinates</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="node_modules/ol/ol.css">
<style>
.map {
width: 100%;
height: 400px;
}
td {
padding: 0 0.5em;
text-align: right;
}
</style>
</head>
<body>
<div id="map" class="map">
<div id="popup"></div>
</div>
<div id="info"></div>

<!-- 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 src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>
<script type="module" src="main.js"></script>
</body>
</html>