@mapwhit/tilerenderer 0.52.0 → 1.0.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/README.md +7 -0
- package/build/min/package.json +1 -1
- package/build/min/src/shaders/_prelude.fragment.glsl.js +2 -2
- package/build/min/src/shaders/_prelude.vertex.glsl.js +2 -2
- package/build/min/src/shaders/background.fragment.glsl.js +2 -2
- package/build/min/src/shaders/background.vertex.glsl.js +1 -1
- package/build/min/src/shaders/background_pattern.fragment.glsl.js +2 -2
- package/build/min/src/shaders/background_pattern.vertex.glsl.js +1 -1
- package/build/min/src/shaders/circle.fragment.glsl.js +2 -2
- package/build/min/src/shaders/circle.vertex.glsl.js +2 -2
- package/build/min/src/shaders/clipping_mask.fragment.glsl.js +1 -1
- package/build/min/src/shaders/clipping_mask.vertex.glsl.js +1 -1
- package/build/min/src/shaders/collision_box.fragment.glsl.js +1 -1
- package/build/min/src/shaders/collision_box.vertex.glsl.js +1 -1
- package/build/min/src/shaders/collision_circle.fragment.glsl.js +1 -1
- package/build/min/src/shaders/collision_circle.vertex.glsl.js +1 -1
- package/build/min/src/shaders/debug.fragment.glsl.js +1 -1
- package/build/min/src/shaders/debug.vertex.glsl.js +1 -1
- package/build/min/src/shaders/fill.fragment.glsl.js +2 -2
- package/build/min/src/shaders/fill.vertex.glsl.js +2 -2
- package/build/min/src/shaders/fill_extrusion.fragment.glsl.js +2 -2
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.js +2 -2
- package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.js +2 -2
- package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.js +2 -2
- package/build/min/src/shaders/fill_outline.fragment.glsl.js +2 -2
- package/build/min/src/shaders/fill_outline.vertex.glsl.js +2 -2
- package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.js +2 -2
- package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.js +2 -2
- package/build/min/src/shaders/fill_pattern.fragment.glsl.js +2 -2
- package/build/min/src/shaders/fill_pattern.vertex.glsl.js +2 -2
- package/build/min/src/shaders/heatmap.fragment.glsl.js +2 -2
- package/build/min/src/shaders/heatmap.vertex.glsl.js +2 -2
- package/build/min/src/shaders/heatmap_texture.fragment.glsl.js +2 -2
- package/build/min/src/shaders/heatmap_texture.vertex.glsl.js +1 -1
- package/build/min/src/shaders/hillshade.fragment.glsl.js +2 -2
- package/build/min/src/shaders/hillshade.vertex.glsl.js +1 -1
- package/build/min/src/shaders/hillshade_prepare.fragment.glsl.js +2 -2
- package/build/min/src/shaders/hillshade_prepare.vertex.glsl.js +1 -1
- package/build/min/src/shaders/line.fragment.glsl.js +2 -2
- package/build/min/src/shaders/line.vertex.glsl.js +2 -2
- package/build/min/src/shaders/line_gradient.fragment.glsl.js +2 -2
- package/build/min/src/shaders/line_gradient.vertex.glsl.js +2 -2
- package/build/min/src/shaders/line_pattern.fragment.glsl.js +2 -2
- package/build/min/src/shaders/line_pattern.vertex.glsl.js +2 -2
- package/build/min/src/shaders/line_sdf.fragment.glsl.js +2 -2
- package/build/min/src/shaders/line_sdf.vertex.glsl.js +2 -2
- package/build/min/src/shaders/raster.fragment.glsl.js +2 -2
- package/build/min/src/shaders/raster.vertex.glsl.js +1 -1
- package/build/min/src/shaders/symbol_icon.fragment.glsl.js +2 -2
- package/build/min/src/shaders/symbol_icon.vertex.glsl.js +2 -2
- package/build/min/src/shaders/symbol_sdf.fragment.glsl.js +2 -2
- package/build/min/src/shaders/symbol_sdf.vertex.glsl.js +2 -2
- package/package.json +3 -3
- package/src/data/array_types.js +1 -36
- package/src/data/bucket/circle_bucket.js +8 -5
- package/src/data/bucket/fill_bucket.js +8 -5
- package/src/data/bucket/fill_extrusion_bucket.js +8 -5
- package/src/data/bucket/heatmap_bucket.js +0 -4
- package/src/data/bucket/line_bucket.js +9 -6
- package/src/data/bucket/pattern_bucket_features.js +2 -2
- package/src/data/bucket/symbol_bucket.js +99 -129
- package/src/data/bucket.js +26 -21
- package/src/data/dem_data.js +0 -3
- package/src/data/feature_index.js +3 -8
- package/src/data/program_configuration.js +24 -33
- package/src/data/segment.js +0 -4
- package/src/render/draw_background.js +3 -3
- package/src/render/draw_circle.js +4 -4
- package/src/render/draw_fill.js +8 -8
- package/src/render/draw_fill_extrusion.js +8 -8
- package/src/render/draw_heatmap.js +4 -4
- package/src/render/draw_line.js +6 -6
- package/src/render/draw_raster.js +6 -6
- package/src/render/draw_symbol.js +16 -16
- package/src/render/glyph_atlas.js +0 -3
- package/src/render/glyph_manager.js +1 -2
- package/src/render/image_atlas.js +0 -4
- package/src/render/image_manager.js +33 -19
- package/src/render/painter.js +13 -14
- package/src/render/program/circle_program.js +4 -4
- package/src/render/program/fill_extrusion_program.js +1 -1
- package/src/render/program/heatmap_program.js +1 -1
- package/src/render/program/hillshade_program.js +6 -6
- package/src/render/program/line_program.js +3 -3
- package/src/render/program/raster_program.js +6 -6
- package/src/source/geojson_source.js +15 -24
- package/src/source/geojson_worker_source.js +40 -68
- package/src/source/geojson_wrapper.js +9 -1
- package/src/source/image_source.js +6 -16
- package/src/source/query_features.js +4 -5
- package/src/source/raster_dem_tile_source.js +45 -64
- package/src/source/raster_tile_source.js +1 -6
- package/src/source/resources/glyphs.js +2 -2
- package/src/source/resources/index.js +3 -9
- package/src/source/rtl_text_plugin.js +58 -31
- package/src/source/source.js +11 -13
- package/src/source/source_cache.js +135 -151
- package/src/source/source_state.js +101 -12
- package/src/source/tile.js +32 -46
- package/src/source/tile_bounds.js +26 -26
- package/src/source/tile_id.js +2 -5
- package/src/source/vector_tile_source.js +14 -14
- package/src/source/vector_tile_worker_source.js +19 -23
- package/src/source/worker_tile.js +122 -119
- package/src/style/create_style_layer.js +1 -1
- package/src/style/pauseable_placement.js +4 -5
- package/src/style/properties.js +1 -8
- package/src/style/query_utils.js +3 -3
- package/src/style/style.js +286 -216
- package/src/style/style_layer/circle_style_layer.js +13 -11
- package/src/style/style_layer/fill_extrusion_style_layer.js +42 -27
- package/src/style/style_layer/fill_style_layer.js +5 -5
- package/src/style/style_layer/heatmap_style_layer.js +1 -1
- package/src/style/style_layer/hillshade_style_layer.js +1 -1
- package/src/style/style_layer/line_style_layer.js +23 -19
- package/src/style/style_layer/symbol_style_layer.js +13 -13
- package/src/style/style_layer.js +71 -30
- package/src/style/style_layer_index.js +16 -41
- package/src/symbol/anchor.js +0 -4
- package/src/symbol/cross_tile_symbol_index.js +2 -5
- package/src/symbol/opacity_state.js +0 -4
- package/src/symbol/placement.js +3 -3
- package/src/symbol/quads.js +4 -4
- package/src/symbol/symbol_layout.js +7 -7
- package/src/symbol/transform_text.js +1 -1
- package/src/ui/map.js +52 -15
- package/src/util/group_layers.js +41 -0
- package/src/util/image.js +0 -5
- package/src/util/key.js +21 -0
- package/src/util/object.js +8 -53
- package/src/worker.js +1 -4
- package/src/source/resources/images.js +0 -68
- package/src/source/worker.js +0 -110
- package/src/source/worker_source.js +0 -14
- package/src/style-spec/deref.js +0 -51
- package/src/style-spec/group_by_layout.js +0 -46
- package/src/util/actor.js +0 -108
- package/src/util/dispatcher.js +0 -65
- package/src/util/global_worker_pool.js +0 -15
- package/src/util/transfer_registry.js +0 -168
- package/src/util/web_worker_transfer.js +0 -43
- package/src/util/worker_pool.js +0 -41
|
@@ -21,7 +21,7 @@ class CircleStyleLayer extends StyleLayer {
|
|
|
21
21
|
return (
|
|
22
22
|
getMaximumPaintValue('circle-radius', this, circleBucket) +
|
|
23
23
|
getMaximumPaintValue('circle-stroke-width', this, circleBucket) +
|
|
24
|
-
translateDistance(this.
|
|
24
|
+
translateDistance(this._paint.get('circle-translate'))
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -37,24 +37,29 @@ class CircleStyleLayer extends StyleLayer {
|
|
|
37
37
|
) {
|
|
38
38
|
const translatedPolygon = translate(
|
|
39
39
|
queryGeometry,
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
40
|
+
this._paint.get('circle-translate'),
|
|
41
|
+
this._paint.get('circle-translate-anchor'),
|
|
42
42
|
transform.angle,
|
|
43
43
|
pixelsToTileUnits
|
|
44
44
|
);
|
|
45
|
-
const radius = this.
|
|
46
|
-
const stroke = this.
|
|
45
|
+
const radius = this._paint.get('circle-radius').evaluate(feature, featureState);
|
|
46
|
+
const stroke = this._paint.get('circle-stroke-width').evaluate(feature, featureState);
|
|
47
47
|
const size = radius + stroke;
|
|
48
48
|
|
|
49
49
|
// For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile
|
|
50
50
|
// // Otherwise, compare geometry in the plane of the viewport
|
|
51
51
|
// // A circle with fixed scaling relative to the viewport gets larger in tile space as it moves into the distance
|
|
52
52
|
// // A circle with fixed scaling relative to the map gets smaller in viewport space as it moves into the distance
|
|
53
|
-
const
|
|
53
|
+
const pitchScale = this._paint.get('circle-pitch-scale');
|
|
54
|
+
const pitchAlignment = this._paint.get('circle-pitch-alignment');
|
|
55
|
+
const alignWithMap = pitchAlignment === 'map';
|
|
56
|
+
const alignWithViewport = pitchAlignment === 'viewport';
|
|
54
57
|
const transformedPolygon = alignWithMap
|
|
55
58
|
? translatedPolygon
|
|
56
59
|
: projectQueryGeometry(translatedPolygon, pixelPosMatrix);
|
|
57
60
|
const transformedSize = alignWithMap ? size * pixelsToTileUnits : size;
|
|
61
|
+
const adjustViewportToMap = pitchScale === 'viewport' && alignWithMap;
|
|
62
|
+
const adjustMapToViewport = pitchScale === 'map' && alignWithViewport;
|
|
58
63
|
|
|
59
64
|
for (const ring of geometry) {
|
|
60
65
|
for (const point of ring) {
|
|
@@ -62,12 +67,9 @@ class CircleStyleLayer extends StyleLayer {
|
|
|
62
67
|
|
|
63
68
|
let adjustedSize = transformedSize;
|
|
64
69
|
const projectedCenter = vec4.transformMat4([], [point.x, point.y, 0, 1], pixelPosMatrix);
|
|
65
|
-
if (
|
|
70
|
+
if (adjustViewportToMap) {
|
|
66
71
|
adjustedSize *= projectedCenter[3] / transform.cameraToCenterDistance;
|
|
67
|
-
} else if (
|
|
68
|
-
this.paint.get('circle-pitch-scale') === 'map' &&
|
|
69
|
-
this.paint.get('circle-pitch-alignment') === 'viewport'
|
|
70
|
-
) {
|
|
72
|
+
} else if (adjustMapToViewport) {
|
|
71
73
|
adjustedSize *= transform.cameraToCenterDistance / projectedCenter[3];
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -17,7 +17,7 @@ class FillExtrusionStyleLayer extends StyleLayer {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
queryRadius() {
|
|
20
|
-
return translateDistance(this.
|
|
20
|
+
return translateDistance(this._paint.get('fill-extrusion-translate'));
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
is3D() {
|
|
@@ -36,13 +36,13 @@ class FillExtrusionStyleLayer extends StyleLayer {
|
|
|
36
36
|
) {
|
|
37
37
|
const translatedPolygon = translate(
|
|
38
38
|
queryGeometry,
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
39
|
+
this._paint.get('fill-extrusion-translate'),
|
|
40
|
+
this._paint.get('fill-extrusion-translate-anchor'),
|
|
41
41
|
transform.angle,
|
|
42
42
|
pixelsToTileUnits
|
|
43
43
|
);
|
|
44
|
-
const height = this.
|
|
45
|
-
const base = this.
|
|
44
|
+
const height = this._paint.get('fill-extrusion-height').evaluate(feature, featureState);
|
|
45
|
+
const base = this._paint.get('fill-extrusion-base').evaluate(feature, featureState);
|
|
46
46
|
|
|
47
47
|
const projectedQueryGeometry = projectQueryGeometry(translatedPolygon, pixelPosMatrix, transform, 0);
|
|
48
48
|
|
|
@@ -66,27 +66,42 @@ function getIntersectionDistance(projectedQueryGeometry, projectedFace) {
|
|
|
66
66
|
// triangle of the face, using only the xy plane. It doesn't matter if the
|
|
67
67
|
// point is outside the first triangle because all the triangles in the face
|
|
68
68
|
// are in the same plane.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
69
|
+
//
|
|
70
|
+
// Check whether points are coincident and use other points if they are.
|
|
71
|
+
let i = 0;
|
|
72
|
+
const a = projectedFace[i++];
|
|
73
|
+
let b;
|
|
74
|
+
while (!b || a.equals(b)) {
|
|
75
|
+
b = projectedFace[i++];
|
|
76
|
+
if (!b) return Number.POSITIVE_INFINITY;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Loop until point `c` is not colinear with points `a` and `b`.
|
|
80
|
+
for (; i < projectedFace.length; i++) {
|
|
81
|
+
const c = projectedFace[i];
|
|
82
|
+
const p = projectedQueryGeometry[0];
|
|
83
|
+
|
|
84
|
+
const ab = b.sub(a);
|
|
85
|
+
const ac = c.sub(a);
|
|
86
|
+
const ap = p.sub(a);
|
|
87
|
+
|
|
88
|
+
const dotABAB = dot(ab, ab);
|
|
89
|
+
const dotABAC = dot(ab, ac);
|
|
90
|
+
const dotACAC = dot(ac, ac);
|
|
91
|
+
const dotAPAB = dot(ap, ab);
|
|
92
|
+
const dotAPAC = dot(ap, ac);
|
|
93
|
+
const denom = dotABAB * dotACAC - dotABAC * dotABAC;
|
|
94
|
+
|
|
95
|
+
const v = (dotACAC * dotAPAB - dotABAC * dotAPAC) / denom;
|
|
96
|
+
const w = (dotABAB * dotAPAC - dotABAC * dotAPAB) / denom;
|
|
97
|
+
const u = 1 - v - w;
|
|
98
|
+
|
|
99
|
+
// Use the barycentric weighting along with the original triangle z coordinates to get the point of intersection.
|
|
100
|
+
const distance = a.z * u + b.z * v + c.z * w;
|
|
101
|
+
|
|
102
|
+
if (Number.isFinite(distance)) return distance;
|
|
103
|
+
}
|
|
104
|
+
return Number.POSITIVE_INFINITY;
|
|
90
105
|
}
|
|
91
106
|
// The counts as closest is less clear when the query is a box. This
|
|
92
107
|
// returns the distance to the nearest point on the face, whether it is
|
|
@@ -191,4 +206,4 @@ function projectQueryGeometry(queryGeometry, pixelPosMatrix, transform, z) {
|
|
|
191
206
|
return projectedQueryGeometry;
|
|
192
207
|
}
|
|
193
208
|
|
|
194
|
-
module.exports = FillExtrusionStyleLayer;
|
|
209
|
+
module.exports = { FillExtrusionStyleLayer, getIntersectionDistance };
|
|
@@ -13,9 +13,9 @@ class FillStyleLayer extends StyleLayer {
|
|
|
13
13
|
recalculate(parameters) {
|
|
14
14
|
super.recalculate(parameters);
|
|
15
15
|
|
|
16
|
-
const outlineColor = this.
|
|
16
|
+
const outlineColor = this._paint._values['fill-outline-color'];
|
|
17
17
|
if (outlineColor.value.kind === 'constant' && outlineColor.value.value === undefined) {
|
|
18
|
-
this.
|
|
18
|
+
this._paint._values['fill-outline-color'] = this._paint._values['fill-color'];
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -24,14 +24,14 @@ class FillStyleLayer extends StyleLayer {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
queryRadius() {
|
|
27
|
-
return translateDistance(this.
|
|
27
|
+
return translateDistance(this._paint.get('fill-translate'));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
queryIntersectsFeature(queryGeometry, feature, featureState, geometry, zoom, transform, pixelsToTileUnits) {
|
|
31
31
|
const translatedPolygon = translate(
|
|
32
32
|
queryGeometry,
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
33
|
+
this._paint.get('fill-translate'),
|
|
34
|
+
this._paint.get('fill-translate-anchor'),
|
|
35
35
|
transform.angle,
|
|
36
36
|
pixelsToTileUnits
|
|
37
37
|
);
|
|
@@ -8,7 +8,7 @@ class HillshadeStyleLayer extends StyleLayer {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
hasOffscreenPass() {
|
|
11
|
-
return this.
|
|
11
|
+
return this._paint.get('hillshade-exaggeration') !== 0 && this.visibility !== 'none';
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -49,7 +49,7 @@ class LineStyleLayer extends StyleLayer {
|
|
|
49
49
|
recalculate(parameters) {
|
|
50
50
|
super.recalculate(parameters);
|
|
51
51
|
|
|
52
|
-
this.
|
|
52
|
+
this._paint._values['line-floorwidth'] = lineFloorwidthProperty.possiblyEvaluate(
|
|
53
53
|
this._transitioningPaint._values['line-width'].value,
|
|
54
54
|
parameters
|
|
55
55
|
);
|
|
@@ -66,24 +66,24 @@ class LineStyleLayer extends StyleLayer {
|
|
|
66
66
|
getMaximumPaintValue('line-gap-width', this, lineBucket)
|
|
67
67
|
);
|
|
68
68
|
const offset = getMaximumPaintValue('line-offset', this, lineBucket);
|
|
69
|
-
return width / 2 + Math.abs(offset) + translateDistance(this.
|
|
69
|
+
return width / 2 + Math.abs(offset) + translateDistance(this._paint.get('line-translate'));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
queryIntersectsFeature(queryGeometry, feature, featureState, geometry, zoom, transform, pixelsToTileUnits) {
|
|
73
73
|
const translatedPolygon = translate(
|
|
74
74
|
queryGeometry,
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
75
|
+
this._paint.get('line-translate'),
|
|
76
|
+
this._paint.get('line-translate-anchor'),
|
|
77
77
|
transform.angle,
|
|
78
78
|
pixelsToTileUnits
|
|
79
79
|
);
|
|
80
80
|
const halfWidth =
|
|
81
81
|
(pixelsToTileUnits / 2) *
|
|
82
82
|
getLineWidth(
|
|
83
|
-
this.
|
|
84
|
-
this.
|
|
83
|
+
this._paint.get('line-width').evaluate(feature, featureState),
|
|
84
|
+
this._paint.get('line-gap-width').evaluate(feature, featureState)
|
|
85
85
|
);
|
|
86
|
-
const lineOffset = this.
|
|
86
|
+
const lineOffset = this._paint.get('line-offset').evaluate(feature, featureState);
|
|
87
87
|
if (lineOffset) {
|
|
88
88
|
geometry = offsetLine(geometry, lineOffset * pixelsToTileUnits);
|
|
89
89
|
}
|
|
@@ -105,25 +105,29 @@ function getLineWidth(lineWidth, lineGapWidth) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function offsetLine(rings, offset) {
|
|
108
|
-
const newRings =
|
|
109
|
-
const zero = new Point(0, 0);
|
|
108
|
+
const newRings = new Array(rings.length);
|
|
110
109
|
for (let k = 0; k < rings.length; k++) {
|
|
111
110
|
const ring = rings[k];
|
|
112
|
-
const newRing =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
const newRing = new Array(ring.length);
|
|
112
|
+
newRings[k] = newRing;
|
|
113
|
+
|
|
114
|
+
let b = ring[0];
|
|
115
|
+
let aToB = new Point(0, 0);
|
|
116
|
+
for (let i = 0; i < ring.length - 1; i++) {
|
|
116
117
|
const c = ring[i + 1];
|
|
117
|
-
const
|
|
118
|
-
const bToC = i === ring.length - 1 ? zero : c.sub(b)._unit()._perp();
|
|
118
|
+
const bToC = c.sub(b)._unit()._perp();
|
|
119
119
|
const extrude = aToB._add(bToC)._unit();
|
|
120
|
-
|
|
121
120
|
const cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
|
|
122
|
-
|
|
121
|
+
if (cosHalfAngle !== 0) {
|
|
122
|
+
extrude._div(cosHalfAngle);
|
|
123
|
+
}
|
|
124
|
+
newRing[i] = extrude._mult(offset)._add(b);
|
|
123
125
|
|
|
124
|
-
|
|
126
|
+
b = c;
|
|
127
|
+
aToB = bToC;
|
|
125
128
|
}
|
|
126
|
-
|
|
129
|
+
|
|
130
|
+
newRing[ring.length - 1] = aToB._unit()._mult(offset)._add(b);
|
|
127
131
|
}
|
|
128
132
|
return newRings;
|
|
129
133
|
}
|
|
@@ -14,33 +14,33 @@ class SymbolStyleLayer extends StyleLayer {
|
|
|
14
14
|
recalculate(parameters) {
|
|
15
15
|
super.recalculate(parameters);
|
|
16
16
|
|
|
17
|
-
if (this.
|
|
18
|
-
if (this.
|
|
19
|
-
this.
|
|
17
|
+
if (this._layout.get('icon-rotation-alignment') === 'auto') {
|
|
18
|
+
if (this._layout.get('symbol-placement') !== 'point') {
|
|
19
|
+
this._layout._values['icon-rotation-alignment'] = 'map';
|
|
20
20
|
} else {
|
|
21
|
-
this.
|
|
21
|
+
this._layout._values['icon-rotation-alignment'] = 'viewport';
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
if (this.
|
|
26
|
-
if (this.
|
|
27
|
-
this.
|
|
25
|
+
if (this._layout.get('text-rotation-alignment') === 'auto') {
|
|
26
|
+
if (this._layout.get('symbol-placement') !== 'point') {
|
|
27
|
+
this._layout._values['text-rotation-alignment'] = 'map';
|
|
28
28
|
} else {
|
|
29
|
-
this.
|
|
29
|
+
this._layout._values['text-rotation-alignment'] = 'viewport';
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// If unspecified, `*-pitch-alignment` inherits `*-rotation-alignment`
|
|
34
|
-
if (this.
|
|
35
|
-
this.
|
|
34
|
+
if (this._layout.get('text-pitch-alignment') === 'auto') {
|
|
35
|
+
this._layout._values['text-pitch-alignment'] = this._layout.get('text-rotation-alignment');
|
|
36
36
|
}
|
|
37
|
-
if (this.
|
|
38
|
-
this.
|
|
37
|
+
if (this._layout.get('icon-pitch-alignment') === 'auto') {
|
|
38
|
+
this._layout._values['icon-pitch-alignment'] = this._layout.get('icon-rotation-alignment');
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
getValueAndResolveTokens(name, feature) {
|
|
43
|
-
const value = this.
|
|
43
|
+
const value = this._layout.get(name).evaluate(feature, {});
|
|
44
44
|
const unevaluated = this._unevaluatedLayout._values[name];
|
|
45
45
|
if (!unevaluated.isDataDriven() && !isExpression(unevaluated.value)) {
|
|
46
46
|
return resolveTokens(feature.properties, value);
|
package/src/style/style_layer.js
CHANGED
|
@@ -4,10 +4,20 @@ const { Evented } = require('@mapwhit/events');
|
|
|
4
4
|
const { Layout, Transitionable, PossiblyEvaluatedPropertyValue } = require('./properties');
|
|
5
5
|
const { supportsPropertyExpression } = require('@mapwhit/style-expressions');
|
|
6
6
|
const featureFilter = require('../style-spec/feature_filter');
|
|
7
|
+
const createKey = require('../util/key');
|
|
7
8
|
|
|
9
|
+
const keyProperties = ['type', 'minzoom', 'maxzoom', 'filter', 'layout'];
|
|
8
10
|
const TRANSITION_SUFFIX = '-transition';
|
|
9
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Representing a style layer in the map.
|
|
14
|
+
* Properties:
|
|
15
|
+
* `this.paint` - paint properties of the layer as defined in the map style
|
|
16
|
+
* `this._paint` - internal representation of paint properties necessary to calculate expressions
|
|
17
|
+
*/
|
|
10
18
|
class StyleLayer extends Evented {
|
|
19
|
+
#key;
|
|
20
|
+
|
|
11
21
|
constructor(layer, properties) {
|
|
12
22
|
super();
|
|
13
23
|
|
|
@@ -22,7 +32,7 @@ class StyleLayer extends Evented {
|
|
|
22
32
|
|
|
23
33
|
if (layer.type !== 'background') {
|
|
24
34
|
this.source = layer.source;
|
|
25
|
-
this.sourceLayer = layer['source-layer'];
|
|
35
|
+
this['source-layer'] = this.sourceLayer = layer['source-layer'];
|
|
26
36
|
this.filter = layer.filter;
|
|
27
37
|
this._featureFilter = featureFilter(layer.filter);
|
|
28
38
|
}
|
|
@@ -46,10 +56,26 @@ class StyleLayer extends Evented {
|
|
|
46
56
|
}
|
|
47
57
|
|
|
48
58
|
setFilter(filter) {
|
|
59
|
+
this.#key = undefined;
|
|
49
60
|
this.filter = filter;
|
|
50
61
|
this._featureFilter = featureFilter(filter);
|
|
51
62
|
}
|
|
52
63
|
|
|
64
|
+
_setZoomRange(minzoom, maxzoom) {
|
|
65
|
+
if (this.minzoom === minzoom && this.maxzoom === maxzoom) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (minzoom != null) {
|
|
69
|
+
this.#key = undefined;
|
|
70
|
+
this.minzoom = minzoom;
|
|
71
|
+
}
|
|
72
|
+
if (maxzoom != null) {
|
|
73
|
+
this.#key = undefined;
|
|
74
|
+
this.maxzoom = maxzoom;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
53
79
|
getCrossfadeParameters() {
|
|
54
80
|
return this._crossfadeParameters;
|
|
55
81
|
}
|
|
@@ -87,7 +113,32 @@ class StyleLayer extends Evented {
|
|
|
87
113
|
return globalStateRefs;
|
|
88
114
|
}
|
|
89
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Get list of global state references that are used within paint properties.
|
|
118
|
+
* This is used to determine if layer needs to be repainted when global state property changes.
|
|
119
|
+
*
|
|
120
|
+
*/
|
|
121
|
+
getPaintAffectingGlobalStateRefs() {
|
|
122
|
+
const globalStateRefs = new Map();
|
|
123
|
+
|
|
124
|
+
if (this._transitionablePaint) {
|
|
125
|
+
for (const propertyName in this._transitionablePaint._values) {
|
|
126
|
+
const value = this._transitionablePaint._values[propertyName].value;
|
|
127
|
+
|
|
128
|
+
for (const globalStateRef of value.getGlobalStateRefs()) {
|
|
129
|
+
const properties = globalStateRefs.get(globalStateRef) ?? [];
|
|
130
|
+
properties.push({ name: propertyName, value: value.value });
|
|
131
|
+
globalStateRefs.set(globalStateRef, properties);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return globalStateRefs;
|
|
137
|
+
}
|
|
138
|
+
|
|
90
139
|
setLayoutProperty(name, value) {
|
|
140
|
+
this.#key = undefined;
|
|
141
|
+
this.layout[name] = value;
|
|
91
142
|
if (name === 'visibility') {
|
|
92
143
|
this.visibility = value === 'none' ? value : 'visible';
|
|
93
144
|
return;
|
|
@@ -104,6 +155,7 @@ class StyleLayer extends Evented {
|
|
|
104
155
|
}
|
|
105
156
|
|
|
106
157
|
setPaintProperty(name, value) {
|
|
158
|
+
this.paint[name] = value;
|
|
107
159
|
if (name.endsWith(TRANSITION_SUFFIX)) {
|
|
108
160
|
this._transitionablePaint.setTransition(name.slice(0, -TRANSITION_SUFFIX.length), value || undefined);
|
|
109
161
|
return false;
|
|
@@ -118,9 +170,19 @@ class StyleLayer extends Evented {
|
|
|
118
170
|
this._transitionablePaint.setValue(name, value);
|
|
119
171
|
const isDataDriven = this._transitionablePaint._values[name].value.isDataDriven();
|
|
120
172
|
this._handleSpecialPaintPropertyUpdate(name);
|
|
173
|
+
if (isDataDriven !== wasDataDriven || (wasDataDriven && isDataDriven)) {
|
|
174
|
+
// reset transitioning in progress
|
|
175
|
+
this._untransitioned(name);
|
|
176
|
+
}
|
|
121
177
|
return isDataDriven || wasDataDriven || newCrossFadedValue;
|
|
122
178
|
}
|
|
123
179
|
|
|
180
|
+
_untransitioned(name) {
|
|
181
|
+
if (this._transitioningPaint) {
|
|
182
|
+
this._transitioningPaint._values[name] = this._transitionablePaint._values[name].untransitioned();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
124
186
|
_handleSpecialPaintPropertyUpdate() {
|
|
125
187
|
// No-op; can be overridden by derived classes.
|
|
126
188
|
}
|
|
@@ -144,38 +206,17 @@ class StyleLayer extends Evented {
|
|
|
144
206
|
this._crossfadeParameters = parameters.getCrossfadeParameters();
|
|
145
207
|
}
|
|
146
208
|
if (this._unevaluatedLayout) {
|
|
147
|
-
this.
|
|
209
|
+
this._layout = this._unevaluatedLayout.possiblyEvaluate(parameters);
|
|
148
210
|
}
|
|
149
211
|
|
|
150
|
-
this.
|
|
212
|
+
this._paint = this._transitioningPaint.possiblyEvaluate(parameters);
|
|
151
213
|
}
|
|
152
214
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
type: this.type,
|
|
157
|
-
source: this.source,
|
|
158
|
-
'source-layer': this.sourceLayer,
|
|
159
|
-
metadata: this.metadata,
|
|
160
|
-
minzoom: this.minzoom,
|
|
161
|
-
maxzoom: this.maxzoom,
|
|
162
|
-
filter: this.filter,
|
|
163
|
-
layout: this._unevaluatedLayout?.serialize(),
|
|
164
|
-
paint: this._transitionablePaint?.serialize()
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
if (this.visibility === 'none') {
|
|
168
|
-
output.layout = output.layout || {};
|
|
169
|
-
output.layout.visibility = 'none';
|
|
215
|
+
get key() {
|
|
216
|
+
if (!this.#key) {
|
|
217
|
+
this.#key = createKey(keyProperties, this);
|
|
170
218
|
}
|
|
171
|
-
|
|
172
|
-
return filterObject(output, (value, key) => {
|
|
173
|
-
return (
|
|
174
|
-
value !== undefined &&
|
|
175
|
-
!(key === 'layout' && !Object.keys(value).length) &&
|
|
176
|
-
!(key === 'paint' && !Object.keys(value).length)
|
|
177
|
-
);
|
|
178
|
-
});
|
|
219
|
+
return this.#key;
|
|
179
220
|
}
|
|
180
221
|
|
|
181
222
|
is3D() {
|
|
@@ -195,8 +236,8 @@ class StyleLayer extends Evented {
|
|
|
195
236
|
}
|
|
196
237
|
|
|
197
238
|
isStateDependent() {
|
|
198
|
-
for (const property in this.
|
|
199
|
-
const value = this.
|
|
239
|
+
for (const property in this._paint._values) {
|
|
240
|
+
const value = this._paint.get(property);
|
|
200
241
|
if (
|
|
201
242
|
!(value instanceof PossiblyEvaluatedPropertyValue) ||
|
|
202
243
|
!supportsPropertyExpression(value.property.specification)
|
|
@@ -1,54 +1,29 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const { values } = require('../util/object');
|
|
4
|
-
const featureFilter = require('../style-spec/feature_filter');
|
|
5
|
-
const groupByLayout = require('../style-spec/group_by_layout');
|
|
1
|
+
const groupBySource = require('../util/group_layers');
|
|
6
2
|
|
|
7
3
|
class StyleLayerIndex {
|
|
8
|
-
#
|
|
9
|
-
#
|
|
4
|
+
#layers = new Map();
|
|
5
|
+
#fbs = {};
|
|
10
6
|
|
|
11
|
-
constructor(
|
|
12
|
-
if (
|
|
13
|
-
this.
|
|
7
|
+
constructor(layers) {
|
|
8
|
+
if (layers) {
|
|
9
|
+
this.replace(layers);
|
|
14
10
|
}
|
|
15
11
|
}
|
|
16
12
|
|
|
17
|
-
replace(
|
|
18
|
-
this.#
|
|
19
|
-
this.#
|
|
20
|
-
this.update(layerConfigs);
|
|
13
|
+
replace(layers) {
|
|
14
|
+
this.#layers = layers;
|
|
15
|
+
this.#fbs = null;
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
update(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const layer = (this.#layers[layerConfig.id] = createStyleLayer(layerConfig));
|
|
28
|
-
layer._featureFilter = featureFilter(layer.filter);
|
|
29
|
-
}
|
|
30
|
-
for (const id of removedIds) {
|
|
31
|
-
delete this.#layerConfigs[id];
|
|
32
|
-
delete this.#layers[id];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
this.familiesBySource = {};
|
|
36
|
-
|
|
37
|
-
const groups = groupByLayout(values(this.#layerConfigs));
|
|
38
|
-
|
|
39
|
-
for (const layerConfigs of groups) {
|
|
40
|
-
const layers = layerConfigs.map(layerConfig => this.#layers[layerConfig.id]);
|
|
41
|
-
|
|
42
|
-
const layer = layers[0];
|
|
43
|
-
if (layer.visibility === 'none') {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
18
|
+
update() {
|
|
19
|
+
this.#fbs = null;
|
|
20
|
+
}
|
|
46
21
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
sourceLayerFamilies.push(layers);
|
|
22
|
+
get familiesBySource() {
|
|
23
|
+
if (!this.#fbs) {
|
|
24
|
+
this.#fbs = groupBySource(this.#layers.values());
|
|
51
25
|
}
|
|
26
|
+
return this.#fbs;
|
|
52
27
|
}
|
|
53
28
|
}
|
|
54
29
|
|
package/src/symbol/anchor.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const { default: Point } = require('@mapbox/point-geometry');
|
|
2
2
|
|
|
3
|
-
const { register } = require('../util/transfer_registry');
|
|
4
|
-
|
|
5
3
|
class Anchor extends Point {
|
|
6
4
|
constructor(x, y, angle, segment) {
|
|
7
5
|
super(x, y);
|
|
@@ -16,6 +14,4 @@ class Anchor extends Point {
|
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
register('Anchor', Anchor);
|
|
20
|
-
|
|
21
17
|
module.exports = Anchor;
|
|
@@ -260,12 +260,9 @@ class CrossTileSymbolIndex {
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
pruneUnusedLayers(usedLayers) {
|
|
263
|
-
const
|
|
264
|
-
usedLayers.forEach(usedLayer => {
|
|
265
|
-
usedLayerMap[usedLayer] = true;
|
|
266
|
-
});
|
|
263
|
+
const usedLayersSet = new Set(usedLayers);
|
|
267
264
|
for (const layerId in this.layerIndexes) {
|
|
268
|
-
if (!
|
|
265
|
+
if (!usedLayersSet.has(layerId)) {
|
|
269
266
|
delete this.layerIndexes[layerId];
|
|
270
267
|
}
|
|
271
268
|
}
|
package/src/symbol/placement.js
CHANGED
|
@@ -100,7 +100,7 @@ class Placement {
|
|
|
100
100
|
|
|
101
101
|
const collisionBoxArray = tile.collisionBoxArray;
|
|
102
102
|
|
|
103
|
-
const layout = symbolBucket.layers[0].
|
|
103
|
+
const layout = symbolBucket.layers[0]._layout;
|
|
104
104
|
|
|
105
105
|
const scale = 2 ** (this.transform.zoom - tile.tileID.overscaledZ);
|
|
106
106
|
const textPixelRatio = tile.tileSize / EXTENT;
|
|
@@ -159,7 +159,7 @@ class Placement {
|
|
|
159
159
|
seenCrossTileIDs,
|
|
160
160
|
collisionBoxArray
|
|
161
161
|
) {
|
|
162
|
-
const layout = bucket.layers[0].
|
|
162
|
+
const layout = bucket.layers[0]._layout;
|
|
163
163
|
|
|
164
164
|
const partiallyEvaluatedTextSize = symbolSize.evaluateSizeForZoom(
|
|
165
165
|
bucket.textSizeData,
|
|
@@ -411,7 +411,7 @@ class Placement {
|
|
|
411
411
|
if (bucket.hasCollisionBoxData()) bucket.collisionBox.collisionVertexArray.clear();
|
|
412
412
|
if (bucket.hasCollisionCircleData()) bucket.collisionCircle.collisionVertexArray.clear();
|
|
413
413
|
|
|
414
|
-
const layout = bucket.layers[0].
|
|
414
|
+
const layout = bucket.layers[0]._layout;
|
|
415
415
|
const duplicateOpacityState = new JointOpacityState(null, 0, false, false, true);
|
|
416
416
|
const textAllowOverlap = layout.get('text-allow-overlap');
|
|
417
417
|
const iconAllowOverlap = layout.get('icon-allow-overlap');
|