@mapwhit/tilerenderer 0.47.1 → 0.47.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/min/package.json +1 -1
- package/package.json +1 -2
- package/src/data/array_types.js +1 -1
- package/src/data/bucket/circle_bucket.js +1 -1
- package/src/data/bucket/fill_bucket.js +1 -1
- package/src/data/bucket/fill_extrusion_bucket.js +1 -1
- package/src/data/bucket/heatmap_bucket.js +1 -1
- package/src/data/bucket/line_bucket.js +1 -1
- package/src/data/bucket/symbol_bucket.js +1 -1
- package/src/data/dem_data.js +1 -1
- package/src/data/feature_index.js +43 -82
- package/src/data/program_configuration.js +1 -1
- package/src/data/segment.js +2 -2
- package/src/gl/color_mode.js +6 -6
- package/src/index.js +2 -0
- package/src/render/glyph_atlas.js +1 -1
- package/src/render/glyph_manager.js +43 -48
- package/src/render/image_atlas.js +1 -1
- package/src/render/image_manager.js +9 -37
- package/src/source/geojson_source.js +49 -93
- package/src/source/geojson_worker_source.js +33 -134
- package/src/source/image_source.js +9 -14
- package/src/source/load_tilejson.js +27 -34
- package/src/source/raster_dem_tile_source.js +27 -40
- package/src/source/raster_tile_source.js +53 -62
- package/src/source/rtl_text_plugin.js +2 -1
- package/src/source/source_cache.js +22 -20
- package/src/source/source_state.js +17 -26
- package/src/source/tile_id.js +1 -1
- package/src/source/vector_tile_source.js +56 -73
- package/src/source/vector_tile_worker_source.js +20 -85
- package/src/source/worker.js +38 -95
- package/src/source/worker_tile.js +39 -84
- package/src/style/load_sprite.js +14 -17
- package/src/style/properties.js +1 -1
- package/src/style/style.js +22 -22
- package/src/style/style_layer_index.js +17 -23
- package/src/style-spec/reference/v8.json +2 -2
- package/src/symbol/anchor.js +1 -1
- package/src/symbol/collision_index.js +23 -16
- package/src/symbol/grid_index.js +176 -182
- package/src/symbol/mergelines.js +48 -48
- package/src/symbol/opacity_state.js +1 -1
- package/src/ui/camera.js +82 -85
- package/src/ui/map.js +5 -32
- package/src/util/actor.js +46 -42
- package/src/util/browser.js +6 -0
- package/src/util/dictionary_coder.js +13 -21
- package/src/util/dispatcher.js +14 -17
- package/src/util/image.js +1 -1
- package/src/util/loader/image.js +11 -11
- package/src/util/polyfill.js +16 -0
- package/src/util/task_queue.js +39 -43
- package/src/util/transfer_registry.js +167 -0
- package/src/util/web_worker_transfer.js +5 -190
- package/src/source/raster_dem_tile_worker_source.js +0 -26
package/src/source/worker.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
+
require('../util/polyfill');
|
|
2
|
+
|
|
1
3
|
const Actor = require('../util/actor');
|
|
2
4
|
|
|
3
5
|
const StyleLayerIndex = require('../style/style_layer_index');
|
|
4
6
|
const VectorTileWorkerSource = require('./vector_tile_worker_source');
|
|
5
|
-
const RasterDEMTileWorkerSource = require('./raster_dem_tile_worker_source');
|
|
6
7
|
const GeoJSONWorkerSource = require('./geojson_worker_source');
|
|
7
8
|
const assert = require('assert');
|
|
8
9
|
const { plugin: globalRTLTextPlugin } = require('./rtl_text_plugin');
|
|
10
|
+
const DEMData = require('../data/dem_data');
|
|
9
11
|
|
|
10
|
-
/**
|
|
11
|
-
* @private
|
|
12
|
-
*/
|
|
13
12
|
class Worker {
|
|
14
13
|
constructor(self) {
|
|
15
14
|
this.self = self;
|
|
16
15
|
this.actor = new Actor(self, this);
|
|
17
16
|
|
|
17
|
+
this.actors = {};
|
|
18
18
|
this.layerIndexes = {};
|
|
19
19
|
|
|
20
20
|
this.workerSourceTypes = {
|
|
@@ -24,7 +24,6 @@ class Worker {
|
|
|
24
24
|
|
|
25
25
|
// [mapId][sourceType][sourceName] => worker source instance
|
|
26
26
|
this.workerSources = {};
|
|
27
|
-
this.demWorkerSources = {};
|
|
28
27
|
|
|
29
28
|
this.self.registerWorkerSource = (name, WorkerSource) => {
|
|
30
29
|
if (this.workerSourceTypes[name]) {
|
|
@@ -42,63 +41,33 @@ class Worker {
|
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
setLayers(mapId, layers
|
|
44
|
+
setLayers(mapId, layers) {
|
|
46
45
|
this.getLayerIndex(mapId).replace(layers);
|
|
47
|
-
callback();
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
updateLayers(mapId, params
|
|
48
|
+
updateLayers(mapId, params) {
|
|
51
49
|
this.getLayerIndex(mapId).update(params.layers, params.removedIds);
|
|
52
|
-
callback();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
loadTile(mapId, params, callback) {
|
|
56
|
-
assert(params.type);
|
|
57
|
-
this.getWorkerSource(mapId, params.type, params.source).loadTile(params, callback);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
loadDEMTile(mapId, params, callback) {
|
|
61
|
-
this.getDEMWorkerSource(mapId, params.source).loadTile(params, callback);
|
|
62
50
|
}
|
|
63
51
|
|
|
64
|
-
|
|
52
|
+
loadTile(mapId, params) {
|
|
65
53
|
assert(params.type);
|
|
66
|
-
this.getWorkerSource(mapId, params.type, params.source).
|
|
54
|
+
return this.getWorkerSource(mapId, params.type, params.source).loadTile(params);
|
|
67
55
|
}
|
|
68
56
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
removeTile(mapId, params, callback) {
|
|
75
|
-
assert(params.type);
|
|
76
|
-
this.getWorkerSource(mapId, params.type, params.source).removeTile(params, callback);
|
|
57
|
+
loadDEMTile(mapId, params) {
|
|
58
|
+
const { uid, rawImageData, encoding } = params;
|
|
59
|
+
return new DEMData(uid, rawImageData, encoding);
|
|
77
60
|
}
|
|
78
61
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
62
|
+
removeSource(mapId, params) {
|
|
63
|
+
const { type, source } = params;
|
|
64
|
+
assert(type);
|
|
65
|
+
assert(source);
|
|
82
66
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
!this.workerSources[mapId] ||
|
|
89
|
-
!this.workerSources[mapId][params.type] ||
|
|
90
|
-
!this.workerSources[mapId][params.type][params.source]
|
|
91
|
-
) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const worker = this.workerSources[mapId][params.type][params.source];
|
|
96
|
-
delete this.workerSources[mapId][params.type][params.source];
|
|
97
|
-
|
|
98
|
-
if (worker.removeSource !== undefined) {
|
|
99
|
-
worker.removeSource(params, callback);
|
|
100
|
-
} else {
|
|
101
|
-
callback();
|
|
67
|
+
const worker = this.workerSources?.[mapId]?.[type]?.[source];
|
|
68
|
+
if (worker) {
|
|
69
|
+
delete this.workerSources[mapId][type][source];
|
|
70
|
+
worker.removeSource?.(params);
|
|
102
71
|
}
|
|
103
72
|
}
|
|
104
73
|
|
|
@@ -108,65 +77,39 @@ class Worker {
|
|
|
108
77
|
* function taking `(name, workerSourceObject)`.
|
|
109
78
|
* @private
|
|
110
79
|
*/
|
|
111
|
-
loadWorkerSource(map, params
|
|
112
|
-
|
|
113
|
-
this.self.importScripts(params.url);
|
|
114
|
-
callback();
|
|
115
|
-
} catch (e) {
|
|
116
|
-
callback(e.toString());
|
|
117
|
-
}
|
|
80
|
+
loadWorkerSource(map, params) {
|
|
81
|
+
this.self.importScripts(params.url);
|
|
118
82
|
}
|
|
119
83
|
|
|
120
|
-
loadRTLTextPlugin(map, pluginURL
|
|
121
|
-
|
|
84
|
+
loadRTLTextPlugin(map, pluginURL) {
|
|
85
|
+
if (!globalRTLTextPlugin.isLoaded()) {
|
|
86
|
+
this.self.importScripts(pluginURL);
|
|
122
87
|
if (!globalRTLTextPlugin.isLoaded()) {
|
|
123
|
-
|
|
124
|
-
callback(
|
|
125
|
-
globalRTLTextPlugin.isLoaded()
|
|
126
|
-
? null
|
|
127
|
-
: new Error(`RTL Text Plugin failed to import scripts from ${pluginURL}`)
|
|
128
|
-
);
|
|
88
|
+
throw new Error(`RTL Text Plugin failed to import scripts from ${pluginURL}`);
|
|
129
89
|
}
|
|
130
|
-
} catch (e) {
|
|
131
|
-
callback(e.toString());
|
|
132
90
|
}
|
|
133
91
|
}
|
|
134
92
|
|
|
135
93
|
getLayerIndex(mapId) {
|
|
136
|
-
|
|
137
|
-
if (!layerIndexes) {
|
|
138
|
-
layerIndexes = this.layerIndexes[mapId] = new StyleLayerIndex();
|
|
139
|
-
}
|
|
140
|
-
return layerIndexes;
|
|
94
|
+
return (this.layerIndexes[mapId] ??= new StyleLayerIndex());
|
|
141
95
|
}
|
|
142
96
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (!this.workerSources[mapId][type][source]) {
|
|
148
|
-
// use a wrapped actor so that we can attach a target mapId param
|
|
149
|
-
// to any messages invoked by the WorkerSource
|
|
150
|
-
const actor = {
|
|
151
|
-
send: (type, data, callback) => {
|
|
152
|
-
this.actor.send(type, data, callback, mapId);
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
this.workerSources[mapId][type][source] = new this.workerSourceTypes[type](actor, this.getLayerIndex(mapId));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return this.workerSources[mapId][type][source];
|
|
97
|
+
getActor(mapId) {
|
|
98
|
+
return (this.actors[mapId] ??= {
|
|
99
|
+
send: (type, data) => this.actor.send(type, data, mapId)
|
|
100
|
+
});
|
|
160
101
|
}
|
|
161
102
|
|
|
162
|
-
|
|
163
|
-
|
|
103
|
+
getWorkerSource(mapId, type, source) {
|
|
104
|
+
this.workerSources[mapId] ??= {};
|
|
105
|
+
this.workerSources[mapId][type] ??= {};
|
|
164
106
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
107
|
+
return (this.workerSources[mapId][type][source] ??= this.createWorkerSource(type, mapId));
|
|
108
|
+
}
|
|
168
109
|
|
|
169
|
-
|
|
110
|
+
createWorkerSource(type, mapId) {
|
|
111
|
+
const WorkerSource = this.workerSourceTypes[type];
|
|
112
|
+
return new WorkerSource(this.getActor(mapId), this.getLayerIndex(mapId));
|
|
170
113
|
}
|
|
171
114
|
}
|
|
172
115
|
|
|
@@ -2,7 +2,7 @@ const FeatureIndex = require('../data/feature_index');
|
|
|
2
2
|
|
|
3
3
|
const { performSymbolLayout } = require('../symbol/symbol_layout');
|
|
4
4
|
const { CollisionBoxArray } = require('../data/array_types');
|
|
5
|
-
const
|
|
5
|
+
const dictionaryCoder = require('../util/dictionary_coder');
|
|
6
6
|
const SymbolBucket = require('../data/bucket/symbol_bucket');
|
|
7
7
|
const LineBucket = require('../data/bucket/line_bucket');
|
|
8
8
|
const FillBucket = require('../data/bucket/fill_bucket');
|
|
@@ -33,12 +33,12 @@ class WorkerTile {
|
|
|
33
33
|
this.showCollisionBoxes = params.showCollisionBoxes;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
parse(data, layerIndex, actor
|
|
36
|
+
async parse(data, layerIndex, actor) {
|
|
37
37
|
this.status = 'parsing';
|
|
38
38
|
this.data = data;
|
|
39
39
|
|
|
40
40
|
this.collisionBoxArray = new CollisionBoxArray();
|
|
41
|
-
const sourceLayerCoder =
|
|
41
|
+
const sourceLayerCoder = dictionaryCoder(Object.keys(data.layers));
|
|
42
42
|
|
|
43
43
|
const featureIndex = new FeatureIndex(this.tileID);
|
|
44
44
|
featureIndex.bucketLayerIDs = [];
|
|
@@ -99,92 +99,47 @@ class WorkerTile {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
let error;
|
|
103
|
-
let glyphMap;
|
|
104
|
-
let iconMap;
|
|
105
|
-
let patternMap;
|
|
106
|
-
|
|
107
102
|
const stacks = mapObject(options.glyphDependencies, glyphs => Object.keys(glyphs).map(Number));
|
|
108
|
-
if (Object.keys(stacks).length) {
|
|
109
|
-
actor.send('getGlyphs', { uid: this.uid, stacks }, (err, result) => {
|
|
110
|
-
if (!error) {
|
|
111
|
-
error = err;
|
|
112
|
-
glyphMap = result;
|
|
113
|
-
maybePrepare.call(this);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
} else {
|
|
117
|
-
glyphMap = {};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
103
|
const icons = Object.keys(options.iconDependencies);
|
|
121
|
-
if (icons.length) {
|
|
122
|
-
actor.send('getImages', { icons }, (err, result) => {
|
|
123
|
-
if (!error) {
|
|
124
|
-
error = err;
|
|
125
|
-
iconMap = result;
|
|
126
|
-
maybePrepare.call(this);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
} else {
|
|
130
|
-
iconMap = {};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
104
|
const patterns = Object.keys(options.patternDependencies);
|
|
134
|
-
|
|
135
|
-
actor.send('
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
bucket,
|
|
162
|
-
glyphMap,
|
|
163
|
-
glyphAtlas.positions,
|
|
164
|
-
iconMap,
|
|
165
|
-
imageAtlas.iconPositions,
|
|
166
|
-
this.showCollisionBoxes
|
|
167
|
-
);
|
|
168
|
-
} else if (
|
|
169
|
-
bucket.hasPattern &&
|
|
170
|
-
(bucket instanceof LineBucket || bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket)
|
|
171
|
-
) {
|
|
172
|
-
recalculateLayers(bucket.layers, this.zoom);
|
|
173
|
-
bucket.addFeatures(options, imageAtlas.patternPositions);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
this.status = 'done';
|
|
178
|
-
|
|
179
|
-
callback(null, {
|
|
180
|
-
buckets: values(buckets).filter(b => !b.isEmpty()),
|
|
181
|
-
featureIndex,
|
|
182
|
-
collisionBoxArray: this.collisionBoxArray,
|
|
183
|
-
glyphAtlasImage: glyphAtlas.image,
|
|
184
|
-
imageAtlas
|
|
185
|
-
});
|
|
105
|
+
const tasks = [
|
|
106
|
+
Object.keys(stacks).length ? actor.send('getGlyphs', { uid: this.uid, stacks }) : {},
|
|
107
|
+
icons.length ? actor.send('getImages', { icons }) : {},
|
|
108
|
+
patterns.length ? actor.send('getImages', { icons: patterns }) : {}
|
|
109
|
+
];
|
|
110
|
+
const [glyphMap, iconMap, patternMap] = await Promise.all(tasks);
|
|
111
|
+
const glyphAtlas = new GlyphAtlas(glyphMap);
|
|
112
|
+
const imageAtlas = new ImageAtlas(iconMap, patternMap);
|
|
113
|
+
|
|
114
|
+
for (const key in buckets) {
|
|
115
|
+
const bucket = buckets[key];
|
|
116
|
+
if (bucket instanceof SymbolBucket) {
|
|
117
|
+
recalculateLayers(bucket.layers, this.zoom);
|
|
118
|
+
performSymbolLayout(
|
|
119
|
+
bucket,
|
|
120
|
+
glyphMap,
|
|
121
|
+
glyphAtlas.positions,
|
|
122
|
+
iconMap,
|
|
123
|
+
imageAtlas.iconPositions,
|
|
124
|
+
this.showCollisionBoxes
|
|
125
|
+
);
|
|
126
|
+
} else if (
|
|
127
|
+
bucket.hasPattern &&
|
|
128
|
+
(bucket instanceof LineBucket || bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket)
|
|
129
|
+
) {
|
|
130
|
+
recalculateLayers(bucket.layers, this.zoom);
|
|
131
|
+
bucket.addFeatures(options, imageAtlas.patternPositions);
|
|
186
132
|
}
|
|
187
133
|
}
|
|
134
|
+
|
|
135
|
+
this.status = 'done';
|
|
136
|
+
return {
|
|
137
|
+
buckets: values(buckets).filter(b => !b.isEmpty()),
|
|
138
|
+
featureIndex,
|
|
139
|
+
collisionBoxArray: this.collisionBoxArray,
|
|
140
|
+
glyphAtlasImage: glyphAtlas.image,
|
|
141
|
+
imageAtlas
|
|
142
|
+
};
|
|
188
143
|
}
|
|
189
144
|
}
|
|
190
145
|
|
package/src/style/load_sprite.js
CHANGED
|
@@ -4,23 +4,20 @@ const loadImage = require('../util/loader/image');
|
|
|
4
4
|
|
|
5
5
|
module.exports = loadSprite;
|
|
6
6
|
|
|
7
|
-
function loadSprite(sprite
|
|
8
|
-
loadImage(sprite.image
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const imageData = browser.getImageData(image);
|
|
14
|
-
const result = {};
|
|
7
|
+
async function loadSprite(sprite) {
|
|
8
|
+
const image = await loadImage(sprite.image);
|
|
9
|
+
const { json } = sprite;
|
|
10
|
+
if (json && image) {
|
|
11
|
+
const imageData = browser.getImageData(image);
|
|
12
|
+
const result = {};
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
callback(null, result);
|
|
14
|
+
for (const id in json) {
|
|
15
|
+
const { width, height, x, y, sdf, pixelRatio } = json[id];
|
|
16
|
+
const data = new RGBAImage({ width, height });
|
|
17
|
+
RGBAImage.copy(imageData, data, { x, y }, { x: 0, y: 0 }, { width, height });
|
|
18
|
+
result[id] = { data, pixelRatio, sdf };
|
|
24
19
|
}
|
|
25
|
-
|
|
20
|
+
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
26
23
|
}
|
package/src/style/properties.js
CHANGED
|
@@ -4,7 +4,7 @@ const { clone } = require('../util/object');
|
|
|
4
4
|
const { easeCubicInOut } = require('../util/util');
|
|
5
5
|
const interpolate = require('../style-spec/util/interpolate');
|
|
6
6
|
const { normalizePropertyExpression } = require('../style-spec/expression');
|
|
7
|
-
const { register } = require('../util/
|
|
7
|
+
const { register } = require('../util/transfer_registry');
|
|
8
8
|
const EvaluationParameters = require('./evaluation_parameters');
|
|
9
9
|
|
|
10
10
|
/**
|
package/src/style/style.js
CHANGED
|
@@ -46,7 +46,9 @@ class Style extends Evented {
|
|
|
46
46
|
|
|
47
47
|
const self = this;
|
|
48
48
|
this._rtlTextPluginCallback = Style.registerForPluginAvailability(args => {
|
|
49
|
-
self.dispatcher
|
|
49
|
+
self.dispatcher
|
|
50
|
+
.broadcast('loadRTLTextPlugin', args.pluginURL)
|
|
51
|
+
.then(_ => args.completionCallback(), args.completionCallback);
|
|
50
52
|
for (const id in self.sourceCaches) {
|
|
51
53
|
self.sourceCaches[id].reload(); // Should be a no-op if the plugin loads before any tiles load
|
|
52
54
|
}
|
|
@@ -93,20 +95,20 @@ class Style extends Evented {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
if (json.sprite) {
|
|
96
|
-
loadSprite(json.sprite
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
loadSprite(json.sprite)
|
|
99
|
+
.then(images => {
|
|
100
|
+
if (images) {
|
|
101
|
+
for (const id in images) {
|
|
102
|
+
this.imageManager.addImage(id, images[id]);
|
|
103
|
+
}
|
|
102
104
|
}
|
|
103
|
-
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
this.imageManager.setLoaded();
|
|
107
|
+
this.fire(new Event('data', { dataType: 'style' }));
|
|
108
|
+
})
|
|
109
|
+
.catch(err => this.fire(new ErrorEvent(err)));
|
|
108
110
|
} else {
|
|
109
|
-
this.imageManager.setLoaded(
|
|
111
|
+
this.imageManager.setLoaded();
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
this.glyphManager.setGlyphsLoader(json.glyphs);
|
|
@@ -776,14 +778,12 @@ class Style extends Evented {
|
|
|
776
778
|
return callback(null, null);
|
|
777
779
|
}
|
|
778
780
|
|
|
779
|
-
this.dispatcher
|
|
780
|
-
'loadWorkerSource',
|
|
781
|
-
{
|
|
781
|
+
this.dispatcher
|
|
782
|
+
.broadcast('loadWorkerSource', {
|
|
782
783
|
name: name,
|
|
783
784
|
url: SourceType.workerSourceURL
|
|
784
|
-
}
|
|
785
|
-
callback
|
|
786
|
-
);
|
|
785
|
+
})
|
|
786
|
+
.then(data => callback(null, data), callback);
|
|
787
787
|
}
|
|
788
788
|
|
|
789
789
|
getLight() {
|
|
@@ -939,12 +939,12 @@ class Style extends Evented {
|
|
|
939
939
|
|
|
940
940
|
// Callbacks from web workers
|
|
941
941
|
|
|
942
|
-
getImages(
|
|
943
|
-
this.imageManager.getImages(
|
|
942
|
+
getImages(_mapId, { icons }) {
|
|
943
|
+
return this.imageManager.getImages(icons);
|
|
944
944
|
}
|
|
945
945
|
|
|
946
|
-
getGlyphs(
|
|
947
|
-
return this.glyphManager.getGlyphs(
|
|
946
|
+
getGlyphs(_mapId, { stacks }) {
|
|
947
|
+
return this.glyphManager.getGlyphs(stacks);
|
|
948
948
|
}
|
|
949
949
|
}
|
|
950
950
|
|
|
@@ -5,54 +5,48 @@ const featureFilter = require('../style-spec/feature_filter');
|
|
|
5
5
|
const groupByLayout = require('../style-spec/group_by_layout');
|
|
6
6
|
|
|
7
7
|
class StyleLayerIndex {
|
|
8
|
+
#layerConfigs = {};
|
|
9
|
+
#layers = {};
|
|
10
|
+
|
|
8
11
|
constructor(layerConfigs) {
|
|
9
12
|
if (layerConfigs) {
|
|
10
|
-
this.
|
|
13
|
+
this.update(layerConfigs);
|
|
11
14
|
}
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
replace(layerConfigs) {
|
|
15
|
-
this
|
|
16
|
-
this
|
|
17
|
-
this.update(layerConfigs
|
|
18
|
+
this.#layerConfigs = {};
|
|
19
|
+
this.#layers = {};
|
|
20
|
+
this.update(layerConfigs);
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
update(layerConfigs, removedIds) {
|
|
23
|
+
update(layerConfigs, removedIds = []) {
|
|
21
24
|
for (const layerConfig of layerConfigs) {
|
|
22
|
-
this
|
|
25
|
+
this.#layerConfigs[layerConfig.id] = layerConfig;
|
|
23
26
|
|
|
24
|
-
const layer = (this
|
|
27
|
+
const layer = (this.#layers[layerConfig.id] = createStyleLayer(layerConfig));
|
|
25
28
|
layer._featureFilter = featureFilter(layer.filter);
|
|
26
29
|
}
|
|
27
30
|
for (const id of removedIds) {
|
|
28
|
-
delete this
|
|
29
|
-
delete this
|
|
31
|
+
delete this.#layerConfigs[id];
|
|
32
|
+
delete this.#layers[id];
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
this.familiesBySource = {};
|
|
33
36
|
|
|
34
|
-
const groups = groupByLayout(values(this
|
|
37
|
+
const groups = groupByLayout(values(this.#layerConfigs));
|
|
35
38
|
|
|
36
39
|
for (const layerConfigs of groups) {
|
|
37
|
-
const layers = layerConfigs.map(layerConfig => this
|
|
40
|
+
const layers = layerConfigs.map(layerConfig => this.#layers[layerConfig.id]);
|
|
38
41
|
|
|
39
42
|
const layer = layers[0];
|
|
40
43
|
if (layer.visibility === 'none') {
|
|
41
44
|
continue;
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
sourceGroup = this.familiesBySource[sourceId] = {};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const sourceLayerId = layer.sourceLayer || '_geojsonTileLayer';
|
|
51
|
-
let sourceLayerFamilies = sourceGroup[sourceLayerId];
|
|
52
|
-
if (!sourceLayerFamilies) {
|
|
53
|
-
sourceLayerFamilies = sourceGroup[sourceLayerId] = [];
|
|
54
|
-
}
|
|
55
|
-
|
|
47
|
+
const { source = '', sourceLayer = '_geojsonTileLayer' } = layer;
|
|
48
|
+
const sourceGroup = (this.familiesBySource[source] ??= {});
|
|
49
|
+
const sourceLayerFamilies = (sourceGroup[sourceLayer] ??= []);
|
|
56
50
|
sourceLayerFamilies.push(layers);
|
|
57
51
|
}
|
|
58
52
|
}
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
},
|
|
81
81
|
"transition": {
|
|
82
82
|
"type": "transition",
|
|
83
|
-
"doc": "A global transition definition to use as a default across properties.",
|
|
83
|
+
"doc": "A global transition definition to use as a default across properties, to be used for timing transitions between one value and the next when no property-specific transition is set. Collision-based symbol fading is controlled independently of the style's `transition` property.",
|
|
84
84
|
"example": {
|
|
85
85
|
"duration": 300,
|
|
86
86
|
"delay": 0
|
|
@@ -2621,7 +2621,7 @@
|
|
|
2621
2621
|
}
|
|
2622
2622
|
},
|
|
2623
2623
|
"feature-state": {
|
|
2624
|
-
"doc": "Retrieves a property value from the current feature's state. Returns null if the requested property is not present on the feature's state
|
|
2624
|
+
"doc": "Retrieves a property value from the current feature's state. Returns null if the requested property is not present on the feature's state. A feature's state is not part of the GeoJSON or vector tile data, and must be set programmatically on each feature. Note that [\"feature-state\"] can only be used with paint properties that support data-driven styling.",
|
|
2625
2625
|
"group": "Feature data",
|
|
2626
2626
|
"sdk-support": {
|
|
2627
2627
|
"basic functionality": {
|
package/src/symbol/anchor.js
CHANGED
|
@@ -39,6 +39,8 @@ class CollisionIndex {
|
|
|
39
39
|
|
|
40
40
|
this.screenRightBoundary = transform.width + viewportPadding;
|
|
41
41
|
this.screenBottomBoundary = transform.height + viewportPadding;
|
|
42
|
+
this.gridRightBoundary = transform.width + 2 * viewportPadding;
|
|
43
|
+
this.gridBottomBoundary = transform.height + 2 * viewportPadding;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
placeCollisionBox(collisionBox, allowOverlap, textPixelRatio, posMatrix, collisionGroupPredicate) {
|
|
@@ -53,14 +55,16 @@ class CollisionIndex {
|
|
|
53
55
|
const brX = collisionBox.x2 * tileToViewport + projectedPoint.point.x;
|
|
54
56
|
const brY = collisionBox.y2 * tileToViewport + projectedPoint.point.y;
|
|
55
57
|
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
if (
|
|
59
|
+
!this.isInsideGrid(tlX, tlY, brX, brY) ||
|
|
60
|
+
(!allowOverlap && this.grid.hitTest(tlX, tlY, brX, brY, collisionGroupPredicate))
|
|
61
|
+
) {
|
|
62
|
+
return {
|
|
63
|
+
box: [],
|
|
64
|
+
offscreen: false
|
|
65
|
+
};
|
|
63
66
|
}
|
|
67
|
+
|
|
64
68
|
return {
|
|
65
69
|
box: [tlX, tlY, brX, brY],
|
|
66
70
|
offscreen: this.isOffscreen(tlX, tlY, brX, brY)
|
|
@@ -135,6 +139,7 @@ class CollisionIndex {
|
|
|
135
139
|
);
|
|
136
140
|
|
|
137
141
|
let collisionDetected = false;
|
|
142
|
+
let inGrid = false;
|
|
138
143
|
let entirelyOffscreen = true;
|
|
139
144
|
|
|
140
145
|
const tileToViewport = projectedAnchor.perspectiveRatio * textPixelRatio;
|
|
@@ -211,14 +216,12 @@ class CollisionIndex {
|
|
|
211
216
|
placedCollisionCircles.push(projectedPoint.x, projectedPoint.y, radius, collisionBoxArrayIndex);
|
|
212
217
|
markCollisionCircleUsed(collisionCircles, k, true);
|
|
213
218
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
projectedPoint.y + radius
|
|
221
|
-
);
|
|
219
|
+
const x1 = projectedPoint.x - radius;
|
|
220
|
+
const y1 = projectedPoint.y - radius;
|
|
221
|
+
const x2 = projectedPoint.x + radius;
|
|
222
|
+
const y2 = projectedPoint.y + radius;
|
|
223
|
+
entirelyOffscreen = entirelyOffscreen && this.isOffscreen(x1, y1, x2, y2);
|
|
224
|
+
inGrid = inGrid || this.isInsideGrid(x1, y1, x2, y2);
|
|
222
225
|
|
|
223
226
|
if (!allowOverlap) {
|
|
224
227
|
if (this.grid.hitTestCircle(projectedPoint.x, projectedPoint.y, radius, collisionGroupPredicate)) {
|
|
@@ -236,7 +239,7 @@ class CollisionIndex {
|
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
return {
|
|
239
|
-
circles: collisionDetected ? [] : placedCollisionCircles,
|
|
242
|
+
circles: collisionDetected || !inGrid ? [] : placedCollisionCircles,
|
|
240
243
|
offscreen: entirelyOffscreen
|
|
241
244
|
};
|
|
242
245
|
}
|
|
@@ -370,6 +373,10 @@ class CollisionIndex {
|
|
|
370
373
|
x2 < viewportPadding || x1 >= this.screenRightBoundary || y2 < viewportPadding || y1 > this.screenBottomBoundary
|
|
371
374
|
);
|
|
372
375
|
}
|
|
376
|
+
|
|
377
|
+
isInsideGrid(x1, y1, x2, y2) {
|
|
378
|
+
return x2 >= 0 && x1 < this.gridRightBoundary && y2 >= 0 && y1 < this.gridBottomBoundary;
|
|
379
|
+
}
|
|
373
380
|
}
|
|
374
381
|
|
|
375
382
|
function markCollisionCircleUsed(collisionCircles, index, used) {
|