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.
- package/build/generate-query-test-fixtures.ts +3 -2
- package/build/generate-struct-arrays.ts +0 -2
- package/build/generate-style-spec.ts +12 -17
- package/build/generate-typings.ts +11 -1
- package/build/rollup_plugins.ts +0 -4
- package/dist/maplibre-gl-csp-worker.js +1 -1
- package/dist/maplibre-gl-csp.js +1 -1
- package/dist/maplibre-gl-dev.js +376 -1402
- package/dist/maplibre-gl.d.ts +13 -16
- package/dist/maplibre-gl.js +4 -4
- package/dist/style-spec/index.d.ts +1768 -0
- package/package.json +14 -16
- package/src/data/array_types.g.ts +0 -5
- package/src/data/bucket/fill_bucket.ts +0 -2
- package/src/data/bucket/fill_extrusion_bucket.ts +0 -2
- package/src/data/bucket/symbol_bucket.test.ts +30 -19
- package/src/data/feature_position_map.ts +1 -2
- package/src/gl/framebuffer.ts +3 -2
- package/src/gl/index_buffer.ts +1 -2
- package/src/gl/vertex_buffer.ts +1 -2
- package/src/index.test.ts +9 -0
- package/src/index.ts +12 -4
- package/src/render/image_manager.ts +5 -7
- package/src/render/program/pattern.ts +0 -2
- package/src/render/program.ts +12 -9
- package/src/render/vertex_array_object.ts +1 -3
- package/src/source/geojson_worker_source.ts +0 -4
- package/src/source/query_features.ts +0 -3
- package/src/source/rtl_text_plugin.ts +3 -4
- package/src/source/source_cache.ts +0 -2
- package/src/source/tile_id.ts +8 -8
- package/src/source/worker.ts +0 -7
- package/src/source/worker_tile.ts +12 -3
- package/src/style/format_section_override.ts +1 -2
- package/src/style/properties.ts +1 -3
- package/src/style/style.ts +5 -5
- package/src/style/style_layer/custom_style_layer.ts +1 -2
- package/src/style/style_layer/symbol_style_layer.ts +1 -3
- package/src/style-spec/CHANGELOG.md +10 -0
- package/src/style-spec/composite.test.ts +7 -8
- package/src/style-spec/expression/compound_expression.ts +0 -4
- package/src/style-spec/expression/definitions/assertion.ts +2 -4
- package/src/style-spec/expression/definitions/case.ts +1 -2
- package/src/style-spec/expression/definitions/coalesce.ts +1 -3
- package/src/style-spec/expression/definitions/coercion.ts +2 -4
- package/src/style-spec/expression/definitions/match.ts +0 -3
- package/src/style-spec/expression/index.ts +13 -15
- package/src/style-spec/expression/parsing_context.ts +4 -4
- package/src/style-spec/expression/parsing_error.ts +2 -2
- package/src/style-spec/expression/values.ts +0 -2
- package/src/style-spec/feature_filter/feature_filter.test.ts +39 -2
- package/src/style-spec/function/convert.ts +1 -3
- package/src/style-spec/migrate/v8.test.ts +12 -14
- package/src/style-spec/migrate/v9.test.ts +2 -4
- package/src/style-spec/migrate.test.ts +6 -8
- package/src/style-spec/package.json +2 -1
- package/src/style-spec/types.g.ts +12 -17
- package/src/symbol/collision_index.ts +0 -3
- package/src/symbol/path_interpolator.ts +0 -2
- package/src/symbol/placement.ts +14 -9
- package/src/symbol/shaping.ts +0 -4
- package/src/symbol/symbol_layout.ts +56 -56
- package/src/ui/camera.ts +0 -10
- package/src/ui/control/geolocate_control.ts +4 -6
- package/src/ui/handler/handler_util.ts +1 -2
- package/src/ui/handler/scroll_zoom.ts +0 -2
- package/src/ui/handler_manager.ts +0 -2
- package/src/ui/map.test.ts +11 -0
- package/src/ui/map.ts +11 -0
- package/src/util/ajax.ts +1 -2
- package/src/util/color_ramp.ts +1 -2
- package/src/util/dictionary_coder.ts +1 -3
- package/src/util/dispatcher.ts +1 -4
- package/src/util/dom.ts +0 -3
- package/src/util/image.ts +1 -3
- package/src/util/struct_array.ts +0 -5
- package/src/util/task_queue.ts +1 -3
- package/src/util/web_worker_transfer.ts +5 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
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": "
|
|
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
|
|
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 |
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
...(number | ColorSpecification
|
|
87
|
-
| ['
|
|
88
|
-
number | 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
|
|
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
|
-
| ['+',
|
|
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
|
}
|
package/src/symbol/placement.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
785
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1137
|
-
|
|
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) {
|
package/src/symbol/shaping.ts
CHANGED
|
@@ -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
|
|