@mapwhit/tilerenderer 0.47.1 → 0.48.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.
Files changed (76) hide show
  1. package/build/min/package.json +1 -1
  2. package/package.json +1 -2
  3. package/src/data/array_types.js +1 -1
  4. package/src/data/bucket/circle_bucket.js +1 -1
  5. package/src/data/bucket/fill_bucket.js +1 -1
  6. package/src/data/bucket/fill_extrusion_bucket.js +1 -1
  7. package/src/data/bucket/heatmap_bucket.js +1 -1
  8. package/src/data/bucket/line_bucket.js +1 -1
  9. package/src/data/bucket/symbol_bucket.js +26 -12
  10. package/src/data/dem_data.js +1 -1
  11. package/src/data/feature_index.js +43 -82
  12. package/src/data/program_configuration.js +19 -11
  13. package/src/data/segment.js +2 -2
  14. package/src/geo/transform.js +4 -2
  15. package/src/gl/color_mode.js +6 -6
  16. package/src/index.js +3 -1
  17. package/src/render/glyph_atlas.js +1 -1
  18. package/src/render/glyph_manager.js +43 -48
  19. package/src/render/image_atlas.js +1 -1
  20. package/src/render/image_manager.js +9 -37
  21. package/src/source/geojson_source.js +49 -93
  22. package/src/source/geojson_worker_source.js +33 -134
  23. package/src/source/image_source.js +9 -14
  24. package/src/source/load_tilejson.js +27 -34
  25. package/src/source/raster_dem_tile_source.js +27 -40
  26. package/src/source/raster_tile_source.js +53 -62
  27. package/src/source/rtl_text_plugin.js +3 -1
  28. package/src/source/source_cache.js +23 -21
  29. package/src/source/source_state.js +17 -26
  30. package/src/source/tile.js +6 -5
  31. package/src/source/tile_id.js +1 -1
  32. package/src/source/vector_tile_source.js +56 -73
  33. package/src/source/vector_tile_worker_source.js +20 -85
  34. package/src/source/worker.js +37 -103
  35. package/src/source/worker_tile.js +39 -84
  36. package/src/style/load_sprite.js +14 -17
  37. package/src/style/properties.js +1 -1
  38. package/src/style/style.js +22 -37
  39. package/src/style/style_layer/symbol_style_layer_properties.js +1 -1
  40. package/src/style/style_layer_index.js +17 -23
  41. package/src/style-spec/expression/compound_expression.js +30 -16
  42. package/src/style-spec/expression/definitions/coercion.js +13 -0
  43. package/src/style-spec/expression/definitions/comparison.js +193 -0
  44. package/src/style-spec/expression/definitions/formatted.js +123 -0
  45. package/src/style-spec/expression/definitions/index.js +10 -60
  46. package/src/style-spec/expression/definitions/interpolate.js +17 -7
  47. package/src/style-spec/expression/definitions/literal.js +5 -0
  48. package/src/style-spec/expression/parsing_context.js +4 -0
  49. package/src/style-spec/expression/types.js +12 -1
  50. package/src/style-spec/feature_filter/index.js +1 -1
  51. package/src/style-spec/reference/v8.json +120 -49
  52. package/src/symbol/anchor.js +1 -1
  53. package/src/symbol/collision_index.js +23 -16
  54. package/src/symbol/get_anchors.js +11 -22
  55. package/src/symbol/grid_index.js +176 -182
  56. package/src/symbol/mergelines.js +51 -48
  57. package/src/symbol/opacity_state.js +1 -1
  58. package/src/symbol/placement.js +8 -2
  59. package/src/symbol/quads.js +7 -6
  60. package/src/symbol/shaping.js +185 -40
  61. package/src/symbol/symbol_layout.js +9 -6
  62. package/src/symbol/transform_text.js +12 -1
  63. package/src/ui/camera.js +82 -85
  64. package/src/ui/map.js +13 -57
  65. package/src/util/actor.js +46 -42
  66. package/src/util/browser.js +6 -0
  67. package/src/util/dictionary_coder.js +13 -21
  68. package/src/util/dispatcher.js +14 -17
  69. package/src/util/image.js +1 -1
  70. package/src/util/loader/image.js +11 -11
  71. package/src/util/polyfill.js +16 -0
  72. package/src/util/task_queue.js +39 -43
  73. package/src/util/transfer_registry.js +167 -0
  74. package/src/util/web_worker_transfer.js +5 -190
  75. package/src/source/raster_dem_tile_worker_source.js +0 -26
  76. package/src/style-spec/expression/definitions/equals.js +0 -93
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.46.2"
2
+ "version": "0.47.2"
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.47.1",
4
+ "version": "0.48.0",
5
5
  "main": "src/index.js",
