@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.
- package/build/min/package.json +1 -1
- package/package.json +1 -2
- package/src/data/array_types.js +1 -1
- package/src/data/bucket/circle_bucket.js +1 -1
- package/src/data/bucket/fill_bucket.js +1 -1
- package/src/data/bucket/fill_extrusion_bucket.js +1 -1
- package/src/data/bucket/heatmap_bucket.js +1 -1
- package/src/data/bucket/line_bucket.js +1 -1
- package/src/data/bucket/symbol_bucket.js +26 -12
- package/src/data/dem_data.js +1 -1
- package/src/data/feature_index.js +43 -82
- package/src/data/program_configuration.js +19 -11
- package/src/data/segment.js +2 -2
- package/src/geo/transform.js +4 -2
- package/src/gl/color_mode.js +6 -6
- package/src/index.js +3 -1
- package/src/render/glyph_atlas.js +1 -1
- package/src/render/glyph_manager.js +43 -48
- package/src/render/image_atlas.js +1 -1
- package/src/render/image_manager.js +9 -37
- package/src/source/geojson_source.js +49 -93
- package/src/source/geojson_worker_source.js +33 -134
- package/src/source/image_source.js +9 -14
- package/src/source/load_tilejson.js +27 -34
- package/src/source/raster_dem_tile_source.js +27 -40
- package/src/source/raster_tile_source.js +53 -62
- package/src/source/rtl_text_plugin.js +3 -1
- package/src/source/source_cache.js +23 -21
- package/src/source/source_state.js +17 -26
- package/src/source/tile.js +6 -5
- package/src/source/tile_id.js +1 -1
- package/src/source/vector_tile_source.js +56 -73
- package/src/source/vector_tile_worker_source.js +20 -85
- package/src/source/worker.js +37 -103
- package/src/source/worker_tile.js +39 -84
- package/src/style/load_sprite.js +14 -17
- package/src/style/properties.js +1 -1
- package/src/style/style.js +22 -37
- package/src/style/style_layer/symbol_style_layer_properties.js +1 -1
- package/src/style/style_layer_index.js +17 -23
- package/src/style-spec/expression/compound_expression.js +30 -16
- package/src/style-spec/expression/definitions/coercion.js +13 -0
- package/src/style-spec/expression/definitions/comparison.js +193 -0
- package/src/style-spec/expression/definitions/formatted.js +123 -0
- package/src/style-spec/expression/definitions/index.js +10 -60
- package/src/style-spec/expression/definitions/interpolate.js +17 -7
- package/src/style-spec/expression/definitions/literal.js +5 -0
- package/src/style-spec/expression/parsing_context.js +4 -0
- package/src/style-spec/expression/types.js +12 -1
- package/src/style-spec/feature_filter/index.js +1 -1
- package/src/style-spec/reference/v8.json +120 -49
- package/src/symbol/anchor.js +1 -1
- package/src/symbol/collision_index.js +23 -16
- package/src/symbol/get_anchors.js +11 -22
- package/src/symbol/grid_index.js +176 -182
- package/src/symbol/mergelines.js +51 -48
- package/src/symbol/opacity_state.js +1 -1
- package/src/symbol/placement.js +8 -2
- package/src/symbol/quads.js +7 -6
- package/src/symbol/shaping.js +185 -40
- package/src/symbol/symbol_layout.js +9 -6
- package/src/symbol/transform_text.js +12 -1
- package/src/ui/camera.js +82 -85
- package/src/ui/map.js +13 -57
- package/src/util/actor.js +46 -42
- package/src/util/browser.js +6 -0
- package/src/util/dictionary_coder.js +13 -21
- package/src/util/dispatcher.js +14 -17
- package/src/util/image.js +1 -1
- package/src/util/loader/image.js +11 -11
- package/src/util/polyfill.js +16 -0
- package/src/util/task_queue.js +39 -43
- package/src/util/transfer_registry.js +167 -0
- package/src/util/web_worker_transfer.js +5 -190
- package/src/source/raster_dem_tile_worker_source.js +0 -26
- package/src/style-spec/expression/definitions/equals.js +0 -93
package/build/min/package.json
CHANGED
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.
|
|
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": {
|
package/src/data/array_types.js
CHANGED
|
@@ -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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
const
|
|
294
|
-
|
|
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
|
|
package/src/data/dem_data.js
CHANGED
|
@@ -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/
|
|
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
|
|
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/
|
|
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.
|
|
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
|
|
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 (
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
176
|
-
|
|
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,
|
|
165
|
+
const geojsonFeature = new GeoJSONFeature(feature, z, x, y);
|
|
192
166
|
geojsonFeature.layer = styleLayer.serialize();
|
|
193
|
-
|
|
194
|
-
|
|
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
|
|
244
|
-
minX =
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
maxY =
|
|
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/
|
|
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
|
|
174
|
-
this.paintVertexArray
|
|
175
|
-
|
|
176
|
-
this.
|
|
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
|
|
269
|
-
this.paintVertexArray
|
|
270
|
-
|
|
271
|
-
this.
|
|
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
|
|
package/src/data/segment.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const warn = require('../util/warn');
|
|
2
2
|
|
|
3
|
-
const { register } = require('../util/
|
|
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,
|
package/src/geo/transform.js
CHANGED
|
@@ -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 = [-
|
|
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
|
-
*
|
|
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
|
}
|
package/src/gl/color_mode.js
CHANGED
|
@@ -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.
|
|
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
|
|
|
@@ -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
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
51
|
-
|
|
46
|
+
async function retrieveGlyph({ entries, loader, localIdeographFontFamily }, { stack, id }) {
|
|
47
|
+
const entry = (entries[stack] ??= { glyphs: {}, requests: {} });
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
let glyph = entry.glyphs[id];
|
|
50
|
+
if (glyph) {
|
|
51
|
+
return { stack, id, glyph };
|
|
52
|
+
}
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
glyph = tinySDF(localIdeographFontFamily, entry, stack, id);
|
|
55
|
+
if (glyph) {
|
|
56
|
+
return { stack, id, glyph };
|
|
57
|
+
}
|
|
62
58
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
}
|