@mapwhit/tilerenderer 0.47.1 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/min/package.json +1 -1
- package/package.json +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 +26 -12
- package/src/data/dem_data.js +1 -1
- package/src/data/feature_index.js +43 -82
- package/src/data/program_configuration.js +19 -11
- package/src/data/segment.js +2 -2
- package/src/geo/transform.js +4 -2
- package/src/gl/color_mode.js +6 -6
- package/src/index.js +3 -1
- 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 +3 -1
- package/src/source/source_cache.js +23 -21
- package/src/source/source_state.js +17 -26
- package/src/source/tile.js +6 -5
- 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 +37 -103
- 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 -37
- package/src/style/style_layer/symbol_style_layer_properties.js +1 -1
- package/src/style/style_layer_index.js +17 -23
- package/src/style-spec/expression/compound_expression.js +30 -16
- package/src/style-spec/expression/definitions/coercion.js +13 -0
- package/src/style-spec/expression/definitions/comparison.js +193 -0
- package/src/style-spec/expression/definitions/formatted.js +123 -0
- package/src/style-spec/expression/definitions/index.js +10 -60
- package/src/style-spec/expression/definitions/interpolate.js +17 -7
- package/src/style-spec/expression/definitions/literal.js +5 -0
- package/src/style-spec/expression/parsing_context.js +4 -0
- package/src/style-spec/expression/types.js +12 -1
- package/src/style-spec/feature_filter/index.js +1 -1
- package/src/style-spec/reference/v8.json +120 -49
- package/src/symbol/anchor.js +1 -1
- package/src/symbol/collision_index.js +23 -16
- package/src/symbol/get_anchors.js +11 -22
- package/src/symbol/grid_index.js +176 -182
- package/src/symbol/mergelines.js +51 -48
- package/src/symbol/opacity_state.js +1 -1
- package/src/symbol/placement.js +8 -2
- package/src/symbol/quads.js +7 -6
- package/src/symbol/shaping.js +185 -40
- package/src/symbol/symbol_layout.js +9 -6
- package/src/symbol/transform_text.js +12 -1
- package/src/ui/camera.js +82 -85
- package/src/ui/map.js +13 -57
- 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/style-spec/expression/definitions/equals.js +0 -93
|
@@ -25,56 +25,44 @@ class RasterDEMTileSource extends RasterTileSource {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
loadTile(tile
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
async loadTile(tile) {
|
|
29
|
+
try {
|
|
30
|
+
tile.abortController = new window.AbortController();
|
|
31
|
+
const data = await this.tiles(tile.tileID.canonical, tile.abortController).catch(() => {});
|
|
32
|
+
tile.neighboringTiles = this._getNeighboringTiles(tile.tileID);
|
|
33
|
+
if (!data) {
|
|
34
|
+
const err = new Error('Tile could not be loaded');
|
|
35
|
+
err.status = 404; // will try to use the parent/child tile
|
|
36
|
+
throw err;
|
|
33
37
|
}
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
tile.needsHillshadePrepare = true;
|
|
38
|
-
tile.state = 'loaded';
|
|
39
|
-
callback(null);
|
|
38
|
+
const img = await loadImage(data);
|
|
39
|
+
if (!img) {
|
|
40
|
+
return;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
const imageLoaded = (err, img) => {
|
|
43
|
-
delete tile.request;
|
|
44
|
-
if (tile.aborted) {
|
|
45
|
-
tile.state = 'unloaded';
|
|
46
|
-
callback(null);
|
|
47
|
-
} else if (err) {
|
|
48
|
-
tile.state = 'errored';
|
|
49
|
-
callback(err);
|
|
50
|
-
} else if (img) {
|
|
42
|
+
if (!tile.dem) {
|
|
51
43
|
const rawImageData = browser.getImageData(img);
|
|
52
44
|
const params = {
|
|
53
45
|
uid: tile.uid,
|
|
54
46
|
coord: tile.tileID,
|
|
55
47
|
source: this.id,
|
|
56
|
-
rawImageData
|
|
48
|
+
rawImageData,
|
|
57
49
|
encoding: this.encoding
|
|
58
50
|
};
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
tile.
|
|
51
|
+
const dem = await this.dispatcher.send('loadDEMTile', params);
|
|
52
|
+
if (dem) {
|
|
53
|
+
tile.dem = dem;
|
|
54
|
+
tile.needsHillshadePrepare = true;
|
|
55
|
+
tile.state = 'loaded';
|
|
62
56
|
}
|
|
63
57
|
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const err = new Error('Tile could not be loaded');
|
|
73
|
-
err.status = 404; // will try to use the parent/child tile
|
|
74
|
-
return done(err);
|
|
75
|
-
}
|
|
76
|
-
tile.request = loadImage(data, imageLoaded);
|
|
77
|
-
});
|
|
58
|
+
} catch (err) {
|
|
59
|
+
if (tile.aborted) {
|
|
60
|
+
tile.state = 'unloaded';
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
tile.state = 'errored';
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
78
66
|
}
|
|
79
67
|
|
|
80
68
|
_getNeighboringTiles(tileID) {
|
|
@@ -133,7 +121,6 @@ class RasterDEMTileSource extends RasterTileSource {
|
|
|
133
121
|
delete tile.neighboringTiles;
|
|
134
122
|
|
|
135
123
|
tile.state = 'unloaded';
|
|
136
|
-
this.dispatcher.send('removeDEMTile', { uid: tile.uid, source: this.id }, undefined, tile.workerID);
|
|
137
124
|
}
|
|
138
125
|
}
|
|
139
126
|
|
|
@@ -24,22 +24,21 @@ class RasterTileSource extends Evented {
|
|
|
24
24
|
Object.assign(this, pick(options, ['url', 'scheme', 'tileSize']));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
load() {
|
|
27
|
+
async load() {
|
|
28
28
|
this.fire(new Event('dataloading', { dataType: 'source' }));
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
29
|
+
try {
|
|
30
|
+
const tileJSON = await loadTileJSON(this._options);
|
|
31
|
+
Object.assign(this, tileJSON);
|
|
32
|
+
if (tileJSON.bounds) this.tileBounds = new TileBounds(tileJSON.bounds, this.minzoom, this.maxzoom);
|
|
33
|
+
|
|
34
|
+
// `content` is included here to prevent a race condition where `Style#_updateSources` is called
|
|
35
|
+
// before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
|
|
36
|
+
// ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
|
|
37
|
+
this.fire(new Event('data', { dataType: 'source', sourceDataType: 'metadata' }));
|
|
38
|
+
this.fire(new Event('data', { dataType: 'source', sourceDataType: 'content' }));
|
|
39
|
+
} catch (err) {
|
|
40
|
+
this.fire(new ErrorEvent(err));
|
|
41
|
+
}
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
onAdd(map) {
|
|
@@ -55,67 +54,59 @@ class RasterTileSource extends Evented {
|
|
|
55
54
|
return !this.tileBounds || this.tileBounds.contains(tileID.canonical);
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
loadTile(tile
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
async loadTile(tile) {
|
|
58
|
+
try {
|
|
59
|
+
tile.abortController = new window.AbortController();
|
|
60
|
+
const data = await this.tiles(tile.tileID.canonical, tile.abortController).catch(() => {});
|
|
61
|
+
if (!data) {
|
|
62
|
+
const err = new Error('Tile could not be loaded');
|
|
63
|
+
err.status = 404; // will try to use the parent/child tile
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
const img = await loadImage(data);
|
|
67
|
+
if (!img) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
61
70
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} else
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (context.extTextureFilterAnisotropic) {
|
|
79
|
-
gl.texParameterf(
|
|
80
|
-
gl.TEXTURE_2D,
|
|
81
|
-
context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,
|
|
82
|
-
context.extTextureFilterAnisotropicMax
|
|
83
|
-
);
|
|
84
|
-
}
|
|
71
|
+
tile.texture = this.map.painter.getTileTexture(img.width);
|
|
72
|
+
if (tile.texture) {
|
|
73
|
+
tile.texture.update(img, { useMipmap: true });
|
|
74
|
+
} else {
|
|
75
|
+
const { context } = this.map.painter;
|
|
76
|
+
const { gl } = context;
|
|
77
|
+
tile.texture = new Texture(context, img, gl.RGBA, { useMipmap: true });
|
|
78
|
+
tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST);
|
|
79
|
+
|
|
80
|
+
if (context.extTextureFilterAnisotropic) {
|
|
81
|
+
gl.texParameterf(
|
|
82
|
+
gl.TEXTURE_2D,
|
|
83
|
+
context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,
|
|
84
|
+
context.extTextureFilterAnisotropicMax
|
|
85
|
+
);
|
|
85
86
|
}
|
|
87
|
+
}
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
tile.state = 'loaded';
|
|
90
|
+
} catch (err) {
|
|
91
|
+
if (tile.aborted) {
|
|
92
|
+
tile.state = 'unloaded';
|
|
93
|
+
return;
|
|
90
94
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.tiles(tile.tileID.canonical, tile.abortController)
|
|
95
|
-
.catch(() => {})
|
|
96
|
-
.then(data => {
|
|
97
|
-
if (!data) {
|
|
98
|
-
const err = new Error('Tile could not be loaded');
|
|
99
|
-
err.status = 404; // will try to use the parent/child tile
|
|
100
|
-
return done(err);
|
|
101
|
-
}
|
|
102
|
-
tile.request = loadImage(data, done);
|
|
103
|
-
});
|
|
95
|
+
tile.state = 'errored';
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
104
98
|
}
|
|
105
99
|
|
|
106
|
-
abortTile(tile
|
|
100
|
+
abortTile(tile) {
|
|
107
101
|
if (tile.abortController) {
|
|
108
102
|
tile.aborted = true;
|
|
109
103
|
tile.abortController.abort();
|
|
110
104
|
delete tile.abortController;
|
|
111
|
-
delete tile.request;
|
|
112
105
|
}
|
|
113
|
-
callback();
|
|
114
106
|
}
|
|
115
107
|
|
|
116
|
-
unloadTile(tile
|
|
108
|
+
unloadTile(tile) {
|
|
117
109
|
if (tile.texture) this.map.painter.saveTileTexture(tile.texture);
|
|
118
|
-
callback();
|
|
119
110
|
}
|
|
120
111
|
|
|
121
112
|
hasTransition() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { Event, Evented } = require('../util/evented');
|
|
2
|
+
const browser = require('../util/browser');
|
|
2
3
|
|
|
3
4
|
let pluginRequested = false;
|
|
4
5
|
let pluginURL = null;
|
|
@@ -27,7 +28,7 @@ function setRTLTextPlugin(url, callback) {
|
|
|
27
28
|
throw new Error('setRTLTextPlugin cannot be called multiple times.');
|
|
28
29
|
}
|
|
29
30
|
pluginRequested = true;
|
|
30
|
-
pluginURL = url;
|
|
31
|
+
pluginURL = browser.resolveURL(url);
|
|
31
32
|
_completionCallback = error => {
|
|
32
33
|
if (error) {
|
|
33
34
|
// Clear loaded state to allow retries
|
|
@@ -46,6 +47,7 @@ function setRTLTextPlugin(url, callback) {
|
|
|
46
47
|
const plugin = {
|
|
47
48
|
applyArabicShaping: null,
|
|
48
49
|
processBidirectionalText: null,
|
|
50
|
+
processStyledBidirectionalText: null,
|
|
49
51
|
isLoaded: function () {
|
|
50
52
|
return (
|
|
51
53
|
foregroundLoadComplete || // Foreground: loaded if the completion callback returned successfully
|
|
@@ -110,16 +110,16 @@ class SourceCache extends Evented {
|
|
|
110
110
|
if (this.transform) this.update(this.transform);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
_loadTile(tile
|
|
114
|
-
return this._source.loadTile(tile
|
|
113
|
+
_loadTile(tile) {
|
|
114
|
+
return this._source.loadTile(tile);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
_unloadTile(tile) {
|
|
118
|
-
|
|
118
|
+
return this._source.unloadTile?.(tile);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
_abortTile(tile) {
|
|
122
|
-
|
|
122
|
+
return this._source.abortTile?.(tile);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
serialize() {
|
|
@@ -127,9 +127,7 @@ class SourceCache extends Evented {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
prepare(context) {
|
|
130
|
-
|
|
131
|
-
this._source.prepare();
|
|
132
|
-
}
|
|
130
|
+
this._source.prepare?.();
|
|
133
131
|
|
|
134
132
|
this._state.coalesceChanges(this._tiles, this.map ? this.map.painter : null);
|
|
135
133
|
for (const i in this._tiles) {
|
|
@@ -183,7 +181,7 @@ class SourceCache extends Evented {
|
|
|
183
181
|
this._cache.reset();
|
|
184
182
|
|
|
185
183
|
for (const i in this._tiles) {
|
|
186
|
-
this._reloadTile(i, 'reloading');
|
|
184
|
+
if (this._tiles[i].state !== 'errored') this._reloadTile(i, 'reloading');
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
187
|
|
|
@@ -202,21 +200,22 @@ class SourceCache extends Evented {
|
|
|
202
200
|
if (tile.state !== 'loading') {
|
|
203
201
|
tile.state = state;
|
|
204
202
|
}
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
this._loadTile(tile).then(
|
|
204
|
+
() => this._tileLoaded(tile),
|
|
205
|
+
err => this._tileLoadError(tile, err)
|
|
206
|
+
);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
209
|
+
_tileLoadError(tile, err) {
|
|
210
|
+
tile.state = 'errored';
|
|
211
|
+
// ignore do nothing strategy
|
|
212
|
+
if (err.doNothing) return;
|
|
213
|
+
if (err.status !== 404) this._source.fire(new ErrorEvent(err, { tile }));
|
|
214
|
+
// continue to try loading parent/children tiles if a tile doesn't exist (404)
|
|
215
|
+
else this.update(this.transform);
|
|
216
|
+
}
|
|
219
217
|
|
|
218
|
+
_tileLoaded(tile, err) {
|
|
220
219
|
tile.timeAdded = browser.now();
|
|
221
220
|
if (this.getSource().type === 'raster-dem' && tile.dem) this._backfillDEM(tile);
|
|
222
221
|
this._state.initializeTileState(tile, this.map ? this.map.painter : null);
|
|
@@ -610,7 +609,10 @@ class SourceCache extends Evented {
|
|
|
610
609
|
const cached = Boolean(tile);
|
|
611
610
|
if (!cached) {
|
|
612
611
|
tile = new Tile(tileID, this._source.tileSize * tileID.overscaleFactor());
|
|
613
|
-
this._loadTile(tile
|
|
612
|
+
this._loadTile(tile).then(
|
|
613
|
+
() => this._tileLoaded(tile),
|
|
614
|
+
err => this._tileLoadError(tile, err)
|
|
615
|
+
);
|
|
614
616
|
}
|
|
615
617
|
|
|
616
618
|
// Impossible, but silence flow.
|
|
@@ -5,50 +5,41 @@
|
|
|
5
5
|
* @private
|
|
6
6
|
*/
|
|
7
7
|
class SourceFeatureState {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.stateChanges = {};
|
|
11
|
-
}
|
|
8
|
+
#state = {};
|
|
9
|
+
#stateChanges = {};
|
|
12
10
|
|
|
13
11
|
updateState(sourceLayer, feature, state) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Object.assign(this.stateChanges[sourceLayer][feature], state);
|
|
12
|
+
const changes = (this.#stateChanges[sourceLayer] ??= {});
|
|
13
|
+
const featureState = (changes[feature] ??= {});
|
|
14
|
+
Object.assign(featureState, state);
|
|
18
15
|
}
|
|
19
16
|
|
|
20
17
|
getState(sourceLayer, feature) {
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
return Object.assign({}, base[feature], changes[feature]);
|
|
18
|
+
const base = this.#state[sourceLayer];
|
|
19
|
+
const changes = this.#stateChanges[sourceLayer];
|
|
20
|
+
return Object.assign({}, base?.[feature], changes?.[feature]);
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
initializeTileState(tile, painter) {
|
|
28
|
-
tile.setFeatureState(this
|
|
24
|
+
tile.setFeatureState(this.#state, painter);
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
coalesceChanges(tiles, painter) {
|
|
32
28
|
const changes = {};
|
|
33
|
-
for (const sourceLayer in this
|
|
34
|
-
this
|
|
29
|
+
for (const sourceLayer in this.#stateChanges) {
|
|
30
|
+
this.#state[sourceLayer] ??= {};
|
|
35
31
|
const layerStates = {};
|
|
36
|
-
for (const id in this
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Object.assign(this.state[sourceLayer][id], this.stateChanges[sourceLayer][id]);
|
|
41
|
-
layerStates[id] = this.state[sourceLayer][id];
|
|
32
|
+
for (const id in this.#stateChanges[sourceLayer]) {
|
|
33
|
+
this.#state[sourceLayer][id] ??= {};
|
|
34
|
+
Object.assign(this.#state[sourceLayer][id], this.#stateChanges[sourceLayer][id]);
|
|
35
|
+
layerStates[id] = this.#state[sourceLayer][id];
|
|
42
36
|
}
|
|
43
37
|
changes[sourceLayer] = layerStates;
|
|
44
38
|
}
|
|
45
|
-
this
|
|
39
|
+
this.#stateChanges = {};
|
|
46
40
|
if (Object.keys(changes).length === 0) return;
|
|
47
41
|
|
|
48
|
-
|
|
49
|
-
const tile = tiles[id];
|
|
50
|
-
tile.setFeatureState(changes, painter);
|
|
51
|
-
}
|
|
42
|
+
Object.values(tiles).forEach(tile => tile.setFeatureState(changes, painter));
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
45
|
|
package/src/source/tile.js
CHANGED
|
@@ -101,8 +101,9 @@ class Tile {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
this.queryPadding = 0;
|
|
104
|
-
for (const
|
|
105
|
-
|
|
104
|
+
for (const id in this.buckets) {
|
|
105
|
+
const bucket = this.buckets[id];
|
|
106
|
+
this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id).queryRadius(bucket));
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
if (data.imageAtlas) {
|
|
@@ -297,8 +298,8 @@ class Tile {
|
|
|
297
298
|
|
|
298
299
|
const vtLayers = this.latestFeatureIndex.loadVTLayers();
|
|
299
300
|
|
|
300
|
-
for (const
|
|
301
|
-
const bucket = this.buckets[
|
|
301
|
+
for (const id in this.buckets) {
|
|
302
|
+
const bucket = this.buckets[id];
|
|
302
303
|
// Buckets are grouped by common source-layer
|
|
303
304
|
const sourceLayerId = bucket.layers[0]['sourceLayer'] || '_geojsonTileLayer';
|
|
304
305
|
const sourceLayer = vtLayers[sourceLayerId];
|
|
@@ -307,7 +308,7 @@ class Tile {
|
|
|
307
308
|
|
|
308
309
|
bucket.update(sourceLayerStates, sourceLayer, this.imageAtlas?.patternPositions || {});
|
|
309
310
|
if (painter?.style) {
|
|
310
|
-
this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(
|
|
311
|
+
this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id).queryRadius(bucket));
|
|
311
312
|
}
|
|
312
313
|
}
|
|
313
314
|
}
|
package/src/source/tile_id.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { getTileBBox } = require('@mapbox/whoots-js');
|
|
2
2
|
|
|
3
3
|
const assert = require('assert');
|
|
4
|
-
const { register } = require('../util/
|
|
4
|
+
const { register } = require('../util/transfer_registry');
|
|
5
5
|
const Coordinate = require('../geo/coordinate');
|
|
6
6
|
|
|
7
7
|
class CanonicalTileID {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const config = require('../util/config');
|
|
2
1
|
const { Event, ErrorEvent, Evented } = require('../util/evented');
|
|
3
2
|
const { pick } = require('../util/object');
|
|
4
3
|
const loadTileJSON = require('./load_tilejson');
|
|
@@ -29,29 +28,25 @@ class VectorTileSource extends Evented {
|
|
|
29
28
|
throw new Error('vector tile sources must have a tileSize of 512');
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
this.updateWorkerConfig(config);
|
|
33
|
-
config.on('change', c => this.updateWorkerConfig(c));
|
|
34
|
-
|
|
35
31
|
this.setEventedParent(eventedParent);
|
|
36
32
|
}
|
|
37
33
|
|
|
38
|
-
load() {
|
|
34
|
+
async load() {
|
|
39
35
|
this.fire(new Event('dataloading', { dataType: 'source' }));
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
37
|
+
try {
|
|
38
|
+
const tileJSON = await loadTileJSON(this._options);
|
|
39
|
+
Object.assign(this, tileJSON);
|
|
40
|
+
if (tileJSON.bounds) this.tileBounds = new TileBounds(tileJSON.bounds, this.minzoom, this.maxzoom);
|
|
41
|
+
|
|
42
|
+
// `content` is included here to prevent a race condition where `Style#_updateSources` is called
|
|
43
|
+
// before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
|
|
44
|
+
// ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
|
|
45
|
+
this.fire(new Event('data', { dataType: 'source', sourceDataType: 'metadata' }));
|
|
46
|
+
this.fire(new Event('data', { dataType: 'source', sourceDataType: 'content' }));
|
|
47
|
+
} catch (err) {
|
|
48
|
+
this.fire(new ErrorEvent(err));
|
|
49
|
+
}
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
hasTile(tileID) {
|
|
@@ -67,78 +62,66 @@ class VectorTileSource extends Evented {
|
|
|
67
62
|
return Object.assign({}, this._options);
|
|
68
63
|
}
|
|
69
64
|
|
|
70
|
-
loadTile(tile
|
|
71
|
-
tile.
|
|
72
|
-
|
|
73
|
-
.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
tileID: tile.tileID,
|
|
84
|
-
zoom: tile.tileID.overscaledZ,
|
|
85
|
-
tileSize: this.tileSize * tile.tileID.overscaleFactor(),
|
|
86
|
-
type: this.type,
|
|
87
|
-
source: this.id,
|
|
88
|
-
pixelRatio: browser.devicePixelRatio,
|
|
89
|
-
showCollisionBoxes: this.map.showCollisionBoxes
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
if (tile.workerID === undefined || tile.state === 'expired') {
|
|
93
|
-
tile.workerID = this.dispatcher.send('loadTile', params, done.bind(this));
|
|
94
|
-
} else if (tile.state === 'loading') {
|
|
95
|
-
// schedule tile reloading after it has been loaded
|
|
96
|
-
tile.reloadCallback = callback;
|
|
97
|
-
} else {
|
|
98
|
-
this.dispatcher.send('reloadTile', params, done.bind(this), tile.workerID);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
function done(err, data) {
|
|
103
|
-
if (tile.aborted) return callback(null);
|
|
104
|
-
|
|
105
|
-
if (err) {
|
|
106
|
-
return callback(err);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (data?.resourceTiming) tile.resourceTiming = data.resourceTiming;
|
|
65
|
+
async loadTile(tile) {
|
|
66
|
+
if (tile.workerID != null && tile.state === 'loading') {
|
|
67
|
+
tile.reloadPromise ??= Promise.withResolvers();
|
|
68
|
+
return tile.reloadPromise.promise;
|
|
69
|
+
}
|
|
70
|
+
const data = await this.#loadTile(tile);
|
|
71
|
+
if (tile.reloadPromise) {
|
|
72
|
+
const { resolve, reject } = tile.reloadPromise;
|
|
73
|
+
tile.reloadPromise = null;
|
|
74
|
+
return this.loadTile(tile).then(resolve, reject);
|
|
75
|
+
}
|
|
76
|
+
return data;
|
|
77
|
+
}
|
|
110
78
|
|
|
79
|
+
async #loadTile(tile) {
|
|
80
|
+
try {
|
|
81
|
+
tile.abortController = new window.AbortController();
|
|
82
|
+
const rawData = await this.tiles(tile.tileID.canonical, tile.abortController).catch(() => {});
|
|
83
|
+
if (!rawData) {
|
|
84
|
+
const err = new Error('Tile could not be loaded');
|
|
85
|
+
err.status = 404; // will try to use the parent/child tile
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
const params = {
|
|
89
|
+
response: { data: rawData.slice() },
|
|
90
|
+
uid: tile.uid,
|
|
91
|
+
tileID: tile.tileID,
|
|
92
|
+
zoom: tile.tileID.overscaledZ,
|
|
93
|
+
tileSize: this.tileSize * tile.tileID.overscaleFactor(),
|
|
94
|
+
type: this.type,
|
|
95
|
+
source: this.id,
|
|
96
|
+
pixelRatio: browser.devicePixelRatio,
|
|
97
|
+
showCollisionBoxes: this.map.showCollisionBoxes
|
|
98
|
+
};
|
|
99
|
+
tile.workerID ??= this.dispatcher.nextWorkerId();
|
|
100
|
+
const data = await this.dispatcher.send('loadTile', params, tile.workerID);
|
|
101
|
+
data.rawTileData = rawData;
|
|
111
102
|
tile.loadVectorData(data, this.map.painter);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.loadTile(tile, tile.reloadCallback);
|
|
117
|
-
tile.reloadCallback = null;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (tile.aborted) {
|
|
105
|
+
tile.state = 'unloaded';
|
|
106
|
+
return;
|
|
118
107
|
}
|
|
108
|
+
tile.state = 'errored';
|
|
109
|
+
throw err;
|
|
119
110
|
}
|
|
120
111
|
}
|
|
121
112
|
|
|
122
113
|
abortTile(tile) {
|
|
123
114
|
tile.aborted = true;
|
|
124
115
|
tile.abortController.abort();
|
|
125
|
-
this.dispatcher.send('abortTile', { uid: tile.uid, type: this.type, source: this.id }, undefined, tile.workerID);
|
|
126
116
|
}
|
|
127
117
|
|
|
128
118
|
unloadTile(tile) {
|
|
129
119
|
tile.unloadVectorData();
|
|
130
|
-
this.dispatcher.send('removeTile', { uid: tile.uid, type: this.type, source: this.id }, undefined, tile.workerID);
|
|
131
120
|
}
|
|
132
121
|
|
|
133
122
|
hasTransition() {
|
|
134
123
|
return false;
|
|
135
124
|
}
|
|
136
|
-
|
|
137
|
-
updateWorkerConfig() {
|
|
138
|
-
this.dispatcher.broadcast('vector.updateConfig', {
|
|
139
|
-
source: this.id
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
125
|
}
|
|
143
126
|
|
|
144
127
|
module.exports = VectorTileSource;
|