maplibre-gl 2.2.1 → 2.3.1-pre.2

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 (78) hide show
  1. package/build/generate-query-test-fixtures.ts +3 -2
  2. package/build/generate-struct-arrays.ts +0 -2
  3. package/build/generate-style-spec.ts +12 -17
  4. package/build/generate-typings.ts +11 -1
  5. package/build/rollup_plugins.ts +0 -4
  6. package/dist/maplibre-gl-csp-worker.js +1 -1
  7. package/dist/maplibre-gl-csp.js +1 -1
  8. package/dist/maplibre-gl-dev.js +376 -1402
  9. package/dist/maplibre-gl.d.ts +13 -16
  10. package/dist/maplibre-gl.js +4 -4
  11. package/dist/style-spec/index.d.ts +1768 -0
  12. package/package.json +14 -16
  13. package/src/data/array_types.g.ts +0 -5
  14. package/src/data/bucket/fill_bucket.ts +0 -2
  15. package/src/data/bucket/fill_extrusion_bucket.ts +0 -2
  16. package/src/data/bucket/symbol_bucket.test.ts +30 -19
  17. package/src/data/feature_position_map.ts +1 -2
  18. package/src/gl/framebuffer.ts +3 -2
  19. package/src/gl/index_buffer.ts +1 -2
  20. package/src/gl/vertex_buffer.ts +1 -2
  21. package/src/index.test.ts +9 -0
  22. package/src/index.ts +12 -4
  23. package/src/render/image_manager.ts +5 -7
  24. package/src/render/program/pattern.ts +0 -2
  25. package/src/render/program.ts +12 -9
  26. package/src/render/vertex_array_object.ts +1 -3
  27. package/src/source/geojson_worker_source.ts +0 -4
  28. package/src/source/query_features.ts +0 -3
  29. package/src/source/rtl_text_plugin.ts +3 -4
  30. package/src/source/source_cache.ts +0 -2
  31. package/src/source/tile_id.ts +8 -8
  32. package/src/source/worker.ts +0 -7
  33. package/src/source/worker_tile.ts +12 -3
  34. package/src/style/format_section_override.ts +1 -2
  35. package/src/style/properties.ts +1 -3
  36. package/src/style/style.ts +5 -5
  37. package/src/style/style_layer/custom_style_layer.ts +1 -2
  38. package/src/style/style_layer/symbol_style_layer.ts +1 -3
  39. package/src/style-spec/CHANGELOG.md +10 -0
  40. package/src/style-spec/composite.test.ts +7 -8
  41. package/src/style-spec/expression/compound_expression.ts +0 -4
  42. package/src/style-spec/expression/definitions/assertion.ts +2 -4
  43. package/src/style-spec/expression/definitions/case.ts +1 -2
  44. package/src/style-spec/expression/definitions/coalesce.ts +1 -3
  45. package/src/style-spec/expression/definitions/coercion.ts +2 -4
  46. package/src/style-spec/expression/definitions/match.ts +0 -3
  47. package/src/style-spec/expression/index.ts +13 -15
  48. package/src/style-spec/expression/parsing_context.ts +4 -4
  49. package/src/style-spec/expression/parsing_error.ts +2 -2
  50. package/src/style-spec/expression/values.ts +0 -2
  51. package/src/style-spec/feature_filter/feature_filter.test.ts +39 -2
  52. package/src/style-spec/function/convert.ts +1 -3
  53. package/src/style-spec/migrate/v8.test.ts +12 -14
  54. package/src/style-spec/migrate/v9.test.ts +2 -4
  55. package/src/style-spec/migrate.test.ts +6 -8
  56. package/src/style-spec/package.json +2 -1
  57. package/src/style-spec/types.g.ts +12 -17
  58. package/src/symbol/collision_index.ts +0 -3
  59. package/src/symbol/path_interpolator.ts +0 -2
  60. package/src/symbol/placement.ts +14 -9
  61. package/src/symbol/shaping.ts +0 -4
  62. package/src/symbol/symbol_layout.ts +56 -56
  63. package/src/ui/camera.ts +0 -10
  64. package/src/ui/control/geolocate_control.ts +4 -6
  65. package/src/ui/handler/handler_util.ts +1 -2
  66. package/src/ui/handler/scroll_zoom.ts +0 -2
  67. package/src/ui/handler_manager.ts +0 -2
  68. package/src/ui/map.test.ts +11 -0
  69. package/src/ui/map.ts +11 -0
  70. package/src/util/ajax.ts +1 -2
  71. package/src/util/color_ramp.ts +1 -2
  72. package/src/util/dictionary_coder.ts +1 -3
  73. package/src/util/dispatcher.ts +1 -4
  74. package/src/util/dom.ts +0 -3
  75. package/src/util/image.ts +1 -3
  76. package/src/util/struct_array.ts +0 -5
  77. package/src/util/task_queue.ts +1 -3
  78. package/src/util/web_worker_transfer.ts +5 -6
