0%

mapboxgl实时更新10w点

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mapbox GL | 10万点实时颜色更新</title>
<link
href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css"
rel="stylesheet"
/>
<script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>
<style>
html,
body,
#map {
height: 100%;
margin: 0;
}
#panel {
position: absolute;
top: 10px;
left: 10px;
z-index: 10;
background: rgba(0, 0, 0, 0.6);
color: white;
padding: 10px;
border-radius: 8px;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="panel">10万点,颜色实时更新(feature-state)</div>

<script>
mapboxgl.accessToken =
"pk.eyJ1Ijoic3NpdmFsZW4iLCJhIjoiY205N3J1OWw5MGFoNzJscHQ2cjA1N21qcCJ9.KA0V5-Mh_KCV4DV5HkpAeg";

const map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/dark-v11",
center: [116.397, 39.908],
zoom: 9,
renderWorldCopies: false,
});

map.on("load", () => {
// 1. 添加 source,使用 promoteId
map.addSource("points", {
type: "geojson",
data: { type: "FeatureCollection", features: [] },
promoteId: "id",
cluster: false,
});

// 2. 添加图层,颜色用 feature-state.v
map.addLayer({
id: "points-layer",
type: "circle",
source: "points",
paint: {
"circle-color": [
"interpolate",
["linear"],
["coalesce", ["feature-state", "v"], 0], // state.v不存在时用0
0.0,
"#2DC4B2",
0.25,
"#3BB3C3",
0.5,
"#669EC4",
0.75,
"#8B88B6",
1.0,
"#A2719B",
],

"circle-radius": [
"let",
"r",
["coalesce", ["get", "r"], 2],
[
"interpolate",
["linear"],
["zoom"],
3,
["*", ["var", "r"], 0.7],
12,
["*", ["var", "r"], 1.4],
],
],
"circle-opacity": 0.8,
},
});

// 3. 生成 10 万点数据(带 id)
const N = 100000;
const features = [];
for (let i = 0; i < N; i++) {
features.push({
type: "Feature",
id: i, // id 字段,与 promoteId 对应
properties: { id: i },
geometry: {
type: "Point",
coordinates: [
116.0 + Math.random(), // 经度
39.5 + Math.random(), // 纬度
],
},
});
}
map
.getSource("points")
.setData({ type: "FeatureCollection", features });

// 4. 模拟实时颜色更新(每帧改 2000 个点)
function randomUpdate() {
for (let k = 0; k < 2000; k++) {
const id = Math.floor(Math.random() * N);
const v = Math.random();
map.setFeatureState({ source: "points", id }, { v });
}
requestAnimationFrame(randomUpdate);
}
randomUpdate();

// 如果是 WebSocket,直接在 onmessage 里调用 setFeatureState({source:'points',id},{v})
});
</script>
</body>
</html>