@mesh3d/cesium-vectortile-gl 0.4.6 → 0.5.1
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/README.md +29 -0
- package/Source/VectorTileset.js +61 -0
- package/Source/layers/BackgroundRenderLayer.js +15 -0
- package/Source/layers/FillRenderLayer.js +29 -0
- package/Source/layers/IRenderLayer.js +13 -0
- package/Source/layers/LineRenderLayer.js +43 -0
- package/Source/layers/SymbolRenderLayer.js +35 -0
- package/Source/layers/visualizers/FillLayerVisualizer.js +11 -2
- package/Source/layers/visualizers/LineLayerVisualizer.js +11 -2
- package/Source/layers/visualizers/SymbolLayerVisualizer.js +17 -3
- package/Source/style/StyleLayer.js +27 -0
- package/Source/style/StyleLayerProperties.js +22 -0
- package/dist/THIRD-PARTY-LICENSES.txt +29 -29
- package/dist/cvt-gl.js +1458 -1293
- 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/package.json +6 -15
- package/style-edit.html +26 -0
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
- ✅ **GPU 精准剔除**:利用 FBO + RTT 技术生成瓦片 ID 纹理,在 GPU 中高效剔除不可见矢量片段
|
|
14
14
|
- ✅ **高度可扩展**:提供清晰接口,轻松接入新数据源(如 TopoJSON)或自定义图层类型(如热力图、流线)
|
|
15
15
|
- ✅ **文字符号自动避让**:使用 `maplibre-gl` `GridIndex`类,结合 Cesium.Label 屏幕空间位置和包围盒计算API,实现符号碰撞检测(自动避让)
|
|
16
|
+
- ✅ **样式动态修改**:提供`setLayoutProperty`、`setPaintProperty`、`setFilter`等`样式修改API`,可动态控制图层`显隐`、`颜色`、`透明度`
|
|
16
17
|
|
|
17
18
|
#### 🧠 技术栈亮点
|
|
18
19
|
|
|
@@ -83,6 +84,34 @@ const tileset = new VectorTileset({
|
|
|
83
84
|
viewer.scene.primitives.add(tileset)
|
|
84
85
|
```
|
|
85
86
|
|
|
87
|
+
### 样式修改示例
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
tileset.readyEvent.addEventListener(() => {
|
|
91
|
+
// 1、修改绘制属性(颜色、透明度),不会触发强制刷新,实时变化
|
|
92
|
+
tileset.setPaintProperty('background', 'background-color', 'skyblue')
|
|
93
|
+
tileset.setPaintProperty('geolines', 'line-color', 'green')
|
|
94
|
+
tileset.setPaintProperty('us_states:fill', 'fill-color', 'red')
|
|
95
|
+
tileset.setPaintProperty('countries-label', 'text-color', 'blue')
|
|
96
|
+
|
|
97
|
+
// 2、修改布局属性,除 visibility 外,都会触发强制刷新
|
|
98
|
+
// 2.1、布局属性修改:图层显隐,不会触发强制刷新
|
|
99
|
+
tileset.setLayoutProperty('coastline', 'visibility', 'none')
|
|
100
|
+
// 2.2、布局属性修改(非visibility):字体大小修改,会触发强制刷新
|
|
101
|
+
tileset.setLayoutProperty('countries-label', 'text-size', {
|
|
102
|
+
stops: [
|
|
103
|
+
[2, 12],
|
|
104
|
+
[4, 16],
|
|
105
|
+
[6, 20]
|
|
106
|
+
]
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// 3、修改过滤器。
|
|
110
|
+
//和setLayoutProperty一样(visibility例外)会触发强制刷新
|
|
111
|
+
tileset.setFilter('geolines', null)
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
86
115
|
### 可选:Web Worker 多线程瓦片处理
|
|
87
116
|
|
|
88
117
|
将瓦片解析、坐标转换、几何构建放到子线程,减轻主线程卡顿。不传 `workerUrl` 时仍走主线程。
|
package/Source/VectorTileset.js
CHANGED
|
@@ -33,6 +33,7 @@ export class VectorTileset {
|
|
|
33
33
|
this._tilesToRender = []
|
|
34
34
|
/**@type {StyleLayer[]} */
|
|
35
35
|
this._styleLayers = []
|
|
36
|
+
this._styleLayerIndexMap = new Map()
|
|
36
37
|
/**@type {VectorTileRenderList} */
|
|
37
38
|
this._renderList = new VectorTileRenderList(this._styleLayers)
|
|
38
39
|
this.numLoading = 0
|
|
@@ -95,6 +96,7 @@ export class VectorTileset {
|
|
|
95
96
|
//初始化样式图层
|
|
96
97
|
for (let i = 0; i < style.layers.length; i++) {
|
|
97
98
|
this._styleLayers[i] = new StyleLayer(style.layers[i])
|
|
99
|
+
this._styleLayerIndexMap.set(style.layers[i].id, i)
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
//创建顶级瓦片LOD
|
|
@@ -257,6 +259,65 @@ export class VectorTileset {
|
|
|
257
259
|
}
|
|
258
260
|
}
|
|
259
261
|
|
|
262
|
+
//样式编辑API
|
|
263
|
+
|
|
264
|
+
setLayoutProperty(layerId, name, value) {
|
|
265
|
+
const styleLayerIndexMap = this._styleLayerIndexMap
|
|
266
|
+
if (!styleLayerIndexMap.has(layerId)) {
|
|
267
|
+
warnOnce(`不存在图层:${layerId}`)
|
|
268
|
+
return false
|
|
269
|
+
}
|
|
270
|
+
const layerIndex = styleLayerIndexMap.get(layerId)
|
|
271
|
+
const styleLayer = this._styleLayers[layerIndex]
|
|
272
|
+
const changed = styleLayer.setLayoutProperty(name, value)
|
|
273
|
+
//强制更新
|
|
274
|
+
if (changed && name !== 'visibility') {
|
|
275
|
+
this._forceUpdate()
|
|
276
|
+
}
|
|
277
|
+
return changed
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
setPaintProperty(layerId, name, value) {
|
|
281
|
+
const styleLayerIndexMap = this._styleLayerIndexMap
|
|
282
|
+
if (!styleLayerIndexMap.has(layerId)) {
|
|
283
|
+
warnOnce(`不存在图层:${layerId}`)
|
|
284
|
+
return false
|
|
285
|
+
}
|
|
286
|
+
const layerIndex = styleLayerIndexMap.get(layerId)
|
|
287
|
+
const styleLayer = this._styleLayers[layerIndex]
|
|
288
|
+
return styleLayer.setPaintProperty(name, value)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
setFilter(layerId, filter) {
|
|
292
|
+
const styleLayerIndexMap = this._styleLayerIndexMap
|
|
293
|
+
if (!styleLayerIndexMap.has(layerId)) {
|
|
294
|
+
warnOnce(`不存在图层:${layerId}`)
|
|
295
|
+
return false
|
|
296
|
+
}
|
|
297
|
+
const layerIndex = styleLayerIndexMap.get(layerId)
|
|
298
|
+
const styleLayer = this._styleLayers[layerIndex]
|
|
299
|
+
const changed = styleLayer.setFilter(filter)
|
|
300
|
+
if (changed) {
|
|
301
|
+
this._forceUpdate()
|
|
302
|
+
}
|
|
303
|
+
return changed
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
//强制更新
|
|
307
|
+
_forceUpdate() {
|
|
308
|
+
for (const cacheTile of this._cacheTiles) {
|
|
309
|
+
cacheTile.unload()
|
|
310
|
+
}
|
|
311
|
+
for (const cacheTile of this._tilesToRender) {
|
|
312
|
+
cacheTile.unload()
|
|
313
|
+
}
|
|
314
|
+
for (const cacheTile of this._tilesToUpdate) {
|
|
315
|
+
cacheTile.unload()
|
|
316
|
+
}
|
|
317
|
+
this._tilesToRender.length = 0
|
|
318
|
+
this._tilesToUpdate.length = 0
|
|
319
|
+
}
|
|
320
|
+
|
|
260
321
|
destroy() {
|
|
261
322
|
const scene = this.scene
|
|
262
323
|
const rootTiles = this._rootTiles
|
|
@@ -80,6 +80,21 @@ export class BackgroundRenderLayer extends IRenderLayer {
|
|
|
80
80
|
|
|
81
81
|
frameState.commandList = preCommandList
|
|
82
82
|
}
|
|
83
|
+
if (this.primitive && this.paintNeedsUpdate) {
|
|
84
|
+
const style = this.style,
|
|
85
|
+
tile = this.tile
|
|
86
|
+
const color = style.convertColor(
|
|
87
|
+
style.paint.getDataConstValue('background-color', tile.z)
|
|
88
|
+
)
|
|
89
|
+
const opacity = style.paint.getDataConstValue(
|
|
90
|
+
'background-opacity',
|
|
91
|
+
tile.z
|
|
92
|
+
)
|
|
93
|
+
color.alpha *= opacity
|
|
94
|
+
this.primitive.appearance.material.uniforms.color = color
|
|
95
|
+
|
|
96
|
+
this.paintNeedsUpdate = false
|
|
97
|
+
}
|
|
83
98
|
}
|
|
84
99
|
|
|
85
100
|
destroy() {
|
|
@@ -10,7 +10,36 @@ export class FillRenderLayer extends IRenderLayer {
|
|
|
10
10
|
*/
|
|
11
11
|
update(frameState, tileset) {
|
|
12
12
|
//可以在这里实现同步样式,动态更新图层颜色等样式
|
|
13
|
+
if (this.paintNeedsUpdate) {
|
|
14
|
+
const style = this.style,
|
|
15
|
+
tile = this.tile,
|
|
16
|
+
batchTable = this._batchTable
|
|
13
17
|
|
|
18
|
+
for (const feature of this.features) {
|
|
19
|
+
const fillColor = style.convertColor(
|
|
20
|
+
style.paint.getDataValue('fill-color', tile.z, feature)
|
|
21
|
+
)
|
|
22
|
+
const fillOpacity = style.paint.getDataValue(
|
|
23
|
+
'fill-opacity',
|
|
24
|
+
tile.z,
|
|
25
|
+
feature
|
|
26
|
+
)
|
|
27
|
+
feature.fillColor = fillColor
|
|
28
|
+
feature.fillOpacity = fillOpacity
|
|
29
|
+
|
|
30
|
+
const batchId = feature.batchId
|
|
31
|
+
const colorBytes = fillColor.toBytes()
|
|
32
|
+
colorBytes[3] = Math.floor(colorBytes[3] * fillOpacity)
|
|
33
|
+
batchTable.setBatchedAttribute(batchId, 0, {
|
|
34
|
+
x: colorBytes[0],
|
|
35
|
+
y: colorBytes[1],
|
|
36
|
+
z: colorBytes[2],
|
|
37
|
+
w: colorBytes[3]
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.paintNeedsUpdate = false
|
|
42
|
+
}
|
|
14
43
|
super.update(frameState, tileset)
|
|
15
44
|
}
|
|
16
45
|
}
|
|
@@ -82,6 +82,10 @@ export class IRenderLayer {
|
|
|
82
82
|
* @type {'none'|'done'|'error'}
|
|
83
83
|
*/
|
|
84
84
|
this.state = 'none'
|
|
85
|
+
/**
|
|
86
|
+
* 绘制(paint)属性版本号,用于监听绘制属性变化
|
|
87
|
+
*/
|
|
88
|
+
this.paintVersion = styleLayer.paintVersion
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
get id() {
|
|
@@ -92,6 +96,15 @@ export class IRenderLayer {
|
|
|
92
96
|
return this.style.type
|
|
93
97
|
}
|
|
94
98
|
|
|
99
|
+
get paintNeedsUpdate() {
|
|
100
|
+
return this.paintVersion !== this.style.paintVersion
|
|
101
|
+
}
|
|
102
|
+
set paintNeedsUpdate(val) {
|
|
103
|
+
if (!val) {
|
|
104
|
+
this.paintVersion = this.style.paintVersion
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
/**
|
|
96
109
|
* 更渲染图层,可在该方法内实现绘图命令构建、动态样式更新等图层渲染准备相关功能。该方法可以被子类重写或复用
|
|
97
110
|
* @param {Cesium.FrameState} frameState
|
|
@@ -5,6 +5,7 @@ import { IRenderLayer } from './IRenderLayer'
|
|
|
5
5
|
import { registerRenderLayer } from './registerRenderLayer'
|
|
6
6
|
import { VectorTileLOD } from '../VectorTileLOD'
|
|
7
7
|
import { LineLayerVisualizer } from './visualizers/LineLayerVisualizer'
|
|
8
|
+
import { warnOnce } from 'maplibre-gl/src/util/util'
|
|
8
9
|
|
|
9
10
|
export class LineRenderLayer extends IRenderLayer {
|
|
10
11
|
/**
|
|
@@ -91,7 +92,49 @@ export class LineRenderLayer extends IRenderLayer {
|
|
|
91
92
|
// }
|
|
92
93
|
// if (this.primitive && this.primitive.length) {
|
|
93
94
|
// this.primitive.update(frameState)
|
|
95
|
+
// this._batchTable = primitive._batchTable
|
|
94
96
|
// }
|
|
97
|
+
if (this.paintNeedsUpdate) {
|
|
98
|
+
const style = this.style,
|
|
99
|
+
tile = this.tile,
|
|
100
|
+
batchTable = this._batchTable
|
|
101
|
+
|
|
102
|
+
for (const feature of this.features) {
|
|
103
|
+
const lineWidth = style.paint.getDataValue(
|
|
104
|
+
'line-width',
|
|
105
|
+
tile.z,
|
|
106
|
+
feature
|
|
107
|
+
)
|
|
108
|
+
const lineColor = style.convertColor(
|
|
109
|
+
style.paint.getDataValue('line-color', tile.z, feature)
|
|
110
|
+
)
|
|
111
|
+
const lineOpacity = style.paint.getDataValue(
|
|
112
|
+
'line-opacity',
|
|
113
|
+
tile.z,
|
|
114
|
+
feature
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
if (lineWidth !== feature.lineWidth) {
|
|
118
|
+
warnOnce('不支持动态修改 line 图层样式属性:line-width')
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
feature.lineColor = lineColor
|
|
122
|
+
feature.lineOpacity = lineOpacity
|
|
123
|
+
feature.lineWidth = lineWidth
|
|
124
|
+
|
|
125
|
+
const batchId = feature.batchId
|
|
126
|
+
const colorBytes = lineColor.toBytes()
|
|
127
|
+
colorBytes[3] = Math.floor(colorBytes[3] * lineOpacity)
|
|
128
|
+
batchTable.setBatchedAttribute(batchId, 0, {
|
|
129
|
+
x: colorBytes[0],
|
|
130
|
+
y: colorBytes[1],
|
|
131
|
+
z: colorBytes[2],
|
|
132
|
+
w: colorBytes[3]
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.paintNeedsUpdate = false
|
|
137
|
+
}
|
|
95
138
|
super.update(frameState, tileset)
|
|
96
139
|
}
|
|
97
140
|
|
|
@@ -22,6 +22,41 @@ export class SymbolRenderLayer extends IRenderLayer {
|
|
|
22
22
|
*/
|
|
23
23
|
update(frameState, tileset) {
|
|
24
24
|
//TODO:动态更新符号样式
|
|
25
|
+
if (this.paintNeedsUpdate) {
|
|
26
|
+
const style = this.style,
|
|
27
|
+
tile = this.tile
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < this.features.length; i++) {
|
|
30
|
+
const feature = this.features[i]
|
|
31
|
+
const label = this.labels[i]
|
|
32
|
+
|
|
33
|
+
const textColor = style.convertColor(
|
|
34
|
+
style.paint.getDataValue('text-color', tile.z, feature)
|
|
35
|
+
)
|
|
36
|
+
const outlineColor = style.convertColor(
|
|
37
|
+
style.paint.getDataValue('text-halo-color', tile.z, feature)
|
|
38
|
+
)
|
|
39
|
+
const outlineWidth = style.paint.getDataValue(
|
|
40
|
+
'text-halo-width',
|
|
41
|
+
tile.z,
|
|
42
|
+
feature
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
feature.textColor = textColor
|
|
46
|
+
feature.outlineColor = outlineColor
|
|
47
|
+
feature.outlineWidth = outlineWidth
|
|
48
|
+
|
|
49
|
+
label.fillColor = textColor
|
|
50
|
+
label.style = outlineWidth && Cesium.LabelStyle.FILL_AND_OUTLINE
|
|
51
|
+
label.outlineWidth = outlineWidth * feature.textSize
|
|
52
|
+
label.outlineColor = outlineColor
|
|
53
|
+
|
|
54
|
+
label._baseFillColor = label.fillColor.clone()
|
|
55
|
+
label._baseOutlineColor = label.outlineColor.clone()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.paintNeedsUpdate = false
|
|
59
|
+
}
|
|
25
60
|
|
|
26
61
|
super.update(frameState, tileset)
|
|
27
62
|
}
|
|
@@ -92,6 +92,7 @@ export class FillLayerVisualizer extends ILayerVisualizer {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
scope.addFeature(fillFeature, granularity)
|
|
95
|
+
layer.features.push(fillFeature)
|
|
95
96
|
|
|
96
97
|
featureId++
|
|
97
98
|
}
|
|
@@ -427,6 +428,9 @@ void main()
|
|
|
427
428
|
*/
|
|
428
429
|
onBatchTableCreated(batchTable) {
|
|
429
430
|
this._batchTable = batchTable
|
|
431
|
+
for (const layer of this.layers) {
|
|
432
|
+
layer._batchTable = batchTable
|
|
433
|
+
}
|
|
430
434
|
}
|
|
431
435
|
|
|
432
436
|
/**
|
|
@@ -511,6 +515,9 @@ void main()
|
|
|
511
515
|
if (err.stack) console.trace(err.stack)
|
|
512
516
|
else console.error(err)
|
|
513
517
|
return
|
|
518
|
+
} finally {
|
|
519
|
+
//恢复系统的 commandList
|
|
520
|
+
frameState.commandList = preCommandList
|
|
514
521
|
}
|
|
515
522
|
|
|
516
523
|
//使用合批后的 drawCommand 创建副本,为渲染图层分配 drawCommand
|
|
@@ -522,10 +529,12 @@ void main()
|
|
|
522
529
|
this.setState('error')
|
|
523
530
|
}
|
|
524
531
|
|
|
525
|
-
//恢复系统的 commandList
|
|
526
|
-
frameState.commandList = preCommandList
|
|
527
532
|
this.geometryInstances = []
|
|
528
533
|
}
|
|
534
|
+
|
|
535
|
+
if (this._batchTable && this._batchTable._batchValuesDirty) {
|
|
536
|
+
this._batchTable.update(frameState)
|
|
537
|
+
}
|
|
529
538
|
}
|
|
530
539
|
|
|
531
540
|
destroy() {
|
|
@@ -92,6 +92,7 @@ export class LineLayerVisualizer extends ILayerVisualizer {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
scope.addFeature(lineFeature)
|
|
95
|
+
layer.features.push(lineFeature)
|
|
95
96
|
|
|
96
97
|
featureId++
|
|
97
98
|
}
|
|
@@ -560,6 +561,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput)
|
|
|
560
561
|
*/
|
|
561
562
|
onBatchTableCreated(batchTable) {
|
|
562
563
|
this._batchTable = batchTable
|
|
564
|
+
for (const layer of this.layers) {
|
|
565
|
+
layer._batchTable = batchTable
|
|
566
|
+
}
|
|
563
567
|
}
|
|
564
568
|
|
|
565
569
|
/**
|
|
@@ -667,6 +671,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput)
|
|
|
667
671
|
if (err.stack) console.trace(err.stack)
|
|
668
672
|
else console.error(err)
|
|
669
673
|
return
|
|
674
|
+
} finally {
|
|
675
|
+
//恢复系统的 commandList
|
|
676
|
+
frameState.commandList = preCommandList
|
|
670
677
|
}
|
|
671
678
|
|
|
672
679
|
//使用合批后的 drawCommand 创建副本,为渲染图层分配 drawCommand
|
|
@@ -678,14 +685,16 @@ czm_material czm_getMaterial(czm_materialInput materialInput)
|
|
|
678
685
|
this.setState('error')
|
|
679
686
|
}
|
|
680
687
|
|
|
681
|
-
//恢复系统的 commandList
|
|
682
|
-
frameState.commandList = preCommandList
|
|
683
688
|
this.geometryInstances = []
|
|
684
689
|
}
|
|
685
690
|
|
|
686
691
|
if (this.primitive && frameState.camera.pitch > -1.309) {
|
|
687
692
|
warnOnce('line图层:不支持透视,建议保持相机俯仰角(pitch)小于 -75 度')
|
|
688
693
|
}
|
|
694
|
+
|
|
695
|
+
if (this._batchTable && this._batchTable._batchValuesDirty) {
|
|
696
|
+
this._batchTable.update(frameState)
|
|
697
|
+
}
|
|
689
698
|
}
|
|
690
699
|
|
|
691
700
|
destroy() {
|
|
@@ -82,7 +82,8 @@ export class SymbolLayerVisualizer extends ILayerVisualizer {
|
|
|
82
82
|
outlineWidth,
|
|
83
83
|
outlineColor,
|
|
84
84
|
textOffset,
|
|
85
|
-
textOrigin
|
|
85
|
+
textOrigin,
|
|
86
|
+
properties
|
|
86
87
|
) {
|
|
87
88
|
if (
|
|
88
89
|
!Cesium.Rectangle.contains(
|
|
@@ -116,6 +117,17 @@ export class SymbolLayerVisualizer extends ILayerVisualizer {
|
|
|
116
117
|
label.batchId = labels.length
|
|
117
118
|
labels.push(label)
|
|
118
119
|
layer.labels.push(label)
|
|
120
|
+
layer.features.push({
|
|
121
|
+
text,
|
|
122
|
+
font,
|
|
123
|
+
textSize,
|
|
124
|
+
textColor,
|
|
125
|
+
outlineWidth,
|
|
126
|
+
outlineColor,
|
|
127
|
+
textOffset,
|
|
128
|
+
textOrigin,
|
|
129
|
+
properties
|
|
130
|
+
})
|
|
119
131
|
}
|
|
120
132
|
|
|
121
133
|
for (const sourceFeature of features) {
|
|
@@ -229,7 +241,8 @@ export class SymbolLayerVisualizer extends ILayerVisualizer {
|
|
|
229
241
|
outlineWidth,
|
|
230
242
|
outlineColor,
|
|
231
243
|
textOffset,
|
|
232
|
-
textOrigin
|
|
244
|
+
textOrigin,
|
|
245
|
+
properties
|
|
233
246
|
)
|
|
234
247
|
} else if (geometryType == 'MultiPoint') {
|
|
235
248
|
coordinates.forEach(coord => {
|
|
@@ -242,7 +255,8 @@ export class SymbolLayerVisualizer extends ILayerVisualizer {
|
|
|
242
255
|
outlineWidth,
|
|
243
256
|
outlineColor,
|
|
244
257
|
textOffset,
|
|
245
|
-
textOrigin
|
|
258
|
+
textOrigin,
|
|
259
|
+
properties
|
|
246
260
|
)
|
|
247
261
|
})
|
|
248
262
|
} else {
|
|
@@ -21,6 +21,33 @@ export class StyleLayer {
|
|
|
21
21
|
if (layer.filter) {
|
|
22
22
|
this.filter = featureFilter(layer.filter)
|
|
23
23
|
}
|
|
24
|
+
this.paintVersion = 0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setLayoutProperty(name, value) {
|
|
28
|
+
return this.layout.setProperty(name, value)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
setPaintProperty(name, value) {
|
|
32
|
+
const changed = this.paint.setProperty(name, value)
|
|
33
|
+
if (changed) {
|
|
34
|
+
this.paintVersion++
|
|
35
|
+
}
|
|
36
|
+
return changed
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setFilter(filter) {
|
|
40
|
+
if (!filter) {
|
|
41
|
+
const changed = Cesium.defined(this.filter)
|
|
42
|
+
this.filter = null
|
|
43
|
+
delete this.data.filter
|
|
44
|
+
return changed
|
|
45
|
+
} else if (JSON.stringify(this.data.filter) !== JSON.stringify(filter)) {
|
|
46
|
+
this.data.filter = filter
|
|
47
|
+
this.filter = featureFilter(filter)
|
|
48
|
+
return true
|
|
49
|
+
}
|
|
50
|
+
return false
|
|
24
51
|
}
|
|
25
52
|
|
|
26
53
|
/**
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { expression, latest } from '@maplibre/maplibre-gl-style-spec'
|
|
2
|
+
import { warnOnce } from 'maplibre-gl/src/util/util'
|
|
2
3
|
|
|
3
4
|
export class StyleLayerProperties {
|
|
4
5
|
constructor(groupName, styleProperties = {}) {
|
|
5
6
|
this.data = styleProperties
|
|
6
7
|
/**@type {Map<string,import('@maplibre/maplibre-gl-style-spec').StylePropertyExpression>} */
|
|
7
8
|
this.props = new Map()
|
|
9
|
+
this.groupName = groupName
|
|
8
10
|
|
|
9
11
|
const groupReference = latest[groupName]
|
|
10
12
|
for (const key in groupReference) {
|
|
@@ -20,6 +22,26 @@ export class StyleLayerProperties {
|
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
setProperty(name, value) {
|
|
26
|
+
const groupReference = latest[this.groupName]
|
|
27
|
+
if (Object.hasOwnProperty.call(groupReference, name)) {
|
|
28
|
+
const reference = groupReference[name]
|
|
29
|
+
const oldValue = this.data[name]
|
|
30
|
+
if (oldValue === value) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
const property = expression.normalizePropertyExpression(
|
|
34
|
+
!Cesium.defined(value) ? reference.default : value,
|
|
35
|
+
reference
|
|
36
|
+
)
|
|
37
|
+
this.props.set(name, property)
|
|
38
|
+
return true
|
|
39
|
+
} else {
|
|
40
|
+
warnOnce(`maplibre样式规范不支持属性:${this.groupName}.${name}`)
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
23
45
|
/**
|
|
24
46
|
* Replace tokens in a string template with values in an object
|
|
25
47
|
*
|
|
@@ -704,34 +704,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
704
704
|
|
|
705
705
|
---
|
|
706
706
|
|
|
707
|
-
Name: earcut
|
|
708
|
-
Version: 3.0.2
|
|
709
|
-
License: ISC
|
|
710
|
-
Private: false
|
|
711
|
-
Description: The fastest and smallest JavaScript polygon triangulation library for your WebGL apps
|
|
712
|
-
Repository: git://github.com/mapbox/earcut.git
|
|
713
|
-
Author: Vladimir Agafonkin
|
|
714
|
-
License Copyright:
|
|
715
|
-
===
|
|
716
|
-
|
|
717
|
-
ISC License
|
|
718
|
-
|
|
719
|
-
Copyright (c) 2024, Mapbox
|
|
720
|
-
|
|
721
|
-
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
722
|
-
with or without fee is hereby granted, provided that the above copyright notice
|
|
723
|
-
and this permission notice appear in all copies.
|
|
724
|
-
|
|
725
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
726
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
727
|
-
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
728
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
729
|
-
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
730
|
-
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
731
|
-
THIS SOFTWARE.
|
|
732
|
-
|
|
733
|
-
---
|
|
734
|
-
|
|
735
707
|
Name: @mapbox/unitbezier
|
|
736
708
|
Version: 0.0.1
|
|
737
709
|
License: BSD-2-Clause
|
|
@@ -769,4 +741,32 @@ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
769
741
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
770
742
|
|
|
771
743
|
Ported from Webkit
|
|
772
|
-
http://svn.webkit.org/repository/webkit/trunk/Source/WebCore/platform/graphics/UnitBezier.h
|
|
744
|
+
http://svn.webkit.org/repository/webkit/trunk/Source/WebCore/platform/graphics/UnitBezier.h
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
Name: earcut
|
|
749
|
+
Version: 3.0.2
|
|
750
|
+
License: ISC
|
|
751
|
+
Private: false
|
|
752
|
+
Description: The fastest and smallest JavaScript polygon triangulation library for your WebGL apps
|
|
753
|
+
Repository: git://github.com/mapbox/earcut.git
|
|
754
|
+
Author: Vladimir Agafonkin
|
|
755
|
+
License Copyright:
|
|
756
|
+
===
|
|
757
|
+
|
|
758
|
+
ISC License
|
|
759
|
+
|
|
760
|
+
Copyright (c) 2024, Mapbox
|
|
761
|
+
|
|
762
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
763
|
+
with or without fee is hereby granted, provided that the above copyright notice
|
|
764
|
+
and this permission notice appear in all copies.
|
|
765
|
+
|
|
766
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
767
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
768
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
769
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
770
|
+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
771
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
772
|
+
THIS SOFTWARE.
|