@@ -1,4 +1,4 @@
1
- import assert from 'assert';
1
+
2
2
  import type {StylePropertySpecification} from '../style-spec';
3
3
 
4
4
  export default convertFunction;
@@ -138,7 +138,6 @@ function convertPropertyFunction(parameters, propertySpec, stops) {
138
138
  const type = getFunctionType(parameters, propertySpec);
139
139
  const get = ['get', parameters.property];
140
140
  if (type === 'categorical' && typeof stops[0][0] === 'boolean') {
141
- assert(parameters.stops.length > 0 && parameters.stops.length <= 2);
142
141
  const expression: any = ['case'];
143
142
  for (const stop of stops) {
144
143
  expression.push(['==', get, stop[0]], stop[1]);
@@ -236,7 +235,6 @@ function getFunctionType(parameters, propertySpec) {
236
235
  if (parameters.type) {
237
236
  return parameters.type;
238
237
  } else {
239
- assert(propertySpec.expression);
240
238
  return (propertySpec.expression as any).interpolated ? 'exponential' : 'interval';
241
239
  }
242
240
  }
@@ -1,5 +1,3 @@
1
- // @ts-nocheck
2
-
3
1
  import migrate from './v8';
4
2
 
5
3
  describe('migrate v8', () => {
@@ -23,7 +21,7 @@ describe('migrate v8', () => {
23
21
  }
24
22
  }
25
23
  ]
26
- };
24
+ } as any;
27
25
 
28
26
  const output = {
29
27
  'version': 8,
@@ -68,7 +66,7 @@ describe('migrate v8', () => {
68
66
  }
69
67
  }
70
68
  ]
71
- };
69
+ } as any;
72
70
 
73
71
  const output = {
74
72
  'version': 8,
@@ -103,7 +101,7 @@ describe('migrate v8', () => {
103
101
  }
104
102
  },
105
103
  'layers': []
106
- };
104
+ } as any;
107
105
 
108
106
  const output = {
109
107
  'version': 8,
@@ -140,7 +138,7 @@ describe('migrate v8', () => {
140
138
  }
141
139
  }
142
140
  }]
143
- };
141
+ } as any;
144
142
 
145
143
  const output = {
146
144
  'version': 8,
@@ -187,7 +185,7 @@ describe('migrate v8', () => {
187
185
  }
188
186
  }
189
187
  }]
190
- };
188
+ } as any;
191
189
 
192
190
  const output = {
193
191
  'version': 8,
@@ -233,7 +231,7 @@ describe('migrate v8', () => {
233
231
  }
234
232
  }
235
233
  ]
236
- };
234
+ } as any;
237
235
 
238
236
  const output = {
239
237
  'version': 8,
@@ -276,7 +274,7 @@ describe('migrate v8', () => {
276
274
  }
277
275
  }
278
276
  ]
279
- };
277
+ } as any;
280
278
 
281
279
  const output = {
282
280
  'version': 8,
@@ -328,7 +326,7 @@ describe('migrate v8', () => {
328
326
  }
329
327
  }
330
328
  ]
331
- };
329
+ } as any;
332
330
 
333
331
  const output = {
334
332
  'version': 8,
@@ -389,7 +387,7 @@ describe('migrate v8', () => {
389
387
  }
390
388
  }
391
389
  ]
392
- };
390
+ } as any;
393
391
 
394
392
  const output = {
395
393
  'version': 8,
@@ -445,7 +443,7 @@ describe('migrate v8', () => {
445
443
  }
446
444
  }
447
445
  ]
448
- };
446
+ } as any;
449
447
 
