@mapwhit/tilerenderer 0.51.1 → 0.52.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/build/min/package.json +1 -1
- package/package.json +6 -6
- package/src/data/bucket/circle_bucket.js +12 -3
- package/src/data/bucket/fill_bucket.js +13 -3
- package/src/data/bucket/fill_extrusion_bucket.js +13 -3
- package/src/data/bucket/line_bucket.js +13 -3
- package/src/data/bucket/symbol_bucket.js +14 -4
- package/src/data/program_configuration.js +21 -21
- package/src/render/glyph_atlas.js +1 -1
- package/src/render/image_atlas.js +1 -1
- package/src/render/image_manager.js +1 -1
- package/src/source/geojson_source.js +2 -1
- package/src/source/geojson_worker_source.js +4 -4
- package/src/source/vector_tile_source.js +2 -1
- package/src/source/vector_tile_worker_source.js +1 -0
- package/src/source/worker_tile.js +8 -6
- package/src/style/evaluation_parameters.js +6 -4
- package/src/style/properties.js +4 -0
- package/src/style/style.js +82 -3
- package/src/style/style_layer.js +56 -1
- package/src/style-spec/feature_filter/index.js +13 -4
- package/src/style-spec/reference/v8.json +53 -13
- package/src/ui/map.js +24 -1
- package/src/util/transfer_registry.js +1 -0
package/build/min/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapwhit/tilerenderer",
|
|
3
3
|
"description": "A WebGL interactive maps library",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.52.1",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/index.js",
|
|
7
7
|
"./worker": "./src/worker.js"
|
|
@@ -19,18 +19,18 @@
|
|
|
19
19
|
"@mapwhit/events": "^0.0.1",
|
|
20
20
|
"@mapwhit/geojson-rewind": "^1.0.0",
|
|
21
21
|
"@mapwhit/pbf": "^1.0.0",
|
|
22
|
-
"@mapwhit/style-expressions": "^
|
|
23
|
-
"@mapwhit/vector-tile": "^
|
|
24
|
-
"@mapwhit/vt-pbf": "^
|
|
22
|
+
"@mapwhit/style-expressions": "^1.1.0",
|
|
23
|
+
"@mapwhit/vector-tile": "^2.0.1",
|
|
24
|
+
"@mapwhit/vt-pbf": "^2.0.0",
|
|
25
25
|
"@pirxpilot/nanoassert": "~1",
|
|
26
26
|
"csscolorparser": "^1.0.3",
|
|
27
27
|
"earcut": "^3.0.1",
|
|
28
28
|
"geojson-vt": "^4.0.2",
|
|
29
29
|
"grid-index": "^1.1.0",
|
|
30
30
|
"murmurhash-js": "^1.0.0",
|
|
31
|
-
"potpack": "^1.0
|
|
31
|
+
"potpack": "^2.1.0",
|
|
32
32
|
"quickselect": "^3.0.0",
|
|
33
|
-
"supercluster": "^
|
|
33
|
+
"supercluster": "^8.0.1",
|
|
34
34
|
"tinyqueue": "^3.0.0"
|
|
35
35
|
},
|
|
36
36
|
"browser": {
|
|
@@ -23,6 +23,7 @@ function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) {
|
|
|
23
23
|
class CircleBucket {
|
|
24
24
|
constructor(options) {
|
|
25
25
|
this.zoom = options.zoom;
|
|
26
|
+
this.globalState = options.globalState;
|
|
26
27
|
this.overscaling = options.overscaling;
|
|
27
28
|
this.layers = options.layers;
|
|
28
29
|
this.layerIds = this.layers.map(layer => layer.id);
|
|
@@ -37,7 +38,9 @@ class CircleBucket {
|
|
|
37
38
|
|
|
38
39
|
populate(features, options) {
|
|
39
40
|
for (const { feature, index, sourceLayerIndex } of features) {
|
|
40
|
-
if (
|
|
41
|
+
if (
|
|
42
|
+
this.layers[0]._featureFilter(new EvaluationParameters(this.zoom, { globalState: this.globalState }), feature)
|
|
43
|
+
) {
|
|
41
44
|
const geometry = loadGeometry(feature);
|
|
42
45
|
this.addFeature(feature, geometry, index);
|
|
43
46
|
options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
|
|
@@ -47,7 +50,10 @@ class CircleBucket {
|
|
|
47
50
|
|
|
48
51
|
update(states, vtLayer, imagePositions) {
|
|
49
52
|
if (!this.stateDependentLayers.length) return;
|
|
50
|
-
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers,
|
|
53
|
+
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
|
|
54
|
+
imagePositions,
|
|
55
|
+
globalState: this.globalState
|
|
56
|
+
});
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
isEmpty() {
|
|
@@ -109,7 +115,10 @@ class CircleBucket {
|
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
117
|
|
|
112
|
-
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
|
|
118
|
+
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
|
|
119
|
+
imagePositions: {},
|
|
120
|
+
globalState: this.globalState
|
|
121
|
+
});
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
|
|
@@ -16,6 +16,7 @@ const EvaluationParameters = require('../../style/evaluation_parameters');
|
|
|
16
16
|
class FillBucket {
|
|
17
17
|
constructor(options) {
|
|
18
18
|
this.zoom = options.zoom;
|
|
19
|
+
this.globalState = options.globalState;
|
|
19
20
|
this.overscaling = options.overscaling;
|
|
20
21
|
this.layers = options.layers;
|
|
21
22
|
this.layerIds = this.layers.map(layer => layer.id);
|
|
@@ -35,7 +36,10 @@ class FillBucket {
|
|
|
35
36
|
this.hasPattern = hasPattern('fill', this.layers, options);
|
|
36
37
|
|
|
37
38
|
for (const { feature, index, sourceLayerIndex } of features) {
|
|
38
|
-
if (
|
|
39
|
+
if (
|
|
40
|
+
!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom, { globalState: this.globalState }), feature)
|
|
41
|
+
)
|
|
42
|
+
continue;
|
|
39
43
|
|
|
40
44
|
const geometry = loadGeometry(feature);
|
|
41
45
|
|
|
@@ -64,7 +68,10 @@ class FillBucket {
|
|
|
64
68
|
|
|
65
69
|
update(states, vtLayer, imagePositions) {
|
|
66
70
|
if (!this.stateDependentLayers.length) return;
|
|
67
|
-
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers,
|
|
71
|
+
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
|
|
72
|
+
imagePositions,
|
|
73
|
+
globalState: this.globalState
|
|
74
|
+
});
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
addFeatures(options, imagePositions) {
|
|
@@ -157,7 +164,10 @@ class FillBucket {
|
|
|
157
164
|
triangleSegment.primitiveLength += indices.length / 3;
|
|
158
165
|
}
|
|
159
166
|
|
|
160
|
-
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index,
|
|
167
|
+
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
|
|
168
|
+
imagePositions,
|
|
169
|
+
globalState: this.globalState
|
|
170
|
+
});
|
|
161
171
|
}
|
|
162
172
|
}
|
|
163
173
|
|
|
@@ -36,6 +36,7 @@ function addVertex(vertexArray, x, y, nx, ny, nz, t, e) {
|
|
|
36
36
|
class FillExtrusionBucket {
|
|
37
37
|
constructor(options) {
|
|
38
38
|
this.zoom = options.zoom;
|
|
39
|
+
this.globalState = options.globalState;
|
|
39
40
|
this.overscaling = options.overscaling;
|
|
40
41
|
this.layers = options.layers;
|
|
41
42
|
this.layerIds = this.layers.map(layer => layer.id);
|
|
@@ -53,7 +54,10 @@ class FillExtrusionBucket {
|
|
|
53
54
|
this.hasPattern = hasPattern('fill-extrusion', this.layers, options);
|
|
54
55
|
|
|
55
56
|
for (const { feature, index, sourceLayerIndex } of features) {
|
|
56
|
-
if (
|
|
57
|
+
if (
|
|
58
|
+
!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom, { globalState: this.globalState }), feature)
|
|
59
|
+
)
|
|
60
|
+
continue;
|
|
57
61
|
|
|
58
62
|
const geometry = loadGeometry(feature);
|
|
59
63
|
|
|
@@ -89,7 +93,10 @@ class FillExtrusionBucket {
|
|
|
89
93
|
|
|
90
94
|
update(states, vtLayer, imagePositions) {
|
|
91
95
|
if (!this.stateDependentLayers.length) return;
|
|
92
|
-
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers,
|
|
96
|
+
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
|
|
97
|
+
imagePositions,
|
|
98
|
+
globalState: this.globalState
|
|
99
|
+
});
|
|
93
100
|
}
|
|
94
101
|
|
|
95
102
|
isEmpty() {
|
|
@@ -225,7 +232,10 @@ class FillExtrusionBucket {
|
|
|
225
232
|
segment.vertexLength += numVertices;
|
|
226
233
|
}
|
|
227
234
|
|
|
228
|
-
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index,
|
|
235
|
+
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
|
|
236
|
+
imagePositions,
|
|
237
|
+
globalState: this.globalState
|
|
238
|
+
});
|
|
229
239
|
}
|
|
230
240
|
}
|
|
231
241
|
|
|
@@ -72,6 +72,7 @@ function addLineVertex(layoutVertexBuffer, point, extrude, round, up, dir, lines
|
|
|
72
72
|
class LineBucket {
|
|
73
73
|
constructor(options) {
|
|
74
74
|
this.zoom = options.zoom;
|
|
75
|
+
this.globalState = options.globalState;
|
|
75
76
|
this.overscaling = options.overscaling;
|
|
76
77
|
this.layers = options.layers;
|
|
77
78
|
this.layerIds = this.layers.map(layer => layer.id);
|
|
@@ -90,7 +91,10 @@ class LineBucket {
|
|
|
90
91
|
this.hasPattern = hasPattern('line', this.layers, options);
|
|
91
92
|
|
|
92
93
|
for (const { feature, index, sourceLayerIndex } of features) {
|
|
93
|
-
if (
|
|
94
|
+
if (
|
|
95
|
+
!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom, { globalState: this.globalState }), feature)
|
|
96
|
+
)
|
|
97
|
+
continue;
|
|
94
98
|
|
|
95
99
|
const geometry = loadGeometry(feature);
|
|
96
100
|
|
|
@@ -119,7 +123,10 @@ class LineBucket {
|
|
|
119
123
|
|
|
120
124
|
update(states, vtLayer, imagePositions) {
|
|
121
125
|
if (!this.stateDependentLayers.length) return;
|
|
122
|
-
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers,
|
|
126
|
+
this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
|
|
127
|
+
imagePositions,
|
|
128
|
+
globalState: this.globalState
|
|
129
|
+
});
|
|
123
130
|
}
|
|
124
131
|
|
|
125
132
|
addFeatures(options, imagePositions) {
|
|
@@ -494,7 +501,10 @@ class LineBucket {
|
|
|
494
501
|
startOfLine = false;
|
|
495
502
|
}
|
|
496
503
|
|
|
497
|
-
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index,
|
|
504
|
+
this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
|
|
505
|
+
imagePositions,
|
|
506
|
+
globalState: this.globalState
|
|
507
|
+
});
|
|
498
508
|
}
|
|
499
509
|
|
|
500
510
|
/**
|
|
@@ -176,6 +176,7 @@ class SymbolBucket {
|
|
|
176
176
|
constructor(options) {
|
|
177
177
|
this.collisionBoxArray = options.collisionBoxArray;
|
|
178
178
|
this.zoom = options.zoom;
|
|
179
|
+
this.globalState = options.globalState;
|
|
179
180
|
this.overscaling = options.overscaling;
|
|
180
181
|
this.layers = options.layers;
|
|
181
182
|
this.layerIds = this.layers.map(layer => layer.id);
|
|
@@ -258,7 +259,7 @@ class SymbolBucket {
|
|
|
258
259
|
|
|
259
260
|
const icons = options.iconDependencies;
|
|
260
261
|
const stacks = options.glyphDependencies;
|
|
261
|
-
const globalProperties = new EvaluationParameters(this.zoom);
|
|
262
|
+
const globalProperties = new EvaluationParameters(this.zoom, { globalState: this.globalState });
|
|
262
263
|
|
|
263
264
|
for (const { feature, index, sourceLayerIndex } of features) {
|
|
264
265
|
if (!layer._featureFilter(globalProperties, feature)) {
|
|
@@ -327,8 +328,14 @@ class SymbolBucket {
|
|
|
327
328
|
|
|
328
329
|
update(states, vtLayer, imagePositions) {
|
|
329
330
|
if (!this.stateDependentLayers.length) return;
|
|
330
|
-
this.text.programConfigurations.updatePaintArrays(states, vtLayer, this.layers,
|
|
331
|
-
|
|
331
|
+
this.text.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, {
|
|
332
|
+
imagePositions,
|
|
333
|
+
globalState: this.globalState
|
|
334
|
+
});
|
|
335
|
+
this.icon.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, {
|
|
336
|
+
imagePositions,
|
|
337
|
+
globalState: this.globalState
|
|
338
|
+
});
|
|
332
339
|
}
|
|
333
340
|
|
|
334
341
|
isEmpty() {
|
|
@@ -457,7 +464,10 @@ class SymbolBucket {
|
|
|
457
464
|
false
|
|
458
465
|
);
|
|
459
466
|
|
|
460
|
-
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {
|
|
467
|
+
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {
|
|
468
|
+
imagePositions: {},
|
|
469
|
+
globalState: this.globalState
|
|
470
|
+
});
|
|
461
471
|
}
|
|
462
472
|
|
|
463
473
|
_addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, point, anchorX, anchorY, extrude) {
|
|
@@ -128,13 +128,13 @@ class SourceExpressionBinder {
|
|
|
128
128
|
|
|
129
129
|
setConstantPatternPositions() {}
|
|
130
130
|
|
|
131
|
-
populatePaintArray(newLength, feature,
|
|
131
|
+
populatePaintArray(newLength, feature, options) {
|
|
132
132
|
const paintArray = this.paintVertexArray;
|
|
133
133
|
|
|
134
134
|
const start = paintArray.length;
|
|
135
135
|
paintArray.reserve(newLength);
|
|
136
136
|
|
|
137
|
-
const value = this.expression.evaluate(new EvaluationParameters(0), feature, {});
|
|
137
|
+
const value = this.expression.evaluate(new EvaluationParameters(0, options), feature, {});
|
|
138
138
|
|
|
139
139
|
if (this.type === 'color') {
|
|
140
140
|
const color = packColor(value);
|
|
@@ -150,9 +150,9 @@ class SourceExpressionBinder {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
updatePaintArray(start, end, feature, featureState,
|
|
153
|
+
updatePaintArray(start, end, feature, featureState, options) {
|
|
154
154
|
const paintArray = this.paintVertexArray;
|
|
155
|
-
const value = this.expression.evaluate(
|
|
155
|
+
const value = this.expression.evaluate(new EvaluationParameters(0, options), feature, featureState);
|
|
156
156
|
|
|
157
157
|
if (this.type === 'color') {
|
|
158
158
|
const color = packColor(value);
|
|
@@ -224,14 +224,14 @@ class CompositeExpressionBinder {
|
|
|
224
224
|
|
|
225
225
|
setConstantPatternPositions() {}
|
|
226
226
|
|
|
227
|
-
populatePaintArray(newLength, feature) {
|
|
227
|
+
populatePaintArray(newLength, feature, options) {
|
|
228
228
|
const paintArray = this.paintVertexArray;
|
|
229
229
|
|
|
230
230
|
const start = paintArray.length;
|
|
231
231
|
paintArray.reserve(newLength);
|
|
232
232
|
|
|
233
|
-
const min = this.expression.evaluate(new EvaluationParameters(this.zoom), feature, {});
|
|
234
|
-
const max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1), feature, {});
|
|
233
|
+
const min = this.expression.evaluate(new EvaluationParameters(this.zoom, options), feature, {});
|
|
234
|
+
const max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1, options), feature, {});
|
|
235
235
|
|
|
236
236
|
if (this.type === 'color') {
|
|
237
237
|
const minColor = packColor(min);
|
|
@@ -247,11 +247,11 @@ class CompositeExpressionBinder {
|
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
updatePaintArray(start, end, feature, featureState) {
|
|
250
|
+
updatePaintArray(start, end, feature, featureState, options) {
|
|
251
251
|
const paintArray = this.paintVertexArray;
|
|
252
252
|
|
|
253
|
-
const min = this.expression.evaluate(
|
|
254
|
-
const max = this.expression.evaluate(
|
|
253
|
+
const min = this.expression.evaluate(new EvaluationParameters(this.zoom, options), feature, featureState);
|
|
254
|
+
const max = this.expression.evaluate(new EvaluationParameters(this.zoom + 1, options), feature, featureState);
|
|
255
255
|
|
|
256
256
|
if (this.type === 'color') {
|
|
257
257
|
const minColor = packColor(min);
|
|
@@ -331,7 +331,7 @@ class CrossFadedCompositeBinder {
|
|
|
331
331
|
|
|
332
332
|
setConstantPatternPositions() {}
|
|
333
333
|
|
|
334
|
-
populatePaintArray(length, feature, imagePositions) {
|
|
334
|
+
populatePaintArray(length, feature, { imagePositions }) {
|
|
335
335
|
// We populate two paint arrays because, for cross-faded properties, we don't know which direction
|
|
336
336
|
// we're cross-fading to at layout time. In order to keep vertex attributes to a minimum and not pass
|
|
337
337
|
// unnecessary vertex data to the shaders, we determine which to upload at draw time.
|
|
@@ -379,7 +379,7 @@ class CrossFadedCompositeBinder {
|
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
updatePaintArray(start, end, feature, featureState, imagePositions) {
|
|
382
|
+
updatePaintArray(start, end, feature, featureState, { imagePositions }) {
|
|
383
383
|
// We populate two paint arrays because, for cross-faded properties, we don't know which direction
|
|
384
384
|
// we're cross-fading to at layout time. In order to keep vertex attributes to a minimum and not pass
|
|
385
385
|
// unnecessary vertex data to the shaders, we determine which to upload at draw time.
|
|
@@ -546,12 +546,12 @@ class ProgramConfiguration {
|
|
|
546
546
|
return self;
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
-
populatePaintArrays(newLength, feature, index,
|
|
549
|
+
populatePaintArrays(newLength, feature, index, options) {
|
|
550
550
|
for (const property in this.binders) {
|
|
551
551
|
const binder = this.binders[property];
|
|
552
|
-
binder.populatePaintArray(newLength, feature,
|
|
552
|
+
binder.populatePaintArray(newLength, feature, options);
|
|
553
553
|
}
|
|
554
|
-
if (feature.id) {
|
|
554
|
+
if (feature.id !== undefined) {
|
|
555
555
|
const featureId = String(feature.id);
|
|
556
556
|
this._idMap[featureId] = this._idMap[featureId] || [];
|
|
557
557
|
this._idMap[featureId].push({
|
|
@@ -571,7 +571,7 @@ class ProgramConfiguration {
|
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
-
updatePaintArrays(featureStates, vtLayer, layer,
|
|
574
|
+
updatePaintArrays(featureStates, vtLayer, layer, options) {
|
|
575
575
|
let dirty = false;
|
|
576
576
|
for (const id in featureStates) {
|
|
577
577
|
const posArray = this._idMap[id];
|
|
@@ -588,7 +588,7 @@ class ProgramConfiguration {
|
|
|
588
588
|
//AHM: Remove after https://github.com/mapbox/mapbox-gl-js/issues/6255
|
|
589
589
|
const value = layer.paint.get(property);
|
|
590
590
|
binder.expression = value.value;
|
|
591
|
-
binder.updatePaintArray(pos.start, pos.end, feature, featureState,
|
|
591
|
+
binder.updatePaintArray(pos.start, pos.end, feature, featureState, options);
|
|
592
592
|
dirty = true;
|
|
593
593
|
}
|
|
594
594
|
}
|
|
@@ -687,17 +687,17 @@ class ProgramConfigurationSet {
|
|
|
687
687
|
this.needsUpload = false;
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
-
populatePaintArrays(length, feature, index,
|
|
690
|
+
populatePaintArrays(length, feature, index, options) {
|
|
691
691
|
for (const key in this.programConfigurations) {
|
|
692
|
-
this.programConfigurations[key].populatePaintArrays(length, feature, index,
|
|
692
|
+
this.programConfigurations[key].populatePaintArrays(length, feature, index, options);
|
|
693
693
|
}
|
|
694
694
|
this.needsUpload = true;
|
|
695
695
|
}
|
|
696
696
|
|
|
697
|
-
updatePaintArrays(featureStates, vtLayer, layers,
|
|
697
|
+
updatePaintArrays(featureStates, vtLayer, layers, options) {
|
|
698
698
|
for (const layer of layers) {
|
|
699
699
|
this.needsUpload =
|
|
700
|
-
this.programConfigurations[layer.id].updatePaintArrays(featureStates, vtLayer, layer,
|
|
700
|
+
this.programConfigurations[layer.id].updatePaintArrays(featureStates, vtLayer, layer, options) ||
|
|
701
701
|
this.needsUpload;
|
|
702
702
|
}
|
|
703
703
|
}
|
|
@@ -184,7 +184,8 @@ class GeoJSONSource extends Evented {
|
|
|
184
184
|
tileSize: this.tileSize,
|
|
185
185
|
source: this.id,
|
|
186
186
|
pixelRatio: browser.devicePixelRatio,
|
|
187
|
-
showCollisionBoxes: this.map.showCollisionBoxes
|
|
187
|
+
showCollisionBoxes: this.map.showCollisionBoxes,
|
|
188
|
+
globalState: this.map.getGlobalState()
|
|
188
189
|
};
|
|
189
190
|
|
|
190
191
|
const justReloaded = tile.workerID != null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const rewind = require('@mapwhit/geojson-rewind');
|
|
2
2
|
const GeoJSONWrapper = require('./geojson_wrapper');
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const { fromVectorTileJs } = require('@mapwhit/vt-pbf');
|
|
4
|
+
const { default: Supercluster } = require('supercluster');
|
|
5
5
|
const { default: geojsonvt } = require('geojson-vt');
|
|
6
6
|
const VectorTileWorkerSource = require('./vector_tile_worker_source');
|
|
7
7
|
|
|
@@ -29,7 +29,7 @@ function loadGeoJSONTile(params) {
|
|
|
29
29
|
// Encode the geojson-vt tile into binary vector tile form. This
|
|
30
30
|
// is a convenience that allows `FeatureIndex` to operate the same way
|
|
31
31
|
// across `VectorTileSource` and `GeoJSONSource` data.
|
|
32
|
-
let pbf =
|
|
32
|
+
let pbf = fromVectorTileJs(geojsonWrapper);
|
|
33
33
|
if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) {
|
|
34
34
|
// Compatibility with node Buffer (https://github.com/mapbox/pbf/issues/35)
|
|
35
35
|
pbf = new Uint8Array(pbf);
|
|
@@ -81,7 +81,7 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
|
|
|
81
81
|
this._createGeoJSONIndex = params.cluster
|
|
82
82
|
? () => {
|
|
83
83
|
rewind(data, true);
|
|
84
|
-
return
|
|
84
|
+
return new Supercluster(params.superclusterOptions).load(data.features);
|
|
85
85
|
}
|
|
86
86
|
: () => {
|
|
87
87
|
rewind(data, true);
|
|
@@ -94,7 +94,8 @@ class VectorTileSource extends Evented {
|
|
|
94
94
|
type: this.type,
|
|
95
95
|
source: this.id,
|
|
96
96
|
pixelRatio: browser.devicePixelRatio,
|
|
97
|
-
showCollisionBoxes: this.map.showCollisionBoxes
|
|
97
|
+
showCollisionBoxes: this.map.showCollisionBoxes,
|
|
98
|
+
globalState: this.map.getGlobalState()
|
|
98
99
|
};
|
|
99
100
|
tile.workerID ??= this.dispatcher.nextWorkerId();
|
|
100
101
|
const data = await this.dispatcher.send('loadTile', params, tile.workerID);
|
|
@@ -49,6 +49,7 @@ class VectorTileWorkerSource {
|
|
|
49
49
|
}
|
|
50
50
|
const { vectorTile, rawData } = response;
|
|
51
51
|
const workerTile = new WorkerTile(params);
|
|
52
|
+
workerTile.globalState = params.globalState;
|
|
52
53
|
workerTile.vectorTile = vectorTile;
|
|
53
54
|
const result = await workerTile.parse(vectorTile, this.layerIndex, this.resources);
|
|
54
55
|
if (rawData) {
|
|
@@ -31,6 +31,7 @@ class WorkerTile {
|
|
|
31
31
|
this.source = params.source;
|
|
32
32
|
this.overscaling = this.tileID.overscaleFactor();
|
|
33
33
|
this.showCollisionBoxes = params.showCollisionBoxes;
|
|
34
|
+
this.globalState = params.globalState;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
async parse(data, layerIndex, resources) {
|
|
@@ -81,7 +82,7 @@ class WorkerTile {
|
|
|
81
82
|
if (layer.maxzoom && this.zoom >= layer.maxzoom) continue;
|
|
82
83
|
if (layer.visibility === 'none') continue;
|
|
83
84
|
|
|
84
|
-
recalculateLayers(family, this.zoom);
|
|
85
|
+
recalculateLayers(family, this.zoom, this.globalState);
|
|
85
86
|
|
|
86
87
|
const bucket = (buckets[layer.id] = layer.createBucket({
|
|
87
88
|
index: featureIndex.bucketLayerIDs.length,
|
|
@@ -91,7 +92,8 @@ class WorkerTile {
|
|
|
91
92
|
overscaling: this.overscaling,
|
|
92
93
|
collisionBoxArray: this.collisionBoxArray,
|
|
93
94
|
sourceLayerIndex: sourceLayerIndex,
|
|
94
|
-
sourceID: this.source
|
|
95
|
+
sourceID: this.source,
|
|
96
|
+
globalState: this.globalState
|
|
95
97
|
}));
|
|
96
98
|
|
|
97
99
|
bucket.populate(features, options);
|
|
@@ -114,7 +116,7 @@ class WorkerTile {
|
|
|
114
116
|
for (const key in buckets) {
|
|
115
117
|
const bucket = buckets[key];
|
|
116
118
|
if (bucket instanceof SymbolBucket) {
|
|
117
|
-
recalculateLayers(bucket.layers, this.zoom);
|
|
119
|
+
recalculateLayers(bucket.layers, this.zoom, this.globalState);
|
|
118
120
|
performSymbolLayout(
|
|
119
121
|
bucket,
|
|
120
122
|
glyphMap,
|
|
@@ -127,7 +129,7 @@ class WorkerTile {
|
|
|
127
129
|
bucket.hasPattern &&
|
|
128
130
|
(bucket instanceof LineBucket || bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket)
|
|
129
131
|
) {
|
|
130
|
-
recalculateLayers(bucket.layers, this.zoom);
|
|
132
|
+
recalculateLayers(bucket.layers, this.zoom, this.globalState);
|
|
131
133
|
bucket.addFeatures(options, imageAtlas.patternPositions);
|
|
132
134
|
}
|
|
133
135
|
}
|
|
@@ -143,9 +145,9 @@ class WorkerTile {
|
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
|
|
146
|
-
function recalculateLayers(layers, zoom) {
|
|
148
|
+
function recalculateLayers(layers, zoom, globalState) {
|
|
147
149
|
// Layers are shared and may have been used by a WorkerTile with a different zoom.
|
|
148
|
-
const parameters = new EvaluationParameters(zoom);
|
|
150
|
+
const parameters = new EvaluationParameters(zoom, { globalState });
|
|
149
151
|
for (const layer of layers) {
|
|
150
152
|
layer.recalculate(parameters);
|
|
151
153
|
}
|
|
@@ -8,15 +8,17 @@ class EvaluationParameters {
|
|
|
8
8
|
this.zoom = zoom;
|
|
9
9
|
|
|
10
10
|
if (options) {
|
|
11
|
-
this.now = options.now;
|
|
12
|
-
this.fadeDuration = options.fadeDuration;
|
|
13
|
-
this.zoomHistory = options.zoomHistory;
|
|
14
|
-
this.transition = options.transition;
|
|
11
|
+
this.now = options.now || 0;
|
|
12
|
+
this.fadeDuration = options.fadeDuration || 0;
|
|
13
|
+
this.zoomHistory = options.zoomHistory || new ZoomHistory();
|
|
14
|
+
this.transition = options.transition || {};
|
|
15
|
+
this.globalState = options.globalState || {};
|
|
15
16
|
} else {
|
|
16
17
|
this.now = 0;
|
|
17
18
|
this.fadeDuration = 0;
|
|
18
19
|
this.zoomHistory = new ZoomHistory();
|
|
19
20
|
this.transition = {};
|
|
21
|
+
this.globalState = {};
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
|
package/src/style/properties.js
CHANGED
|
@@ -75,6 +75,10 @@ class PropertyValue {
|
|
|
75
75
|
return this.expression.kind === 'source' || this.expression.kind === 'composite';
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
getGlobalStateRefs() {
|
|
79
|
+
return this.expression.globalStateRefs ?? new Set();
|
|
80
|
+
}
|
|
81
|
+
|
|
78
82
|
possiblyEvaluate(parameters) {
|
|
79
83
|
return this.property.possiblyEvaluate(this, parameters);
|
|
80
84
|
}
|
package/src/style/style.js
CHANGED
|
@@ -41,6 +41,7 @@ class Style extends Evented {
|
|
|
41
41
|
this.sourceCaches = {};
|
|
42
42
|
this.zoomHistory = new ZoomHistory();
|
|
43
43
|
this._loaded = false;
|
|
44
|
+
this._globalState = {};
|
|
44
45
|
|
|
45
46
|
this._resetUpdates();
|
|
46
47
|
|
|
@@ -78,6 +79,78 @@ class Style extends Evented {
|
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
setGlobalStateProperty(name, value) {
|
|
83
|
+
this._checkLoaded();
|
|
84
|
+
|
|
85
|
+
const newValue = value === null ? (this.stylesheet.state?.[name]?.default ?? null) : value;
|
|
86
|
+
|
|
87
|
+
if (deepEqual(newValue, this._globalState[name])) {
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
this._globalState[name] = newValue;
|
|
92
|
+
|
|
93
|
+
this._applyGlobalStateChanges([name]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getGlobalState() {
|
|
97
|
+
return this._globalState;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setGlobalState(newStylesheetState) {
|
|
101
|
+
this._checkLoaded();
|
|
102
|
+
|
|
103
|
+
const changedGlobalStateRefs = [];
|
|
104
|
+
|
|
105
|
+
for (const propertyName in newStylesheetState) {
|
|
106
|
+
const didChange = !deepEqual(this._globalState[propertyName], newStylesheetState[propertyName].default);
|
|
107
|
+
|
|
108
|
+
if (didChange) {
|
|
109
|
+
changedGlobalStateRefs.push(propertyName);
|
|
110
|
+
this._globalState[propertyName] = newStylesheetState[propertyName].default;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this._applyGlobalStateChanges(changedGlobalStateRefs);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* * Find all sources that are affected by the global state changes and reload them.
|
|
119
|
+
* Find all paint properties that are affected by the global state changes and update them.
|
|
120
|
+
* For example, if a layer filter uses global-state expression, this function will find the source id of that layer.
|
|
121
|
+
*/
|
|
122
|
+
_applyGlobalStateChanges(globalStateRefs) {
|
|
123
|
+
if (globalStateRefs.length === 0) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const sourceIdsToReload = new Set();
|
|
128
|
+
|
|
129
|
+
for (const layerId in this._layers) {
|
|
130
|
+
const layer = this._layers[layerId];
|
|
131
|
+
const layoutAffectingGlobalStateRefs = layer.getLayoutAffectingGlobalStateRefs();
|
|
132
|
+
const paintAffectingGlobalStateRefs = layer.getPaintAffectingGlobalStateRefs();
|
|
133
|
+
|
|
134
|
+
for (const ref of globalStateRefs) {
|
|
135
|
+
if (layoutAffectingGlobalStateRefs.has(ref)) {
|
|
136
|
+
sourceIdsToReload.add(layer.source);
|
|
137
|
+
}
|
|
138
|
+
if (paintAffectingGlobalStateRefs.has(ref)) {
|
|
139
|
+
for (const { name, value } of paintAffectingGlobalStateRefs.get(ref)) {
|
|
140
|
+
this._updatePaintProperty(layer, name, value);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const id in this.sourceCaches) {
|
|
147
|
+
if (sourceIdsToReload.has(id)) {
|
|
148
|
+
this._reloadSource(id);
|
|
149
|
+
this._changed = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
81
154
|
loadJSON(json) {
|
|
82
155
|
this.fire(new Event('dataloading', { dataType: 'style' }));
|
|
83
156
|
|
|
@@ -128,6 +201,8 @@ class Style extends Evented {
|
|
|
128
201
|
|
|
129
202
|
this.light = new Light(this.stylesheet.light);
|
|
130
203
|
|
|
204
|
+
this.setGlobalState(this.stylesheet.state ?? null);
|
|
205
|
+
|
|
131
206
|
this.fire(new Event('data', { dataType: 'style' }));
|
|
132
207
|
this.fire(new Event('style.load'));
|
|
133
208
|
}
|
|
@@ -547,12 +622,12 @@ class Style extends Evented {
|
|
|
547
622
|
}
|
|
548
623
|
|
|
549
624
|
if (filter === null || filter === undefined) {
|
|
550
|
-
layer.
|
|
625
|
+
layer.setFilter(undefined);
|
|
551
626
|
this._updateLayer(layer);
|
|
552
627
|
return;
|
|
553
628
|
}
|
|
554
629
|
|
|
555
|
-
layer.
|
|
630
|
+
layer.setFilter(clone(filter));
|
|
556
631
|
this._updateLayer(layer);
|
|
557
632
|
}
|
|
558
633
|
|
|
@@ -605,13 +680,17 @@ class Style extends Evented {
|
|
|
605
680
|
|
|
606
681
|
if (deepEqual(layer.getPaintProperty(name), value)) return;
|
|
607
682
|
|
|
683
|
+
this._updatePaintProperty(layer, name, value);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
_updatePaintProperty(layer, name, value) {
|
|
608
687
|
const requiresRelayout = layer.setPaintProperty(name, value);
|
|
609
688
|
if (requiresRelayout) {
|
|
610
689
|
this._updateLayer(layer);
|
|
611
690
|
}
|
|
612
691
|
|
|
613
692
|
this._changed = true;
|
|
614
|
-
this._updatedPaintProps[
|
|
693
|
+
this._updatedPaintProps[layer.id] = true;
|
|
615
694
|
}
|
|
616
695
|
|
|
617
696
|
getPaintProperty(layer, name) {
|
package/src/style/style_layer.js
CHANGED
|
@@ -3,6 +3,7 @@ const { filterObject } = require('../util/object');
|
|
|
3
3
|
const { Evented } = require('@mapwhit/events');
|
|
4
4
|
const { Layout, Transitionable, PossiblyEvaluatedPropertyValue } = require('./properties');
|
|
5
5
|
const { supportsPropertyExpression } = require('@mapwhit/style-expressions');
|
|
6
|
+
const featureFilter = require('../style-spec/feature_filter');
|
|
6
7
|
|
|
7
8
|
const TRANSITION_SUFFIX = '-transition';
|
|
8
9
|
|
|
@@ -23,9 +24,10 @@ class StyleLayer extends Evented {
|
|
|
23
24
|
this.source = layer.source;
|
|
24
25
|
this.sourceLayer = layer['source-layer'];
|
|
25
26
|
this.filter = layer.filter;
|
|
27
|
+
this._featureFilter = featureFilter(layer.filter);
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
this._featureFilter
|
|
30
|
+
this._featureFilter ??= featureFilter.addGlobalStateRefs(() => true);
|
|
29
31
|
|
|
30
32
|
if (properties.layout) {
|
|
31
33
|
this._unevaluatedLayout = new Layout(properties.layout);
|
|
@@ -43,6 +45,11 @@ class StyleLayer extends Evented {
|
|
|
43
45
|
this._transitioningPaint = this._transitionablePaint.untransitioned();
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
setFilter(filter) {
|
|
49
|
+
this.filter = filter;
|
|
50
|
+
this._featureFilter = featureFilter(filter);
|
|
51
|
+
}
|
|
52
|
+
|
|
46
53
|
getCrossfadeParameters() {
|
|
47
54
|
return this._crossfadeParameters;
|
|
48
55
|
}
|
|
@@ -55,6 +62,54 @@ class StyleLayer extends Evented {
|
|
|
55
62
|
return this._unevaluatedLayout.getValue(name);
|
|
56
63
|
}
|
|
57
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Get list of global state references that are used within layout or filter properties.
|
|
67
|
+
* This is used to determine if layer source need to be reloaded when global state property changes.
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
getLayoutAffectingGlobalStateRefs() {
|
|
71
|
+
const globalStateRefs = new Set();
|
|
72
|
+
|
|
73
|
+
if (this._unevaluatedLayout) {
|
|
74
|
+
for (const propertyName in this._unevaluatedLayout._values) {
|
|
75
|
+
const value = this._unevaluatedLayout._values[propertyName];
|
|
76
|
+
|
|
77
|
+
for (const globalStateRef of value.getGlobalStateRefs()) {
|
|
78
|
+
globalStateRefs.add(globalStateRef);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const globalStateRef of this._featureFilter.getGlobalStateRefs()) {
|
|
84
|
+
globalStateRefs.add(globalStateRef);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return globalStateRefs;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get list of global state references that are used within paint properties.
|
|
92
|
+
* This is used to determine if layer needs to be repainted when global state property changes.
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
getPaintAffectingGlobalStateRefs() {
|
|
96
|
+
const globalStateRefs = new Map();
|
|
97
|
+
|
|
98
|
+
if (this._transitionablePaint) {
|
|
99
|
+
for (const propertyName in this._transitionablePaint._values) {
|
|
100
|
+
const value = this._transitionablePaint._values[propertyName].value;
|
|
101
|
+
|
|
102
|
+
for (const globalStateRef of value.getGlobalStateRefs()) {
|
|
103
|
+
const properties = globalStateRefs.get(globalStateRef) ?? [];
|
|
104
|
+
properties.push({ name: propertyName, value: value.value });
|
|
105
|
+
globalStateRefs.set(globalStateRef, properties);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return globalStateRefs;
|
|
111
|
+
}
|
|
112
|
+
|
|
58
113
|
setLayoutProperty(name, value) {
|
|
59
114
|
if (name === 'visibility') {
|
|
60
115
|
this.visibility = value === 'none' ? value : 'visible';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
const { createExpression } = require('@mapwhit/style-expressions');
|
|
1
|
+
const { createExpression, findGlobalStateRefs } = require('@mapwhit/style-expressions');
|
|
2
2
|
|
|
3
3
|
module.exports = createFilter;
|
|
4
4
|
|
|
5
5
|
createFilter.isExpressionFilter = isExpressionFilter;
|
|
6
|
+
createFilter.addGlobalStateRefs = addGlobalStateRefs;
|
|
6
7
|
|
|
7
8
|
function isExpressionFilter(filter) {
|
|
8
9
|
if (filter === true || filter === false) {
|
|
@@ -66,7 +67,7 @@ const filterSpec = {
|
|
|
66
67
|
*/
|
|
67
68
|
function createFilter(filter) {
|
|
68
69
|
if (filter === null || filter === undefined) {
|
|
69
|
-
return () => true;
|
|
70
|
+
return addGlobalStateRefs(() => true);
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
if (!isExpressionFilter(filter)) {
|
|
@@ -77,7 +78,15 @@ function createFilter(filter) {
|
|
|
77
78
|
if (compiled.result === 'error') {
|
|
78
79
|
throw new Error(compiled.value.map(err => `${err.key}: ${err.message}`).join(', '));
|
|
79
80
|
}
|
|
80
|
-
return (
|
|
81
|
+
return addGlobalStateRefs(
|
|
82
|
+
(globalProperties, feature) => compiled.value.evaluate(globalProperties, feature),
|
|
83
|
+
() => findGlobalStateRefs(compiled.value.expression)
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function addGlobalStateRefs(filter, getGlobalStateRefs = () => new Set()) {
|
|
88
|
+
filter.getGlobalStateRefs = getGlobalStateRefs;
|
|
89
|
+
return filter;
|
|
81
90
|
}
|
|
82
91
|
|
|
83
92
|
// Comparison function to sort numbers and strings
|
|
@@ -86,7 +95,7 @@ function compare(a, b) {
|
|
|
86
95
|
}
|
|
87
96
|
|
|
88
97
|
function convertFilter(filter) {
|
|
89
|
-
if (!filter) return true;
|
|
98
|
+
if (!filter || filter.length === 0) return true;
|
|
90
99
|
const [op, ...args] = filter;
|
|
91
100
|
if (filter.length <= 1) return op !== 'any';
|
|
92
101
|
switch (op) {
|
|
@@ -48,6 +48,26 @@
|
|
|
48
48
|
"doc": "Default pitch, in degrees. Zero is perpendicular to the surface, for a look straight down at the map, while a greater value like 60 looks ahead towards the horizon. The style pitch will be used only if the map has not been positioned by other means (e.g. map options or user interaction).",
|
|
49
49
|
"example": 50
|
|
50
50
|
},
|
|
51
|
+
"state": {
|
|
52
|
+
"type": "state",
|
|
53
|
+
"default": {},
|
|
54
|
+
"doc": "An object used to define default values when using the [`global-state`](https://maplibre.org/maplibre-style-spec/expressions/#global-state) expression.",
|
|
55
|
+
"example": {
|
|
56
|
+
"chargerType": {
|
|
57
|
+
"default": ["CCS", "CHAdeMO", "Type2"]
|
|
58
|
+
},
|
|
59
|
+
"minPreferredChargingSpeed": {
|
|
60
|
+
"default": 50
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"sdk-support": {
|
|
64
|
+
"basic functionality": {
|
|
65
|
+
"js": "https://github.com/maplibre/maplibre-gl-js/issues/4964",
|
|
66
|
+
"android": "https://github.com/maplibre/maplibre-native/issues/3302",
|
|
67
|
+
"ios": "https://github.com/maplibre/maplibre-native/issues/3302"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
51
71
|
"light": {
|
|
52
72
|
"type": "light",
|
|
53
73
|
"doc": "The global light source.",
|
|
@@ -1293,8 +1313,8 @@
|
|
|
1293
1313
|
},
|
|
1294
1314
|
{
|
|
1295
1315
|
"symbol-placement": [
|
|
1296
|
-
|
|
1297
|
-
|
|
1316
|
+
"line",
|
|
1317
|
+
"line-center"
|
|
1298
1318
|
]
|
|
1299
1319
|
}
|
|
1300
1320
|
],
|
|
@@ -1816,10 +1836,10 @@
|
|
|
1816
1836
|
"requires": [
|
|
1817
1837
|
"text-field",
|
|
1818
1838
|
{
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1839
|
+
"symbol-placement": [
|
|
1840
|
+
"line",
|
|
1841
|
+
"line-center"
|
|
1842
|
+
]
|
|
1823
1843
|
}
|
|
1824
1844
|
],
|
|
1825
1845
|
"sdk-support": {
|
|
@@ -1907,10 +1927,10 @@
|
|
|
1907
1927
|
"text-rotation-alignment": "map"
|
|
1908
1928
|
},
|
|
1909
1929
|
{
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1930
|
+
"symbol-placement": [
|
|
1931
|
+
"line",
|
|
1932
|
+
"line-center"
|
|
1933
|
+
]
|
|
1914
1934
|
}
|
|
1915
1935
|
],
|
|
1916
1936
|
"sdk-support": {
|
|
@@ -2554,6 +2574,24 @@
|
|
|
2554
2574
|
}
|
|
2555
2575
|
}
|
|
2556
2576
|
},
|
|
2577
|
+
"global-state": {
|
|
2578
|
+
"doc": "Retrieves a property value from global state that can be set with platform-specific APIs. Defaults can be provided using the [`state`](https://maplibre.org/maplibre-style-spec/root/#state) root property. Returns `null` if no value nor default value is set for the retrieved property.",
|
|
2579
|
+
"group": "Lookup",
|
|
2580
|
+
"example": {
|
|
2581
|
+
"syntax": {
|
|
2582
|
+
"method": ["string"],
|
|
2583
|
+
"result": "value"
|
|
2584
|
+
},
|
|
2585
|
+
"value": ["global-state", "someProperty"]
|
|
2586
|
+
},
|
|
2587
|
+
"sdk-support": {
|
|
2588
|
+
"basic functionality": {
|
|
2589
|
+
"js": "https://github.com/maplibre/maplibre-gl-js/issues/4964",
|
|
2590
|
+
"android": "https://github.com/maplibre/maplibre-native/issues/3302",
|
|
2591
|
+
"ios": "https://github.com/maplibre/maplibre-native/issues/3302"
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
},
|
|
2557
2595
|
"to-string": {
|
|
2558
2596
|
"doc": "Converts the input value to a string. If the input is `null`, the result is `\"\"`. If the input is a boolean, the result is `\"true\"` or `\"false\"`. If the input is a number, it is converted to a string as specified by the [\"NumberToString\" algorithm](https://tc39.github.io/ecma262/#sec-tostring-applied-to-the-number-type) of the ECMAScript Language Specification. If the input is a color, it is converted to a string of the form `\"rgba(r,g,b,a)\"`, where `r`, `g`, and `b` are numerals ranging from 0 to 255, and `a` ranges from 0 to 1. Otherwise, the input is converted to a string in the format specified by the [`JSON.stringify`](https://tc39.github.io/ecma262/#sec-json.stringify) function of the ECMAScript Language Specification.",
|
|
2559
2597
|
"group": "Types",
|
|
@@ -3722,7 +3760,9 @@
|
|
|
3722
3760
|
},
|
|
3723
3761
|
"expression": {
|
|
3724
3762
|
"interpolated": false,
|
|
3725
|
-
"parameters": [
|
|
3763
|
+
"parameters": [
|
|
3764
|
+
"zoom"
|
|
3765
|
+
]
|
|
3726
3766
|
},
|
|
3727
3767
|
"property-type": "data-constant"
|
|
3728
3768
|
}
|
|
@@ -5232,10 +5272,10 @@
|
|
|
5232
5272
|
"type": "enum",
|
|
5233
5273
|
"values": {
|
|
5234
5274
|
"map": {
|
|
5235
|
-
|
|
5275
|
+
"doc": "The hillshade illumination is relative to the north direction."
|
|
5236
5276
|
},
|
|
5237
5277
|
"viewport": {
|
|
5238
|
-
|
|
5278
|
+
"doc": "The hillshade illumination is relative to the top of the viewport."
|
|
5239
5279
|
}
|
|
5240
5280
|
},
|
|
5241
5281
|
"default": "viewport",
|
package/src/ui/map.js
CHANGED
|
@@ -201,6 +201,28 @@ class Map extends Camera {
|
|
|
201
201
|
this.on('dataloading', this._onDataLoading);
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Sets a global state property that can be retrieved with the [`global-state` expression](https://maplibre.org/maplibre-style-spec/expressions/#global-state).
|
|
206
|
+
* If the value is null, it resets the property to its default value defined in the [`state` style property](https://maplibre.org/maplibre-style-spec/root/#state).
|
|
207
|
+
*
|
|
208
|
+
* @param propertyName - The name of the state property to set.
|
|
209
|
+
* @param value - The value of the state property to set.
|
|
210
|
+
*/
|
|
211
|
+
setGlobalStateProperty(propertyName, value) {
|
|
212
|
+
if (!this.style.setGlobalStateProperty(propertyName, value)) {
|
|
213
|
+
return this._update(true);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Returns the global map state
|
|
219
|
+
*
|
|
220
|
+
* @returns The map state object.
|
|
221
|
+
*/
|
|
222
|
+
getGlobalState() {
|
|
223
|
+
return this.style.getGlobalState();
|
|
224
|
+
}
|
|
225
|
+
|
|
204
226
|
/**
|
|
205
227
|
* Adds a {@link IControl} to the map, calling `control.onAdd(this)`.
|
|
206
228
|
*
|
|
@@ -1248,7 +1270,8 @@ class Map extends Camera {
|
|
|
1248
1270
|
now,
|
|
1249
1271
|
fadeDuration: this._fadeDuration,
|
|
1250
1272
|
zoomHistory: this.style.zoomHistory,
|
|
1251
|
-
transition: this.style.getTransition()
|
|
1273
|
+
transition: this.style.getTransition(),
|
|
1274
|
+
globalState: this.style.getGlobalState()
|
|
1252
1275
|
});
|
|
1253
1276
|
|
|
1254
1277
|
const factor = parameters.crossFadingFactor();
|