@mapwhit/tilerenderer 0.47.2 → 0.49.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 +3 -2
- package/src/data/array_types.js +169 -0
- package/src/data/bucket/symbol_attributes.js +18 -0
- package/src/data/bucket/symbol_bucket.js +116 -73
- package/src/data/program_configuration.js +18 -10
- package/src/geo/transform.js +17 -7
- package/src/index.js +1 -1
- package/src/render/glyph_atlas.js +3 -6
- package/src/render/image_atlas.js +3 -6
- package/src/render/image_manager.js +41 -41
- package/src/source/rtl_text_plugin.js +1 -0
- package/src/source/source_cache.js +1 -1
- package/src/source/tile.js +6 -5
- package/src/source/worker.js +1 -10
- package/src/style/style.js +4 -19
- package/src/style/style_layer/symbol_style_layer_properties.js +7 -1
- package/src/style-spec/expression/compound_expression.js +30 -16
- package/src/style-spec/expression/definitions/assertion.js +52 -5
- 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 +11 -62
- 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 +6 -7
- package/src/style-spec/expression/types.js +12 -1
- package/src/style-spec/feature_filter/convert.js +197 -0
- package/src/style-spec/feature_filter/index.js +5 -2
- package/src/style-spec/function/convert.js +78 -100
- package/src/style-spec/reference/v8.json +160 -52
- package/src/symbol/collision_index.js +0 -1
- package/src/symbol/cross_tile_symbol_index.js +12 -7
- package/src/symbol/get_anchors.js +11 -22
- package/src/symbol/mergelines.js +4 -1
- package/src/symbol/placement.js +58 -54
- package/src/symbol/quads.js +7 -6
- package/src/symbol/shaping.js +185 -40
- package/src/symbol/symbol_layout.js +40 -37
- package/src/symbol/transform_text.js +12 -1
- package/src/ui/map.js +8 -25
- package/src/style-spec/expression/definitions/array.js +0 -82
- 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.49.0",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"repository": {
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@mapbox/gl-matrix": "^0.0.1",
|
|
13
13
|
"@mapbox/point-geometry": "^0.1.0",
|
|
14
|
-
"@mapbox/shelf-pack": "^3.0.0",
|
|
15
14
|
"@mapbox/tiny-sdf": "^1.1.0",
|
|
16
15
|
"@mapbox/unitbezier": "^0.0.0",
|
|
17
16
|
"@mapbox/vector-tile": "^1.3.1",
|
|
@@ -24,6 +23,8 @@
|
|
|
24
23
|
"earcut": "^2.0.3",
|
|
25
24
|
"geojson-vt": "^3.1.2",
|
|
26
25
|
"grid-index": "^1.1.0",
|
|
26
|
+
"murmurhash-js": "^1.0.0",
|
|
27
|
+
"potpack": "^1.0.1",
|
|
27
28
|
"quickselect": "^2.0.0",
|
|
28
29
|
"supercluster": "^2.0.1",
|
|
29
30
|
"tinyqueue": "^1.1.0"
|
package/src/data/array_types.js
CHANGED
|
@@ -513,6 +513,68 @@ class StructArrayLayout2i2ui3ul3ui2f2ub40 extends StructArray {
|
|
|
513
513
|
StructArrayLayout2i2ui3ul3ui2f2ub40.prototype.bytesPerElement = 40;
|
|
514
514
|
register('StructArrayLayout2i2ui3ul3ui2f2ub40', StructArrayLayout2i2ui3ul3ui2f2ub40);
|
|
515
515
|
|
|
516
|
+
/**
|
|
517
|
+
* Implementation of the StructArray layout:
|
|
518
|
+
* [0]: Int16[4]
|
|
519
|
+
* [8]: Uint16[9]
|
|
520
|
+
* [28]: Uint32[1]
|
|
521
|
+
*
|
|
522
|
+
* @private
|
|
523
|
+
*/
|
|
524
|
+
class StructArrayLayout4i9ui1ul32 extends StructArray {
|
|
525
|
+
_refreshViews() {
|
|
526
|
+
this.uint8 = new Uint8Array(this.arrayBuffer);
|
|
527
|
+
this.int16 = new Int16Array(this.arrayBuffer);
|
|
528
|
+
this.uint16 = new Uint16Array(this.arrayBuffer);
|
|
529
|
+
this.uint32 = new Uint32Array(this.arrayBuffer);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
emplaceBack(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {
|
|
533
|
+
const i = this.length;
|
|
534
|
+
this.resize(i + 1);
|
|
535
|
+
const o2 = i * 16;
|
|
536
|
+
const o4 = i * 8;
|
|
537
|
+
this.int16[o2 + 0] = v0;
|
|
538
|
+
this.int16[o2 + 1] = v1;
|
|
539
|
+
this.int16[o2 + 2] = v2;
|
|
540
|
+
this.int16[o2 + 3] = v3;
|
|
541
|
+
this.uint16[o2 + 4] = v4;
|
|
542
|
+
this.uint16[o2 + 5] = v5;
|
|
543
|
+
this.uint16[o2 + 6] = v6;
|
|
544
|
+
this.uint16[o2 + 7] = v7;
|
|
545
|
+
this.uint16[o2 + 8] = v8;
|
|
546
|
+
this.uint16[o2 + 9] = v9;
|
|
547
|
+
this.uint16[o2 + 10] = v10;
|
|
548
|
+
this.uint16[o2 + 11] = v11;
|
|
549
|
+
this.uint16[o2 + 12] = v12;
|
|
550
|
+
this.uint32[o4 + 7] = v13;
|
|
551
|
+
return i;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {
|
|
555
|
+
const o2 = i * 16;
|
|
556
|
+
const o4 = i * 8;
|
|
557
|
+
this.int16[o2 + 0] = v0;
|
|
558
|
+
this.int16[o2 + 1] = v1;
|
|
559
|
+
this.int16[o2 + 2] = v2;
|
|
560
|
+
this.int16[o2 + 3] = v3;
|
|
561
|
+
this.uint16[o2 + 4] = v4;
|
|
562
|
+
this.uint16[o2 + 5] = v5;
|
|
563
|
+
this.uint16[o2 + 6] = v6;
|
|
564
|
+
this.uint16[o2 + 7] = v7;
|
|
565
|
+
this.uint16[o2 + 8] = v8;
|
|
566
|
+
this.uint16[o2 + 9] = v9;
|
|
567
|
+
this.uint16[o2 + 10] = v10;
|
|
568
|
+
this.uint16[o2 + 11] = v11;
|
|
569
|
+
this.uint16[o2 + 12] = v12;
|
|
570
|
+
this.uint32[o4 + 7] = v13;
|
|
571
|
+
return i;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
StructArrayLayout4i9ui1ul32.prototype.bytesPerElement = 32;
|
|
576
|
+
register('StructArrayLayout4i9ui1ul32', StructArrayLayout4i9ui1ul32);
|
|
577
|
+
|
|
516
578
|
/**
|
|
517
579
|
* Implementation of the StructArray layout:
|
|
518
580
|
* [0]: Float32[1]
|
|
@@ -974,6 +1036,111 @@ class PlacedSymbolArray extends StructArrayLayout2i2ui3ul3ui2f2ub40 {
|
|
|
974
1036
|
|
|
975
1037
|
register('PlacedSymbolArray', PlacedSymbolArray);
|
|
976
1038
|
|
|
1039
|
+
class SymbolInstanceStruct extends Struct {
|
|
1040
|
+
get anchorX() {
|
|
1041
|
+
return this._structArray.int16[this._pos2 + 0];
|
|
1042
|
+
}
|
|
1043
|
+
set anchorX(x) {
|
|
1044
|
+
this._structArray.int16[this._pos2 + 0] = x;
|
|
1045
|
+
}
|
|
1046
|
+
get anchorY() {
|
|
1047
|
+
return this._structArray.int16[this._pos2 + 1];
|
|
1048
|
+
}
|
|
1049
|
+
set anchorY(x) {
|
|
1050
|
+
this._structArray.int16[this._pos2 + 1] = x;
|
|
1051
|
+
}
|
|
1052
|
+
get horizontalPlacedTextSymbolIndex() {
|
|
1053
|
+
return this._structArray.int16[this._pos2 + 2];
|
|
1054
|
+
}
|
|
1055
|
+
set horizontalPlacedTextSymbolIndex(x) {
|
|
1056
|
+
this._structArray.int16[this._pos2 + 2] = x;
|
|
1057
|
+
}
|
|
1058
|
+
get verticalPlacedTextSymbolIndex() {
|
|
1059
|
+
return this._structArray.int16[this._pos2 + 3];
|
|
1060
|
+
}
|
|
1061
|
+
set verticalPlacedTextSymbolIndex(x) {
|
|
1062
|
+
this._structArray.int16[this._pos2 + 3] = x;
|
|
1063
|
+
}
|
|
1064
|
+
get key() {
|
|
1065
|
+
return this._structArray.uint16[this._pos2 + 4];
|
|
1066
|
+
}
|
|
1067
|
+
set key(x) {
|
|
1068
|
+
this._structArray.uint16[this._pos2 + 4] = x;
|
|
1069
|
+
}
|
|
1070
|
+
get textBoxStartIndex() {
|
|
1071
|
+
return this._structArray.uint16[this._pos2 + 5];
|
|
1072
|
+
}
|
|
1073
|
+
set textBoxStartIndex(x) {
|
|
1074
|
+
this._structArray.uint16[this._pos2 + 5] = x;
|
|
1075
|
+
}
|
|
1076
|
+
get textBoxEndIndex() {
|
|
1077
|
+
return this._structArray.uint16[this._pos2 + 6];
|
|
1078
|
+
}
|
|
1079
|
+
set textBoxEndIndex(x) {
|
|
1080
|
+
this._structArray.uint16[this._pos2 + 6] = x;
|
|
1081
|
+
}
|
|
1082
|
+
get iconBoxStartIndex() {
|
|
1083
|
+
return this._structArray.uint16[this._pos2 + 7];
|
|
1084
|
+
}
|
|
1085
|
+
set iconBoxStartIndex(x) {
|
|
1086
|
+
this._structArray.uint16[this._pos2 + 7] = x;
|
|
1087
|
+
}
|
|
1088
|
+
get iconBoxEndIndex() {
|
|
1089
|
+
return this._structArray.uint16[this._pos2 + 8];
|
|
1090
|
+
}
|
|
1091
|
+
set iconBoxEndIndex(x) {
|
|
1092
|
+
this._structArray.uint16[this._pos2 + 8] = x;
|
|
1093
|
+
}
|
|
1094
|
+
get featureIndex() {
|
|
1095
|
+
return this._structArray.uint16[this._pos2 + 9];
|
|
1096
|
+
}
|
|
1097
|
+
set featureIndex(x) {
|
|
1098
|
+
this._structArray.uint16[this._pos2 + 9] = x;
|
|
1099
|
+
}
|
|
1100
|
+
get numGlyphVertices() {
|
|
1101
|
+
return this._structArray.uint16[this._pos2 + 10];
|
|
1102
|
+
}
|
|
1103
|
+
set numGlyphVertices(x) {
|
|
1104
|
+
this._structArray.uint16[this._pos2 + 10] = x;
|
|
1105
|
+
}
|
|
1106
|
+
get numVerticalGlyphVertices() {
|
|
1107
|
+
return this._structArray.uint16[this._pos2 + 11];
|
|
1108
|
+
}
|
|
1109
|
+
set numVerticalGlyphVertices(x) {
|
|
1110
|
+
this._structArray.uint16[this._pos2 + 11] = x;
|
|
1111
|
+
}
|
|
1112
|
+
get numIconVertices() {
|
|
1113
|
+
return this._structArray.uint16[this._pos2 + 12];
|
|
1114
|
+
}
|
|
1115
|
+
set numIconVertices(x) {
|
|
1116
|
+
this._structArray.uint16[this._pos2 + 12] = x;
|
|
1117
|
+
}
|
|
1118
|
+
get crossTileID() {
|
|
1119
|
+
return this._structArray.uint32[this._pos4 + 7];
|
|
1120
|
+
}
|
|
1121
|
+
set crossTileID(x) {
|
|
1122
|
+
this._structArray.uint32[this._pos4 + 7] = x;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
SymbolInstanceStruct.prototype.size = 32;
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* @private
|
|
1130
|
+
*/
|
|
1131
|
+
class SymbolInstanceArray extends StructArrayLayout4i9ui1ul32 {
|
|
1132
|
+
/**
|
|
1133
|
+
* Return the SymbolInstanceStruct at the given location in the array.
|
|
1134
|
+
* @param {number} index The index of the element.
|
|
1135
|
+
*/
|
|
1136
|
+
get(index) {
|
|
1137
|
+
assert(!this.isTransferred);
|
|
1138
|
+
return new SymbolInstanceStruct(this, index);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
register('SymbolInstanceArray', SymbolInstanceArray);
|
|
1143
|
+
|
|
977
1144
|
class GlyphOffsetStruct extends Struct {
|
|
978
1145
|
get offsetX() {
|
|
979
1146
|
return this._structArray.float32[this._pos4 + 0];
|
|
@@ -1104,6 +1271,7 @@ module.exports = {
|
|
|
1104
1271
|
StructArrayLayout2i2i2i12,
|
|
1105
1272
|
StructArrayLayout2ub4,
|
|
1106
1273
|
StructArrayLayout2i2ui3ul3ui2f2ub40,
|
|
1274
|
+
StructArrayLayout4i9ui1ul32,
|
|
1107
1275
|
StructArrayLayout1f4,
|
|
1108
1276
|
StructArrayLayout3i6,
|
|
1109
1277
|
StructArrayLayout1ul2ui8,
|
|
@@ -1134,5 +1302,6 @@ module.exports = {
|
|
|
1134
1302
|
FeatureIndexArray,
|
|
1135
1303
|
GlyphOffsetArray,
|
|
1136
1304
|
PlacedSymbolArray,
|
|
1305
|
+
SymbolInstanceArray,
|
|
1137
1306
|
SymbolLineVertexArray
|
|
1138
1307
|
};
|
|
@@ -73,6 +73,23 @@ const placement = createLayout([
|
|
|
73
73
|
{ type: 'Uint8', name: 'hidden' }
|
|
74
74
|
]);
|
|
75
75
|
|
|
76
|
+
const symbolInstance = createLayout([
|
|
77
|
+
{ type: 'Int16', name: 'anchorX' },
|
|
78
|
+
{ type: 'Int16', name: 'anchorY' },
|
|
79
|
+
{ type: 'Int16', name: 'horizontalPlacedTextSymbolIndex' },
|
|
80
|
+
{ type: 'Int16', name: 'verticalPlacedTextSymbolIndex' },
|
|
81
|
+
{ type: 'Uint16', name: 'key' },
|
|
82
|
+
{ type: 'Uint16', name: 'textBoxStartIndex' },
|
|
83
|
+
{ type: 'Uint16', name: 'textBoxEndIndex' },
|
|
84
|
+
{ type: 'Uint16', name: 'iconBoxStartIndex' },
|
|
85
|
+
{ type: 'Uint16', name: 'iconBoxEndIndex' },
|
|
86
|
+
{ type: 'Uint16', name: 'featureIndex' },
|
|
87
|
+
{ type: 'Uint16', name: 'numGlyphVertices' },
|
|
88
|
+
{ type: 'Uint16', name: 'numVerticalGlyphVertices' },
|
|
89
|
+
{ type: 'Uint16', name: 'numIconVertices' },
|
|
90
|
+
{ type: 'Uint32', name: 'crossTileID' }
|
|
91
|
+
]);
|
|
92
|
+
|
|
76
93
|
const glyphOffset = createLayout([{ type: 'Float32', name: 'offsetX' }]);
|
|
77
94
|
|
|
78
95
|
const lineVertex = createLayout([
|
|
@@ -90,6 +107,7 @@ module.exports = {
|
|
|
90
107
|
collisionBoxLayout,
|
|
91
108
|
collisionCircleLayout,
|
|
92
109
|
placement,
|
|
110
|
+
symbolInstance,
|
|
93
111
|
glyphOffset,
|
|
94
112
|
lineVertex
|
|
95
113
|
};
|
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
CollisionCircleLayoutArray,
|
|
15
15
|
CollisionVertexArray,
|
|
16
16
|
PlacedSymbolArray,
|
|
17
|
+
SymbolInstanceArray,
|
|
17
18
|
GlyphOffsetArray,
|
|
18
19
|
SymbolLineVertexArray
|
|
19
20
|
} = require('../array_types');
|
|
@@ -31,6 +32,7 @@ const { verticalizedCharacterMap } = require('../../util/verticalize_punctuation
|
|
|
31
32
|
const { getSizeData } = require('../../symbol/symbol_size');
|
|
32
33
|
const { register } = require('../../util/transfer_registry');
|
|
33
34
|
const EvaluationParameters = require('../../style/evaluation_parameters');
|
|
35
|
+
const { Formatted } = require('../../style-spec/expression/definitions/formatted');
|
|
34
36
|
|
|
35
37
|
// Opacity arrays are frequently updated but don't contain a lot of information, so we pack them
|
|
36
38
|
// tight. Each Uint32 is actually four duplicate Uint8s for the four corners of a glyph
|
|
@@ -189,11 +191,13 @@ class SymbolBucket {
|
|
|
189
191
|
this.iconSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['icon-size']);
|
|
190
192
|
|
|
191
193
|
const layout = this.layers[0].layout;
|
|
194
|
+
const zOrderByViewportY = layout.get('symbol-z-order') === 'viewport-y';
|
|
192
195
|
this.sortFeaturesByY =
|
|
193
|
-
|
|
194
|
-
layout.get('
|
|
195
|
-
|
|
196
|
-
|
|
196
|
+
zOrderByViewportY &&
|
|
197
|
+
(layout.get('text-allow-overlap') ||
|
|
198
|
+
layout.get('icon-allow-overlap') ||
|
|
199
|
+
layout.get('text-ignore-placement') ||
|
|
200
|
+
layout.get('icon-ignore-placement'));
|
|
197
201
|
|
|
198
202
|
this.sourceID = options.sourceID;
|
|
199
203
|
}
|
|
@@ -219,6 +223,19 @@ class SymbolBucket {
|
|
|
219
223
|
|
|
220
224
|
this.glyphOffsetArray = new GlyphOffsetArray();
|
|
221
225
|
this.lineVertexArray = new SymbolLineVertexArray();
|
|
226
|
+
this.symbolInstances = new SymbolInstanceArray();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
calculateGlyphDependencies(text, stack, textAlongLine, doesAllowVerticalWritingMode) {
|
|
230
|
+
for (let i = 0; i < text.length; i++) {
|
|
231
|
+
stack[text.charCodeAt(i)] = true;
|
|
232
|
+
if (textAlongLine && doesAllowVerticalWritingMode) {
|
|
233
|
+
const verticalChar = verticalizedCharacterMap[text.charAt(i)];
|
|
234
|
+
if (verticalChar) {
|
|
235
|
+
stack[verticalChar.charCodeAt(0)] = true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
222
239
|
}
|
|
223
240
|
|
|
224
241
|
populate(features, options) {
|
|
@@ -229,7 +246,7 @@ class SymbolBucket {
|
|
|
229
246
|
const textField = layout.get('text-field');
|
|
230
247
|
const iconImage = layout.get('icon-image');
|
|
231
248
|
const hasText =
|
|
232
|
-
(textField.value.kind !== 'constant' || textField.value.value.length > 0) &&
|
|
249
|
+
(textField.value.kind !== 'constant' || textField.value.value.toString().length > 0) &&
|
|
233
250
|
(textFont.value.kind !== 'constant' || textFont.value.value.length > 0);
|
|
234
251
|
const hasIcon = iconImage.value.kind !== 'constant' || (iconImage.value.value && iconImage.value.value.length > 0);
|
|
235
252
|
|
|
@@ -286,15 +303,16 @@ class SymbolBucket {
|
|
|
286
303
|
const stack = (stacks[fontStack] = stacks[fontStack] || {});
|
|
287
304
|
const textAlongLine =
|
|
288
305
|
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
|
-
}
|
|
306
|
+
if (text instanceof Formatted) {
|
|
307
|
+
for (const section of text.sections) {
|
|
308
|
+
const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text.toString());
|
|
309
|
+
const sectionFont = section.fontStack || fontStack;
|
|
310
|
+
const sectionStack = (stacks[sectionFont] = stacks[sectionFont] || {});
|
|
311
|
+
this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, doesAllowVerticalWritingMode);
|
|
297
312
|
}
|
|
313
|
+
} else {
|
|
314
|
+
const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text);
|
|
315
|
+
this.calculateGlyphDependencies(text, stack, textAlongLine, doesAllowVerticalWritingMode);
|
|
298
316
|
}
|
|
299
317
|
}
|
|
300
318
|
}
|
|
@@ -441,15 +459,15 @@ class SymbolBucket {
|
|
|
441
459
|
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {});
|
|
442
460
|
}
|
|
443
461
|
|
|
444
|
-
_addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, point,
|
|
462
|
+
_addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, point, anchorX, anchorY, extrude) {
|
|
445
463
|
collisionVertexArray.emplaceBack(0, 0);
|
|
446
464
|
return layoutVertexArray.emplaceBack(
|
|
447
465
|
// pos
|
|
448
466
|
point.x,
|
|
449
467
|
point.y,
|
|
450
468
|
// a_anchor_pos
|
|
451
|
-
|
|
452
|
-
|
|
469
|
+
anchorX,
|
|
470
|
+
anchorY,
|
|
453
471
|
// extrude
|
|
454
472
|
Math.round(extrude.x),
|
|
455
473
|
Math.round(extrude.y)
|
|
@@ -463,32 +481,39 @@ class SymbolBucket {
|
|
|
463
481
|
const layoutVertexArray = arrays.layoutVertexArray;
|
|
464
482
|
const collisionVertexArray = arrays.collisionVertexArray;
|
|
465
483
|
|
|
484
|
+
const anchorX = symbolInstance.anchorX;
|
|
485
|
+
const anchorY = symbolInstance.anchorY;
|
|
486
|
+
|
|
466
487
|
this._addCollisionDebugVertex(
|
|
467
488
|
layoutVertexArray,
|
|
468
489
|
collisionVertexArray,
|
|
469
490
|
boxAnchorPoint,
|
|
470
|
-
|
|
491
|
+
anchorX,
|
|
492
|
+
anchorY,
|
|
471
493
|
new Point(x1, y1)
|
|
472
494
|
);
|
|
473
495
|
this._addCollisionDebugVertex(
|
|
474
496
|
layoutVertexArray,
|
|
475
497
|
collisionVertexArray,
|
|
476
498
|
boxAnchorPoint,
|
|
477
|
-
|
|
499
|
+
anchorX,
|
|
500
|
+
anchorY,
|
|
478
501
|
new Point(x2, y1)
|
|
479
502
|
);
|
|
480
503
|
this._addCollisionDebugVertex(
|
|
481
504
|
layoutVertexArray,
|
|
482
505
|
collisionVertexArray,
|
|
483
506
|
boxAnchorPoint,
|
|
484
|
-
|
|
507
|
+
anchorX,
|
|
508
|
+
anchorY,
|
|
485
509
|
new Point(x2, y2)
|
|
486
510
|
);
|
|
487
511
|
this._addCollisionDebugVertex(
|
|
488
512
|
layoutVertexArray,
|
|
489
513
|
collisionVertexArray,
|
|
490
514
|
boxAnchorPoint,
|
|
491
|
-
|
|
515
|
+
anchorX,
|
|
516
|
+
anchorY,
|
|
492
517
|
new Point(x1, y2)
|
|
493
518
|
);
|
|
494
519
|
|
|
@@ -510,49 +535,41 @@ class SymbolBucket {
|
|
|
510
535
|
}
|
|
511
536
|
}
|
|
512
537
|
|
|
513
|
-
|
|
514
|
-
for (
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
538
|
+
addDebugCollisionBoxes(startIndex, endIndex, symbolInstance) {
|
|
539
|
+
for (let b = startIndex; b < endIndex; b++) {
|
|
540
|
+
const box = this.collisionBoxArray.get(b);
|
|
541
|
+
const x1 = box.x1;
|
|
542
|
+
const y1 = box.y1;
|
|
543
|
+
const x2 = box.x2;
|
|
544
|
+
const y2 = box.y2;
|
|
545
|
+
|
|
546
|
+
// If the radius > 0, this collision box is actually a circle
|
|
547
|
+
// The data we add to the buffers is exactly the same, but we'll render with a different shader.
|
|
548
|
+
const isCircle = box.radius > 0;
|
|
549
|
+
this.addCollisionDebugVertices(
|
|
550
|
+
x1,
|
|
551
|
+
y1,
|
|
552
|
+
x2,
|
|
553
|
+
y2,
|
|
554
|
+
isCircle ? this.collisionCircle : this.collisionBox,
|
|
555
|
+
box.anchorPoint,
|
|
556
|
+
symbolInstance,
|
|
557
|
+
isCircle
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
523
561
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
const box = this.collisionBoxArray.get(b);
|
|
530
|
-
const x1 = box.x1;
|
|
531
|
-
const y1 = box.y1;
|
|
532
|
-
const x2 = box.x2;
|
|
533
|
-
const y2 = box.y2;
|
|
534
|
-
|
|
535
|
-
// If the radius > 0, this collision box is actually a circle
|
|
536
|
-
// The data we add to the buffers is exactly the same, but we'll render with a different shader.
|
|
537
|
-
const isCircle = box.radius > 0;
|
|
538
|
-
this.addCollisionDebugVertices(
|
|
539
|
-
x1,
|
|
540
|
-
y1,
|
|
541
|
-
x2,
|
|
542
|
-
y2,
|
|
543
|
-
isCircle ? this.collisionCircle : this.collisionBox,
|
|
544
|
-
box.anchorPoint,
|
|
545
|
-
symbolInstance,
|
|
546
|
-
isCircle
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
562
|
+
generateCollisionDebugBuffers() {
|
|
563
|
+
for (let i = 0; i < this.symbolInstances.length; i++) {
|
|
564
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
565
|
+
this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance);
|
|
566
|
+
this.addDebugCollisionBoxes(symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance);
|
|
550
567
|
}
|
|
551
568
|
}
|
|
552
569
|
|
|
553
570
|
// These flat arrays are meant to be quicker to iterate over than the source
|
|
554
571
|
// CollisionBoxArray
|
|
555
|
-
|
|
572
|
+
_deserializeCollisionBoxesForSymbol(collisionBoxArray, textStartIndex, textEndIndex, iconStartIndex, iconEndIndex) {
|
|
556
573
|
const collisionArrays = {};
|
|
557
574
|
for (let k = textStartIndex; k < textEndIndex; k++) {
|
|
558
575
|
const box = collisionBoxArray.get(k);
|
|
@@ -600,6 +617,22 @@ class SymbolBucket {
|
|
|
600
617
|
return collisionArrays;
|
|
601
618
|
}
|
|
602
619
|
|
|
620
|
+
deserializeCollisionBoxes(collisionBoxArray) {
|
|
621
|
+
this.collisionArrays = [];
|
|
622
|
+
for (let i = 0; i < this.symbolInstances.length; i++) {
|
|
623
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
624
|
+
this.collisionArrays.push(
|
|
625
|
+
this._deserializeCollisionBoxesForSymbol(
|
|
626
|
+
collisionBoxArray,
|
|
627
|
+
symbolInstance.textBoxStartIndex,
|
|
628
|
+
symbolInstance.textBoxEndIndex,
|
|
629
|
+
symbolInstance.iconBoxStartIndex,
|
|
630
|
+
symbolInstance.iconBoxEndIndex
|
|
631
|
+
)
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
603
636
|
hasTextData() {
|
|
604
637
|
return this.text.segments.get().length > 0;
|
|
605
638
|
}
|
|
@@ -616,6 +649,16 @@ class SymbolBucket {
|
|
|
616
649
|
return this.collisionCircle.segments.get().length > 0;
|
|
617
650
|
}
|
|
618
651
|
|
|
652
|
+
addIndicesForPlacedTextSymbol(placedTextSymbolIndex) {
|
|
653
|
+
const placedSymbol = this.text.placedSymbolArray.get(placedTextSymbolIndex);
|
|
654
|
+
|
|
655
|
+
const endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4;
|
|
656
|
+
for (let vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) {
|
|
657
|
+
this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
|
|
658
|
+
this.text.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
619
662
|
sortFeatures(angle) {
|
|
620
663
|
if (!this.sortFeaturesByY) return;
|
|
621
664
|
|
|
@@ -639,12 +682,16 @@ class SymbolBucket {
|
|
|
639
682
|
const sin = Math.sin(angle);
|
|
640
683
|
const cos = Math.cos(angle);
|
|
641
684
|
|
|
685
|
+
const rotatedYs = [];
|
|
686
|
+
const featureIndexes = [];
|
|
687
|
+
for (let i = 0; i < this.symbolInstances.length; i++) {
|
|
688
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
689
|
+
rotatedYs.push(Math.round(sin * symbolInstance.anchorX + cos * symbolInstance.anchorY) | 0);
|
|
690
|
+
featureIndexes.push(symbolInstance.featureIndex);
|
|
691
|
+
}
|
|
692
|
+
|
|
642
693
|
symbolInstanceIndexes.sort((aIndex, bIndex) => {
|
|
643
|
-
|
|
644
|
-
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;
|
|
647
|
-
return aRotated - bRotated || b.featureIndex - a.featureIndex;
|
|
694
|
+
return rotatedYs[aIndex] - rotatedYs[bIndex] || featureIndexes[bIndex] - featureIndexes[aIndex];
|
|
648
695
|
});
|
|
649
696
|
|
|
650
697
|
this.text.indexArray.clear();
|
|
@@ -653,17 +700,14 @@ class SymbolBucket {
|
|
|
653
700
|
this.featureSortOrder = [];
|
|
654
701
|
|
|
655
702
|
for (const i of symbolInstanceIndexes) {
|
|
656
|
-
const symbolInstance = this.symbolInstances
|
|
703
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
657
704
|
this.featureSortOrder.push(symbolInstance.featureIndex);
|
|
658
705
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
|
|
665
|
-
this.text.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
|
|
666
|
-
}
|
|
706
|
+
if (symbolInstance.horizontalPlacedTextSymbolIndex >= 0) {
|
|
707
|
+
this.addIndicesForPlacedTextSymbol(symbolInstance.horizontalPlacedTextSymbolIndex);
|
|
708
|
+
}
|
|
709
|
+
if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) {
|
|
710
|
+
this.addIndicesForPlacedTextSymbol(symbolInstance.verticalPlacedTextSymbolIndex);
|
|
667
711
|
}
|
|
668
712
|
|
|
669
713
|
const placedIcon = this.icon.placedSymbolArray.get(i);
|
|
@@ -680,8 +724,7 @@ class SymbolBucket {
|
|
|
680
724
|
}
|
|
681
725
|
|
|
682
726
|
register('SymbolBucket', SymbolBucket, {
|
|
683
|
-
omit: ['layers', 'collisionBoxArray', 'features', 'compareText']
|
|
684
|
-
shallow: ['symbolInstances']
|
|
727
|
+
omit: ['layers', 'collisionBoxArray', 'features', 'compareText']
|
|
685
728
|
});
|
|
686
729
|
|
|
687
730
|
// this constant is based on the size of StructArray indexes used in a symbol
|
|
@@ -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/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;
|
|
@@ -176,13 +177,21 @@ class Transform {
|
|
|
176
177
|
* @private
|
|
177
178
|
*/
|
|
178
179
|
getVisibleUnwrappedCoordinates(tileID) {
|
|
179
|
-
const ul = this.pointCoordinate(new Point(0, 0), 0);
|
|
180
|
-
const ur = this.pointCoordinate(new Point(this.width, 0), 0);
|
|
181
|
-
const w0 = Math.floor(ul.column);
|
|
182
|
-
const w1 = Math.floor(ur.column);
|
|
183
180
|
const result = [new UnwrappedTileID(0, tileID)];
|
|
184
181
|
if (this._renderWorldCopies) {
|
|
185
|
-
|
|
182
|
+
const utl = this.pointCoordinate(new Point(0, 0), 0);
|
|
183
|
+
const utr = this.pointCoordinate(new Point(this.width, 0), 0);
|
|
184
|
+
const ubl = this.pointCoordinate(new Point(this.width, this.height), 0);
|
|
185
|
+
const ubr = this.pointCoordinate(new Point(0, this.height), 0);
|
|
186
|
+
const w0 = Math.floor(Math.min(utl.column, utr.column, ubl.column, ubr.column));
|
|
187
|
+
const w1 = Math.floor(Math.max(utl.column, utr.column, ubl.column, ubr.column));
|
|
188
|
+
|
|
189
|
+
// Add an extra copy of the world on each side to properly render ImageSources and CanvasSources.
|
|
190
|
+
// Both sources draw outside the tile boundaries of the tile that "contains them" so we need
|
|
191
|
+
// to add extra copies on both sides in case offscreen tiles need to draw into on-screen ones.
|
|
192
|
+
const extraWorldCopy = 1;
|
|
193
|
+
|
|
194
|
+
for (let w = w0 - extraWorldCopy; w <= w1 + extraWorldCopy; w++) {
|
|
186
195
|
if (w === 0) continue;
|
|
187
196
|
result.push(new UnwrappedTileID(w, tileID));
|
|
188
197
|
}
|
|
@@ -262,7 +271,7 @@ class Transform {
|
|
|
262
271
|
}
|
|
263
272
|
|
|
264
273
|
/**
|
|
265
|
-
*
|
|
274
|
+
* longitude to absolute x coord
|
|
266
275
|
* @returns {number} pixel coordinate
|
|
267
276
|
*/
|
|
268
277
|
lngX(lng) {
|
|
@@ -273,6 +282,7 @@ class Transform {
|
|
|
273
282
|
* @returns {number} pixel coordinate
|
|
274
283
|
*/
|
|
275
284
|
latY(lat) {
|
|
285
|
+
lat = clamp(lat, -this.maxValidLatitude, this.maxValidLatitude);
|
|
276
286
|
const y = (180 / Math.PI) * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
|
|
277
287
|
return ((180 - y) * this.worldSize) / 360;
|
|
278
288
|
}
|