@mapwhit/tilerenderer 1.1.1 → 1.2.0
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 +5 -5
- package/src/data/bucket/circle_bucket.js +3 -8
- package/src/data/bucket/fill_bucket.js +4 -17
- package/src/data/bucket/fill_extrusion_bucket.js +4 -15
- package/src/data/bucket/line_bucket.js +4 -17
- package/src/data/bucket/pattern_bucket_features.js +4 -4
- package/src/data/bucket/symbol_bucket.js +4 -8
- package/src/data/feature_index.js +1 -1
- package/src/source/geojson_source.js +4 -3
- package/src/source/geojson_worker_source.js +26 -10
- package/src/source/load_tilejson.js +18 -6
- package/src/source/raster_tile_source.js +4 -5
- package/src/source/tile.js +3 -0
- package/src/source/vector_tile_source.js +4 -6
- package/src/source/vector_tile_worker_source.js +6 -26
- package/src/source/worker_tile.js +67 -53
- package/src/style/create_style_layer.js +2 -2
- package/src/style/evaluation_parameters.js +0 -2
- package/src/style/properties.js +24 -15
- package/src/style/style.js +18 -8
- package/src/style/style_layer/background_style_layer.js +2 -2
- package/src/style/style_layer/circle_style_layer.js +3 -3
- package/src/style/style_layer/fill_extrusion_style_layer.js +3 -3
- package/src/style/style_layer/fill_style_layer.js +3 -3
- package/src/style/style_layer/heatmap_style_layer.js +3 -3
- package/src/style/style_layer/hillshade_style_layer.js +3 -3
- package/src/style/style_layer/line_style_layer.js +3 -3
- package/src/style/style_layer/raster_style_layer.js +2 -2
- package/src/style/style_layer/symbol_style_layer.js +2 -2
- package/src/style/style_layer.js +28 -7
- package/src/style-spec/feature_filter/index.js +7 -5
- package/src/style-spec/reference/v8.json +68 -9
- package/src/style-spec/visibility.js +37 -0
- package/src/symbol/collision_index.js +2 -2
- package/src/symbol/symbol_layout.js +1 -1
- package/src/ui/map.js +10 -3
- package/src/util/classify_rings.js +1 -1
- package/src/util/group_layers.js +1 -1
- package/src/util/object.js +0 -45
- package/src/util/util.js +0 -55
- package/src/util/async.js +0 -29
- package/src/util/find_pole_of_inaccessibility.js +0 -144
- package/src/util/intersection_tests.js +0 -245
|
@@ -13,72 +13,86 @@ import { mapObject } from '../util/object.js';
|
|
|
13
13
|
import { OverscaledTileID } from './tile_id.js';
|
|
14
14
|
export default makeWorkerTile;
|
|
15
15
|
|
|
16
|
-
async function makeWorkerTile(params,
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const overscaling = tileID.overscaleFactor();
|
|
20
|
-
const { zoom, pixelRatio, source, showCollisionBoxes, globalState, justReloaded, painter } = params;
|
|
21
|
-
|
|
22
|
-
const collisionBoxArray = new CollisionBoxArray();
|
|
23
|
-
const sourceLayerCoder = dictionaryCoder(Object.keys(vectorTile.layers));
|
|
24
|
-
|
|
25
|
-
const featureIndex = new FeatureIndex(tileID);
|
|
26
|
-
featureIndex.bucketLayerIDs = [];
|
|
27
|
-
|
|
28
|
-
const uniqueBuckets = new Map();
|
|
29
|
-
|
|
30
|
-
const options = {
|
|
31
|
-
featureIndex,
|
|
32
|
-
iconDependencies: {},
|
|
33
|
-
patternDependencies: {},
|
|
34
|
-
glyphDependencies: {}
|
|
35
|
-
};
|
|
16
|
+
async function makeWorkerTile(params, { layers }, layerIndex, resources) {
|
|
17
|
+
const options = initializeBucketsOptions(params);
|
|
36
18
|
|
|
19
|
+
const { source } = params;
|
|
20
|
+
const sourceLayerCoder = dictionaryCoder(Object.keys(layers));
|
|
37
21
|
const layerFamilies = layerIndex.familiesBySource.get(source) ?? new Map();
|
|
38
22
|
for (const [sourceLayerId, sourceLayerFamilies] of layerFamilies) {
|
|
39
|
-
const sourceLayer =
|
|
23
|
+
const sourceLayer = layers[sourceLayerId];
|
|
40
24
|
if (!sourceLayer) {
|
|
41
25
|
continue;
|
|
42
26
|
}
|
|
43
|
-
|
|
44
27
|
const sourceLayerIndex = sourceLayerCoder.encode(sourceLayerId);
|
|
45
28
|
const features = new Array(sourceLayer.length);
|
|
46
29
|
for (let index = 0; index < sourceLayer.length; index++) {
|
|
47
30
|
features[index] = { feature: sourceLayer.feature(index), index, sourceLayerIndex };
|
|
48
31
|
}
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
|
|
33
|
+
makeBucketsForSourceLayer(sourceLayerFamilies, sourceLayerIndex, features, params, options);
|
|
34
|
+
}
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
36
|
+
return await finalizeBuckets(params, options, resources);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function makeSingleSourceLayerWorkerTile(params, features, sourceLayerFamilies, resources) {
|
|
40
|
+
const options = initializeBucketsOptions(params);
|
|
41
|
+
|
|
42
|
+
makeBucketsForSourceLayer(sourceLayerFamilies, 0, features, params, options);
|
|
62
43
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
44
|
+
return await finalizeBuckets(params, options, resources);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function initializeBucketsOptions(params) {
|
|
48
|
+
const tileID = createTileID(params);
|
|
49
|
+
|
|
50
|
+
const featureIndex = new FeatureIndex(tileID);
|
|
51
|
+
featureIndex.bucketLayerIDs = [];
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
collisionBoxArray: new CollisionBoxArray(),
|
|
55
|
+
featureIndex,
|
|
56
|
+
glyphDependencies: {},
|
|
57
|
+
iconDependencies: {},
|
|
58
|
+
overscaling: tileID.overscaleFactor(),
|
|
59
|
+
patternDependencies: {},
|
|
60
|
+
uniqueBuckets: new Map()
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function makeBucketsForSourceLayer(sourceLayerFamilies, sourceLayerIndex, features, params, options) {
|
|
65
|
+
const { zoom, pixelRatio, source } = params;
|
|
66
|
+
const { featureIndex, overscaling, collisionBoxArray, uniqueBuckets } = options;
|
|
67
|
+
|
|
68
|
+
for (const layers of sourceLayerFamilies.values()) {
|
|
69
|
+
const layer = layers[0];
|
|
70
|
+
|
|
71
|
+
if (layer.isHidden(zoom, layer.minzoom && Math.floor(layer.minzoom))) {
|
|
72
|
+
continue;
|
|
79
73
|
}
|
|
74
|
+
|
|
75
|
+
recalculateLayers(layers, zoom);
|
|
76
|
+
|
|
77
|
+
const bucket = layer.createBucket({
|
|
78
|
+
index: featureIndex.bucketLayerIDs.length,
|
|
79
|
+
layers,
|
|
80
|
+
zoom,
|
|
81
|
+
pixelRatio,
|
|
82
|
+
overscaling,
|
|
83
|
+
collisionBoxArray,
|
|
84
|
+
sourceLayerIndex,
|
|
85
|
+
sourceID: source
|
|
86
|
+
});
|
|
87
|
+
uniqueBuckets.set(layer.id, bucket);
|
|
88
|
+
bucket.populate(features, options);
|
|
89
|
+
featureIndex.bucketLayerIDs.push(layers.map(l => l.id));
|
|
80
90
|
}
|
|
91
|
+
}
|
|
81
92
|
|
|
93
|
+
async function finalizeBuckets(params, options, resources) {
|
|
94
|
+
const { zoom, showCollisionBoxes, justReloaded, painter } = params;
|
|
95
|
+
const { collisionBoxArray, featureIndex, uniqueBuckets } = options;
|
|
82
96
|
const buckets = new Map();
|
|
83
97
|
const { glyphAtlas, imageAtlas, glyphMap, iconMap } = await makeAtlasses(options, resources);
|
|
84
98
|
let hasSymbolBuckets = false;
|
|
@@ -86,7 +100,7 @@ async function makeWorkerTile(params, vectorTile, layerIndex, resources) {
|
|
|
86
100
|
for (const bucket of uniqueBuckets.values()) {
|
|
87
101
|
if (bucket instanceof SymbolBucket) {
|
|
88
102
|
hasSymbolBuckets = true;
|
|
89
|
-
recalculateLayers(bucket.layers, zoom
|
|
103
|
+
recalculateLayers(bucket.layers, zoom);
|
|
90
104
|
performSymbolLayout(
|
|
91
105
|
bucket,
|
|
92
106
|
glyphMap,
|
|
@@ -102,7 +116,7 @@ async function makeWorkerTile(params, vectorTile, layerIndex, resources) {
|
|
|
102
116
|
bucket.hasPattern &&
|
|
103
117
|
(bucket instanceof LineBucket || bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket)
|
|
104
118
|
) {
|
|
105
|
-
recalculateLayers(bucket.layers, zoom
|
|
119
|
+
recalculateLayers(bucket.layers, zoom);
|
|
106
120
|
bucket.addFeatures(options, imageAtlas.patternPositions);
|
|
107
121
|
}
|
|
108
122
|
if (bucket.isEmpty()) {
|
|
@@ -152,9 +166,9 @@ function createTileID({ tileID }) {
|
|
|
152
166
|
return new OverscaledTileID(overscaledZ, wrap, z, x, y);
|
|
153
167
|
}
|
|
154
168
|
|
|
155
|
-
function recalculateLayers(layers, zoom
|
|
169
|
+
function recalculateLayers(layers, zoom) {
|
|
156
170
|
// Layers are shared and may have been used by a WorkerTile with a different zoom.
|
|
157
|
-
const parameters = new EvaluationParameters(zoom
|
|
171
|
+
const parameters = new EvaluationParameters(zoom);
|
|
158
172
|
for (const layer of layers) {
|
|
159
173
|
layer.recalculate(parameters);
|
|
160
174
|
}
|
|
@@ -20,6 +20,6 @@ const subclasses = {
|
|
|
20
20
|
raster
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export default function createStyleLayer(layer) {
|
|
24
|
-
return new subclasses[layer.type](layer);
|
|
23
|
+
export default function createStyleLayer(layer, globalState) {
|
|
24
|
+
return new subclasses[layer.type](layer, globalState);
|
|
25
25
|
}
|
|
@@ -12,13 +12,11 @@ export default class EvaluationParameters {
|
|
|
12
12
|
this.fadeDuration = options.fadeDuration || 0;
|
|
13
13
|
this.zoomHistory = options.zoomHistory || new ZoomHistory();
|
|
14
14
|
this.transition = options.transition || {};
|
|
15
|
-
this.globalState = options.globalState || {};
|
|
16
15
|
} else {
|
|
17
16
|
this.now = 0;
|
|
18
17
|
this.fadeDuration = 0;
|
|
19
18
|
this.zoomHistory = new ZoomHistory();
|
|
20
19
|
this.transition = {};
|
|
21
|
-
this.globalState = {};
|
|
22
20
|
}
|
|
23
21
|
}
|
|
24
22
|
|
package/src/style/properties.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { interpolate, normalizePropertyExpression } from '@mapwhit/style-expressions';
|
|
2
2
|
import assert from 'assert';
|
|
3
|
-
import { clone } from '../util/object.js';
|
|
4
3
|
import { easeCubicInOut } from '../util/util.js';
|
|
5
4
|
import EvaluationParameters from './evaluation_parameters.js';
|
|
6
5
|
|
|
@@ -60,12 +59,13 @@ import EvaluationParameters from './evaluation_parameters.js';
|
|
|
60
59
|
* @private
|
|
61
60
|
*/
|
|
62
61
|
export class PropertyValue {
|
|
63
|
-
constructor(property, value) {
|
|
62
|
+
constructor(property, value, globalState) {
|
|
64
63
|
this.property = property;
|
|
65
64
|
this.value = value;
|
|
66
65
|
this.expression = normalizePropertyExpression(
|
|
67
66
|
value === undefined ? property.specification.default : value,
|
|
68
|
-
property.specification
|
|
67
|
+
property.specification,
|
|
68
|
+
globalState
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -97,9 +97,9 @@ export class PropertyValue {
|
|
|
97
97
|
* @private
|
|
98
98
|
*/
|
|
99
99
|
export class TransitionablePropertyValue {
|
|
100
|
-
constructor(property) {
|
|
100
|
+
constructor(property, globalState) {
|
|
101
101
|
this.property = property;
|
|
102
|
-
this.value = new PropertyValue(property, undefined);
|
|
102
|
+
this.value = new PropertyValue(property, undefined, globalState);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
transitioned(parameters, prior) {
|
|
@@ -132,36 +132,39 @@ export class TransitionablePropertyValue {
|
|
|
132
132
|
* @private
|
|
133
133
|
*/
|
|
134
134
|
export class Transitionable {
|
|
135
|
-
|
|
135
|
+
#globalState; // reference to global state
|
|
136
|
+
constructor(properties, globalState) {
|
|
136
137
|
this._properties = properties;
|
|
137
138
|
this._values = Object.create(properties.defaultTransitionablePropertyValues);
|
|
139
|
+
this.#globalState = globalState;
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
getValue(name) {
|
|
141
|
-
return
|
|
143
|
+
return structuredClone(this._values[name].value.value);
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
setValue(name, value) {
|
|
145
147
|
if (!this._values.hasOwnProperty(name)) {
|
|
146
|
-
this._values[name] = new TransitionablePropertyValue(this._values[name].property);
|
|
148
|
+
this._values[name] = new TransitionablePropertyValue(this._values[name].property, this.#globalState);
|
|
147
149
|
}
|
|
148
150
|
// Note that we do not _remove_ an own property in the case where a value is being reset
|
|
149
151
|
// to the default: the transition might still be non-default.
|
|
150
152
|
this._values[name].value = new PropertyValue(
|
|
151
153
|
this._values[name].property,
|
|
152
|
-
value === null ? undefined :
|
|
154
|
+
value === null ? undefined : structuredClone(value),
|
|
155
|
+
this.#globalState
|
|
153
156
|
);
|
|
154
157
|
}
|
|
155
158
|
|
|
156
159
|
getTransition(name) {
|
|
157
|
-
return
|
|
160
|
+
return structuredClone(this._values[name].transition);
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
setTransition(name, value) {
|
|
161
164
|
if (!this._values.hasOwnProperty(name)) {
|
|
162
|
-
this._values[name] = new TransitionablePropertyValue(this._values[name].property);
|
|
165
|
+
this._values[name] = new TransitionablePropertyValue(this._values[name].property, this.#globalState);
|
|
163
166
|
}
|
|
164
|
-
this._values[name].transition =
|
|
167
|
+
this._values[name].transition = structuredClone(value) || undefined;
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
serialize() {
|
|
@@ -308,17 +311,23 @@ export class Transitioning {
|
|
|
308
311
|
* @private
|
|
309
312
|
*/
|
|
310
313
|
export class Layout {
|
|
311
|
-
|
|
314
|
+
#globalState; // reference to global state
|
|
315
|
+
constructor(properties, globalState) {
|
|
312
316
|
this._properties = properties;
|
|
313
317
|
this._values = Object.create(properties.defaultPropertyValues);
|
|
318
|
+
this.#globalState = globalState;
|
|
314
319
|
}
|
|
315
320
|
|
|
316
321
|
getValue(name) {
|
|
317
|
-
return
|
|
322
|
+
return structuredClone(this._values[name].value);
|
|
318
323
|
}
|
|
319
324
|
|
|
320
325
|
setValue(name, value) {
|
|
321
|
-
this._values[name] = new PropertyValue(
|
|
326
|
+
this._values[name] = new PropertyValue(
|
|
327
|
+
this._values[name].property,
|
|
328
|
+
value === null ? undefined : structuredClone(value),
|
|
329
|
+
this.#globalState
|
|
330
|
+
);
|
|
322
331
|
}
|
|
323
332
|
|
|
324
333
|
serialize() {
|
package/src/style/style.js
CHANGED
|
@@ -10,7 +10,7 @@ import { getType as getSourceType, setType as setSourceType } from '../source/so
|
|
|
10
10
|
import SourceCache from '../source/source_cache.js';
|
|
11
11
|
import CrossTileSymbolIndex from '../symbol/cross_tile_symbol_index.js';
|
|
12
12
|
import browser from '../util/browser.js';
|
|
13
|
-
import {
|
|
13
|
+
import { deepEqual } from '../util/object.js';
|
|
14
14
|
import createStyleLayer from './create_style_layer.js';
|
|
15
15
|
import Light from './light.js';
|
|
16
16
|
import loadSprite from './load_sprite.js';
|
|
@@ -138,6 +138,8 @@ class Style extends Evented {
|
|
|
138
138
|
for (const layer of this._layers.values()) {
|
|
139
139
|
const layoutAffectingGlobalStateRefs = layer.getLayoutAffectingGlobalStateRefs();
|
|
140
140
|
const paintAffectingGlobalStateRefs = layer.getPaintAffectingGlobalStateRefs();
|
|
141
|
+
const visibilityAffectingGlobalStateRefs = layer.getVisibilityAffectingGlobalStateRefs();
|
|
142
|
+
let visibilityToEval;
|
|
141
143
|
|
|
142
144
|
for (const ref of globalStateRefs) {
|
|
143
145
|
if (layoutAffectingGlobalStateRefs.has(ref)) {
|
|
@@ -148,6 +150,13 @@ class Style extends Evented {
|
|
|
148
150
|
this._updatePaintProperty(layer, name, value);
|
|
149
151
|
}
|
|
150
152
|
}
|
|
153
|
+
if (visibilityAffectingGlobalStateRefs?.has(ref)) {
|
|
154
|
+
visibilityToEval = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (visibilityToEval) {
|
|
158
|
+
layer.recalculateVisibility();
|
|
159
|
+
this._updateLayer(layer);
|
|
151
160
|
}
|
|
152
161
|
}
|
|
153
162
|
|
|
@@ -199,11 +208,14 @@ class Style extends Evented {
|
|
|
199
208
|
const layers = this.stylesheet.layers;
|
|
200
209
|
|
|
201
210
|
this._layers.clear();
|
|
211
|
+
|
|
212
|
+
this.setGlobalState(this.stylesheet.state ?? null);
|
|
213
|
+
|
|
202
214
|
for (let layer of layers) {
|
|
203
215
|
if (layer.ref) {
|
|
204
216
|
continue; // just ignore layers that reference other layers
|
|
205
217
|
}
|
|
206
|
-
layer = createStyleLayer(layer);
|
|
218
|
+
layer = createStyleLayer(layer, this._globalState);
|
|
207
219
|
layer.setEventedParent(this, { layer: { id: layer.id } });
|
|
208
220
|
this._layers.set(layer.id, layer);
|
|
209
221
|
}
|
|
@@ -213,8 +225,6 @@ class Style extends Evented {
|
|
|
213
225
|
this.light = this.stylesheet.light;
|
|
214
226
|
this._light = new Light(this.light);
|
|
215
227
|
|
|
216
|
-
this.setGlobalState(this.stylesheet.state ?? null);
|
|
217
|
-
|
|
218
228
|
this.fire(new Event('data', { dataType: 'style' }));
|
|
219
229
|
this.fire(new Event('style.load'));
|
|
220
230
|
}
|
|
@@ -520,11 +530,11 @@ class Style extends Evented {
|
|
|
520
530
|
|
|
521
531
|
if (typeof layerObject.source === 'object') {
|
|
522
532
|
this.addSource(id, layerObject.source);
|
|
523
|
-
layerObject =
|
|
533
|
+
layerObject = structuredClone(layerObject);
|
|
524
534
|
layerObject = Object.assign(layerObject, { source: id });
|
|
525
535
|
}
|
|
526
536
|
|
|
527
|
-
const layer = createStyleLayer(layerObject);
|
|
537
|
+
const layer = createStyleLayer(layerObject, this._globalState);
|
|
528
538
|
this._validateLayer(layer);
|
|
529
539
|
|
|
530
540
|
layer.setEventedParent(this, { layer: { id: id } });
|
|
@@ -656,7 +666,7 @@ class Style extends Evented {
|
|
|
656
666
|
return;
|
|
657
667
|
}
|
|
658
668
|
|
|
659
|
-
layer.setFilter(
|
|
669
|
+
layer.setFilter(structuredClone(filter));
|
|
660
670
|
this._updateLayer(layer);
|
|
661
671
|
}
|
|
662
672
|
|
|
@@ -666,7 +676,7 @@ class Style extends Evented {
|
|
|
666
676
|
* @returns {*} the layer's filter, if any
|
|
667
677
|
*/
|
|
668
678
|
getFilter(layer) {
|
|
669
|
-
return
|
|
679
|
+
return structuredClone(this.getLayer(layer).filter);
|
|
670
680
|
}
|
|
671
681
|
|
|
672
682
|
setLayoutProperty(layerId, name, value) {
|
|
@@ -2,8 +2,8 @@ import StyleLayer from '../style_layer.js';
|
|
|
2
2
|
import properties from './background_style_layer_properties.js';
|
|
3
3
|
|
|
4
4
|
class BackgroundStyleLayer extends StyleLayer {
|
|
5
|
-
constructor(layer) {
|
|
6
|
-
super(layer, properties);
|
|
5
|
+
constructor(layer, globalState) {
|
|
6
|
+
super(layer, properties, globalState);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import glMatrix from '@mapbox/gl-matrix';
|
|
2
2
|
import Point from '@mapbox/point-geometry';
|
|
3
|
+
import { polygonIntersectsBufferedPoint } from '@mapwhit/geometry';
|
|
3
4
|
import CircleBucket from '../../data/bucket/circle_bucket.js';
|
|
4
|
-
import { polygonIntersectsBufferedPoint } from '../../util/intersection_tests.js';
|
|
5
5
|
import { getMaximumPaintValue, translate, translateDistance } from '../query_utils.js';
|
|
6
6
|
import StyleLayer from '../style_layer.js';
|
|
7
7
|
import properties from './circle_style_layer_properties.js';
|
|
@@ -9,8 +9,8 @@ import properties from './circle_style_layer_properties.js';
|
|
|
9
9
|
const { vec4 } = glMatrix;
|
|
10
10
|
|
|
11
11
|
class CircleStyleLayer extends StyleLayer {
|
|
12
|
-
constructor(layer) {
|
|
13
|
-
super(layer, properties);
|
|
12
|
+
constructor(layer, globalState) {
|
|
13
|
+
super(layer, properties, globalState);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
createBucket(parameters) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import glMatrix from '@mapbox/gl-matrix';
|
|
2
2
|
import Point from '@mapbox/point-geometry';
|
|
3
|
+
import { polygonIntersectsMultiPolygon, polygonIntersectsPolygon } from '@mapwhit/geometry';
|
|
3
4
|
import FillExtrusionBucket from '../../data/bucket/fill_extrusion_bucket.js';
|
|
4
|
-
import { polygonIntersectsMultiPolygon, polygonIntersectsPolygon } from '../../util/intersection_tests.js';
|
|
5
5
|
import { translate, translateDistance } from '../query_utils.js';
|
|
6
6
|
import StyleLayer from '../style_layer.js';
|
|
7
7
|
import properties from './fill_extrusion_style_layer_properties.js';
|
|
@@ -9,8 +9,8 @@ import properties from './fill_extrusion_style_layer_properties.js';
|
|
|
9
9
|
const { vec4 } = glMatrix;
|
|
10
10
|
|
|
11
11
|
export class FillExtrusionStyleLayer extends StyleLayer {
|
|
12
|
-
constructor(layer) {
|
|
13
|
-
super(layer, properties);
|
|
12
|
+
constructor(layer, globalState) {
|
|
13
|
+
super(layer, properties, globalState);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
createBucket(parameters) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { polygonIntersectsMultiPolygon } from '@mapwhit/geometry';
|
|
1
2
|
import FillBucket from '../../data/bucket/fill_bucket.js';
|
|
2
|
-
import { polygonIntersectsMultiPolygon } from '../../util/intersection_tests.js';
|
|
3
3
|
import { translate, translateDistance } from '../query_utils.js';
|
|
4
4
|
import StyleLayer from '../style_layer.js';
|
|
5
5
|
import properties from './fill_style_layer_properties.js';
|
|
6
6
|
|
|
7
7
|
class FillStyleLayer extends StyleLayer {
|
|
8
|
-
constructor(layer) {
|
|
9
|
-
super(layer, properties);
|
|
8
|
+
constructor(layer, globalState) {
|
|
9
|
+
super(layer, properties, globalState);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
recalculate(parameters) {
|
|
@@ -8,8 +8,8 @@ class HeatmapStyleLayer extends StyleLayer {
|
|
|
8
8
|
return new HeatmapBucket(options);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
constructor(layer) {
|
|
12
|
-
super(layer, properties);
|
|
11
|
+
constructor(layer, globalState) {
|
|
12
|
+
super(layer, properties, globalState);
|
|
13
13
|
|
|
14
14
|
// make sure color ramp texture is generated for default heatmap color too
|
|
15
15
|
this._updateColorRamp();
|
|
@@ -43,7 +43,7 @@ class HeatmapStyleLayer extends StyleLayer {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
hasOffscreenPass() {
|
|
46
|
-
return this._paint.get('heatmap-opacity') !== 0 && this.
|
|
46
|
+
return this._paint.get('heatmap-opacity') !== 0 && !this.isHidden();
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -2,12 +2,12 @@ import StyleLayer from '../style_layer.js';
|
|
|
2
2
|
import properties from './hillshade_style_layer_properties.js';
|
|
3
3
|
|
|
4
4
|
class HillshadeStyleLayer extends StyleLayer {
|
|
5
|
-
constructor(layer) {
|
|
6
|
-
super(layer, properties);
|
|
5
|
+
constructor(layer, globalState) {
|
|
6
|
+
super(layer, properties, globalState);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
hasOffscreenPass() {
|
|
10
|
-
return this._paint.get('hillshade-exaggeration') !== 0 && this.
|
|
10
|
+
return this._paint.get('hillshade-exaggeration') !== 0 && !this.isHidden();
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Point from '@mapbox/point-geometry';
|
|
2
|
+
import { polygonIntersectsBufferedMultiLine } from '@mapwhit/geometry';
|
|
2
3
|
import LineBucket from '../../data/bucket/line_bucket.js';
|
|
3
4
|
import renderColorRamp from '../../util/color_ramp.js';
|
|
4
|
-
import { polygonIntersectsBufferedMultiLine } from '../../util/intersection_tests.js';
|
|
5
5
|
import EvaluationParameters from '../evaluation_parameters.js';
|
|
6
6
|
import { DataDrivenProperty } from '../properties.js';
|
|
7
7
|
import { getMaximumPaintValue, translate, translateDistance } from '../query_utils.js';
|
|
@@ -29,8 +29,8 @@ const lineFloorwidthProperty = new LineFloorwidthProperty(properties.paint.prope
|
|
|
29
29
|
lineFloorwidthProperty.useIntegerZoom = true;
|
|
30
30
|
|
|
31
31
|
class LineStyleLayer extends StyleLayer {
|
|
32
|
-
constructor(layer) {
|
|
33
|
-
super(layer, properties);
|
|
32
|
+
constructor(layer, globalState) {
|
|
33
|
+
super(layer, properties, globalState);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
_handleSpecialPaintPropertyUpdate(name) {
|
|
@@ -2,8 +2,8 @@ import StyleLayer from '../style_layer.js';
|
|
|
2
2
|
import properties from './raster_style_layer_properties.js';
|
|
3
3
|
|
|
4
4
|
class RasterStyleLayer extends StyleLayer {
|
|
5
|
-
constructor(layer) {
|
|
6
|
-
super(layer, properties);
|
|
5
|
+
constructor(layer, globalState) {
|
|
6
|
+
super(layer, properties, globalState);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
@@ -6,8 +6,8 @@ import StyleLayer from '../style_layer.js';
|
|
|
6
6
|
import properties from './symbol_style_layer_properties.js';
|
|
7
7
|
|
|
8
8
|
class SymbolStyleLayer extends StyleLayer {
|
|
9
|
-
constructor(layer) {
|
|
10
|
-
super(layer, properties);
|
|
9
|
+
constructor(layer, globalState) {
|
|
10
|
+
super(layer, properties, globalState);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
recalculate(parameters) {
|
package/src/style/style_layer.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Evented } from '@mapwhit/events';
|
|
2
2
|
import { supportsPropertyExpression } from '@mapwhit/style-expressions';
|
|
3
3
|
import featureFilter from '../style-spec/feature_filter/index.js';
|
|
4
|
+
import visibilityExpression from '../style-spec/visibility.js';
|
|
4
5
|
import createKey from '../util/key.js';
|
|
5
6
|
import { Layout, PossiblyEvaluatedPropertyValue, Transitionable } from './properties.js';
|
|
6
7
|
|
|
@@ -16,7 +17,7 @@ const TRANSITION_SUFFIX = '-transition';
|
|
|
16
17
|
class StyleLayer extends Evented {
|
|
17
18
|
#key;
|
|
18
19
|
|
|
19
|
-
constructor(layer, properties) {
|
|
20
|
+
constructor(layer, properties, globalState) {
|
|
20
21
|
super();
|
|
21
22
|
|
|
22
23
|
this.id = layer.id;
|
|
@@ -28,6 +29,8 @@ class StyleLayer extends Evented {
|
|
|
28
29
|
this.paint = {};
|
|
29
30
|
this.layout = {};
|
|
30
31
|
|
|
32
|
+
this._visibilityExpression = visibilityExpression(this.visibility, globalState);
|
|
33
|
+
|
|
31
34
|
if (layer.type !== 'background') {
|
|
32
35
|
this.source = layer.source;
|
|
33
36
|
this['source-layer'] = this.sourceLayer = layer['source-layer'];
|
|
@@ -38,10 +41,10 @@ class StyleLayer extends Evented {
|
|
|
38
41
|
this._featureFilter ??= featureFilter.addGlobalStateRefs(() => true);
|
|
39
42
|
|
|
40
43
|
if (properties.layout) {
|
|
41
|
-
this._unevaluatedLayout = new Layout(properties.layout);
|
|
44
|
+
this._unevaluatedLayout = new Layout(properties.layout, globalState);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
this._transitionablePaint = new Transitionable(properties.paint);
|
|
47
|
+
this._transitionablePaint = new Transitionable(properties.paint, globalState);
|
|
45
48
|
|
|
46
49
|
for (const property in layer.paint) {
|
|
47
50
|
this.setPaintProperty(property, layer.paint[property]);
|
|
@@ -94,6 +97,10 @@ class StyleLayer extends Evented {
|
|
|
94
97
|
getLayoutAffectingGlobalStateRefs() {
|
|
95
98
|
const globalStateRefs = new Set();
|
|
96
99
|
|
|
100
|
+
for (const globalStateRef of this._visibilityExpression.getGlobalStateRefs()) {
|
|
101
|
+
globalStateRefs.add(globalStateRef);
|
|
102
|
+
}
|
|
103
|
+
|
|
97
104
|
if (this._unevaluatedLayout) {
|
|
98
105
|
for (const propertyName in this._unevaluatedLayout._values) {
|
|
99
106
|
const value = this._unevaluatedLayout._values[propertyName];
|
|
@@ -134,11 +141,21 @@ class StyleLayer extends Evented {
|
|
|
134
141
|
return globalStateRefs;
|
|
135
142
|
}
|
|
136
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Get list of global state references that are used within visibility expression.
|
|
146
|
+
* This is used to determine if layer visibility needs to be updated when global state property changes.
|
|
147
|
+
*/
|
|
148
|
+
getVisibilityAffectingGlobalStateRefs() {
|
|
149
|
+
return this._visibilityExpression.getGlobalStateRefs();
|
|
150
|
+
}
|
|
151
|
+
|
|
137
152
|
setLayoutProperty(name, value) {
|
|
138
153
|
this.#key = undefined;
|
|
139
154
|
this.layout[name] = value;
|
|
140
155
|
if (name === 'visibility') {
|
|
141
|
-
this.visibility = value
|
|
156
|
+
this.visibility = value;
|
|
157
|
+
this._visibilityExpression.setValue(value);
|
|
158
|
+
this.recalculateVisibility();
|
|
142
159
|
return;
|
|
143
160
|
}
|
|
144
161
|
|
|
@@ -184,14 +201,14 @@ class StyleLayer extends Evented {
|
|
|
184
201
|
// No-op; can be overridden by derived classes.
|
|
185
202
|
}
|
|
186
203
|
|
|
187
|
-
isHidden(zoom) {
|
|
188
|
-
if (
|
|
204
|
+
isHidden(zoom = this.minzoom, minzoom = this.minzoom) {
|
|
205
|
+
if (minzoom && zoom < minzoom) {
|
|
189
206
|
return true;
|
|
190
207
|
}
|
|
191
208
|
if (this.maxzoom && zoom >= this.maxzoom) {
|
|
192
209
|
return true;
|
|
193
210
|
}
|
|
194
|
-
return this.visibility === 'none';
|
|
211
|
+
return this.visibility === 'none' || this._visibility === 'none';
|
|
195
212
|
}
|
|
196
213
|
|
|
197
214
|
updateTransitions(parameters) {
|
|
@@ -202,6 +219,10 @@ class StyleLayer extends Evented {
|
|
|
202
219
|
return this._transitioningPaint.hasTransition();
|
|
203
220
|
}
|
|
204
221
|
|
|
222
|
+
recalculateVisibility() {
|
|
223
|
+
this._visibility = this._visibilityExpression.evaluate();
|
|
224
|
+
}
|
|
225
|
+
|
|
205
226
|
recalculate(parameters) {
|
|
206
227
|
if (parameters.getCrossfadeParameters) {
|
|
207
228
|
this._crossfadeParameters = parameters.getCrossfadeParameters();
|
|
@@ -63,7 +63,7 @@ const filterSpec = {
|
|
|
63
63
|
* @param {Array} filter mapbox gl filter
|
|
64
64
|
* @returns {Function} filter-evaluating function
|
|
65
65
|
*/
|
|
66
|
-
export default function createFilter(filter) {
|
|
66
|
+
export default function createFilter(filter, globalState) {
|
|
67
67
|
if (filter === null || filter === undefined) {
|
|
68
68
|
return addGlobalStateRefs(() => true);
|
|
69
69
|
}
|
|
@@ -72,13 +72,15 @@ export default function createFilter(filter) {
|
|
|
72
72
|
filter = convertFilter(filter);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const compiled = createExpression(filter, filterSpec);
|
|
75
|
+
const compiled = createExpression(filter, filterSpec, globalState);
|
|
76
76
|
if (compiled.result === 'error') {
|
|
77
77
|
throw new Error(compiled.value.map(err => `${err.key}: ${err.message}`).join(', '));
|
|
78
78
|
}
|
|
79
|
-
return
|
|
80
|
-
(
|
|
81
|
-
|
|
79
|
+
return Object.assign(
|
|
80
|
+
addGlobalStateRefs(
|
|
81
|
+
(globalProperties, feature) => compiled.value.evaluate(globalProperties, feature),
|
|
82
|
+
() => findGlobalStateRefs(compiled.value.expression)
|
|
83
|
+
)
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
|