@mapwhit/tilerenderer 0.48.0 → 0.50.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/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +1 -9
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +4 -4
- 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 +108 -78
- package/src/geo/transform.js +13 -5
- 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/shaders/fill_extrusion.fragment.glsl +0 -7
- package/src/shaders/fill_extrusion.vertex.glsl +4 -4
- package/src/style/style_layer/symbol_style_layer_properties.js +6 -0
- package/src/style-spec/expression/definitions/assertion.js +52 -5
- package/src/style-spec/expression/definitions/coalesce.js +1 -3
- package/src/style-spec/expression/definitions/coercion.js +32 -21
- package/src/style-spec/expression/definitions/collator.js +1 -23
- package/src/style-spec/expression/definitions/{formatted.js → format.js} +3 -29
- package/src/style-spec/expression/definitions/index.js +8 -26
- package/src/style-spec/expression/definitions/let.js +1 -1
- package/src/style-spec/expression/definitions/literal.js +1 -1
- package/src/style-spec/expression/evaluation_context.js +3 -0
- package/src/style-spec/expression/index.js +18 -17
- package/src/style-spec/expression/parsing_context.js +28 -24
- package/src/style-spec/expression/types/collator.js +24 -0
- package/src/style-spec/expression/types/formatted.js +39 -0
- package/src/style-spec/expression/types.js +1 -1
- package/src/style-spec/expression/values.js +24 -1
- package/src/style-spec/feature_filter/convert.js +197 -0
- package/src/style-spec/feature_filter/index.js +4 -1
- package/src/style-spec/function/convert.js +86 -102
- package/src/style-spec/function/index.js +4 -0
- package/src/style-spec/reference/v8.json +43 -6
- package/src/symbol/collision_index.js +0 -1
- package/src/symbol/cross_tile_symbol_index.js +12 -7
- package/src/symbol/mergelines.js +2 -2
- package/src/symbol/placement.js +71 -54
- package/src/symbol/shaping.js +9 -18
- package/src/symbol/symbol_layout.js +33 -33
- package/src/symbol/transform_text.js +5 -8
- package/src/style-spec/expression/definitions/array.js +0 -82
package/build/min/package.json
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
varying vec4 v_color;
|
|
2
|
-
#pragma mapbox: define lowp float base
|
|
3
|
-
#pragma mapbox: define lowp float height
|
|
4
|
-
#pragma mapbox: define highp vec4 color
|
|
5
|
-
void main(){
|
|
6
|
-
#pragma mapbox: initialize lowp float base
|
|
7
|
-
#pragma mapbox: initialize lowp float height
|
|
8
|
-
#pragma mapbox: initialize highp vec4 color
|
|
9
|
-
gl_FragColor=v_color;
|
|
1
|
+
varying vec4 v_color;void main(){gl_FragColor=v_color;
|
|
10
2
|
#ifdef OVERDRAW_INSPECTOR
|
|
11
3
|
gl_FragColor=vec4(1.);
|
|
12
4
|
#endif
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
uniform mat4 u_matrix;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;attribute vec2 a_pos;attribute vec4 a_normal_ed;varying vec4 v_color;
|
|
2
|
-
#pragma mapbox: define
|
|
3
|
-
#pragma mapbox: define
|
|
2
|
+
#pragma mapbox: define highp float base
|
|
3
|
+
#pragma mapbox: define highp float height
|
|
4
4
|
#pragma mapbox: define highp vec4 color
|
|
5
5
|
void main(){
|
|
6
|
-
#pragma mapbox: initialize
|
|
7
|
-
#pragma mapbox: initialize
|
|
6
|
+
#pragma mapbox: initialize highp float base
|
|
7
|
+
#pragma mapbox: initialize highp float height
|
|
8
8
|
#pragma mapbox: initialize highp vec4 color
|
|
9
9
|
vec3 normal=a_normal_ed.xyz;base=max(0.,base);height=max(0.,height);float t=mod(normal.x,2.);gl_Position=u_matrix*vec4(a_pos,t>0.?height:base,1);float colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.,0.,0.,1.);vec4 ambientlight=vec4(0.03,0.03,0.03,1.);color+=ambientlight;float directional=clamp(dot(normal/16384.,u_lightpos),0.,1.);directional=mix((1.-u_lightintensity),max((1.-colorvalue+u_lightintensity),1.),directional);if(normal.y!=0.){directional*=((1.-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.,0.5),mix(0.7,0.98,1.-u_lightintensity),1.)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.,0.3,1.-u_lightcolor.r),1.);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.,0.3,1.-u_lightcolor.g),1.);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.,0.3,1.-u_lightcolor.b),1.);v_color*=u_opacity;}
|
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.50.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,7 +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');
|
|
34
|
-
const { Formatted } = require('../../style-spec/expression/
|
|
35
|
+
const { Formatted } = require('../../style-spec/expression/types/formatted');
|
|
35
36
|
|
|
36
37
|
// Opacity arrays are frequently updated but don't contain a lot of information, so we pack them
|
|
37
38
|
// tight. Each Uint32 is actually four duplicate Uint8s for the four corners of a glyph
|
|
@@ -190,11 +191,13 @@ class SymbolBucket {
|
|
|
190
191
|
this.iconSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['icon-size']);
|
|
191
192
|
|
|
192
193
|
const layout = this.layers[0].layout;
|
|
194
|
+
const zOrderByViewportY = layout.get('symbol-z-order') === 'viewport-y';
|
|
193
195
|
this.sortFeaturesByY =
|
|
194
|
-
|
|
195
|
-
layout.get('
|
|
196
|
-
|
|
197
|
-
|
|
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'));
|
|
198
201
|
|
|
199
202
|
this.sourceID = options.sourceID;
|
|
200
203
|
}
|
|
@@ -220,6 +223,7 @@ class SymbolBucket {
|
|
|
220
223
|
|
|
221
224
|
this.glyphOffsetArray = new GlyphOffsetArray();
|
|
222
225
|
this.lineVertexArray = new SymbolLineVertexArray();
|
|
226
|
+
this.symbolInstances = new SymbolInstanceArray();
|
|
223
227
|
}
|
|
224
228
|
|
|
225
229
|
calculateGlyphDependencies(text, stack, textAlongLine, doesAllowVerticalWritingMode) {
|
|
@@ -263,8 +267,15 @@ class SymbolBucket {
|
|
|
263
267
|
|
|
264
268
|
let text;
|
|
265
269
|
if (hasText) {
|
|
266
|
-
|
|
267
|
-
|
|
270
|
+
// Expression evaluation will automatically coerce to Formatted
|
|
271
|
+
// but plain string token evaluation skips that pathway so do the
|
|
272
|
+
// conversion here.
|
|
273
|
+
const resolvedTokens = layer.getValueAndResolveTokens('text-field', feature);
|
|
274
|
+
text = transformText(
|
|
275
|
+
resolvedTokens instanceof Formatted ? resolvedTokens : Formatted.fromString(resolvedTokens),
|
|
276
|
+
layer,
|
|
277
|
+
feature
|
|
278
|
+
);
|
|
268
279
|
}
|
|
269
280
|
|
|
270
281
|
let icon;
|
|
@@ -296,19 +307,13 @@ class SymbolBucket {
|
|
|
296
307
|
|
|
297
308
|
if (text) {
|
|
298
309
|
const fontStack = textFont.evaluate(feature, {}).join(',');
|
|
299
|
-
const stack = (stacks[fontStack] = stacks[fontStack] || {});
|
|
300
310
|
const textAlongLine =
|
|
301
311
|
layout.get('text-rotation-alignment') === 'map' && layout.get('symbol-placement') !== 'point';
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, doesAllowVerticalWritingMode);
|
|
308
|
-
}
|
|
309
|
-
} else {
|
|
310
|
-
const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text);
|
|
311
|
-
this.calculateGlyphDependencies(text, stack, textAlongLine, doesAllowVerticalWritingMode);
|
|
312
|
+
for (const section of text.sections) {
|
|
313
|
+
const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text.toString());
|
|
314
|
+
const sectionFont = section.fontStack || fontStack;
|
|
315
|
+
const sectionStack = (stacks[sectionFont] = stacks[sectionFont] || {});
|
|
316
|
+
this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, doesAllowVerticalWritingMode);
|
|
312
317
|
}
|
|
313
318
|
}
|
|
314
319
|
}
|
|
@@ -455,15 +460,15 @@ class SymbolBucket {
|
|
|
455
460
|
arrays.programConfigurations.populatePaintArrays(arrays.layoutVertexArray.length, feature, feature.index, {});
|
|
456
461
|
}
|
|
457
462
|
|
|
458
|
-
_addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, point,
|
|
463
|
+
_addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, point, anchorX, anchorY, extrude) {
|
|
459
464
|
collisionVertexArray.emplaceBack(0, 0);
|
|
460
465
|
return layoutVertexArray.emplaceBack(
|
|
461
466
|
// pos
|
|
462
467
|
point.x,
|
|
463
468
|
point.y,
|
|
464
469
|
// a_anchor_pos
|
|
465
|
-
|
|
466
|
-
|
|
470
|
+
anchorX,
|
|
471
|
+
anchorY,
|
|
467
472
|
// extrude
|
|
468
473
|
Math.round(extrude.x),
|
|
469
474
|
Math.round(extrude.y)
|
|
@@ -477,32 +482,39 @@ class SymbolBucket {
|
|
|
477
482
|
const layoutVertexArray = arrays.layoutVertexArray;
|
|
478
483
|
const collisionVertexArray = arrays.collisionVertexArray;
|
|
479
484
|
|
|
485
|
+
const anchorX = symbolInstance.anchorX;
|
|
486
|
+
const anchorY = symbolInstance.anchorY;
|
|
487
|
+
|
|
480
488
|
this._addCollisionDebugVertex(
|
|
481
489
|
layoutVertexArray,
|
|
482
490
|
collisionVertexArray,
|
|
483
491
|
boxAnchorPoint,
|
|
484
|
-
|
|
492
|
+
anchorX,
|
|
493
|
+
anchorY,
|
|
485
494
|
new Point(x1, y1)
|
|
486
495
|
);
|
|
487
496
|
this._addCollisionDebugVertex(
|
|
488
497
|
layoutVertexArray,
|
|
489
498
|
collisionVertexArray,
|
|
490
499
|
boxAnchorPoint,
|
|
491
|
-
|
|
500
|
+
anchorX,
|
|
501
|
+
anchorY,
|
|
492
502
|
new Point(x2, y1)
|
|
493
503
|
);
|
|
494
504
|
this._addCollisionDebugVertex(
|
|
495
505
|
layoutVertexArray,
|
|
496
506
|
collisionVertexArray,
|
|
497
507
|
boxAnchorPoint,
|
|
498
|
-
|
|
508
|
+
anchorX,
|
|
509
|
+
anchorY,
|
|
499
510
|
new Point(x2, y2)
|
|
500
511
|
);
|
|
501
512
|
this._addCollisionDebugVertex(
|
|
502
513
|
layoutVertexArray,
|
|
503
514
|
collisionVertexArray,
|
|
504
515
|
boxAnchorPoint,
|
|
505
|
-
|
|
516
|
+
anchorX,
|
|
517
|
+
anchorY,
|
|
506
518
|
new Point(x1, y2)
|
|
507
519
|
);
|
|
508
520
|
|
|
@@ -524,49 +536,41 @@ class SymbolBucket {
|
|
|
524
536
|
}
|
|
525
537
|
}
|
|
526
538
|
|
|
527
|
-
|
|
528
|
-
for (
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
539
|
+
addDebugCollisionBoxes(startIndex, endIndex, symbolInstance) {
|
|
540
|
+
for (let b = startIndex; b < endIndex; b++) {
|
|
541
|
+
const box = this.collisionBoxArray.get(b);
|
|
542
|
+
const x1 = box.x1;
|
|
543
|
+
const y1 = box.y1;
|
|
544
|
+
const x2 = box.x2;
|
|
545
|
+
const y2 = box.y2;
|
|
546
|
+
|
|
547
|
+
// If the radius > 0, this collision box is actually a circle
|
|
548
|
+
// The data we add to the buffers is exactly the same, but we'll render with a different shader.
|
|
549
|
+
const isCircle = box.radius > 0;
|
|
550
|
+
this.addCollisionDebugVertices(
|
|
551
|
+
x1,
|
|
552
|
+
y1,
|
|
553
|
+
x2,
|
|
554
|
+
y2,
|
|
555
|
+
isCircle ? this.collisionCircle : this.collisionBox,
|
|
556
|
+
box.anchorPoint,
|
|
557
|
+
symbolInstance,
|
|
558
|
+
isCircle
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
537
562
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
const box = this.collisionBoxArray.get(b);
|
|
544
|
-
const x1 = box.x1;
|
|
545
|
-
const y1 = box.y1;
|
|
546
|
-
const x2 = box.x2;
|
|
547
|
-
const y2 = box.y2;
|
|
548
|
-
|
|
549
|
-
// If the radius > 0, this collision box is actually a circle
|
|
550
|
-
// The data we add to the buffers is exactly the same, but we'll render with a different shader.
|
|
551
|
-
const isCircle = box.radius > 0;
|
|
552
|
-
this.addCollisionDebugVertices(
|
|
553
|
-
x1,
|
|
554
|
-
y1,
|
|
555
|
-
x2,
|
|
556
|
-
y2,
|
|
557
|
-
isCircle ? this.collisionCircle : this.collisionBox,
|
|
558
|
-
box.anchorPoint,
|
|
559
|
-
symbolInstance,
|
|
560
|
-
isCircle
|
|
561
|
-
);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
563
|
+
generateCollisionDebugBuffers() {
|
|
564
|
+
for (let i = 0; i < this.symbolInstances.length; i++) {
|
|
565
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
566
|
+
this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance);
|
|
567
|
+
this.addDebugCollisionBoxes(symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance);
|
|
564
568
|
}
|
|
565
569
|
}
|
|
566
570
|
|
|
567
571
|
// These flat arrays are meant to be quicker to iterate over than the source
|
|
568
572
|
// CollisionBoxArray
|
|
569
|
-
|
|
573
|
+
_deserializeCollisionBoxesForSymbol(collisionBoxArray, textStartIndex, textEndIndex, iconStartIndex, iconEndIndex) {
|
|
570
574
|
const collisionArrays = {};
|
|
571
575
|
for (let k = textStartIndex; k < textEndIndex; k++) {
|
|
572
576
|
const box = collisionBoxArray.get(k);
|
|
@@ -614,6 +618,22 @@ class SymbolBucket {
|
|
|
614
618
|
return collisionArrays;
|
|
615
619
|
}
|
|
616
620
|
|
|
621
|
+
deserializeCollisionBoxes(collisionBoxArray) {
|
|
622
|
+
this.collisionArrays = [];
|
|
623
|
+
for (let i = 0; i < this.symbolInstances.length; i++) {
|
|
624
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
625
|
+
this.collisionArrays.push(
|
|
626
|
+
this._deserializeCollisionBoxesForSymbol(
|
|
627
|
+
collisionBoxArray,
|
|
628
|
+
symbolInstance.textBoxStartIndex,
|
|
629
|
+
symbolInstance.textBoxEndIndex,
|
|
630
|
+
symbolInstance.iconBoxStartIndex,
|
|
631
|
+
symbolInstance.iconBoxEndIndex
|
|
632
|
+
)
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
617
637
|
hasTextData() {
|
|
618
638
|
return this.text.segments.get().length > 0;
|
|
619
639
|
}
|
|
@@ -630,6 +650,16 @@ class SymbolBucket {
|
|
|
630
650
|
return this.collisionCircle.segments.get().length > 0;
|
|
631
651
|
}
|
|
632
652
|
|
|
653
|
+
addIndicesForPlacedTextSymbol(placedTextSymbolIndex) {
|
|
654
|
+
const placedSymbol = this.text.placedSymbolArray.get(placedTextSymbolIndex);
|
|
655
|
+
|
|
656
|
+
const endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4;
|
|
657
|
+
for (let vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) {
|
|
658
|
+
this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
|
|
659
|
+
this.text.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
633
663
|
sortFeatures(angle) {
|
|
634
664
|
if (!this.sortFeaturesByY) return;
|
|
635
665
|
|
|
@@ -653,12 +683,16 @@ class SymbolBucket {
|
|
|
653
683
|
const sin = Math.sin(angle);
|
|
654
684
|
const cos = Math.cos(angle);
|
|
655
685
|
|
|
686
|
+
const rotatedYs = [];
|
|
687
|
+
const featureIndexes = [];
|
|
688
|
+
for (let i = 0; i < this.symbolInstances.length; i++) {
|
|
689
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
690
|
+
rotatedYs.push(Math.round(sin * symbolInstance.anchorX + cos * symbolInstance.anchorY) | 0);
|
|
691
|
+
featureIndexes.push(symbolInstance.featureIndex);
|
|
692
|
+
}
|
|
693
|
+
|
|
656
694
|
symbolInstanceIndexes.sort((aIndex, bIndex) => {
|
|
657
|
-
|
|
658
|
-
const b = this.symbolInstances[bIndex];
|
|
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;
|
|
661
|
-
return aRotated - bRotated || b.featureIndex - a.featureIndex;
|
|
695
|
+
return rotatedYs[aIndex] - rotatedYs[bIndex] || featureIndexes[bIndex] - featureIndexes[aIndex];
|
|
662
696
|
});
|
|
663
697
|
|
|
664
698
|
this.text.indexArray.clear();
|
|
@@ -667,17 +701,14 @@ class SymbolBucket {
|
|
|
667
701
|
this.featureSortOrder = [];
|
|
668
702
|
|
|
669
703
|
for (const i of symbolInstanceIndexes) {
|
|
670
|
-
const symbolInstance = this.symbolInstances
|
|
704
|
+
const symbolInstance = this.symbolInstances.get(i);
|
|
671
705
|
this.featureSortOrder.push(symbolInstance.featureIndex);
|
|
672
706
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
|
|
679
|
-
this.text.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
|
|
680
|
-
}
|
|
707
|
+
if (symbolInstance.horizontalPlacedTextSymbolIndex >= 0) {
|
|
708
|
+
this.addIndicesForPlacedTextSymbol(symbolInstance.horizontalPlacedTextSymbolIndex);
|
|
709
|
+
}
|
|
710
|
+
if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) {
|
|
711
|
+
this.addIndicesForPlacedTextSymbol(symbolInstance.verticalPlacedTextSymbolIndex);
|
|
681
712
|
}
|
|
682
713
|
|
|
683
714
|
const placedIcon = this.icon.placedSymbolArray.get(i);
|
|
@@ -694,8 +725,7 @@ class SymbolBucket {
|
|
|
694
725
|
}
|
|
695
726
|
|
|
696
727
|
register('SymbolBucket', SymbolBucket, {
|
|
697
|
-
omit: ['layers', 'collisionBoxArray', 'features', 'compareText']
|
|
698
|
-
shallow: ['symbolInstances']
|
|
728
|
+
omit: ['layers', 'collisionBoxArray', 'features', 'compareText']
|
|
699
729
|
});
|
|
700
730
|
|
|
701
731
|
// this constant is based on the size of StructArray indexes used in a symbol
|
package/src/geo/transform.js
CHANGED
|
@@ -177,13 +177,21 @@ class Transform {
|
|
|
177
177
|
* @private
|
|
178
178
|
*/
|
|
179
179
|
getVisibleUnwrappedCoordinates(tileID) {
|
|
180
|
-
const ul = this.pointCoordinate(new Point(0, 0), 0);
|
|
181
|
-
const ur = this.pointCoordinate(new Point(this.width, 0), 0);
|
|
182
|
-
const w0 = Math.floor(ul.column);
|
|
183
|
-
const w1 = Math.floor(ur.column);
|
|
184
180
|
const result = [new UnwrappedTileID(0, tileID)];
|
|
185
181
|
if (this._renderWorldCopies) {
|
|
186
|
-
|
|
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++) {
|
|
187
195
|
if (w === 0) continue;
|
|
188
196
|
result.push(new UnwrappedTileID(w, tileID));
|
|
189
197
|
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
const ShelfPack = require('@mapbox/shelf-pack');
|
|
2
|
-
|
|
3
1
|
const { AlphaImage } = require('../util/image');
|
|
4
2
|
const { register } = require('../util/transfer_registry');
|
|
3
|
+
const potpack = require('potpack');
|
|
5
4
|
|
|
6
5
|
const padding = 1;
|
|
7
6
|
|
|
8
7
|
class GlyphAtlas {
|
|
9
8
|
constructor(stacks) {
|
|
10
9
|
const positions = {};
|
|
11
|
-
const pack = new ShelfPack(0, 0, { autoResize: true });
|
|
12
10
|
const bins = [];
|
|
13
11
|
|
|
14
12
|
for (const stack in stacks) {
|
|
@@ -30,9 +28,8 @@ class GlyphAtlas {
|
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const image = new AlphaImage({ width: pack.w, height: pack.h });
|
|
31
|
+
const { w, h } = potpack(bins);
|
|
32
|
+
const image = new AlphaImage({ width: w ?? 1, height: h ?? 1 });
|
|
36
33
|
|
|
37
34
|
for (const stack in stacks) {
|
|
38
35
|
const glyphs = stacks[stack];
|