450
448
  const output = {
451
449
  'version': 8,
@@ -479,7 +477,7 @@ describe('migrate v8', () => {
479
477
  'version': 7,
480
478
  'glyphs': 'mapbox://fontstack/{fontstack}/{range}.pbf',
481
479
  'layers': []
482
- };
480
+ } as any;
483
481
 
484
482
  const output = {
485
483
  'version': 8,
@@ -495,7 +493,7 @@ describe('migrate v8', () => {
495
493
  'version': 7,
496
494
  'glyphs': 'mapbox://fonts/v1/boxmap/{fontstack}/{range}.pbf',
497
495
  'layers': []
498
- };
496
+ } as any;
499
497
 
500
498
  const output = {
501
499
  'version': 8,
@@ -1,5 +1,3 @@
1
- // @ts-nocheck
2
-
3
1
  import migrate from './v9';
4
2
 
5
3
  describe('migrate v9', () => {
@@ -18,7 +16,7 @@ describe('migrate v9', () => {
18
16
  id: 'child',
19
17
  ref: 'parent'
20
18
  }]
21
- };
19
+ } as any;
22
20
 
23
21
  expect(migrate(input)).toEqual({
24
22
  version: 9,
@@ -58,7 +56,7 @@ describe('migrate v9', () => {
58
56
  'fill-color': 'blue'
59
57
  }
60
58
  }]
61
- };
59
+ } as any;
62
60
 
63
61
  expect(migrate(input)).toEqual({
64
62
  version: 9,
@@ -1,5 +1,3 @@
1
- // @ts-nocheck
2
-
3
1
  import migrate from './migrate';
4
2
  import * as spec from './style-spec';
5
3
  import v8 from './reference/v8.json';
@@ -8,18 +6,18 @@ import validate from './validate_style';
8
6
  describe('migrate', () => {
9
7
  test('does not migrate from version 5', () => {
10
8
  expect(() => {
11
- migrate({version: 5, layers: []});
9
+ migrate({version: 5, layers: []} as any);
12
10
  }).toThrow(new Error('Cannot migrate from 5'));
13
11
  });
14
12
 
15
13
  test('does not migrate from version 6', () => {
16
14
  expect(() => {
17
- migrate({version: 6, layers: []});
15
+ migrate({version: 6, layers: []} as any);
18
16
  }).toThrow(new Error('Cannot migrate from 6'));
19
17
  });
20
18
 
21
19
  test('migrates to latest version from version 7', () => {
22
- expect(migrate({version: 7, layers: []}).version).toEqual(spec.latest.$version);
20
+ expect(migrate({version: 7, layers: []} as any).version).toEqual(spec.latest.$version);
23
21
  });
24
22
 
25
23
  test('converts token strings to expressions', () => {
@@ -30,7 +28,7 @@ describe('migrate', () => {
30
28
  type: 'symbol',
31
29
  layout: {'text-field': 'a{x}', 'icon-image': '{y}'}
32
30
  }]
33
- });
31
+ } as any);
34
32
  expect(migrated.layers[0].layout['text-field']).toEqual(['concat', 'a', ['get', 'x']]);
35
33
  expect(migrated.layers[0].layout['icon-image']).toEqual(['to-string', ['get', 'y']]);
36
34
  });
@@ -57,7 +55,7 @@ describe('migrate', () => {
57
55
  }
58
56
  }
59
57
  }]
60
- });
58
+ } as any);
61
59
  expect(migrated.layers[0].paint['background-opacity']).toEqual([
62
60
  'interpolate',
63
61
  ['linear'],
@@ -101,7 +99,7 @@ describe('migrate', () => {
101
99
  }
102
100
  }
103
101
  }]
