@mapwhit/tilerenderer 0.49.0 → 0.51.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/.dir +0 -0
- package/build/min/src/shaders/_prelude.fragment.glsl.js +14 -0
- package/build/min/src/shaders/_prelude.vertex.glsl.js +14 -0
- package/build/min/src/shaders/background.fragment.glsl.js +5 -0
- package/build/min/src/shaders/background.vertex.glsl.js +1 -0
- package/build/min/src/shaders/background_pattern.fragment.glsl.js +5 -0
- package/build/min/src/shaders/background_pattern.vertex.glsl.js +1 -0
- package/build/min/src/shaders/circle.fragment.glsl.js +20 -0
- package/build/min/src/shaders/circle.vertex.glsl.js +17 -0
- package/build/min/src/shaders/clipping_mask.fragment.glsl.js +1 -0
- package/build/min/src/shaders/clipping_mask.vertex.glsl.js +1 -0
- package/build/min/src/shaders/collision_box.fragment.glsl.js +1 -0
- package/build/min/src/shaders/collision_box.vertex.glsl.js +1 -0
- package/build/min/src/shaders/collision_circle.fragment.glsl.js +1 -0
- package/build/min/src/shaders/collision_circle.vertex.glsl.js +1 -0
- package/build/min/src/shaders/debug.fragment.glsl.js +1 -0
- package/build/min/src/shaders/debug.vertex.glsl.js +1 -0
- package/build/min/src/shaders/fill.fragment.glsl.js +10 -0
- package/build/min/src/shaders/fill.vertex.glsl.js +7 -0
- package/build/min/src/shaders/fill_extrusion.fragment.glsl.js +5 -0
- package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +1 -9
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.js +9 -0
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +4 -4
- package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.js +15 -0
- package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.js +11 -0
- package/build/min/src/shaders/fill_outline.fragment.glsl.js +10 -0
- package/build/min/src/shaders/fill_outline.vertex.glsl.js +7 -0
- package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.js +13 -0
- package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.js +9 -0
- package/build/min/src/shaders/fill_pattern.fragment.glsl.js +13 -0
- package/build/min/src/shaders/fill_pattern.vertex.glsl.js +9 -0
- package/build/min/src/shaders/heatmap.fragment.glsl.js +10 -0
- package/build/min/src/shaders/heatmap.vertex.glsl.js +8 -0
- package/build/min/src/shaders/heatmap_texture.fragment.glsl.js +5 -0
- package/build/min/src/shaders/heatmap_texture.vertex.glsl.js +1 -0
- package/build/min/src/shaders/hillshade.fragment.glsl.js +7 -0
- package/build/min/src/shaders/hillshade.vertex.glsl.js +1 -0
- package/build/min/src/shaders/hillshade_prepare.fragment.glsl.js +8 -0
- package/build/min/src/shaders/hillshade_prepare.vertex.glsl.js +1 -0
- package/build/min/src/shaders/line.fragment.glsl.js +12 -0
- package/build/min/src/shaders/line.vertex.glsl.js +17 -0
- package/build/min/src/shaders/line_gradient.fragment.glsl.js +10 -0
- package/build/min/src/shaders/line_gradient.vertex.glsl.js +16 -0
- package/build/min/src/shaders/line_pattern.fragment.glsl.js +15 -0
- package/build/min/src/shaders/line_pattern.vertex.glsl.js +20 -0
- package/build/min/src/shaders/line_sdf.fragment.glsl.js +17 -0
- package/build/min/src/shaders/line_sdf.vertex.glsl.js +20 -0
- package/build/min/src/shaders/raster.fragment.glsl.js +5 -0
- package/build/min/src/shaders/raster.vertex.glsl.js +1 -0
- package/build/min/src/shaders/symbol_icon.fragment.glsl.js +9 -0
- package/build/min/src/shaders/symbol_icon.vertex.glsl.js +5 -0
- package/build/min/src/shaders/symbol_sdf.fragment.glsl.js +19 -0
- package/build/min/src/shaders/symbol_sdf.vertex.glsl.js +13 -0
- package/package.json +7 -7
- package/src/data/bucket/fill_bucket.js +1 -1
- package/src/data/bucket/fill_extrusion_bucket.js +2 -2
- package/src/data/bucket/line_bucket.js +1 -1
- package/src/data/bucket/symbol_bucket.js +16 -15
- package/src/data/feature_index.js +1 -1
- package/src/data/program_configuration.js +1 -1
- package/src/gl/color_mode.js +1 -1
- package/src/gl/value.js +1 -1
- package/src/render/draw_debug.js +1 -1
- package/src/render/draw_fill.js +1 -1
- package/src/render/draw_heatmap.js +1 -1
- package/src/render/glyph_manager.js +6 -130
- package/src/render/painter.js +1 -1
- package/src/render/uniform_binding.js +1 -1
- package/src/shaders/fill_extrusion.fragment.glsl +0 -7
- package/src/shaders/fill_extrusion.vertex.glsl +4 -4
- package/src/shaders/index.js +50 -50
- package/src/source/geojson_worker_source.js +4 -4
- package/src/source/geojson_wrapper.js +34 -26
- package/src/source/resources/glyphs.js +73 -0
- package/src/source/resources/images.js +68 -0
- package/src/source/resources/index.js +22 -0
- package/src/source/vector_tile_worker_source.js +5 -5
- package/src/source/worker.js +6 -5
- package/src/source/worker_tile.js +4 -4
- package/src/style/properties.js +1 -2
- package/src/style/style.js +3 -3
- package/src/style/style_layer/symbol_style_layer.js +1 -1
- package/src/style/style_layer.js +1 -1
- package/src/style-spec/feature_filter/index.js +43 -34
- package/src/style-spec/group_by_layout.js +10 -32
- package/src/style-spec/reference/v8.json +1 -1
- package/src/symbol/mergelines.js +1 -3
- package/src/symbol/placement.js +21 -2
- package/src/symbol/shaping.js +9 -18
- package/src/symbol/symbol_layout.js +1 -2
- package/src/symbol/symbol_size.js +1 -1
- package/src/symbol/transform_text.js +4 -8
- package/src/ui/map.js +11 -39
- package/src/util/browser.js +3 -18
- package/src/util/classify_rings.js +1 -1
- package/src/util/dom.js +0 -88
- package/src/util/find_pole_of_inaccessibility.js +2 -2
- package/src/util/web_worker_transfer.js +4 -4
- package/src/style/load_glyph_range.js +0 -17
- package/src/style-spec/expression/compound_expression.js +0 -132
- package/src/style-spec/expression/definitions/assertion.js +0 -116
- package/src/style-spec/expression/definitions/at.js +0 -57
- package/src/style-spec/expression/definitions/case.js +0 -73
- package/src/style-spec/expression/definitions/coalesce.js +0 -68
- package/src/style-spec/expression/definitions/coercion.js +0 -109
- package/src/style-spec/expression/definitions/collator.js +0 -102
- package/src/style-spec/expression/definitions/comparison.js +0 -193
- package/src/style-spec/expression/definitions/formatted.js +0 -123
- package/src/style-spec/expression/definitions/index.js +0 -356
- package/src/style-spec/expression/definitions/interpolate.js +0 -245
- package/src/style-spec/expression/definitions/length.js +0 -54
- package/src/style-spec/expression/definitions/let.js +0 -60
- package/src/style-spec/expression/definitions/literal.js +0 -69
- package/src/style-spec/expression/definitions/match.js +0 -142
- package/src/style-spec/expression/definitions/step.js +0 -116
- package/src/style-spec/expression/definitions/var.js +0 -38
- package/src/style-spec/expression/evaluation_context.js +0 -35
- package/src/style-spec/expression/index.js +0 -329
- package/src/style-spec/expression/is_constant.js +0 -63
- package/src/style-spec/expression/parsing_context.js +0 -212
- package/src/style-spec/expression/parsing_error.js +0 -9
- package/src/style-spec/expression/runtime_error.js +0 -12
- package/src/style-spec/expression/scope.js +0 -34
- package/src/style-spec/expression/stops.js +0 -37
- package/src/style-spec/expression/types.js +0 -88
- package/src/style-spec/expression/values.js +0 -126
- package/src/style-spec/function/convert.js +0 -234
- package/src/style-spec/function/index.js +0 -299
- package/src/style-spec/util/color.js +0 -73
- package/src/style-spec/util/color_spaces.js +0 -128
- package/src/style-spec/util/get_type.js +0 -18
- package/src/style-spec/util/interpolate.js +0 -21
- package/src/style-spec/util/properties.js +0 -17
- package/src/style-spec/util/result.js +0 -19
- package/src/ui/anchor.js +0 -24
- package/src/ui/bind_handlers.js +0 -199
- package/src/ui/events.js +0 -210
- package/src/ui/handler/box_zoom.js +0 -151
- package/src/ui/handler/dblclick_zoom.js +0 -91
- package/src/ui/handler/drag_pan.js +0 -285
- package/src/ui/handler/drag_rotate.js +0 -290
- package/src/ui/handler/frame.js +0 -28
- package/src/ui/handler/inertia.js +0 -45
- package/src/ui/handler/keyboard.js +0 -148
- package/src/ui/handler/scroll_zoom.js +0 -284
- package/src/ui/handler/touch_zoom_rotate.js +0 -263
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const Point = require('@mapbox/point-geometry');
|
|
2
|
-
|
|
3
|
-
const mvt = require('@mapbox/vector-tile');
|
|
4
|
-
const toGeoJSON = mvt.VectorTileFeature.prototype.toGeoJSON;
|
|
2
|
+
const { VectorTileFeature } = require('@mapwhit/vector-tile');
|
|
5
3
|
const EXTENT = require('../data/extent');
|
|
6
4
|
|
|
5
|
+
const { toGeoJSON } = VectorTileFeature.prototype;
|
|
6
|
+
|
|
7
7
|
// The feature type used by geojson-vt and supercluster. Should be extracted to
|
|
8
8
|
// global type and used in module definitions for those two modules.
|
|
9
9
|
|
|
@@ -11,10 +11,6 @@ class FeatureWrapper {
|
|
|
11
11
|
constructor(feature) {
|
|
12
12
|
this._feature = feature;
|
|
13
13
|
|
|
14
|
-
this.extent = EXTENT;
|
|
15
|
-
this.type = feature.type;
|
|
16
|
-
this.properties = feature.tags;
|
|
17
|
-
|
|
18
14
|
// If the feature has a top-level `id` property, copy it over, but only
|
|
19
15
|
// if it can be coerced to an integer, because this wrapper is used for
|
|
20
16
|
// serializing geojson feature data into vector tile PBF data, and the
|
|
@@ -26,23 +22,22 @@ class FeatureWrapper {
|
|
|
26
22
|
}
|
|
27
23
|
}
|
|
28
24
|
|
|
25
|
+
get type() {
|
|
26
|
+
return this._feature.type;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get properties() {
|
|
30
|
+
return this._feature.tags;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get extent() {
|
|
34
|
+
return EXTENT;
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
loadGeometry() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
geometry.push([new Point(point[0], point[1])]);
|
|
34
|
-
}
|
|
35
|
-
return geometry;
|
|
36
|
-
}
|
|
37
|
-
const geometry = [];
|
|
38
|
-
for (const ring of this._feature.geometry) {
|
|
39
|
-
const newRing = [];
|
|
40
|
-
for (const point of ring) {
|
|
41
|
-
newRing.push(new Point(point[0], point[1]));
|
|
42
|
-
}
|
|
43
|
-
geometry.push(newRing);
|
|
44
|
-
}
|
|
45
|
-
return geometry;
|
|
38
|
+
return this.type === 1
|
|
39
|
+
? this._feature.geometry.map(p => [makePoint(p)])
|
|
40
|
+
: this._feature.geometry.map(ring => ring.map(makePoint));
|
|
46
41
|
}
|
|
47
42
|
|
|
48
43
|
toGeoJSON(x, y, z) {
|
|
@@ -53,15 +48,28 @@ class FeatureWrapper {
|
|
|
53
48
|
class GeoJSONWrapper {
|
|
54
49
|
constructor(features) {
|
|
55
50
|
this.layers = { _geojsonTileLayer: this };
|
|
56
|
-
this.name = '_geojsonTileLayer';
|
|
57
|
-
this.extent = EXTENT;
|
|
58
|
-
this.length = features.length;
|
|
59
51
|
this._features = features;
|
|
60
52
|
}
|
|
61
53
|
|
|
54
|
+
get extent() {
|
|
55
|
+
return EXTENT;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get length() {
|
|
59
|
+
return this._features.length;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get name() {
|
|
63
|
+
return '_geojsonTileLayer';
|
|
64
|
+
}
|
|
65
|
+
|
|
62
66
|
feature(i) {
|
|
63
67
|
return new FeatureWrapper(this._features[i]);
|
|
64
68
|
}
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
module.exports = GeoJSONWrapper;
|
|
72
|
+
|
|
73
|
+
function makePoint(arr) {
|
|
74
|
+
return new Point(arr[0], arr[1]);
|
|
75
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const parseGlyphPBF = require('../../style/parse_glyph_pbf');
|
|
2
|
+
|
|
3
|
+
module.exports = glyphCache;
|
|
4
|
+
|
|
5
|
+
const MAX_GLYPH_ID = 65535;
|
|
6
|
+
|
|
7
|
+
function glyphCache({ actor, mapId, parseGlyphs = parseGlyphPBF }) {
|
|
8
|
+
const entries = {};
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
getGlyphs
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
async function getGlyphs({ stacks }) {
|
|
15
|
+
const all = [];
|
|
16
|
+
for (const [stack, ids] of Object.entries(stacks)) {
|
|
17
|
+
const addedRanges = new Set();
|
|
18
|
+
for (const id of ids) {
|
|
19
|
+
if (id > MAX_GLYPH_ID) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const range = Math.floor(id / 256);
|
|
23
|
+
if (!addedRanges.has(range) && !hasRange(stack, range)) {
|
|
24
|
+
addedRanges.add(range);
|
|
25
|
+
all.push(retrieveGlyphRange({ stack, range }));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (all.length > 0) {
|
|
30
|
+
await Promise.all(all);
|
|
31
|
+
}
|
|
32
|
+
const result = {};
|
|
33
|
+
for (const [stack, ids] of Object.entries(stacks)) {
|
|
34
|
+
const entry = getEntry(stack);
|
|
35
|
+
const resultStack = (result[stack] ??= {});
|
|
36
|
+
for (const id of ids) {
|
|
37
|
+
if (id <= MAX_GLYPH_ID) {
|
|
38
|
+
resultStack[id] = entry.glyphs[id] ?? null;
|
|
39
|
+
} else {
|
|
40
|
+
resultStack[id] = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function retrieveGlyphRange({ stack, range }) {
|
|
48
|
+
const entry = getEntry(stack);
|
|
49
|
+
const data = await loadGlyphRange(entry, stack, range);
|
|
50
|
+
if (!data) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
for (const glyph of parseGlyphs(data)) {
|
|
54
|
+
entry.glyphs[glyph.id] = glyph;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function loadGlyphRange(entry, stack, range) {
|
|
59
|
+
const promise = (entry.requests[range] ??= actor.send('loadGlyphRange', { stack, range }, mapId));
|
|
60
|
+
const data = await promise;
|
|
61
|
+
delete entry.requests[range];
|
|
62
|
+
entry.ranges[range] = true;
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getEntry(stack) {
|
|
67
|
+
return (entries[stack] ??= { glyphs: {}, requests: {}, ranges: {} });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function hasRange(stack, range) {
|
|
71
|
+
return getEntry(stack).ranges[range];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module.exports = images;
|
|
2
|
+
|
|
3
|
+
function images({ actor, mapId }) {
|
|
4
|
+
const cache = new Map(); // id -> image
|
|
5
|
+
const inProgress = new Map(); // id -> promise
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
getImages
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
async function getImages({ icons }) {
|
|
12
|
+
const missing = new Set();
|
|
13
|
+
const result = {};
|
|
14
|
+
for (const id of icons) {
|
|
15
|
+
if (cache.has(id)) {
|
|
16
|
+
const image = cache.get(id);
|
|
17
|
+
if (image) {
|
|
18
|
+
result[id] = image;
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
missing.add(id);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (missing.size === 0) {
|
|
25
|
+
// All images are already in the cache
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
const active = new Set();
|
|
29
|
+
const needed = [...missing];
|
|
30
|
+
// Check if any of the missing images are already being fetched
|
|
31
|
+
for (const id of missing) {
|
|
32
|
+
if (inProgress.has(id)) {
|
|
33
|
+
active.add(inProgress.get(id));
|
|
34
|
+
missing.delete(id);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (missing.size > 0) {
|
|
38
|
+
// Fetch the remaining images
|
|
39
|
+
await fetchMissing([...missing]);
|
|
40
|
+
}
|
|
41
|
+
if (active.size > 0) {
|
|
42
|
+
await Promise.all(active);
|
|
43
|
+
}
|
|
44
|
+
for (const id of needed) {
|
|
45
|
+
const image = cache.get(id);
|
|
46
|
+
if (image) {
|
|
47
|
+
result[id] = image;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function fetchMissing(icons) {
|
|
54
|
+
const promise = actor.send('getImages', { icons }, mapId);
|
|
55
|
+
for (const id of icons) {
|
|
56
|
+
inProgress.set(id, promise);
|
|
57
|
+
}
|
|
58
|
+
const result = await promise;
|
|
59
|
+
// Add the fetched images to the cache
|
|
60
|
+
for (const id of icons) {
|
|
61
|
+
cache.set(id, result[id]);
|
|
62
|
+
}
|
|
63
|
+
// Remove the fetched images from the inProgress set
|
|
64
|
+
for (const id of icons) {
|
|
65
|
+
inProgress.delete(id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const makeGlyphs = require('./glyphs');
|
|
2
|
+
const makeImages = require('./images');
|
|
3
|
+
|
|
4
|
+
module.exports = { resources };
|
|
5
|
+
|
|
6
|
+
function resources(actor, mapId) {
|
|
7
|
+
const glyphs = makeGlyphs({ actor, mapId });
|
|
8
|
+
const images = makeImages({ actor, mapId });
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
getGlyphs,
|
|
12
|
+
getImages
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function getGlyphs(params) {
|
|
16
|
+
return glyphs.getGlyphs(params);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getImages(params) {
|
|
20
|
+
return images.getImages(params);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { VectorTile } = require('@
|
|
1
|
+
const { VectorTile } = require('@mapwhit/vector-tile');
|
|
2
2
|
const Protobuf = require('@mapwhit/pbf');
|
|
3
3
|
const WorkerTile = require('./worker_tile');
|
|
4
4
|
|
|
@@ -20,7 +20,7 @@ function loadVectorTile(params) {
|
|
|
20
20
|
* This class is designed to be easily reused to support custom source types
|
|
21
21
|
* for data formats that can be parsed/converted into an in-memory VectorTile
|
|
22
22
|
* representation. To do so, create it with
|
|
23
|
-
* `new VectorTileWorkerSource(
|
|
23
|
+
* `new VectorTileWorkerSource(resources, styleLayers, customLoadVectorDataFunction)`.
|
|
24
24
|
*
|
|
25
25
|
* @private
|
|
26
26
|
*/
|
|
@@ -31,8 +31,8 @@ class VectorTileWorkerSource {
|
|
|
31
31
|
* {@link VectorTileWorkerSource#loadTile}. The default implementation simply
|
|
32
32
|
* loads the pbf at `params.url`.
|
|
33
33
|
*/
|
|
34
|
-
constructor(
|
|
35
|
-
this.
|
|
34
|
+
constructor(resources, layerIndex, loadVectorData = loadVectorTile) {
|
|
35
|
+
this.resources = resources;
|
|
36
36
|
this.layerIndex = layerIndex;
|
|
37
37
|
this.loadVectorData = loadVectorData;
|
|
38
38
|
}
|
|
@@ -50,7 +50,7 @@ class VectorTileWorkerSource {
|
|
|
50
50
|
const { vectorTile, rawData } = response;
|
|
51
51
|
const workerTile = new WorkerTile(params);
|
|
52
52
|
workerTile.vectorTile = vectorTile;
|
|
53
|
-
const result = await workerTile.parse(vectorTile, this.layerIndex, this.
|
|
53
|
+
const result = await workerTile.parse(vectorTile, this.layerIndex, this.resources);
|
|
54
54
|
if (rawData) {
|
|
55
55
|
result.rawTileData = rawData;
|
|
56
56
|
}
|
package/src/source/worker.js
CHANGED
|
@@ -8,8 +8,11 @@ const GeoJSONWorkerSource = require('./geojson_worker_source');
|
|
|
8
8
|
const assert = require('assert');
|
|
9
9
|
const { plugin: globalRTLTextPlugin } = require('./rtl_text_plugin');
|
|
10
10
|
const DEMData = require('../data/dem_data');
|
|
11
|
+
const { resources } = require('./resources');
|
|
11
12
|
|
|
12
13
|
class Worker {
|
|
14
|
+
#resources = {};
|
|
15
|
+
|
|
13
16
|
constructor(self) {
|
|
14
17
|
this.self = self;
|
|
15
18
|
this.actor = new Actor(self, this);
|
|
@@ -85,10 +88,8 @@ class Worker {
|
|
|
85
88
|
return (this.layerIndexes[mapId] ??= new StyleLayerIndex());
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
return (this
|
|
90
|
-
send: (type, data) => this.actor.send(type, data, mapId)
|
|
91
|
-
});
|
|
91
|
+
getResources(mapId) {
|
|
92
|
+
return (this.#resources[mapId] ??= resources(this.actor, mapId));
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
getWorkerSource(mapId, type, source) {
|
|
@@ -100,7 +101,7 @@ class Worker {
|
|
|
100
101
|
|
|
101
102
|
createWorkerSource(type, mapId) {
|
|
102
103
|
const WorkerSource = this.workerSourceTypes[type];
|
|
103
|
-
return new WorkerSource(this.
|
|
104
|
+
return new WorkerSource(this.getResources(mapId), this.getLayerIndex(mapId));
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -33,7 +33,7 @@ class WorkerTile {
|
|
|
33
33
|
this.showCollisionBoxes = params.showCollisionBoxes;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
async parse(data, layerIndex,
|
|
36
|
+
async parse(data, layerIndex, resources) {
|
|
37
37
|
this.status = 'parsing';
|
|
38
38
|
this.data = data;
|
|
39
39
|
|
|
@@ -103,9 +103,9 @@ class WorkerTile {
|
|
|
103
103
|
const icons = Object.keys(options.iconDependencies);
|
|
104
104
|
const patterns = Object.keys(options.patternDependencies);
|
|
105
105
|
const tasks = [
|
|
106
|
-
Object.keys(stacks).length ?
|
|
107
|
-
icons.length ?
|
|
108
|
-
patterns.length ?
|
|
106
|
+
Object.keys(stacks).length ? resources.getGlyphs({ uid: this.uid, stacks }) : {},
|
|
107
|
+
icons.length ? resources.getImages({ icons }) : {},
|
|
108
|
+
patterns.length ? resources.getImages({ icons: patterns }) : {}
|
|
109
109
|
];
|
|
110
110
|
const [glyphMap, iconMap, patternMap] = await Promise.all(tasks);
|
|
111
111
|
const glyphAtlas = new GlyphAtlas(glyphMap);
|
package/src/style/properties.js
CHANGED
|
@@ -2,8 +2,7 @@ const assert = require('assert');
|
|
|
2
2
|
|
|
3
3
|
const { clone } = require('../util/object');
|
|
4
4
|
const { easeCubicInOut } = require('../util/util');
|
|
5
|
-
const interpolate = require('
|
|
6
|
-
const { normalizePropertyExpression } = require('../style-spec/expression');
|
|
5
|
+
const { interpolate, normalizePropertyExpression } = require('@mapwhit/style-expressions');
|
|
7
6
|
const { register } = require('../util/transfer_registry');
|
|
8
7
|
const EvaluationParameters = require('./evaluation_parameters');
|
|
9
8
|
|
package/src/style/style.js
CHANGED
|
@@ -32,7 +32,7 @@ class Style extends Evented {
|
|
|
32
32
|
this.map = map;
|
|
33
33
|
this.dispatcher = dispatcher(getWorkerPool(), this);
|
|
34
34
|
this.imageManager = new ImageManager();
|
|
35
|
-
this.glyphManager = new GlyphManager(
|
|
35
|
+
this.glyphManager = new GlyphManager();
|
|
36
36
|
this.lineAtlas = new LineAtlas(256, 512);
|
|
37
37
|
this.crossTileSymbolIndex = new CrossTileSymbolIndex();
|
|
38
38
|
|
|
@@ -928,8 +928,8 @@ class Style extends Evented {
|
|
|
928
928
|
return this.imageManager.getImages(icons);
|
|
929
929
|
}
|
|
930
930
|
|
|
931
|
-
|
|
932
|
-
return this.glyphManager.
|
|
931
|
+
loadGlyphRange(_mapId, { stack, range }) {
|
|
932
|
+
return this.glyphManager.loadGlyphRange(stack, range);
|
|
933
933
|
}
|
|
934
934
|
}
|
|
935
935
|
|
|
@@ -2,7 +2,7 @@ const StyleLayer = require('../style_layer');
|
|
|
2
2
|
|
|
3
3
|
const SymbolBucket = require('../../data/bucket/symbol_bucket');
|
|
4
4
|
const resolveTokens = require('../../util/token');
|
|
5
|
-
const { isExpression } = require('
|
|
5
|
+
const { isExpression } = require('@mapwhit/style-expressions');
|
|
6
6
|
const assert = require('assert');
|
|
7
7
|
const properties = require('./symbol_style_layer_properties');
|
|
8
8
|
|
package/src/style/style_layer.js
CHANGED
|
@@ -2,7 +2,7 @@ const { filterObject } = require('../util/object');
|
|
|
2
2
|
|
|
3
3
|
const { Evented } = require('../util/evented');
|
|
4
4
|
const { Layout, Transitionable, PossiblyEvaluatedPropertyValue } = require('./properties');
|
|
5
|
-
const { supportsPropertyExpression } = require('
|
|
5
|
+
const { supportsPropertyExpression } = require('@mapwhit/style-expressions');
|
|
6
6
|
|
|
7
7
|
const TRANSITION_SUFFIX = '-transition';
|
|
8
8
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { createExpression } = require('
|
|
1
|
+
const { createExpression } = require('@mapwhit/style-expressions');
|
|
2
2
|
|
|
3
3
|
module.exports = createFilter;
|
|
4
4
|
|
|
@@ -31,8 +31,9 @@ function isExpressionFilter(filter) {
|
|
|
31
31
|
|
|
32
32
|
case 'any':
|
|
33
33
|
case 'all':
|
|
34
|
-
for (
|
|
35
|
-
|
|
34
|
+
for (let i = 1; i < filter.length; i++) {
|
|
35
|
+
const f = filter[i];
|
|
36
|
+
if (typeof f !== 'boolean' && !isExpressionFilter(f)) {
|
|
36
37
|
return false;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
@@ -86,34 +87,37 @@ function compare(a, b) {
|
|
|
86
87
|
|
|
87
88
|
function convertFilter(filter) {
|
|
88
89
|
if (!filter) return true;
|
|
89
|
-
const op = filter
|
|
90
|
+
const [op, ...args] = filter;
|
|
90
91
|
if (filter.length <= 1) return op !== 'any';
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
92
|
+
switch (op) {
|
|
93
|
+
case '!=':
|
|
94
|
+
return convertNegation(convertComparisonOp('==', ...args));
|
|
95
|
+
case '==':
|
|
96
|
+
case '<':
|
|
97
|
+
case '>':
|
|
98
|
+
case '<=':
|
|
99
|
+
case '>=':
|
|
100
|
+
return convertComparisonOp(op, ...args);
|
|
101
|
+
case 'any':
|
|
102
|
+
return convertDisjunctionOp(args);
|
|
103
|
+
case 'all':
|
|
104
|
+
return ['all', ...args.map(convertFilter)];
|
|
105
|
+
case 'none':
|
|
106
|
+
return ['all', ...args.map(convertFilter).map(convertNegation)];
|
|
107
|
+
case 'in':
|
|
108
|
+
return convertInOp(args);
|
|
109
|
+
case '!in':
|
|
110
|
+
return convertNegation(convertInOp(args));
|
|
111
|
+
case 'has':
|
|
112
|
+
return convertHasOp(args[0]);
|
|
113
|
+
case '!has':
|
|
114
|
+
return convertNegation(convertHasOp(args[0]));
|
|
115
|
+
default:
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
114
118
|
}
|
|
115
119
|
|
|
116
|
-
function convertComparisonOp(property, value
|
|
120
|
+
function convertComparisonOp(op, property, value) {
|
|
117
121
|
switch (property) {
|
|
118
122
|
case '$type':
|
|
119
123
|
return [`filter-type-${op}`, value];
|
|
@@ -125,10 +129,10 @@ function convertComparisonOp(property, value, op) {
|
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
function convertDisjunctionOp(filters) {
|
|
128
|
-
return ['any'
|
|
132
|
+
return ['any', ...filters.map(convertFilter)];
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
function convertInOp(property, values) {
|
|
135
|
+
function convertInOp([property, ...values]) {
|
|
132
136
|
if (values.length === 0) {
|
|
133
137
|
return false;
|
|
134
138
|
}
|
|
@@ -138,13 +142,18 @@ function convertInOp(property, values) {
|
|
|
138
142
|
case '$id':
|
|
139
143
|
return ['filter-id-in', ['literal', values]];
|
|
140
144
|
default:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return ['filter-in-small', property, ['literal', values]];
|
|
145
|
+
return isUniformLarge(values)
|
|
146
|
+
? ['filter-in-large', property, ['literal', values.sort(compare)]]
|
|
147
|
+
: ['filter-in-small', property, ['literal', values]];
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
function isUniformLarge(values) {
|
|
152
|
+
if (values.length < 200) return false;
|
|
153
|
+
const type = typeof values[0];
|
|
154
|
+
return values.every(v => typeof v === type);
|
|
155
|
+
}
|
|
156
|
+
|
|
148
157
|
function convertHasOp(property) {
|
|
149
158
|
switch (property) {
|
|
150
159
|
case '$type':
|
|
@@ -1,33 +1,20 @@
|
|
|
1
1
|
const refProperties = require('./util/ref_properties');
|
|
2
2
|
|
|
3
3
|
function stringify(obj) {
|
|
4
|
+
if (obj == null) return 'null';
|
|
4
5
|
const type = typeof obj;
|
|
5
|
-
if (type === 'number' || type === 'boolean' || type === 'string'
|
|
6
|
-
return JSON.stringify(obj);
|
|
6
|
+
if (type === 'number' || type === 'boolean' || type === 'string') return obj;
|
|
7
7
|
|
|
8
8
|
if (Array.isArray(obj)) {
|
|
9
|
-
|
|
10
|
-
for (const val of obj) {
|
|
11
|
-
str += `${stringify(val)},`;
|
|
12
|
-
}
|
|
13
|
-
return `${str}]`;
|
|
9
|
+
return '[' + obj.map(val => stringify(val)).join(',') + ']';
|
|
14
10
|
}
|
|
15
11
|
|
|
16
12
|
const keys = Object.keys(obj).sort();
|
|
17
|
-
|
|
18
|
-
let str = '{';
|
|
19
|
-
for (let i = 0; i < keys.length; i++) {
|
|
20
|
-
str += `${JSON.stringify(keys[i])}:${stringify(obj[keys[i]])},`;
|
|
21
|
-
}
|
|
22
|
-
return `${str}}`;
|
|
13
|
+
return '{' + keys.map(key => `${key}:${stringify(obj[key])}`).join(',') + '}';
|
|
23
14
|
}
|
|
24
15
|
|
|
25
16
|
function getKey(layer) {
|
|
26
|
-
|
|
27
|
-
for (const k of refProperties) {
|
|
28
|
-
key += `/${stringify(layer[k])}`;
|
|
29
|
-
}
|
|
30
|
-
return key;
|
|
17
|
+
return refProperties.map(k => stringify(layer[k])).join('/');
|
|
31
18
|
}
|
|
32
19
|
|
|
33
20
|
module.exports = groupByLayout;
|
|
@@ -49,20 +36,11 @@ module.exports = groupByLayout;
|
|
|
49
36
|
function groupByLayout(layers) {
|
|
50
37
|
const groups = {};
|
|
51
38
|
|
|
52
|
-
for (
|
|
53
|
-
const k = getKey(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
group = groups[k] = [];
|
|
57
|
-
}
|
|
58
|
-
group.push(layers[i]);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const result = [];
|
|
62
|
-
|
|
63
|
-
for (const k in groups) {
|
|
64
|
-
result.push(groups[k]);
|
|
39
|
+
for (const l of layers) {
|
|
40
|
+
const k = getKey(l);
|
|
41
|
+
const group = (groups[k] ??= []);
|
|
42
|
+
group.push(l);
|
|
65
43
|
}
|
|
66
44
|
|
|
67
|
-
return
|
|
45
|
+
return Object.values(groups);
|
|
68
46
|
}
|
|
@@ -3148,7 +3148,7 @@
|
|
|
3148
3148
|
}
|
|
3149
3149
|
},
|
|
3150
3150
|
"concat": {
|
|
3151
|
-
"doc": "Returns a `string` consisting of the concatenation of the inputs.
|
|
3151
|
+
"doc": "Returns a `string` consisting of the concatenation of the inputs. Each input is converted to a string as if by `to-string`.",
|
|
3152
3152
|
"group": "String",
|
|
3153
3153
|
"sdk-support": {
|
|
3154
3154
|
"basic functionality": {
|
package/src/symbol/mergelines.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const { Formatted } = require('../style-spec/expression/definitions/formatted');
|
|
2
|
-
|
|
3
1
|
module.exports = function (features) {
|
|
4
2
|
const leftIndex = new Map();
|
|
5
3
|
const rightIndex = new Map();
|
|
@@ -8,7 +6,7 @@ module.exports = function (features) {
|
|
|
8
6
|
|
|
9
7
|
for (let k = 0; k < features.length; k++) {
|
|
10
8
|
const { geometry, text: featureText } = features[k];
|
|
11
|
-
const text = featureText
|
|
9
|
+
const text = featureText ? featureText.toString() : null;
|
|
12
10
|
|
|
13
11
|
if (!text) {
|
|
14
12
|
add(k);
|
package/src/symbol/placement.js
CHANGED
|
@@ -170,6 +170,25 @@ class Placement {
|
|
|
170
170
|
const textOptional = layout.get('text-optional');
|
|
171
171
|
const iconOptional = layout.get('icon-optional');
|
|
172
172
|
|
|
173
|
+
const textAllowOverlap = layout.get('text-allow-overlap');
|
|
174
|
+
const iconAllowOverlap = layout.get('icon-allow-overlap');
|
|
175
|
+
// This logic is similar to the "defaultOpacityState" logic below in updateBucketOpacities
|
|
176
|
+
// If we know a symbol is always supposed to show, force it to be marked visible even if
|
|
177
|
+
// it wasn't placed into the collision index (because some or all of it was outside the range
|
|
178
|
+
// of the collision grid).
|
|
179
|
+
// There is a subtle edge case here we're accepting:
|
|
180
|
+
// Symbol A has text-allow-overlap: true, icon-allow-overlap: true, icon-optional: false
|
|
181
|
+
// A's icon is outside the grid, so doesn't get placed
|
|
182
|
+
// A's text would be inside grid, but doesn't get placed because of icon-optional: false
|
|
183
|
+
// We still show A because of the allow-overlap settings.
|
|
184
|
+
// Symbol B has allow-overlap: false, and gets placed where A's text would be
|
|
185
|
+
// On panning in, there is a short period when Symbol B and Symbol A will overlap
|
|
186
|
+
// This is the reverse of our normal policy of "fade in on pan", but should look like any other
|
|
187
|
+
// collision and hopefully not be too noticeable.
|
|
188
|
+
// See https://github.com/mapbox/mapbox-gl-js/issues/7172
|
|
189
|
+
const alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || iconOptional);
|
|
190
|
+
const alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || textOptional);
|
|
191
|
+
|
|
173
192
|
const collisionGroup = this.collisionGroups.get(bucket.sourceID);
|
|
174
193
|
|
|
175
194
|
if (!bucket.collisionArrays && collisionBoxArray) {
|
|
@@ -304,8 +323,8 @@ class Placement {
|
|
|
304
323
|
assert(bucket.bucketInstanceId !== 0);
|
|
305
324
|
|
|
306
325
|
this.placements[symbolInstance.crossTileID] = new JointPlacement(
|
|
307
|
-
placeText,
|
|
308
|
-
placeIcon,
|
|
326
|
+
placeText || (alwaysShowText && placedGlyphBoxes),
|
|
327
|
+
placeIcon || alwaysShowIcon,
|
|
309
328
|
offscreen || bucket.justReloaded
|
|
310
329
|
);
|
|
311
330
|
seenCrossTileIDs[symbolInstance.crossTileID] = true;
|