6
6
  "license": "BSD-3-Clause",
7
7
  "repository": {
@@ -26,7 +26,6 @@
26
26
  "grid-index": "^1.1.0",
27
27
  "quickselect": "^2.0.0",
28
28
  "supercluster": "^2.0.1",
29
- "tile-cache": "^1.0.2",
30
29
  "tinyqueue": "^1.1.0"
31
30
  },
32
31
  "browser": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  const assert = require('assert');
4
4
  const { Struct, StructArray } = require('../util/struct_array');
5
- const { register } = require('../util/web_worker_transfer');
5
+ const { register } = require('../util/transfer_registry');
6
6
  const Point = require('@mapbox/point-geometry');
7
7
 
8
8
  /**
@@ -6,7 +6,7 @@ const { ProgramConfigurationSet } = require('../program_configuration');
6
6
  const { TriangleIndexArray } = require('../index_array_type');
7
7
  const loadGeometry = require('../load_geometry');
8
8
  const EXTENT = require('../extent');
9
- const { register } = require('../../util/web_worker_transfer');
9
+ const { register } = require('../../util/transfer_registry');
10
10
  const EvaluationParameters = require('../../style/evaluation_parameters');
11
11
 
12
12
  function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) {
@@ -8,7 +8,7 @@ const earcut = require('earcut');
8
8
  const classifyRings = require('../../util/classify_rings');
9
9
  const assert = require('assert');
10
10
  const EARCUT_MAX_RINGS = 500;
11
- const { register } = require('../../util/web_worker_transfer');
11
+ const { register } = require('../../util/transfer_registry');
12
12
  const { hasPattern, addPatternDependencies } = require('./pattern_bucket_features');
13
13
  const loadGeometry = require('../load_geometry');
14
14
  const EvaluationParameters = require('../../style/evaluation_parameters');
@@ -12,7 +12,7 @@ const {
12
12
  const classifyRings = require('../../util/classify_rings');
13
13
  const assert = require('assert');
14
14
  const EARCUT_MAX_RINGS = 500;
15
- const { register } = require('../../util/web_worker_transfer');
15
+ const { register } = require('../../util/transfer_registry');
16
16
  const { hasPattern, addPatternDependencies } = require('./pattern_bucket_features');
17
17
  const loadGeometry = require('../load_geometry');
18
18
  const EvaluationParameters = require('../../style/evaluation_parameters');
@@ -1,6 +1,6 @@
1
1
  const CircleBucket = require('./circle_bucket');
2
2
 
3
- const { register } = require('../../util/web_worker_transfer');
3
+ const { register } = require('../../util/transfer_registry');
4
4
 
5
5
  class HeatmapBucket extends CircleBucket {
6
6
  // Needed for flow to accept omit: ['layers'] below, due to
@@ -7,7 +7,7 @@ const { TriangleIndexArray } = require('../index_array_type');
7
7
  const EXTENT = require('../extent');
8
8
  const mvt = require('@mapbox/vector-tile');
9
9
  const vectorTileFeatureTypes = mvt.VectorTileFeature.types;
10
- const { register } = require('../../util/web_worker_transfer');
10
+ const { register } = require('../../util/transfer_registry');
11
11
  const { hasPattern, addPatternDependencies } = require('./pattern_bucket_features');
12
12
  const loadGeometry = require('../load_geometry');
13
13
  const EvaluationParameters = require('../../style/evaluation_parameters');
@@ -29,8 +29,9 @@ const mvt = require('@mapbox/vector-tile');
29
29
  const vectorTileFeatureTypes = mvt.VectorTileFeature.types;
30
30
  const { verticalizedCharacterMap } = require('../../util/verticalize_punctuation');
31
31
  const { getSizeData } = require('../../symbol/symbol_size');
32
- const { register } = require('../../util/web_worker_transfer');
32
+ const { register } = require('../../util/transfer_registry');
33
33
  const EvaluationParameters = require('../../style/evaluation_parameters');
34
+ const { Formatted } = require('../../style-spec/expression/definitions/formatted');
34
35
 
35
36
  // Opacity arrays are frequently updated but don't contain a lot of information, so we pack them
36
37
  // tight. Each Uint32 is actually four duplicate Uint8s for the four corners of a glyph
@@ -221,6 +222,18 @@ class SymbolBucket {
221
222
  this.lineVertexArray = new SymbolLineVertexArray();
222
223
  }
223
224
 
225
+ calculateGlyphDependencies(text, stack, textAlongLine, doesAllowVerticalWritingMode) {
226
+ for (let i = 0; i < text.length; i++) {
227
+ stack[text.charCodeAt(i)] = true;
228
+ if (textAlongLine && doesAllowVerticalWritingMode) {
229
+ const verticalChar = verticalizedCharacterMap[text.charAt(i)];
230
+ if (verticalChar) {
231
+ stack[verticalChar.charCodeAt(0)] = true;
232
+ }
233
+ }
234
+ }
235
+ }
236
+
224
237
  populate(features, options) {
225
238
  const layer = this.layers[0];
226
239
  const layout = layer.layout;
@@ -229,7 +242,7 @@ class SymbolBucket {
229
242
  const textField = layout.get('text-field');
230
243
  const iconImage = layout.get('icon-image');
231
244
  const hasText =
232
- (textField.value.kind !== 'constant' || textField.value.value.length > 0) &&
245
+ (textField.value.kind !== 'constant' || textField.value.value.toString().length > 0) &&
233
246
  (textFont.value.kind !== 'constant' || textFont.value.value.length > 0);
234
247
  const hasIcon = iconImage.value.kind !== 'constant' || (iconImage.value.value && iconImage.value.value.length > 0);
235
248
 
@@ -286,15 +299,16 @@ class SymbolBucket {
286
299
  const stack = (stacks[fontStack] = stacks[fontStack] || {});
287
300
  const textAlongLine =
288
301
  layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point';
289
- const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text);
290
- for (let i = 0; i < text.length; i++) {
291
- stack[text.charCodeAt(i)] = true;
292
- if (textAlongLine && doesAllowVerticalWritingMode) {
293
- const verticalChar = verticalizedCharacterMap[text.charAt(i)];
294
- if (verticalChar) {
295
- stack[verticalChar.charCodeAt(0)] = true;
296
- }
302
+ if (text instanceof Formatted) {
303
+ for (const section of text.sections) {
304
+ const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text.toString());
305
+ const sectionFont = section.fontStack || fontStack;
306
+ const sectionStack = (stacks[sectionFont] = stacks[sectionFont] || {});
307
+ this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, doesAllowVerticalWritingMode);
297
308
  }
309
+ } else {
310
+ const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text);
311
+ this.calculateGlyphDependencies(text, stack, textAlongLine, doesAllowVerticalWritingMode);
298
312
  }
299
313
  }
300
314
  }
@@ -642,8 +656,8 @@ class SymbolBucket {
642
656
  symbolInstanceIndexes.sort((aIndex, bIndex) => {
643
657
  const a = this.symbolInstances[aIndex];
644
658
  const b = this.symbolInstances[bIndex];
645
- const aRotated = (sin * a.anchor.x + cos * a.anchor.y) | 0;
646
- const bRotated = (sin * b.anchor.x + cos * b.anchor.y) | 0;
659
+ const aRotated = Math.round(sin * a.anchor.x + cos * a.anchor.y) | 0;
660
+ const bRotated = Math.round(sin * b.anchor.x + cos * b.anchor.y) | 0;
647
661
  return aRotated - bRotated || b.featureIndex - a.featureIndex;
648
662
  });
649
663
 
@@ -1,7 +1,7 @@
1
1
  const { RGBAImage } = require('../util/image');
2
2
 
3
3
  const warn = require('../util/warn');
4
- const { register } = require('../util/web_worker_transfer');
4
+ const { register } = require('../util/transfer_registry');
5
5
 
6
6
  // DEMData is a data structure for decoding, backfilling, and storing elevation data for processing in the hillshade shaders
7
7
  // data can be populated either from a pngraw image tile or from serliazed data sent back from a worker. When data is initially
@@ -2,26 +2,23 @@ const loadGeometry = require('./load_geometry');
2
2
  const EXTENT = require('./extent');
3
3
  const featureFilter = require('../style-spec/feature_filter');
4
4
  const Grid = require('grid-index');
5
- const DictionaryCoder = require('../util/dictionary_coder');
5
+ const dictionaryCoder = require('../util/dictionary_coder');
6
6
  const vt = require('@mapbox/vector-tile');
7
7
  const Protobuf = require('@mapwhit/pbf');
8
8
  const GeoJSONFeature = require('../util/vectortile_to_geojson');
9
9
  const { arraysIntersect } = require('../util/object');
10
- const { register } = require('../util/web_worker_transfer');
10
+ const { register } = require('../util/transfer_registry');
11
11
  const EvaluationParameters = require('../style/evaluation_parameters');
12
12
  const { polygonIntersectsBox } = require('../util/intersection_tests');
13
13
 
14
14
  const { FeatureIndexArray } = require('./array_types');
15
15
 
16
16
  class FeatureIndex {
17
- constructor(tileID, grid, featureIndexArray) {
17
+ constructor(tileID, grid = new Grid(EXTENT, 16, 0), featureIndexArray = new FeatureIndexArray()) {
18
18
  this.tileID = tileID;
19
- this.x = tileID.canonical.x;
20
- this.y = tileID.canonical.y;
21
- this.z = tileID.canonical.z;
22
- this.grid = grid || new Grid(EXTENT, 16, 0);
19
+ this.grid = grid;
23
20
  this.grid3D = new Grid(EXTENT, 16, 0);
24
- this.featureIndexArray = featureIndexArray || new FeatureIndexArray();
21
+ this.featureIndexArray = featureIndexArray;
25
22
  }
26
23
 
27
24
  insert(feature, geometry, featureIndex, sourceLayerIndex, bucketIndex, is3D) {
@@ -30,25 +27,10 @@ class FeatureIndex {
30
27
 
31
28
  const grid = is3D ? this.grid3D : this.grid;
32
29
 
33
- for (let r = 0; r < geometry.length; r++) {
34
- const ring = geometry[r];
35
-
36
- const bbox = [
37
- Number.POSITIVE_INFINITY,
38
- Number.POSITIVE_INFINITY,
39
- Number.NEGATIVE_INFINITY,
40
- Number.NEGATIVE_INFINITY
41
- ];
42
- for (let i = 0; i < ring.length; i++) {
43
- const p = ring[i];
44
- bbox[0] = Math.min(bbox[0], p.x);
45
- bbox[1] = Math.min(bbox[1], p.y);
46
- bbox[2] = Math.max(bbox[2], p.x);
47
- bbox[3] = Math.max(bbox[3], p.y);
48
- }
49
-
50
- if (bbox[0] < EXTENT && bbox[1] < EXTENT && bbox[2] >= 0 && bbox[3] >= 0) {
51
- grid.insert(key, bbox[0], bbox[1], bbox[2], bbox[3]);
30
+ for (const ring of geometry) {
31
+ const { minX, minY, maxX, maxY } = getBounds(ring);
32
+ if (minX < EXTENT && minY < EXTENT && maxX >= 0 && maxY >= 0) {
33
+ grid.insert(key, minX, minY, maxX, maxY);
52
34
  }
53
35
  }
54
36
  }
@@ -56,9 +38,7 @@ class FeatureIndex {
56
38
  loadVTLayers() {
57
39
  if (!this.vtLayers) {
58
40
  this.vtLayers = new vt.VectorTile(new Protobuf(this.rawTileData)).layers;
59
- this.sourceLayerCoder = new DictionaryCoder(
60
- this.vtLayers ? Object.keys(this.vtLayers).sort() : ['_geojsonTileLayer']
61
- );
41
+ this.sourceLayerCoder = dictionaryCoder(this.vtLayers ? Object.keys(this.vtLayers) : ['_geojsonTileLayer']);
62
42
  }
63
43
  return this.vtLayers;
64
44
  }
@@ -99,10 +79,7 @@ class FeatureIndex {
99
79
  }
100
80
  );
101
81
 
102
- for (const key of matching3D) {
103
- matching.push(key);
104
- }
105
-
82
+ matching.push(...matching3D);
106
83
  matching.sort(topDownFeatureComparator);
107
84
 
108
85
  const result = {};
@@ -116,6 +93,26 @@ class FeatureIndex {
116
93
 
117
94
  const match = this.featureIndexArray.get(index);
118
95
  let featureGeometry = null;
96
+ const intersectionTest = (feature, styleLayer) => {
97
+ if (!featureGeometry) {
98
+ featureGeometry = loadGeometry(feature);
99
+ }
100
+ let featureState = {};
101
+ if (feature.id) {
102
+ // `feature-state` expression evaluation requires feature state to be available
103
+ featureState = sourceFeatureState.getState(styleLayer.sourceLayer || '_geojsonTileLayer', String(feature.id));
104
+ }
105
+ return styleLayer.queryIntersectsFeature(
106
+ queryGeometry,
107
+ feature,
108
+ featureState,
109
+ featureGeometry,
110
+ this.tileID.canonical.z,
111
+ args.transform,
112
+ pixelsToTileUnits,
113
+ args.pixelPosMatrix
114
+ );
115
+ };
119
116
  this.loadMatchingFeature(
120
117
  result,
121
118
  match.bucketIndex,
@@ -124,29 +121,7 @@ class FeatureIndex {
124
121
  filter,
125
122
  params.layers,
126
123
  styleLayers,
127
- (feature, styleLayer) => {
128
- if (!featureGeometry) {
129
- featureGeometry = loadGeometry(feature);
130
- }
131
- let featureState = {};
132
- if (feature.id) {
133
- // `feature-state` expression evaluation requires feature state to be available
134
- featureState = sourceFeatureState.getState(
135
- styleLayer.sourceLayer || '_geojsonTileLayer',
136
- String(feature.id)
137
- );
138
- }
139
- return styleLayer.queryIntersectsFeature(
140
- queryGeometry,
141
- feature,
142
- featureState,
143
- featureGeometry,
144
- this.z,
145
- args.transform,
146
- pixelsToTileUnits,
147
- args.pixelPosMatrix
148
- );
149
- }
124
+ intersectionTest
150
125
  );
151
126
  }
152
127
 
@@ -172,10 +147,9 @@ class FeatureIndex {
172
147
 
173
148
  if (!filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) return;
174
149
 
175
- for (let l = 0; l < layerIDs.length; l++) {
176
- const layerID = layerIDs[l];
177
-
178
- if (filterLayerIDs && filterLayerIDs.indexOf(layerID) < 0) {
150
+ const { x, y, z } = this.tileID.canonical;
151
+ for (const layerID of layerIDs) {
152
+ if (filterLayerIDs && !filterLayerIDs.includes(layerID)) {
179
153
  continue;
180
154
  }
181
155
 
@@ -188,13 +162,10 @@ class FeatureIndex {
188
162
  continue;
189
163
  }
190
164
 
191
- const geojsonFeature = new GeoJSONFeature(feature, this.z, this.x, this.y);
165
+ const geojsonFeature = new GeoJSONFeature(feature, z, x, y);
192
166
  geojsonFeature.layer = styleLayer.serialize();
193
- let layerResult = result[layerID];
194
- if (layerResult === undefined) {
195
- layerResult = result[layerID] = [];
196
- }
197
- layerResult.push({ featureIndex: featureIndex, feature: geojsonFeature, intersectionZ });
167
+ const layerResult = (result[layerID] ??= []);
168
+ layerResult.push({ featureIndex, feature: geojsonFeature, intersectionZ });
198
169
  }
199
170
  }
200
171
 
@@ -219,16 +190,6 @@ class FeatureIndex {
219
190
  }
220
191
  return result;
221
192
  }
222
-
223
- hasLayer(id) {
224
- for (const layerIDs of this.bucketLayerIDs) {
225
- for (const layerID of layerIDs) {
226
- if (id === layerID) return true;
227
- }
228
- }
229
-
230
- return false;
231
- }
232
193
  }
233
194
 
234
195
  register('FeatureIndex', FeatureIndex, { omit: ['rawTileData', 'sourceLayerCoder'] });
@@ -240,11 +201,11 @@ function getBounds(geometry) {
240
201
  let minY = Number.POSITIVE_INFINITY;
241
202
  let maxX = Number.NEGATIVE_INFINITY;
242
203
  let maxY = Number.NEGATIVE_INFINITY;
243
- for (const p of geometry) {
244
- minX = Math.min(minX, p.x);
245
- minY = Math.min(minY, p.y);
246
- maxX = Math.max(maxX, p.x);
247
- maxY = Math.max(maxY, p.y);
204
+ for (const { x, y } of geometry) {
205
+ if (x < minX) minX = x;
206
+ if (x > maxX) maxX = x;
207
+ if (y < minY) minY = y;
208
+ if (y > maxY) maxY = y;
248
209
  }
249
210
  return { minX, minY, maxX, maxY };
250
211
  }
@@ -1,6 +1,6 @@
1
1
  const { packUint8ToFloat } = require('../shaders/encode_attribute');
2
2
  const { supportsPropertyExpression } = require('../style-spec/util/properties');
3
- const { register } = require('../util/web_worker_transfer');
3
+ const { register } = require('../util/transfer_registry');
4
4
  const { PossiblyEvaluatedPropertyValue } = require('../style/properties');
5
5
  const {
6
6
  StructArrayLayout1f4,
@@ -170,11 +170,15 @@ class SourceExpressionBinder {
170
170
 
171
171
  upload(context) {
172
172
  if (this.paintVertexArray?.arrayBuffer) {
173
- this.paintVertexBuffer = context.createVertexBuffer(
174
- this.paintVertexArray,
175
- this.paintVertexAttributes,
176
- this.expression.isStateDependent
177
- );
173
+ if (this.paintVertexBuffer?.buffer) {
174
+ this.paintVertexBuffer.updateData(this.paintVertexArray);
175
+ } else {
176
+ this.paintVertexBuffer = context.createVertexBuffer(
177
+ this.paintVertexArray,
178
+ this.paintVertexAttributes,
179
+ this.expression.isStateDependent
180
+ );
181
+ }
178
182
  }
179
183
  }
180
184
 
@@ -265,11 +269,15 @@ class CompositeExpressionBinder {
265
269
 
266
270
  upload(context) {
267
271
  if (this.paintVertexArray?.arrayBuffer) {
268
- this.paintVertexBuffer = context.createVertexBuffer(
269
- this.paintVertexArray,
270
- this.paintVertexAttributes,
271
- this.expression.isStateDependent
272
- );
272
+ if (this.paintVertexBuffer?.buffer) {
273
+ this.paintVertexBuffer.updateData(this.paintVertexArray);
274
+ } else {
275
+ this.paintVertexBuffer = context.createVertexBuffer(
276
+ this.paintVertexArray,
277
+ this.paintVertexAttributes,
278
+ this.expression.isStateDependent
279
+ );
280
+ }
273
281
  }
274
282
  }
275
283
 
@@ -1,6 +1,6 @@
1
1
  const warn = require('../util/warn');
2
2
 
3
- const { register } = require('../util/web_worker_transfer');
3
+ const { register } = require('../util/transfer_registry');
4
4
 
5
5
  class SegmentVector {
6
6
  constructor(segments = []) {
@@ -8,11 +8,11 @@ class SegmentVector {
8
8
  }
9
9
 
10
10
  prepareSegment(numVertices, layoutVertexArray, indexArray) {
11
- let segment = this.segments[this.segments.length - 1];
12
11
  if (numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH)
13
12
  warn.once(
14
13
  `Max vertices per segment is ${SegmentVector.MAX_VERTEX_ARRAY_LENGTH}: bucket requested ${numVertices}`
15
14
  );
15
+ let segment = this.segments.at(-1);
16
16
  if (!segment || segment.vertexLength + numVertices > SegmentVector.MAX_VERTEX_ARRAY_LENGTH) {
17
17
  segment = {
18
18
  vertexOffset: layoutVertexArray.length,
@@ -17,12 +17,13 @@ const { vec4, mat4, mat2 } = require('@mapbox/gl-matrix');
17
17
  class Transform {
18
18
  constructor(minZoom, maxZoom, renderWorldCopies) {
19
19
  this.tileSize = 512; // constant
20
+ this.maxValidLatitude = 85.051129; // constant
20
21
 
21
22
  this._renderWorldCopies = renderWorldCopies === undefined ? true : renderWorldCopies;
22
23
  this._minZoom = minZoom || 0;
23
24
  this._maxZoom = maxZoom || 22;
24
25
 
25
- this.latRange = [-85.05113, 85.05113];
26
+ this.latRange = [-this.maxValidLatitude, this.maxValidLatitude];
26
27
 
27
28
  this.width = 0;
28
29
  this.height = 0;
@@ -262,7 +263,7 @@ class Transform {
262
263
  }
263
264
 
264
265
  /**
265
- * latitude to absolute x coord
266
+ * longitude to absolute x coord
266
267
  * @returns {number} pixel coordinate
267
268
  */
