@mapwhit/tilerenderer 0.52.0 → 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.
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.51.1"
2
+ "version": "0.52.0"
3
3
  }
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.52.0",
4
+ "version": "0.52.1",
5
5
  "exports": {
6
6
  ".": "./src/index.js",
7
7
  "./worker": "./src/worker.js"
@@ -50,7 +50,10 @@ class CircleBucket {
50
50
 
51
51
  update(states, vtLayer, imagePositions) {
52
52
  if (!this.stateDependentLayers.length) return;
53
- this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions);
53
+ this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
54
+ imagePositions,
55
+ globalState: this.globalState
56
+ });
54
57
  }
55
58
 
56
59
  isEmpty() {
@@ -112,7 +115,10 @@ class CircleBucket {
112
115
  }
113
116
  }
114
117
 
115
- this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {});
118
+ this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
119
+ imagePositions: {},
120
+ globalState: this.globalState
121
+ });
116
122
  }
117
123
  }
118
124
 
@@ -68,7 +68,10 @@ class FillBucket {
68
68
 
69
69
  update(states, vtLayer, imagePositions) {
70
70
  if (!this.stateDependentLayers.length) return;
71
- this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions);
71
+ this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
72
+ imagePositions,
73
+ globalState: this.globalState
74
+ });
72
75
  }
73
76
 
74
77
  addFeatures(options, imagePositions) {
@@ -161,7 +164,10 @@ class FillBucket {
161
164
  triangleSegment.primitiveLength += indices.length / 3;
162
165
  }
163
166
 
164
- this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions);
167
+ this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
168
+ imagePositions,
169
+ globalState: this.globalState
170
+ });
165
171
  }
166
172
  }
167
173
 
@@ -93,7 +93,10 @@ class FillExtrusionBucket {
93
93
 
94
94
  update(states, vtLayer, imagePositions) {
95
95
  if (!this.stateDependentLayers.length) return;
96
- this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions);
96
+ this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
97
+ imagePositions,
98
+ globalState: this.globalState
99
+ });
97
100
  }
98
101
 
99
102
  isEmpty() {
@@ -229,7 +232,10 @@ class FillExtrusionBucket {
229
232
  segment.vertexLength += numVertices;
230
233
  }
231
234
 
232
- this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions);
235
+ this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
236
+ imagePositions,
237
+ globalState: this.globalState
238
+ });
233
239
  }
234
240
  }
235
241
 
@@ -123,7 +123,10 @@ class LineBucket {
123
123
 
124
124
  update(states, vtLayer, imagePositions) {
125
125
  if (!this.stateDependentLayers.length) return;
126
- this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, imagePositions);
126
+ this.programConfigurations.updatePaintArrays(states, vtLayer, this.stateDependentLayers, {
127
+ imagePositions,
128
+ globalState: this.globalState
129
+ });
127
130
  }
128
131
 
129
132
  addFeatures(options, imagePositions) {
@@ -498,7 +501,10 @@ class LineBucket {
498
501
  startOfLine = false;
499
502
  }
500
503
 
501
- this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, imagePositions);
504
+ this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length, feature, index, {
505
+ imagePositions,
506
+ globalState: this.globalState
507
+ });
502
508
  }
503
509
 
504
510
  /**
@@ -328,8 +328,14 @@ class SymbolBucket {
328
328
 
329
329
  update(states, vtLayer, imagePositions) {
330
330
  if (!this.stateDependentLayers.length) return;
331
- this.text.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, imagePositions);
332
- this.icon.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, imagePositions);
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
+ });
333
339
  }
334
340
 
335
341
  isEmpty() {
@@ -458,7 +464,10 @@ class SymbolBucket {
458
464
  false
459
465
  );
460
466
 
461
- 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
+ });
462
471
  }
463
472
 
464
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, imagePositions) {
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, imagePositions) {
153
+ updatePaintArray(start, end, feature, featureState, options) {
154
154
  const paintArray = this.paintVertexArray;
155
- const value = this.expression.evaluate({ zoom: 0 }, feature, featureState);
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({ zoom: this.zoom }, feature, featureState);
254
- const max = this.expression.evaluate({ zoom: this.zoom + 1 }, feature, featureState);
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, imagePositions) {
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, imagePositions);
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, imagePositions) {
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, imagePositions);
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, imagePositions) {
690
+ populatePaintArrays(length, feature, index, options) {
691
691
  for (const key in this.programConfigurations) {
692
- this.programConfigurations[key].populatePaintArrays(length, feature, index, imagePositions);
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, imagePositions) {
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, imagePositions) ||
700
+ this.programConfigurations[layer.id].updatePaintArrays(featureStates, vtLayer, layer, options) ||
701
701
  this.needsUpload;
702
702
  }
703
703
  }
@@ -82,7 +82,7 @@ class WorkerTile {
82
82
  if (layer.maxzoom && this.zoom >= layer.maxzoom) continue;
83
83
  if (layer.visibility === 'none') continue;
84
84
 
85
- recalculateLayers(family, this.zoom, { globalState: this.globalState });
85
+ recalculateLayers(family, this.zoom, this.globalState);
86
86
 
87
87
  const bucket = (buckets[layer.id] = layer.createBucket({
88
88
  index: featureIndex.bucketLayerIDs.length,
@@ -116,7 +116,7 @@ class WorkerTile {
116
116
  for (const key in buckets) {
117
117
  const bucket = buckets[key];
118
118
  if (bucket instanceof SymbolBucket) {
119
- recalculateLayers(bucket.layers, this.zoom, { globalState: this.globalState });
119
+ recalculateLayers(bucket.layers, this.zoom, this.globalState);
120
120
  performSymbolLayout(
121
121
  bucket,
122
122
  glyphMap,
@@ -129,7 +129,7 @@ class WorkerTile {
129
129
  bucket.hasPattern &&
130
130
  (bucket instanceof LineBucket || bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket)
131
131
  ) {
132
- recalculateLayers(bucket.layers, this.zoom, { globalState: this.globalState });
132
+ recalculateLayers(bucket.layers, this.zoom, this.globalState);
133
133
  bucket.addFeatures(options, imageAtlas.patternPositions);
134
134
  }
135
135
  }
@@ -145,9 +145,9 @@ class WorkerTile {
145
145
  }
146
146
  }
147
147
 
148
- function recalculateLayers(layers, zoom, options) {
148
+ function recalculateLayers(layers, zoom, globalState) {
149
149
  // Layers are shared and may have been used by a WorkerTile with a different zoom.
150
- const parameters = new EvaluationParameters(zoom, options);
150
+ const parameters = new EvaluationParameters(zoom, { globalState });
151
151
  for (const layer of layers) {
152
152
  layer.recalculate(parameters);
153
153
  }
@@ -90,14 +90,7 @@ class Style extends Evented {
90
90
 
91
91
  this._globalState[name] = newValue;
92
92
 
93
- const sourceIdsToReload = this._findGlobalStateAffectedSources([name]);
94
-
95
- for (const id in this.sourceCaches) {
96
- if (sourceIdsToReload.has(id)) {
97
- this._reloadSource(id);
98
- this._changed = true;
99
- }
100
- }
93
+ this._applyGlobalStateChanges([name]);
101
94
  }
102
95
 
103
96
  getGlobalState() {
@@ -118,23 +111,17 @@ class Style extends Evented {
118
111
  }
119
112
  }
120
113
 
121
- const sourceIdsToReload = this._findGlobalStateAffectedSources(changedGlobalStateRefs);
122
-
123
- for (const id in this.sourceCaches) {
124
- if (sourceIdsToReload.has(id)) {
125
- this._reloadSource(id);
126
- this._changed = true;
127
- }
128
- }
114
+ this._applyGlobalStateChanges(changedGlobalStateRefs);
129
115
  }
130
116
 
131
117
  /**
132
- * Find all sources that are affected by the global state changes.
133
- * For example, if a layer filter uses global-state expression, this function will return the source id of that layer.
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.
134
121
  */
