@mesh3d/cesium-vectortile-gl 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +11 -0
- package/.gitconfig +3 -0
- package/.husky/pre-commit +1 -0
- package/.prettierignore +5 -0
- package/.vscode/settings.json +25 -0
- package/LICENSE.md +203 -203
- package/README.md +202 -167
- package/Source/Cesium.d.ts +2692 -2691
- package/Source/VectorTileLOD.js +720 -532
- package/Source/VectorTileRenderList.js +70 -70
- package/Source/VectorTileset.js +473 -447
- package/Source/layers/BackgroundRenderLayer.js +91 -89
- package/Source/layers/FillRenderLayer.js +18 -18
- package/Source/layers/IRenderLayer.js +160 -152
- package/Source/layers/LineRenderLayer.js +104 -94
- package/Source/layers/SymbolRenderLayer.js +30 -31
- package/Source/layers/index.js +23 -16
- package/Source/layers/registerRenderLayer.js +24 -24
- package/Source/layers/visualizers/FillLayerVisualizer.js +542 -426
- package/Source/layers/visualizers/ILayerVisualizer.js +90 -94
- package/Source/layers/visualizers/LineLayerVisualizer.js +702 -571
- package/Source/layers/visualizers/SymbolLayerVisualizer.js +514 -244
- package/Source/sources/GeoJSONSource.js +53 -46
- package/Source/sources/ISource.js +39 -39
- package/Source/sources/VectorSource.js +94 -52
- package/Source/sources/granularitySettings.js +23 -20
- package/Source/sources/index.js +6 -11
- package/Source/sources/registerSource.js +17 -19
- package/Source/style/StyleLayer.js +43 -43
- package/Source/style/StyleLayerProperties.js +44 -43
- package/Source/style/index.js +2 -2
- package/Source/symbol/SymbolPlacements.js +117 -88
- package/Source/workers/VectorTileWorker.js +41 -0
- package/Source/workers/ellipsoid.js +47 -0
- package/Source/workers/processTileTask.js +329 -0
- package/Source/workers/styleEvaluator.js +168 -0
- package/benchmark.html +148 -0
- package/dist/cvt-gl-worker.js +9274 -0
- package/dist/cvt-gl-worker.js.map +1 -0
- package/dist/cvt-gl.js +2570 -2001
- package/dist/cvt-gl.js.map +1 -1
- package/dist/cvt-gl.min.js +3 -3
- package/dist/cvt-gl.min.js.map +1 -1
- package/eslint.config.mjs +58 -0
- package/index.js +9 -6
- package/mlt.html +26 -25
- package/package.json +64 -41
- package/prettier.config.mjs +30 -0
- package/vite.config.mjs +43 -0
- package/vite.worker.config.mjs +31 -0
- package/worker.html +26 -0
package/Source/VectorTileset.js
CHANGED
|
@@ -1,447 +1,473 @@
|
|
|
1
|
-
import { VectorTileLOD } from
|
|
2
|
-
import { StyleLayer } from
|
|
3
|
-
import './layers/index'
|
|
4
|
-
import { VectorTileRenderList } from
|
|
5
|
-
import { Sources } from
|
|
6
|
-
import { ISource } from
|
|
7
|
-
import { warnOnce } from
|
|
8
|
-
import { SymbolPlacements } from
|
|
9
|
-
|
|
10
|
-
export class VectorTileset {
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
1
|
+
import { VectorTileLOD } from './VectorTileLOD'
|
|
2
|
+
import { StyleLayer } from './style/StyleLayer'
|
|
3
|
+
import './layers/index'
|
|
4
|
+
import { VectorTileRenderList } from './VectorTileRenderList'
|
|
5
|
+
import { Sources } from './sources'
|
|
6
|
+
import { ISource } from './sources/ISource'
|
|
7
|
+
import { warnOnce } from 'maplibre-gl/src/util/util'
|
|
8
|
+
import { SymbolPlacements } from './symbol/SymbolPlacements'
|
|
9
|
+
|
|
10
|
+
export class VectorTileset {
|
|
11
|
+
/**
|
|
12
|
+
* @param {object} options
|
|
13
|
+
* @param {string|import('@maplibre/maplibre-gl-style-spec').StyleSpecification} options.style
|
|
14
|
+
* @param {boolean} [options.showTileColor=false]
|
|
15
|
+
* @param {string} [options.workerUrl] - Web Worker 脚本 URL,用于瓦片解析/几何计算;不传则走主线程
|
|
16
|
+
* @param {number} [options.maximumActiveTasks=4] - 同时进行的 Worker 任务数,与 maxLoading 配合
|
|
17
|
+
*/
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.maximumLevel = 24
|
|
20
|
+
this.show = true
|
|
21
|
+
this.showTileColor = !!options.showTileColor
|
|
22
|
+
this.ready = false
|
|
23
|
+
this.tilingScheme = new Cesium.WebMercatorTilingScheme()
|
|
24
|
+
|
|
25
|
+
this.readyEvent = new Cesium.Event()
|
|
26
|
+
this.errorEvent = new Cesium.Event()
|
|
27
|
+
|
|
28
|
+
this._styleJson = null
|
|
29
|
+
this._style = options.style
|
|
30
|
+
this._rootTiles = []
|
|
31
|
+
this._cacheTiles = []
|
|
32
|
+
this._tilesToUpdate = []
|
|
33
|
+
this._tilesToRender = []
|
|
34
|
+
/**@type {StyleLayer[]} */
|
|
35
|
+
this._styleLayers = []
|
|
36
|
+
/**@type {VectorTileRenderList} */
|
|
37
|
+
this._renderList = new VectorTileRenderList(this._styleLayers)
|
|
38
|
+
this.numLoading = 0
|
|
39
|
+
this.maxLoading = 6
|
|
40
|
+
this.numInitializing = 0
|
|
41
|
+
this.maxInitializing = 6
|
|
42
|
+
/**@type {Cesium.TaskProcessor|null} */
|
|
43
|
+
this._taskProcessor = null
|
|
44
|
+
this._workerUrl = options.workerUrl || null
|
|
45
|
+
this._maximumActiveTasks = options.maximumActiveTasks ?? 4
|
|
46
|
+
/**@type {Cesium.Texture} */
|
|
47
|
+
this.tileIdTexture = null
|
|
48
|
+
this.zoom = 0
|
|
49
|
+
/**
|
|
50
|
+
* 负责符号碰撞检测(自动避让),SymbolPlacements 内部基于 maplibre-gl GridIndex 实现
|
|
51
|
+
*/
|
|
52
|
+
this._symbolPlacements = new SymbolPlacements()
|
|
53
|
+
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
this.init()
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async init() {
|
|
60
|
+
let style = this._style
|
|
61
|
+
if (!style) {
|
|
62
|
+
this.errorEvent.raiseEvent(new Error('请传入 style 参数'))
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.path = ''
|
|
67
|
+
if (typeof style == 'string') {
|
|
68
|
+
this.path = style.split('/').slice(0, -1).join('/')
|
|
69
|
+
if (this.path) this.path += '/'
|
|
70
|
+
style = await Cesium.Resource.fetchJson(style)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//初始化数据源
|
|
74
|
+
|
|
75
|
+
/** @type {{[sourceId:string]:ISource}}*/
|
|
76
|
+
this.sources = {}
|
|
77
|
+
for (const sourceId in style.sources) {
|
|
78
|
+
/**@type {import('@maplibre/maplibre-gl-style-spec').SourceSpecification} */
|
|
79
|
+
const sourceParams = style.sources[sourceId]
|
|
80
|
+
const SourceCls = Sources[sourceParams.type]
|
|
81
|
+
if (SourceCls) {
|
|
82
|
+
this.sources[sourceId] = new SourceCls(sourceParams, this.path)
|
|
83
|
+
try {
|
|
84
|
+
await this.sources[sourceId].init()
|
|
85
|
+
this.maximumLevel = Math.min(
|
|
86
|
+
sourceParams.maxzoom || 24,
|
|
87
|
+
this.maximumLevel
|
|
88
|
+
)
|
|
89
|
+
} catch (err) {
|
|
90
|
+
this.errorEvent.raiseEvent(err)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//初始化样式图层
|
|
96
|
+
for (let i = 0; i < style.layers.length; i++) {
|
|
97
|
+
this._styleLayers[i] = new StyleLayer(style.layers[i])
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//创建顶级瓦片LOD
|
|
101
|
+
const numX = this.tilingScheme.getNumberOfXTilesAtLevel(0)
|
|
102
|
+
const numY = this.tilingScheme.getNumberOfYTilesAtLevel(0)
|
|
103
|
+
let i = 0
|
|
104
|
+
for (let y = 0; y < numY; y++) {
|
|
105
|
+
for (let x = 0; x < numX; x++) {
|
|
106
|
+
var tile = new VectorTileLOD({
|
|
107
|
+
parent: this,
|
|
108
|
+
x,
|
|
109
|
+
y,
|
|
110
|
+
z: 0,
|
|
111
|
+
tilingScheme: this.tilingScheme
|
|
112
|
+
})
|
|
113
|
+
tile.createChildren()
|
|
114
|
+
this._rootTiles[i++] = tile
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//初始化渲染队列
|
|
119
|
+
this._renderList.init()
|
|
120
|
+
|
|
121
|
+
// Web Worker:有 workerUrl 时创建 TaskProcessor,供瓦片解析/几何计算使用
|
|
122
|
+
if (this._workerUrl && typeof Cesium.TaskProcessor !== 'undefined') {
|
|
123
|
+
this._taskProcessor = new Cesium.TaskProcessor(
|
|
124
|
+
this._workerUrl,
|
|
125
|
+
Math.min(this._maximumActiveTasks, this.maxInitializing)
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this._styleJson = style
|
|
130
|
+
this.ready = true
|
|
131
|
+
this.readyEvent.raiseEvent(this)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
//更新瓦片id纹理,用于裁剪超出瓦片边界的像素
|
|
135
|
+
executeTileIdCommands(frameState) {
|
|
136
|
+
const tileIdCommands = this._renderList.tileIdCommands
|
|
137
|
+
|
|
138
|
+
if (tileIdCommands.length > 0) {
|
|
139
|
+
const context = frameState.context
|
|
140
|
+
/**@type {Cesium.FrameBuffer} */
|
|
141
|
+
let tileIdFbo = this._tileIdFbo
|
|
142
|
+
if (!tileIdFbo) {
|
|
143
|
+
tileIdFbo = new Cesium.FramebufferManager({
|
|
144
|
+
depthStencil: true,
|
|
145
|
+
supportsDepthTexture: true
|
|
146
|
+
})
|
|
147
|
+
this._tileIdFbo = tileIdFbo
|
|
148
|
+
this._idClearCommand = new Cesium.ClearCommand({
|
|
149
|
+
color: new Cesium.Color(0.0, 0.0, 0.0, 0.0),
|
|
150
|
+
depth: 1.0,
|
|
151
|
+
stencil: 0.0
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
const pixelDatatype = context.floatingPointTexture
|
|
155
|
+
? Cesium.PixelDatatype.FLOAT
|
|
156
|
+
: Cesium.PixelDatatype.UNSIGNED_BYTE
|
|
157
|
+
const width = context.drawingBufferWidth
|
|
158
|
+
const height = context.drawingBufferHeight
|
|
159
|
+
tileIdFbo.update(context, width, height, 1, pixelDatatype)
|
|
160
|
+
tileIdFbo.clear(context, this._idClearCommand)
|
|
161
|
+
|
|
162
|
+
const framebuffer = tileIdFbo.framebuffer
|
|
163
|
+
for (const tileIdCommand of tileIdCommands) {
|
|
164
|
+
tileIdCommand.framebuffer = framebuffer
|
|
165
|
+
tileIdCommand.execute(context)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.tileIdTexture = tileIdFbo.getColorTexture(0)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
update(frameState) {
|
|
173
|
+
if (!this.ready || !this.show) return
|
|
174
|
+
|
|
175
|
+
if (frameState.context.webgl2) {
|
|
176
|
+
warnOnce('webgl2模式下贴地线面的支持将导致性能下降')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const renderList = this._renderList
|
|
180
|
+
//清空渲染队列
|
|
181
|
+
renderList.beginFrame()
|
|
182
|
+
|
|
183
|
+
this.numInitializing = 0
|
|
184
|
+
|
|
185
|
+
/**@type {Cesium.Globe} */
|
|
186
|
+
const scene = frameState.camera._scene
|
|
187
|
+
const globe = scene.globe
|
|
188
|
+
const globeSuspendLodUpdate = globe._surface._debug.suspendLodUpdate
|
|
189
|
+
this.scene = scene
|
|
190
|
+
|
|
191
|
+
// 获取可见瓦片
|
|
192
|
+
// 优化:采用更高效的LOD调度算法,获取当前帧实际可渲染到屏幕的瓦片,避免出现瓦片层级切换时候出现闪烁
|
|
193
|
+
|
|
194
|
+
/**@type {VectorTileLOD[]} */
|
|
195
|
+
const tilesToUpdate = getTilesToUpdate(frameState, this)
|
|
196
|
+
// const tilesToUpdate = globeSuspendLodUpdate ? this._tilesToUpdate : getTilesToUpdate(frameState, this)
|
|
197
|
+
|
|
198
|
+
//瓦片排序,决定瓦片加载瓦片数据、初始化的优先级
|
|
199
|
+
//优化:采用更精细、高效的优先级策略
|
|
200
|
+
if (!globeSuspendLodUpdate) {
|
|
201
|
+
tilesToUpdate.sort((a, b) => a.distanceToCamera - b.distanceToCamera)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
//更新瓦片状态:请求瓦片数据,创建渲染图层,初始化等
|
|
205
|
+
for (const tile of tilesToUpdate) {
|
|
206
|
+
tile.lastVisitTime = frameState.frameNumber
|
|
207
|
+
tile.expired = false
|
|
208
|
+
tile.update(frameState, renderList, this)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**@type {VectorTileLOD[]} */
|
|
212
|
+
const tilesToRender = globeSuspendLodUpdate
|
|
213
|
+
? this._tilesToRender
|
|
214
|
+
: getTilesToRender(tilesToUpdate, this._tilesToRender)
|
|
215
|
+
if (!globeSuspendLodUpdate) {
|
|
216
|
+
tilesToRender.sort((a, b) => a.distanceToCamera - b.distanceToCamera)
|
|
217
|
+
}
|
|
218
|
+
//渲染瓦片内容
|
|
219
|
+
for (const tile of tilesToRender) {
|
|
220
|
+
tile.lastVisitTime = frameState.frameNumber
|
|
221
|
+
tile.expired = false
|
|
222
|
+
tile.render(frameState, renderList, this)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
//渲染图层分组、排序
|
|
226
|
+
const orderedRenderLayers = renderList.getList()
|
|
227
|
+
//符号碰撞检测
|
|
228
|
+
this._symbolPlacements.update(frameState, orderedRenderLayers, this.zoom)
|
|
229
|
+
//获取渲染命令(DrawCommand),渲染图层内部可以使用Primitive、PolylineCollection、LabelCollection、BillboardCollection等API,
|
|
230
|
+
//也可以自定义DrawCommand
|
|
231
|
+
for (const renderLayer of orderedRenderLayers) {
|
|
232
|
+
renderLayer.render(frameState, this)
|
|
233
|
+
}
|
|
234
|
+
for (const visualizer of renderList.visualizers) {
|
|
235
|
+
visualizer.render(frameState, this)
|
|
236
|
+
}
|
|
237
|
+
//瓦片颜色、深度
|
|
238
|
+
frameState.commandList.push(...renderList.tileCommands)
|
|
239
|
+
|
|
240
|
+
this.executeTileIdCommands(frameState)
|
|
241
|
+
|
|
242
|
+
//释放过期瓦片
|
|
243
|
+
//优化:使用更高效的内存缓存管理策略
|
|
244
|
+
const expiredTiles = []
|
|
245
|
+
for (const cacheTile of this._cacheTiles) {
|
|
246
|
+
if (cacheTile.lastVisitTime < frameState.frameNumber) {
|
|
247
|
+
if (!cacheTile.expired) expiredTiles.push(cacheTile)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
expiredTiles.sort((a, b) => a.lastVisitTime - b.lastVisitTime)
|
|
251
|
+
if (expiredTiles.length > 100) {
|
|
252
|
+
for (const expiredTile of expiredTiles) {
|
|
253
|
+
expiredTile.unload()
|
|
254
|
+
expiredTile.expired = true
|
|
255
|
+
if (expiredTiles.length <= 50) break
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
destroy() {
|
|
261
|
+
const scene = this.scene
|
|
262
|
+
const rootTiles = this._rootTiles
|
|
263
|
+
this.scene = null
|
|
264
|
+
if (scene && scene.primitives.contains(this)) {
|
|
265
|
+
scene.primitives.remove(this)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (rootTiles) {
|
|
269
|
+
for (const tile of rootTiles) {
|
|
270
|
+
tile.destroy()
|
|
271
|
+
}
|
|
272
|
+
rootTiles.length = 0
|
|
273
|
+
this._rootTiles = null
|
|
274
|
+
}
|
|
275
|
+
if (this._cacheTiles) {
|
|
276
|
+
this._cacheTiles.length = 0
|
|
277
|
+
this._cacheTiles = null
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (this.sources) {
|
|
281
|
+
for (const key in this.sources) {
|
|
282
|
+
if (Object.hasOwnProperty.call(this.sources, key)) {
|
|
283
|
+
const source = this.sources[key]
|
|
284
|
+
source.destroy()
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
this.sources = null
|
|
288
|
+
}
|
|
289
|
+
this._styleLayers = null
|
|
290
|
+
|
|
291
|
+
if (this._renderList) {
|
|
292
|
+
this._renderList.destroy()
|
|
293
|
+
this._renderList = null
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (this._taskProcessor && !this._taskProcessor.isDestroyed()) {
|
|
297
|
+
this._taskProcessor.destroy()
|
|
298
|
+
this._taskProcessor = null
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (this._tilesToUpdate) {
|
|
302
|
+
this._tilesToUpdate.length = 0
|
|
303
|
+
this._tilesToUpdate = null
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (this._tilesToRender) {
|
|
307
|
+
this._tilesToRender.length = 0
|
|
308
|
+
this._tilesToRender = null
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (this._tileIdFbo) {
|
|
312
|
+
this._tileIdFbo.destroy()
|
|
313
|
+
this.tileIdTexture = null
|
|
314
|
+
this._tileIdFbo = null
|
|
315
|
+
this._idClearCommand = null
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
this._styleJson = null
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
isDestroyed() {
|
|
322
|
+
return false
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* 遍历LOD四叉树,获取所有可见瓦片,取离相机最近的一个瓦片的 z 作为全局缩放参数 zoom
|
|
328
|
+
* @param {Cesium.FrameState} frameState
|
|
329
|
+
* @param {VectorTileset} tileset
|
|
330
|
+
* @returns
|
|
331
|
+
*/
|
|
332
|
+
function getTilesToUpdate(frameState, tileset) {
|
|
333
|
+
const queue = [...tileset._rootTiles]
|
|
334
|
+
const tilesToUpdate = tileset._tilesToUpdate
|
|
335
|
+
let zoom = 24,
|
|
336
|
+
nearDist = Infinity
|
|
337
|
+
const visitor = {
|
|
338
|
+
//当see大于阈值,继续查找子级瓦片
|
|
339
|
+
visitChildren(tile) {
|
|
340
|
+
if (tile.z >= tileset.maximumLevel) {
|
|
341
|
+
if (tile.distanceToCamera < nearDist) {
|
|
342
|
+
nearDist = tile.distanceToCamera
|
|
343
|
+
zoom = tile.z
|
|
344
|
+
}
|
|
345
|
+
return tilesToUpdate.push(tile)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (tile.children.length == 0) {
|
|
349
|
+
tile.createChildren()
|
|
350
|
+
for (const child of tile.children) {
|
|
351
|
+
tileset._cacheTiles.push(child)
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
for (const child of tile.children) {
|
|
355
|
+
queue.push(child)
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
//否则使用当前瓦片填充视口
|
|
359
|
+
accept(tile) {
|
|
360
|
+
if (tile.distanceToCamera < nearDist) {
|
|
361
|
+
nearDist = tile.distanceToCamera
|
|
362
|
+
zoom = tile.z
|
|
363
|
+
}
|
|
364
|
+
tilesToUpdate.push(tile)
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
tilesToUpdate.length = 0
|
|
369
|
+
|
|
370
|
+
do {
|
|
371
|
+
const tile = queue.shift()
|
|
372
|
+
tile.visit(frameState, visitor)
|
|
373
|
+
} while (queue.length > 0)
|
|
374
|
+
|
|
375
|
+
tileset.zoom = zoom
|
|
376
|
+
|
|
377
|
+
return tilesToUpdate
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* 获取可渲染瓦片
|
|
382
|
+
* @param {VectorTileLOD[]} tilesToUpdate
|
|
383
|
+
* @param {VectorTileLOD[]} tilesToRender
|
|
384
|
+
* @returns
|
|
385
|
+
*/
|
|
386
|
+
function getTilesToRender(tilesToUpdate, tilesToRender) {
|
|
387
|
+
const cache = new Map()
|
|
388
|
+
for (const newTile of tilesToUpdate) {
|
|
389
|
+
if (newTile.renderable) {
|
|
390
|
+
cache.set(newTile, true)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
//在当前可渲染瓦片队列中,找出上一帧所有可渲染瓦片的后代节点瓦片,只有当后代节点瓦片都可渲染才被替代
|
|
395
|
+
const descendantsList = []
|
|
396
|
+
for (let i = 0; i < tilesToRender.length; i++) {
|
|
397
|
+
const oldTile = tilesToRender[i]
|
|
398
|
+
|
|
399
|
+
oldTile.renderable = cache.has(oldTile)
|
|
400
|
+
if (oldTile.renderable) continue //前后两帧都可见,不需要特殊处理
|
|
401
|
+
|
|
402
|
+
const descendants = {
|
|
403
|
+
tiles: [],
|
|
404
|
+
total: 0,
|
|
405
|
+
renderable: 0
|
|
406
|
+
}
|
|
407
|
+
descendantsList[i] = descendants
|
|
408
|
+
|
|
409
|
+
for (const newTile of tilesToUpdate) {
|
|
410
|
+
const dz = newTile.z - oldTile.z
|
|
411
|
+
if (dz === 0) {
|
|
412
|
+
continue
|
|
413
|
+
} else if (dz > 0) {
|
|
414
|
+
//针对需要后代瓦片替换祖先瓦片的情况:先记录所有可见的后代瓦片,并统计可渲染后代瓦片数量
|
|
415
|
+
const scale = Math.pow(2, dz),
|
|
416
|
+
newAncestorX = Math.floor(newTile.x / scale),
|
|
417
|
+
newAncestorY = Math.floor(newTile.y / scale)
|
|
418
|
+
|
|
419
|
+
if (newAncestorX === oldTile.x && newAncestorY === oldTile.y) {
|
|
420
|
+
descendants.total++
|
|
421
|
+
descendants.tiles.push(newTile)
|
|
422
|
+
if (newTile.renderable) descendants.renderable++
|
|
423
|
+
}
|
|
424
|
+
} else {
|
|
425
|
+
//针对需要祖先瓦片覆盖后代瓦片的情况:祖先瓦片可渲染则显示,否则继续显示后代瓦片
|
|
426
|
+
const scale = Math.pow(2, -dz),
|
|
427
|
+
oldAncestorX = Math.floor(oldTile.x / scale),
|
|
428
|
+
oldAncestorY = Math.floor(oldTile.y / scale)
|
|
429
|
+
|
|
430
|
+
if (oldAncestorX === newTile.x && oldAncestorY === newTile.y) {
|
|
431
|
+
oldTile.renderable = !newTile.renderable
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
//针对后代瓦片替换祖先瓦片的情况:只有所有可见的后代瓦片都可渲染,才显示后代瓦片,否则继续显示祖先瓦片
|
|
438
|
+
for (let i = 0; i < tilesToRender.length; i++) {
|
|
439
|
+
const oldTile = tilesToRender[i]
|
|
440
|
+
const descendants = descendantsList[i]
|
|
441
|
+
if (descendants && descendants.total) {
|
|
442
|
+
const descendantsRenderable = descendants.total === descendants.renderable
|
|
443
|
+
oldTile.renderable = !descendantsRenderable
|
|
444
|
+
for (const descendantTile of descendants.tiles) {
|
|
445
|
+
descendantTile.renderable = descendantsRenderable
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
//从 tilesToUpdate 和 tilesToRender 中筛选最终可渲染的瓦片
|
|
451
|
+
|
|
452
|
+
cache.clear()
|
|
453
|
+
|
|
454
|
+
let length = tilesToRender.length
|
|
455
|
+
for (let i = 0; i < length; i++) {
|
|
456
|
+
const tileToRender = tilesToRender.shift()
|
|
457
|
+
if (tileToRender.renderable) {
|
|
458
|
+
tilesToRender.push(tileToRender)
|
|
459
|
+
cache.set(tileToRender, true)
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
length = tilesToUpdate.length
|
|
464
|
+
for (let i = 0; i < length; i++) {
|
|
465
|
+
const tileToUpdate = tilesToUpdate[i]
|
|
466
|
+
if (tileToUpdate.renderable && !cache.has(tileToUpdate)) {
|
|
467
|
+
tilesToRender.push(tileToUpdate)
|
|
468
|
+
cache.set(tileToUpdate, true)
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
return tilesToRender
|
|
473
|
+
}
|