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
|
<!DOCTYPE html>
<html>
<head>
<link href="https://unpkg.com/maplibre-gl@^5.7.2/dist/maplibre-gl.css"/>
<style>
body {
margin: 0;
padding: 0;
}
html, body, #map {
height: 90%;
}
</style>
<title></title>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/maplibre-gl@^5.7.2/dist/maplibre-gl.js"></script>
<script>
const map = new maplibregl.Map({
container: "map",
style: "https://tiles.openfreemap.org/styles/bright",
center: [10.253494570441944, 59.937419399772125],
zoom: 7
});
const markers = new Map();
let t = null;
map.on("moveend", () => {
clearTimeout(t);
t = setTimeout(updateData, 150);
});
map.on("load", () => {
map.loadImage("/pin.png").then(image => map.addImage("custom-marker", image.data));
map.addSource("places", {
type: "geojson",
data: {type: "FeatureCollection", features: []},
// cluster: true,
// clusterRadius: 40,
// clusterMaxZoom: 14
});
map.addLayer({
id: "places-layer",
type: "symbol",
source: "places",
layout: {
"icon-image": "custom-marker"
}
});
updateData();
});
let aborter = new AbortController();
async function updateData() {
const b = map.getBounds();
const south = b.getSouth(), west = b.getWest(), north = b.getNorth(), east = b.getEast();
if (aborter) {
aborter.abort();
}
aborter = new AbortController();
const res = await fetch(`/places?w=${west}&s=${south}&e=${east}&n=${north}`, {
signal: aborter.signal
});
if (!res.ok) {
return;
}
const data = await res.json().finally(() => aborter = null);
map.getSource("places").setData(data);
}
</script>
</body>
</html>
|