135
- _findGlobalStateAffectedSources(globalStateRefs) {
122
+ _applyGlobalStateChanges(globalStateRefs) {
136
123
  if (globalStateRefs.length === 0) {
137
- return new Set();
124
+ return;
138
125
  }
139
126
 
140
127
  const sourceIdsToReload = new Set();
@@ -142,15 +129,26 @@ class Style extends Evented {
142
129
  for (const layerId in this._layers) {
143
130
  const layer = this._layers[layerId];
144
131
  const layoutAffectingGlobalStateRefs = layer.getLayoutAffectingGlobalStateRefs();
132
+ const paintAffectingGlobalStateRefs = layer.getPaintAffectingGlobalStateRefs();
145
133
 
146
134
  for (const ref of globalStateRefs) {
147
135
  if (layoutAffectingGlobalStateRefs.has(ref)) {
148
136
  sourceIdsToReload.add(layer.source);
149
137
  }
138
+ if (paintAffectingGlobalStateRefs.has(ref)) {
139
+ for (const { name, value } of paintAffectingGlobalStateRefs.get(ref)) {
140
+ this._updatePaintProperty(layer, name, value);
141
+ }
142
+ }
150
143
  }
151
144
  }
152
145
 
153
- return sourceIdsToReload;
146
+ for (const id in this.sourceCaches) {
147
+ if (sourceIdsToReload.has(id)) {
148
+ this._reloadSource(id);
149
+ this._changed = true;
150
+ }
151
+ }
154
152
  }
155
153
 
156
154
  loadJSON(json) {
@@ -682,13 +680,17 @@ class Style extends Evented {
682
680
 
683
681
  if (deepEqual(layer.getPaintProperty(name), value)) return;
684
682
 
683
+ this._updatePaintProperty(layer, name, value);
684
+ }
685
+
686
+ _updatePaintProperty(layer, name, value) {
685
687
  const requiresRelayout = layer.setPaintProperty(name, value);
686
688
  if (requiresRelayout) {
687
689
  this._updateLayer(layer);
688
690
  }
689
691
 
690
692
  this._changed = true;
691
- this._updatedPaintProps[layerId] = true;
693
+ this._updatedPaintProps[layer.id] = true;
692
694
  }
693
695
 
694
696
  getPaintProperty(layer, name) {
@@ -87,6 +87,29 @@ class StyleLayer extends Evented {
87
87
  return globalStateRefs;
88
88
  }
89
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
+
90
113
  setLayoutProperty(name, value) {
91
114
  if (name === 'visibility') {
92
115
  this.visibility = value === 'none' ? value : 'visible';
package/src/ui/map.js CHANGED
@@ -205,14 +205,13 @@ class Map extends Camera {
205
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
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
207
  *
208
- * Note that changing `global-state` values defined in layout properties is not supported, and will be ignored.
209
- *
210
208
  * @param propertyName - The name of the state property to set.
211
209
  * @param value - The value of the state property to set.
212
210
  */
213
211
  setGlobalStateProperty(propertyName, value) {
214
- this.style.setGlobalStateProperty(propertyName, value);
215
- return this._update(true);
212
+ if (!this.style.setGlobalStateProperty(propertyName, value)) {
213
+ return this._update(true);
214
+ }
216
215
  }
217
216
 
218
217
  /**