268
269
  lngX(lng) {
@@ -273,6 +274,7 @@ class Transform {
273
274
  * @returns {number} pixel coordinate
274
275
  */
275
276
  latY(lat) {
277
+ lat = clamp(lat, -this.maxValidLatitude, this.maxValidLatitude);
276
278
  const y = (180 / Math.PI) * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
277
279
  return ((180 - y) * this.worldSize) / 360;
278
280
  }
@@ -5,6 +5,12 @@ const ONE = 0x0001;
5
5
  const ONE_MINUS_SRC_ALPHA = 0x0303;
6
6
 
7
7
  class ColorMode {
8
+ static Replace = [ONE, ZERO];
9
+
10
+ static disabled = new ColorMode(ColorMode.Replace, Color.transparent, [false, false, false, false]);
11
+ static unblended = new ColorMode(ColorMode.Replace, Color.transparent, [true, true, true, true]);
12
+ static alphaBlended = new ColorMode([ONE, ONE_MINUS_SRC_ALPHA], Color.transparent, [true, true, true, true]);
13
+
8
14
  constructor(blendFunction, blendColor, mask) {
9
15
  this.blendFunction = blendFunction;
10
16
  this.blendColor = blendColor;
@@ -12,10 +18,4 @@ class ColorMode {
12
18
  }
13
19
  }
14
20
 
15
- ColorMode.Replace = [ONE, ZERO];
16
-
17
- ColorMode.disabled = new ColorMode(ColorMode.Replace, Color.transparent, [false, false, false, false]);
18
- ColorMode.unblended = new ColorMode(ColorMode.Replace, Color.transparent, [true, true, true, true]);
19
- ColorMode.alphaBlended = new ColorMode([ONE, ONE_MINUS_SRC_ALPHA], Color.transparent, [true, true, true, true]);
20
-
21
21
  module.exports = ColorMode;
package/src/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ require('./util/polyfill');
2
+
1
3
  module.exports = {
2
4
  version: require('../package.json').version,
3
5
  setRTLTextPlugin: require('./source/rtl_text_plugin').setRTLTextPlugin,
@@ -41,7 +43,7 @@ module.exports = {
41
43
  * @param {string} pluginURL URL pointing to the Mapbox RTL text plugin source.
42
44
  * @param {Function} callback Called with an error argument if there is an error.
43
45
  * @example
44
- * mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.1.2/mapbox-gl-rtl-text.js');
46
+ * mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.0/mapbox-gl-rtl-text.js');
45
47
  * @see [Add support for right-to-left scripts](https://www.mapbox.com/mapbox-gl-js/example/mapbox-gl-rtl-text/)
46
48
  */
47
49
 
@@ -1,7 +1,7 @@
1
1
  const ShelfPack = require('@mapbox/shelf-pack');
2
2
 
3
3
  const { AlphaImage } = require('../util/image');
4
- const { register } = require('../util/web_worker_transfer');
4
+ const { register } = require('../util/transfer_registry');
5
5
 
6
6
  const padding = 1;
7
7
 
@@ -3,7 +3,6 @@ const loadGlyphRange = require('../style/load_glyph_range');
3
3
  const TinySDF = require('@mapbox/tiny-sdf');
4
4
  const isChar = require('../util/is_char_in_unicode_block');
5
5
  const { AlphaImage } = require('../util/image');
6
- const { callback } = require('../util/callback');
7
6
 
8
7
  class GlyphManager {
9
8
  // exposed as statics to enable stubbing in unit tests
@@ -19,62 +18,58 @@ class GlyphManager {
19
18
  this.loader = loader;
20
19
  }
21
20
 
22
- getGlyphs(glyphs, fn) {
23
- return callback(fn, perform.call(this, glyphs));
24
-
25
- async function perform(glyphs) {
26
- const all = [];
27
- for (const stack in glyphs) {
28
- for (const id of glyphs[stack]) {
29
- all.push(retrieveGlyph(this, { stack, id }));
30
- }
21
+ async getGlyphs(glyphs) {
22
+ const all = [];
23
+ for (const stack in glyphs) {
24
+ for (const id of glyphs[stack]) {
25
+ all.push(retrieveGlyph(this, { stack, id }));
31
26
  }
32
- const fetchedGlyphs = await Promise.all(all);
33
- const result = {};
34
- for (const { stack, id, glyph } of fetchedGlyphs) {
35
- // Clone the glyph so that our own copy of its ArrayBuffer doesn't get transferred.
36
- (result[stack] ??= {})[id] = cloneGlyph(glyph);
37
- }
38
- return result;
39
-
40
- function cloneGlyph(glyph) {
41
- if (glyph) {
42
- return {
43
- id: glyph.id,
44
- bitmap: glyph.bitmap.clone(),
45
- metrics: glyph.metrics
46
- };
47
- }
27
+ }
28
+ const fetchedGlyphs = await Promise.all(all);
29
+ const result = {};
30
+ for (const { stack, id, glyph } of fetchedGlyphs) {
31
+ // Clone the glyph so that our own copy of its ArrayBuffer doesn't get transferred.
32
+ (result[stack] ??= {})[id] = cloneGlyph(glyph);
33
+ }
34
+ return result;
35
+
36
+ function cloneGlyph(glyph) {
37
+ if (glyph) {
38
+ return {
39
+ id: glyph.id,
40
+ bitmap: glyph.bitmap.clone(),
41
+ metrics: glyph.metrics
42
+ };
48
43
  }
44
+ }
49
45
 
50
- async function retrieveGlyph({ entries, loader, localIdeographFontFamily }, { stack, id }) {
51
- const entry = (entries[stack] ??= { glyphs: {}, requests: {} });
46
+ async function retrieveGlyph({ entries, loader, localIdeographFontFamily }, { stack, id }) {
47
+ const entry = (entries[stack] ??= { glyphs: {}, requests: {} });
52
48
 
53
- let glyph = entry.glyphs[id];
54
- if (glyph) {
55
- return { stack, id, glyph };
56
- }
49
+ let glyph = entry.glyphs[id];
50
+ if (glyph) {
51
+ return { stack, id, glyph };
52
+ }
57
53
 
58
- glyph = tinySDF(localIdeographFontFamily, entry, stack, id);
59
- if (glyph) {
60
- return { stack, id, glyph };
61
- }
54
+ glyph = tinySDF(localIdeographFontFamily, entry, stack, id);
55
+ if (glyph) {
56
+ return { stack, id, glyph };
57
+ }
62
58
 
63
- const range = Math.floor(id / 256);
64
- if (range * 256 > 65535) {
65
- throw new Error('glyphs > 65535 not supported');
66
- }
59
+ const range = Math.floor(id / 256);
60
+ if (range * 256 > 65535) {
61
+ throw new Error('glyphs > 65535 not supported');
62
+ }
67
63
 
68
- const promise = (entry.requests[range] ??= GlyphManager.loadGlyphRange(stack, range, loader));
69
- const response = await promise;
70
- if (response) {
71
- for (const id in response) {
72
- entry.glyphs[+id] = response[+id];
73
- }
64
+ const promise = (entry.requests[range] ??= GlyphManager.loadGlyphRange(stack, range, loader));
65
+ const response = await promise;
66
+ if (response) {
67
+ for (const id in response) {
68
+ entry.glyphs[+id] = response[+id];
74
69
  }
75
- delete entry.requests[range];
76
- return { stack, id, glyph: response?.[id] || null };
77
70
  }
71
+ delete entry.requests[range];
72
+ return { stack, id, glyph: response?.[id] || null };
78
73
  }
79
74
  }
80
75
  }
@@ -1,7 +1,7 @@
1
1
  const ShelfPack = require('@mapbox/shelf-pack');
2
2
 
3
3
  const { RGBAImage } = require('../util/image');
4
- const { register } = require('../util/web_worker_transfer');
4
+ const { register } = require('../util/transfer_registry');
5
5
 
6
6
  const padding = 1;
7
7