104
- });
102
+ } as any);
105
103
  expect(migrated.layers[0].layout['icon-image']).toEqual([
106
104
  'match',
107
105
  ['get', 'type'],
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maplibre/maplibre-gl-style-spec",
3
3
  "description": "a specification for maplibre gl styles",
4
- "version": "16.1.0",
4
+ "version": "17.0.1",
5
5
  "author": "MapLibre",
6
6
  "keywords": [
7
7
  "mapbox",
@@ -14,6 +14,7 @@
14
14
  "license": "ISC",
15
15
  "main": "./dist/index.cjs",
16
16
  "module": "./dist/index.mjs",
17
+ "types": "./dist/index.d.ts",
17
18
  "type": "module",
18
19
  "scripts": {
19
20
  },
@@ -24,7 +24,7 @@ export type InterpolationSpecification =
24
24
  | ['linear']
25
25
  | ['exponential', number | ExpressionSpecification]
26
26
  | ['cubic-bezier', number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification]
27
-
27
+
28
28
  export type ExpressionSpecification =
29
29
  // types
30
30
  | ['array', unknown | ExpressionSpecification] // array
@@ -70,31 +70,26 @@ export type ExpressionSpecification =
70
70
  | ['any', ...(boolean | ExpressionSpecification)[]] // boolean
71
71
  | ['case', boolean | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
72
72
  ...(boolean | ExpressionInputType | ExpressionSpecification)[], ExpressionInputType | ExpressionSpecification]
73
- | ['coalesce', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
74
- ...(ExpressionInputType | ExpressionSpecification)[]]
73
+ | ['coalesce', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required
75
74
  | ['match', ExpressionInputType | ExpressionSpecification,
76
75
  ExpressionInputType | ExpressionInputType[], ExpressionInputType | ExpressionSpecification,
77
76
  ...(ExpressionInputType | ExpressionInputType[] | ExpressionSpecification)[], // repeated as above
78
77
  ExpressionInputType]
79
78
  | ['within', unknown | ExpressionSpecification]
80
79
  // Ramps, scales, curves
81
- | ['interpolate', InterpolationSpecification,
82
- number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
83
- ...(number | ExpressionInputType | ExpressionSpecification)[]]
84
- | ['interpolate-hcl', InterpolationSpecification,
85
- number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
86
- ...(number | ColorSpecification | ExpressionSpecification)[]]
87
- | ['interpolate-lab', InterpolationSpecification,
88
- number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
89
- ...(number | ColorSpecification | ExpressionSpecification)[]]
90
- | ['step', number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
91
- ...(number | ExpressionInputType | ExpressionSpecification)[]]
80
+ | ['interpolate', InterpolationSpecification, number | ExpressionSpecification,
81
+ ...(number | number[] | ColorSpecification)[]] // alternating number and number | number[] | ColorSpecification
82
+ | ['interpolate-hcl', InterpolationSpecification, number | ExpressionSpecification,
83
+ ...(number | ColorSpecification)[]] // alternating number and ColorSpecificaton
84
+ | ['interpolate-lab', InterpolationSpecification, number | ExpressionSpecification,
85
+ ...(number | ColorSpecification)[]] // alternating number and ColorSpecification
86
+ | ['step', number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
87
+ ...(number | ExpressionInputType | ExpressionSpecification)[]] // alternating number and ExpressionInputType | ExpressionSpecification
92
88
  // Variable binding
93
89
  | ['let', string, ExpressionInputType | ExpressionSpecification, ...(string | ExpressionInputType | ExpressionSpecification)[]]
94
90
  | ['var', string]
95
91
  // String
96
- | ['concat', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
97
- ...(ExpressionInputType | ExpressionSpecification)[]] // string
92
+ | ['concat', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required -> string
98
93
  | ['downcase', string | ExpressionSpecification] // string
99
94
  | ['is-supported-script', string | ExpressionSpecification] // boolean
100
95
  | ['resolved-locale', CollatorExpressionSpecification] // string
@@ -109,7 +104,7 @@ export type ExpressionSpecification =
109
104
  | ['/', number | ExpressionSpecification, number | ExpressionSpecification] // number
110
105
  | ['%', number | ExpressionSpecification, number | ExpressionSpecification] // number
111
106
  | ['^', number | ExpressionSpecification, number | ExpressionSpecification] // number
112
- | ['+', number | ExpressionSpecification, number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
107
+ | ['+', ...(number | ExpressionSpecification)[]] // at least two inputs required -> number
113
108
  | ['abs', number | ExpressionSpecification] // number
114
109
  | ['acos', number | ExpressionSpecification] // number
115
110
  | ['asin', number | ExpressionSpecification] // number
@@ -6,7 +6,6 @@ import * as intersectionTests from '../util/intersection_tests';
6
6
  import GridIndex from './grid_index';
7
7
  import {mat4, vec4} from 'gl-matrix';
8
8
  import ONE_EM from '../symbol/one_em';
9
- import assert from 'assert';
10
9
 
11
10
  import * as projection from '../symbol/projection';
12
11
 
@@ -181,7 +180,6 @@ class CollisionIndex {
181
180
  for (let i = 1; i < last.path.length; i++) {
182
181
  projectedPath.push(last.path[i]);
183
182
  }
184
- assert(projectedPath.length >= 2);
185
183
 
186
184
  // Tolerate a slightly longer distance than one diameter between two adjacent circles
187
185
  const circleDist = radius * 2.5;
@@ -229,7 +227,6 @@ class CollisionIndex {
229
227
 
230
228
  for (const seg of segments) {
231
229
  // interpolate positions for collision circles. Add a small padding to both ends of the segment
232
- assert(seg.length > 0);
233
230
  interpolator.reset(seg, radius * 0.25);
234
231
 
235
232
  let numCircles = 0;
@@ -1,6 +1,5 @@
1
1
  import {clamp} from '../util/util';
2
2
  import Point from '@mapbox/point-geometry';
3
- import assert from 'assert';
4
3
 
5
4
  class PathInterpolator {
6
5
  points: Array<Point>;
@@ -30,7 +29,6 @@ class PathInterpolator {
30
29
  }
31
30
 
32
31
  lerp(t: number): Point {
33
- assert(this.points.length > 0);
34
32
  if (this.points.length === 1) {
35
33
  return this.points[0];
36
34
  }
@@ -6,7 +6,6 @@ import * as projection from './projection';
6
6
  import {getAnchorJustification, evaluateVariableOffset} from './symbol_layout';
7
7
  import {getAnchorAlignment, WritingMode} from './shaping';
8
8
  import {mat4} from 'gl-matrix';
9
- import assert from 'assert';
10
9
  import pixelsToTileUnits from '../source/pixels_to_tile_units';
11
10
  import Point from '@mapbox/point-geometry';
12
11
  import type Transform from '../geo/transform';
@@ -23,6 +22,7 @@ import type FeatureIndex from '../data/feature_index';
23
22
  import type {OverscaledTileID} from '../source/tile_id';
24
23
  import type {TextAnchor} from './symbol_layout';
25
24
  import Terrain from '../render/terrain';
25
+ import {warnOnce} from '../util/util';
26
26
 
27
27
  class OpacityState {
28
28
  opacity: number;
@@ -391,7 +391,7 @@ export class Placement {
391
391
  this.prevPlacement.placements[symbolInstance.crossTileID].text) {
392
392
  prevAnchor = this.prevPlacement.variableOffsets[symbolInstance.crossTileID].anchor;
393
393
  }
394
- assert(symbolInstance.crossTileID !== 0);
394
+ if (symbolInstance.crossTileID === 0) throw new Error('symbolInstance.crossTileID can\'t be 0');
395
395
  this.variableOffsets[symbolInstance.crossTileID] = {
396
396
  textOffset,
397
397
  width,
@@ -676,7 +676,10 @@ export class Placement {
676
676
  getElevation
677
677
  );
678
678
 
679
- assert(!placedGlyphCircles.circles.length || (!placedGlyphCircles.collisionDetected || showCollisionBoxes));
679
+ if (placedGlyphCircles.circles.length && placedGlyphCircles.collisionDetected && !showCollisionBoxes) {
680
+ warnOnce('Collisions detected, but collision boxes are not shown');
681
+ }
682
+
680
683
  // If text-overlap is set to 'always', force "placedCircles" to true
681
684
  // In theory there should always be at least one circle placed
682
685
  // in this case, but for now quirks in text-anchor
@@ -781,15 +784,15 @@ export class Placement {
781
784
  }
782
785
  }
783
786
 
784
- assert(symbolInstance.crossTileID !== 0);
785
- assert(bucket.bucketInstanceId !== 0);
787
+ if (symbolInstance.crossTileID === 0) throw new Error('symbolInstance.crossTileID can\'t be 0');
788
+ if (bucket.bucketInstanceId === 0) throw new Error('bucket.bucketInstanceId can\'t be 0');
786
789
 
787
790
  this.placements[symbolInstance.crossTileID] = new JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded);
788
791
  seenCrossTileIDs[symbolInstance.crossTileID] = true;
789
792
  };
790
793
 
791
794
  if (zOrderByViewportY) {
792
- assert(bucketPart.symbolInstanceStart === 0);
795
+ if (bucketPart.symbolInstanceStart !== 0) throw new Error('bucket.bucketInstanceId should be 0');
793
796
  const symbolIndexes = bucket.getSortedSymbolIndexes(this.transform.angle);
794
797
  for (let i = symbolIndexes.length - 1; i >= 0; --i) {
795
798
  const symbolIndex = symbolIndexes[i];
@@ -920,7 +923,9 @@ export class Placement {
920
923
  // this.lastPlacementChangeTime is the time of the last commit() that
921
924
  // resulted in a placement change -- in other words, the start time of
922
925
  // the last symbol fade animation
923
- assert(!prevPlacement || prevPlacement.lastPlacementChangeTime !== undefined);
926
+ if (prevPlacement && prevPlacement.lastPlacementChangeTime === undefined) {
927
+ throw new Error('Last placement time for previous placement is not defined');
928
+ }
924
929
  if (placementChanged) {
925
930
  this.lastPlacementChangeTime = now;
926
931
  } else if (typeof this.lastPlacementChangeTime !== 'number') {
@@ -1133,8 +1138,8 @@ export class Placement {
1133
1138
  bucket.textCollisionBox.collisionVertexBuffer.updateData(bucket.textCollisionBox.collisionVertexArray);
1134
1139
  }
1135
1140
 
1136
- assert(bucket.text.opacityVertexArray.length === bucket.text.layoutVertexArray.length / 4);
1137
- assert(bucket.icon.opacityVertexArray.length === bucket.icon.layoutVertexArray.length / 4);
1141
+ if (bucket.text.opacityVertexArray.length !== bucket.text.layoutVertexArray.length / 4) throw new Error(`bucket.text.opacityVertexArray.length (= ${bucket.text.opacityVertexArray.length}) !== bucket.text.layoutVertexArray.length (= ${bucket.text.layoutVertexArray.length}) / 4`);
1142
+ if (bucket.icon.opacityVertexArray.length !== bucket.icon.layoutVertexArray.length / 4) throw new Error(`bucket.icon.opacityVertexArray.length (= ${bucket.icon.opacityVertexArray.length}) !== bucket.icon.layoutVertexArray.length (= ${bucket.icon.layoutVertexArray.length}) / 4`);
1138
1143
 
1139
1144
  // Push generated collision circles to the bucket for debug rendering
1140
1145
  if (bucket.bucketInstanceId in this.collisionCircleArrays) {
@@ -1,4 +1,3 @@
1
- import assert from 'assert';
2
1
  import {
3
2
  charHasUprightVerticalOrientation,
4
3
  charAllowsIdeographicBreaking,
@@ -811,9 +810,6 @@ function fitIconToText(
811
810
  iconOffset: [number, number],
812
811
  fontScale: number
813
812
  ): PositionedIcon {
814
- assert(textFit !== 'none');
815
- assert(Array.isArray(padding) && padding.length === 4);
816
- assert(Array.isArray(iconOffset) && iconOffset.length === 2);
817
813
 
818
814
  const image = shapedIcon.image;
819
815
 
@@ -151,55 +151,55 @@ export function evaluateVariableOffset(anchor: TextAnchor, offset: [number, numb
151
151
  return (offset[1] !== INVALID_TEXT_OFFSET) ? fromTextOffset(anchor, offset[0], offset[1]) : fromRadialOffset(anchor, offset[0]);
152
152
  }
153
153
 
154
- export function performSymbolLayout(
155
- bucket: SymbolBucket,
154
+ export function performSymbolLayout(args: {
155
+ bucket: SymbolBucket;
156
156
  glyphMap: {
157
157
  [_: string]: {
158
158
  [x: number]: StyleGlyph;
159
159
  };
160
- },
160
+ };
161
161
  glyphPositions: {
162
162
  [_: string]: {
163
163
  [x: number]: GlyphPosition;
164
164
  };
165
- },
166
- imageMap: {[_: string]: StyleImage},
167
- imagePositions: {[_: string]: ImagePosition},
168
- showCollisionBoxes: boolean,
169
- canonical: CanonicalTileID
170
- ) {
171
- bucket.createArrays();
165
+ };
166
+ imageMap: {[_: string]: StyleImage};
167
+ imagePositions: {[_: string]: ImagePosition};
168
+ showCollisionBoxes: boolean;
169
+ canonical: CanonicalTileID;
170
+ }) {
171
+ args.bucket.createArrays();
172
172
 
173
- const tileSize = 512 * bucket.overscaling;
174
- bucket.tilePixelRatio = EXTENT / tileSize;
175
- bucket.compareText = {};
176
- bucket.iconsNeedLinear = false;
173
+ const tileSize = 512 * args.bucket.overscaling;
174
+ args.bucket.tilePixelRatio = EXTENT / tileSize;
175
+ args.bucket.compareText = {};
176
+ args.bucket.iconsNeedLinear = false;
177
177
 
178
- const layout = bucket.layers[0].layout;
179
- const unevaluatedLayoutValues = bucket.layers[0]._unevaluatedLayout._values;
178
+ const layout = args.bucket.layers[0].layout;
179
+ const unevaluatedLayoutValues = args.bucket.layers[0]._unevaluatedLayout._values;
180
180
 
181
181
  const sizes: Sizes = {
182
182
  // Filled in below, if *SizeData.kind is 'composite'
183
183
  // compositeIconSizes: undefined,
184
184
  // compositeTextSizes: undefined,
185
- layoutIconSize: unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical),
186
- layoutTextSize: unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(bucket.zoom + 1), canonical),
185
+ layoutIconSize: unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(args.bucket.zoom + 1), args.canonical),
186
+ layoutTextSize: unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(args.bucket.zoom + 1), args.canonical),
187
187
  textMaxSize: unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(18))
188
188
  } as Sizes;
189
189
 
190
- if (bucket.textSizeData.kind === 'composite') {
191
- const {minZoom, maxZoom} = bucket.textSizeData;
190
+ if (args.bucket.textSizeData.kind === 'composite') {
191
+ const {minZoom, maxZoom} = args.bucket.textSizeData;
192
192
  sizes.compositeTextSizes = [
193
- unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(minZoom), canonical),
194
- unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), canonical)
193
+ unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(minZoom), args.canonical),
194
+ unevaluatedLayoutValues['text-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), args.canonical)
195
195
  ];
196
196
  }
197
197
 
198
- if (bucket.iconSizeData.kind === 'composite') {
199
- const {minZoom, maxZoom} = bucket.iconSizeData;
198
+ if (args.bucket.iconSizeData.kind === 'composite') {
199
+ const {minZoom, maxZoom} = args.bucket.iconSizeData;
200
200
  sizes.compositeIconSizes = [
201
- unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(minZoom), canonical),
202
- unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), canonical)
201
+ unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(minZoom), args.canonical),
202
+ unevaluatedLayoutValues['icon-size'].possiblyEvaluate(new EvaluationParameters(maxZoom), args.canonical)
203
203
  ];
204
204
  }
205
205
 
@@ -208,11 +208,11 @@ export function performSymbolLayout(
208
208
  const keepUpright = layout.get('text-keep-upright');
209
209
  const textSize = layout.get('text-size');
210
210
 
211
- for (const feature of bucket.features) {
212
- const fontstack = layout.get('text-font').evaluate(feature, {}, canonical).join(',');
213
- const layoutTextSizeThisZoom = textSize.evaluate(feature, {}, canonical);
214
- const layoutTextSize = sizes.layoutTextSize.evaluate(feature, {}, canonical);
215
- const layoutIconSize = sizes.layoutIconSize.evaluate(feature, {}, canonical);
211
+ for (const feature of args.bucket.features) {
212
+ const fontstack = layout.get('text-font').evaluate(feature, {}, args.canonical).join(',');
213
+ const layoutTextSizeThisZoom = textSize.evaluate(feature, {}, args.canonical);
214
+ const layoutTextSize = sizes.layoutTextSize.evaluate(feature, {}, args.canonical);
215
+ const layoutIconSize = sizes.layoutIconSize.evaluate(feature, {}, args.canonical);
216
216
 
217
217
  const shapedTextOrientations: ShapedTextOrientations = {
218
218
  horizontal: {} as Record<TextJustify, Shaping>,
@@ -222,14 +222,14 @@ export function performSymbolLayout(
222
222
  let textOffset: [number, number] = [0, 0];
223
223
  if (text) {
224
224
  const unformattedText = text.toString();
225
- const spacing = layout.get('text-letter-spacing').evaluate(feature, {}, canonical) * ONE_EM;
225
+ const spacing = layout.get('text-letter-spacing').evaluate(feature, {}, args.canonical) * ONE_EM;
226
226
  const spacingIfAllowed = allowsLetterSpacing(unformattedText) ? spacing : 0;
227
227
 
228
- const textAnchor = layout.get('text-anchor').evaluate(feature, {}, canonical);
228
+ const textAnchor = layout.get('text-anchor').evaluate(feature, {}, args.canonical);
229
229
  const variableTextAnchor = layout.get('text-variable-anchor');
230
230
 
231
231
  if (!variableTextAnchor) {
232
- const radialOffset = layout.get('text-radial-offset').evaluate(feature, {}, canonical);
232
+ const radialOffset = layout.get('text-radial-offset').evaluate(feature, {}, args.canonical);
233
233
  // Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector
234
234
  // is calculated at placement time instead of layout time
235
235
  if (radialOffset) {
@@ -237,25 +237,25 @@ export function performSymbolLayout(
237
237
  // but doesn't actually specify what happens if you use both. We go with the radial offset.
238
238
  textOffset = evaluateVariableOffset(textAnchor, [radialOffset * ONE_EM, INVALID_TEXT_OFFSET]) as [number, number];
239
239
  } else {
240
- textOffset = (layout.get('text-offset').evaluate(feature, {}, canonical).map(t => t * ONE_EM) as [number, number]);
240
+ textOffset = (layout.get('text-offset').evaluate(feature, {}, args.canonical).map(t => t * ONE_EM) as [number, number]);
241
241
  }
242
242
  }
243
243
 
244
244
  let textJustify = textAlongLine ?
245
245
  'center' :
246
- layout.get('text-justify').evaluate(feature, {}, canonical);
246
+ layout.get('text-justify').evaluate(feature, {}, args.canonical);
247
247
 
248
248
  const symbolPlacement = layout.get('symbol-placement');
249
249
  const maxWidth = symbolPlacement === 'point' ?
250
- layout.get('text-max-width').evaluate(feature, {}, canonical) * ONE_EM :
250
+ layout.get('text-max-width').evaluate(feature, {}, args.canonical) * ONE_EM :
251
251
  0;
252
252
 
253
253
  const addVerticalShapingForPointLabelIfNeeded = () => {
254
- if (bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) {
254
+ if (args.bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) {
255
255
  // Vertical POI label placement is meant to be used for scripts that support vertical
256
256
  // writing mode, thus, default left justification is used. If Latin
257
257
  // scripts would need to be supported, this should take into account other justifications.
258
- shapedTextOrientations.vertical = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor,
258
+ shapedTextOrientations.vertical = shapeText(text, args.glyphMap, args.glyphPositions, args.imagePositions, fontstack, maxWidth, lineHeight, textAnchor,
259
259
  'left', spacingIfAllowed, textOffset, WritingMode.vertical, true, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom);
260
260
  }
261
261
  };
@@ -277,7 +277,7 @@ export function performSymbolLayout(
277
277
  } else {
278
278
  // If using text-variable-anchor for the layer, we use a center anchor for all shapings and apply
279
279
  // the offsets for the anchor in the placement step.
280
- const shaping = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, 'center',
280
+ const shaping = shapeText(text, args.glyphMap, args.glyphPositions, args.imagePositions, fontstack, maxWidth, lineHeight, 'center',
281
281
  justification, spacingIfAllowed, textOffset, WritingMode.horizontal, false, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom);
282
282
  if (shaping) {
283
283
  shapedTextOrientations.horizontal[justification] = shaping;
@@ -293,7 +293,7 @@ export function performSymbolLayout(
293
293
  }
294
294
 
295
295
  // Horizontal point or line label.
296
- const shaping = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed,
296
+ const shaping = shapeText(text, args.glyphMap, args.glyphPositions, args.imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed,
297
297
  textOffset, WritingMode.horizontal, false, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom);
298
298
  if (shaping) shapedTextOrientations.horizontal[textJustify] = shaping;
299
299
 
@@ -302,7 +302,7 @@ export function performSymbolLayout(
302
302
 
303
303
  // Verticalized line label.
304
304
  if (allowsVerticalWritingMode(unformattedText) && textAlongLine && keepUpright) {
305
- shapedTextOrientations.vertical = shapeText(text, glyphMap, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify,
305
+ shapedTextOrientations.vertical = shapeText(text, args.glyphMap, args.glyphPositions, args.imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify,
306
306
  spacingIfAllowed, textOffset, WritingMode.vertical, false, symbolPlacement, layoutTextSize, layoutTextSizeThisZoom);
307
307
  }
308
308
  }
@@ -311,36 +311,36 @@ export function performSymbolLayout(
311
311
  let shapedIcon;
312
312
  let isSDFIcon = false;
313
313
  if (feature.icon && feature.icon.name) {
314
- const image = imageMap[feature.icon.name];
314
+ const image = args.imageMap[feature.icon.name];
315
315
  if (image) {
316
316
  shapedIcon = shapeIcon(
317
- imagePositions[feature.icon.name],
318
- layout.get('icon-offset').evaluate(feature, {}, canonical),
319
- layout.get('icon-anchor').evaluate(feature, {}, canonical));
317
+ args.imagePositions[feature.icon.name],
318
+ layout.get('icon-offset').evaluate(feature, {}, args.canonical),
319
+ layout.get('icon-anchor').evaluate(feature, {}, args.canonical));
320
320
  // null/undefined SDF property treated same as default (false)
321
321
  isSDFIcon = !!image.sdf;
322
- if (bucket.sdfIcons === undefined) {
323
- bucket.sdfIcons = isSDFIcon;
324
- } else if (bucket.sdfIcons !== isSDFIcon) {
322
+ if (args.bucket.sdfIcons === undefined) {
323
+ args.bucket.sdfIcons = isSDFIcon;
324
+ } else if (args.bucket.sdfIcons !== isSDFIcon) {
325
325
  warnOnce('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer');
326
326
  }
327
- if (image.pixelRatio !== bucket.pixelRatio) {
328
- bucket.iconsNeedLinear = true;
327
+ if (image.pixelRatio !== args.bucket.pixelRatio) {
328
+ args.bucket.iconsNeedLinear = true;
329
329
  } else if (layout.get('icon-rotate').constantOr(1) !== 0) {
330
- bucket.iconsNeedLinear = true;
330
+ args.bucket.iconsNeedLinear = true;
331
331
  }
332
332
  }
333
333
  }
334
334
 
335
335
  const shapedText = getDefaultHorizontalShaping(shapedTextOrientations.horizontal) || shapedTextOrientations.vertical;
336
- bucket.iconsInText = shapedText ? shapedText.iconsInText : false;
336
+ args.bucket.iconsInText = shapedText ? shapedText.iconsInText : false;
337
337
  if (shapedText || shapedIcon) {
338
- addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, canonical);
338
+ addFeature(args.bucket, feature, shapedTextOrientations, shapedIcon, args.imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon, args.canonical);
339
339
  }
340
340
  }
341
341
 
342
- if (showCollisionBoxes) {
343
- bucket.generateCollisionDebugBuffers();
342
+ if (args.showCollisionBoxes) {
343
+ args.bucket.generateCollisionDebugBuffers();
344
344
  }
345
345
  }
346
346