@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
|
@@ -2,6 +2,7 @@ const { Event, ErrorEvent, Evented } = require('@mapwhit/events');
|
|
|
2
2
|
|
|
3
3
|
const EXTENT = require('../data/extent');
|
|
4
4
|
const browser = require('../util/browser');
|
|
5
|
+
const GeoJSONWorkerSource = require('./geojson_worker_source');
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* A source containing GeoJSON.
|
|
@@ -52,8 +53,9 @@ class GeoJSONSource extends Evented {
|
|
|
52
53
|
#pendingDataEvents = new Set();
|
|
53
54
|
#newData = false;
|
|
54
55
|
#updateInProgress = false;
|
|
56
|
+
#worker;
|
|
55
57
|
|
|
56
|
-
constructor(id, options,
|
|
58
|
+
constructor(id, options, eventedParent, { resources, layerIndex }) {
|
|
57
59
|
super();
|
|
58
60
|
|
|
59
61
|
this.id = id;
|
|
@@ -69,10 +71,9 @@ class GeoJSONSource extends Evented {
|
|
|
69
71
|
this.reparseOverscaled = true;
|
|
70
72
|
this._removed = false;
|
|
71
73
|
|
|
72
|
-
this.dispatcher = dispatcher;
|
|
73
74
|
this.setEventedParent(eventedParent);
|
|
74
75
|
|
|
75
|
-
this.
|
|
76
|
+
this.data = options.data;
|
|
76
77
|
this._options = Object.assign({}, options);
|
|
77
78
|
|
|
78
79
|
if (options.maxzoom !== undefined) this.maxzoom = options.maxzoom;
|
|
@@ -107,6 +108,7 @@ class GeoJSONSource extends Evented {
|
|
|
107
108
|
},
|
|
108
109
|
options.workerOptions
|
|
109
110
|
);
|
|
111
|
+
this.#worker = new GeoJSONWorkerSource(resources, layerIndex);
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
load() {
|
|
@@ -125,7 +127,7 @@ class GeoJSONSource extends Evented {
|
|
|
125
127
|
* @returns {GeoJSONSource} this
|
|
126
128
|
*/
|
|
127
129
|
setData(data) {
|
|
128
|
-
this.
|
|
130
|
+
this.data = data;
|
|
129
131
|
this.#updateData();
|
|
130
132
|
return this;
|
|
131
133
|
}
|
|
@@ -142,7 +144,7 @@ class GeoJSONSource extends Evented {
|
|
|
142
144
|
this.fire(new Event('dataloading', { dataType: 'source' }));
|
|
143
145
|
while (this.#newData) {
|
|
144
146
|
this.#newData = false;
|
|
145
|
-
await this._updateWorkerData(this.
|
|
147
|
+
await this._updateWorkerData(this.data);
|
|
146
148
|
}
|
|
147
149
|
this.#pendingDataEvents.forEach(sourceDataType =>
|
|
148
150
|
this.fire(new Event('data', { dataType: 'source', sourceDataType }))
|
|
@@ -165,13 +167,9 @@ class GeoJSONSource extends Evented {
|
|
|
165
167
|
if (!json) {
|
|
166
168
|
throw new Error('no GeoJSON data');
|
|
167
169
|
}
|
|
168
|
-
const options = { ...this.workerOptions, data:
|
|
169
|
-
this.workerID ??= this.dispatcher.nextWorkerId();
|
|
170
|
+
const options = { ...this.workerOptions, data: json };
|
|
170
171
|
|
|
171
|
-
|
|
172
|
-
// so that other geojson-like source types can easily reuse this
|
|
173
|
-
// implementation
|
|
174
|
-
await this.dispatcher.send(`${this.type}.loadData`, options, this.workerID);
|
|
172
|
+
return await this.#worker.loadData(options);
|
|
175
173
|
}
|
|
176
174
|
|
|
177
175
|
async loadTile(tile) {
|
|
@@ -185,14 +183,15 @@ class GeoJSONSource extends Evented {
|
|
|
185
183
|
source: this.id,
|
|
186
184
|
pixelRatio: browser.devicePixelRatio,
|
|
187
185
|
showCollisionBoxes: this.map.showCollisionBoxes,
|
|
188
|
-
globalState: this.map.getGlobalState()
|
|
186
|
+
globalState: this.map.getGlobalState(),
|
|
187
|
+
justReloaded: tile.workerID != null,
|
|
188
|
+
painter: this.map.painter
|
|
189
189
|
};
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const data = await this.dispatcher.send('loadTile', params, tile.workerID).finally(() => tile.unloadVectorData());
|
|
191
|
+
tile.workerID ??= true;
|
|
192
|
+
const data = await this.#worker.loadTile(params).finally(() => tile.unloadVectorData());
|
|
194
193
|
if (!tile.aborted) {
|
|
195
|
-
tile.loadVectorData(data, this.map.painter
|
|
194
|
+
tile.loadVectorData(data, this.map.painter);
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
|
|
@@ -206,14 +205,6 @@ class GeoJSONSource extends Evented {
|
|
|
206
205
|
|
|
207
206
|
onRemove() {
|
|
208
207
|
this._removed = true;
|
|
209
|
-
return this.dispatcher.send('removeSource', { type: this.type, source: this.id }, this.workerID);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
serialize() {
|
|
213
|
-
return Object.assign({}, this._options, {
|
|
214
|
-
type: this.type,
|
|
215
|
-
data: this._data
|
|
216
|
-
});
|
|
217
208
|
}
|
|
218
209
|
|
|
219
210
|
hasTransition() {
|
|
@@ -1,68 +1,14 @@
|
|
|
1
1
|
const rewind = require('@mapwhit/geojson-rewind');
|
|
2
2
|
const GeoJSONWrapper = require('./geojson_wrapper');
|
|
3
|
-
const { fromVectorTileJs } = require('@mapwhit/vt-pbf');
|
|
4
3
|
const { default: Supercluster } = require('supercluster');
|
|
5
4
|
const { default: geojsonvt } = require('geojson-vt');
|
|
6
5
|
const VectorTileWorkerSource = require('./vector_tile_worker_source');
|
|
7
6
|
|
|
8
|
-
function loadGeoJSONTile(params) {
|
|
9
|
-
if (!this._geoJSONIndex) {
|
|
10
|
-
if (!this._createGeoJSONIndex) {
|
|
11
|
-
return; // we couldn't load the file
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
this._geoJSONIndex = this._createGeoJSONIndex();
|
|
16
|
-
} finally {
|
|
17
|
-
this._createGeoJSONIndex = null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const { z, x, y } = params.tileID.canonical;
|
|
22
|
-
const geoJSONTile = this._geoJSONIndex.getTile(z, x, y);
|
|
23
|
-
if (!geoJSONTile) {
|
|
24
|
-
return; // nothing in the given tile
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features);
|
|
28
|
-
|
|
29
|
-
// Encode the geojson-vt tile into binary vector tile form. This
|
|
30
|
-
// is a convenience that allows `FeatureIndex` to operate the same way
|
|
31
|
-
// across `VectorTileSource` and `GeoJSONSource` data.
|
|
32
|
-
let pbf = fromVectorTileJs(geojsonWrapper);
|
|
33
|
-
if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) {
|
|
34
|
-
// Compatibility with node Buffer (https://github.com/mapbox/pbf/issues/35)
|
|
35
|
-
pbf = new Uint8Array(pbf);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
vectorTile: geojsonWrapper,
|
|
40
|
-
rawData: pbf.buffer
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
7
|
/**
|
|
45
8
|
* The {@link WorkerSource} implementation that supports {@link GeoJSONSource}.
|
|
46
|
-
* This class is designed to be easily reused to support custom source types
|
|
47
|
-
* for data formats that can be parsed/converted into an in-memory GeoJSON
|
|
48
|
-
* representation. To do so, create it with
|
|
49
|
-
* `new GeoJSONWorkerSource(resources, layerIndex, customLoadGeoJSONFunction)`.
|
|
50
|
-
* For a full example, see [mapbox-gl-topojson](https://github.com/developmentseed/mapbox-gl-topojson).
|
|
51
9
|
*
|
|
52
10
|
*/
|
|
53
11
|
class GeoJSONWorkerSource extends VectorTileWorkerSource {
|
|
54
|
-
/**
|
|
55
|
-
* @param [loadGeoJSON] Optional method for custom loading/parsing of
|
|
56
|
-
* GeoJSON based on parameters passed from the main-thread Source.
|
|
57
|
-
* See {@link GeoJSONWorkerSource#loadGeoJSON}.
|
|
58
|
-
*/
|
|
59
|
-
constructor(resources, layerIndex, loadGeoJSON) {
|
|
60
|
-
super(resources, layerIndex, loadGeoJSONTile);
|
|
61
|
-
if (loadGeoJSON) {
|
|
62
|
-
this.loadGeoJSON = loadGeoJSON;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
12
|
/**
|
|
67
13
|
* Fetches (if appropriate), parses, and index geojson data into tiles. This
|
|
68
14
|
* preparatory method must be called before {@link GeoJSONWorkerSource#loadTile}
|
|
@@ -76,7 +22,7 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
|
|
|
76
22
|
* @param callback
|
|
77
23
|
*/
|
|
78
24
|
loadData(params) {
|
|
79
|
-
const data =
|
|
25
|
+
const data = loadJSON(params.data);
|
|
80
26
|
this._geoJSONIndex = null;
|
|
81
27
|
this._createGeoJSONIndex = params.cluster
|
|
82
28
|
? () => {
|
|
@@ -89,20 +35,46 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
|
|
|
89
35
|
};
|
|
90
36
|
}
|
|
91
37
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
38
|
+
getTile(tileID) {
|
|
39
|
+
if (!this._geoJSONIndex) {
|
|
40
|
+
if (!this._createGeoJSONIndex) {
|
|
41
|
+
return; // we couldn't load the file
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
this._geoJSONIndex = this._createGeoJSONIndex();
|
|
46
|
+
} finally {
|
|
47
|
+
this._createGeoJSONIndex = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const { z, x, y } = tileID.canonical;
|
|
51
|
+
return this._geoJSONIndex.getTile(z, x, y);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
loadVectorData({ tileID }) {
|
|
55
|
+
const geoJSONTile = this.getTile(tileID);
|
|
56
|
+
if (!geoJSONTile) {
|
|
57
|
+
return; // nothing in the given tile
|
|
105
58
|
}
|
|
59
|
+
|
|
60
|
+
const vectorTile = new GeoJSONWrapper(geoJSONTile.features);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
vectorTile
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Fetch and parse GeoJSON according to the given params.
|
|
70
|
+
*
|
|
71
|
+
* @param data Literal GeoJSON data. Must be provided.
|
|
72
|
+
*/
|
|
73
|
+
function loadJSON(data) {
|
|
74
|
+
try {
|
|
75
|
+
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
76
|
+
} catch (e) {
|
|
77
|
+
throw new Error('Input data is not a valid GeoJSON object.');
|
|
106
78
|
}
|
|
107
79
|
}
|
|
108
80
|
|
|
@@ -20,6 +20,14 @@ class FeatureWrapper {
|
|
|
20
20
|
if ('id' in feature && !isNaN(feature.id)) {
|
|
21
21
|
this.id = Number.parseInt(feature.id, 10);
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
// fix geometry - it has to be at least array of 2 points
|
|
25
|
+
if (typeof this._feature.geometry[0] === 'number') {
|
|
26
|
+
this._feature.geometry = [this._feature.geometry];
|
|
27
|
+
if (this._feature.geometry.length === 1) {
|
|
28
|
+
this._feature.geometry.push(this._feature.geometry[0]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
23
31
|
}
|
|
24
32
|
|
|
25
33
|
get type() {
|
|
@@ -27,7 +35,7 @@ class FeatureWrapper {
|
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
get properties() {
|
|
30
|
-
return this._feature.tags;
|
|
38
|
+
return this._feature.tags ?? {};
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
get extent() {
|
|
@@ -2,7 +2,6 @@ const { getCoordinatesCenter } = require('../util/util');
|
|
|
2
2
|
|
|
3
3
|
const { CanonicalTileID } = require('./tile_id');
|
|
4
4
|
const LngLat = require('../geo/lng_lat');
|
|
5
|
-
const { default: Point } = require('@mapbox/point-geometry');
|
|
6
5
|
const { Event, ErrorEvent, Evented } = require('@mapwhit/events');
|
|
7
6
|
const loadImage = require('../util/loader/image');
|
|
8
7
|
const EXTENT = require('../data/extent');
|
|
@@ -44,10 +43,9 @@ class ImageSource extends Evented {
|
|
|
44
43
|
/**
|
|
45
44
|
* @private
|
|
46
45
|
*/
|
|
47
|
-
constructor(id, options,
|
|
46
|
+
constructor(id, options, eventedParent) {
|
|
48
47
|
super();
|
|
49
48
|
this.id = id;
|
|
50
|
-
this.dispatcher = dispatcher;
|
|
51
49
|
this.coordinates = options.coordinates;
|
|
52
50
|
|
|
53
51
|
this.type = 'image';
|
|
@@ -125,10 +123,10 @@ class ImageSource extends Evented {
|
|
|
125
123
|
// tile.
|
|
126
124
|
const tileCoords = cornerZ0Coords.map(coord => {
|
|
127
125
|
const zoomedCoord = coord.zoomTo(centerCoord.zoom);
|
|
128
|
-
return
|
|
129
|
-
Math.round((zoomedCoord.column - centerCoord.column) * EXTENT),
|
|
130
|
-
Math.round((zoomedCoord.row - centerCoord.row) * EXTENT)
|
|
131
|
-
|
|
126
|
+
return {
|
|
127
|
+
x: Math.round((zoomedCoord.column - centerCoord.column) * EXTENT),
|
|
128
|
+
y: Math.round((zoomedCoord.row - centerCoord.row) * EXTENT)
|
|
129
|
+
};
|
|
132
130
|
});
|
|
133
131
|
|
|
134
132
|
this._boundsArray = new RasterBoundsArray();
|
|
@@ -185,21 +183,13 @@ class ImageSource extends Evented {
|
|
|
185
183
|
// single tile.
|
|
186
184
|
if (this.tileID?.equals(tile.tileID.canonical)) {
|
|
187
185
|
this.tiles[String(tile.tileID.wrap)] = tile;
|
|
188
|
-
tile.buckets =
|
|
186
|
+
tile.buckets = new Map();
|
|
189
187
|
} else {
|
|
190
188
|
tile.state = 'errored';
|
|
191
189
|
}
|
|
192
190
|
return Promise.resolve();
|
|
193
191
|
}
|
|
194
192
|
|
|
195
|
-
serialize() {
|
|
196
|
-
return {
|
|
197
|
-
type: 'image',
|
|
198
|
-
url: this.options.url,
|
|
199
|
-
coordinates: this.coordinates
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
|
|
203
193
|
hasTransition() {
|
|
204
194
|
return false;
|
|
205
195
|
}
|
|
@@ -20,14 +20,13 @@ function getPixelPosMatrix(transform, tileID) {
|
|
|
20
20
|
function queryIncludes3DLayer(layers, styleLayers, sourceID) {
|
|
21
21
|
if (layers) {
|
|
22
22
|
for (const layerID of layers) {
|
|
23
|
-
const layer = styleLayers
|
|
23
|
+
const layer = styleLayers.get(layerID);
|
|
24
24
|
if (layer && layer.source === sourceID && layer.type === 'fill-extrusion') {
|
|
25
25
|
return true;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
} else {
|
|
29
|
-
for (const
|
|
30
|
-
const layer = styleLayers[key];
|
|
28
|
+
} else if (styleLayers) {
|
|
29
|
+
for (const layer of styleLayers.values()) {
|
|
31
30
|
if (layer.source === sourceID && layer.type === 'fill-extrusion') {
|
|
32
31
|
return true;
|
|
33
32
|
}
|
|
@@ -129,7 +128,7 @@ function queryRenderedSymbols(styleLayers, sourceCaches, queryGeometry, params,
|
|
|
129
128
|
for (const layerName in result) {
|
|
130
129
|
result[layerName].forEach(featureWrapper => {
|
|
131
130
|
const feature = featureWrapper.feature;
|
|
132
|
-
const layer = styleLayers
|
|
131
|
+
const layer = styleLayers.get(layerName);
|
|
133
132
|
const sourceCache = sourceCaches[layer.source];
|
|
134
133
|
const state = sourceCache.getFeatureState(feature.layer['source-layer'], feature.id);
|
|
135
134
|
feature.source = feature.layer.source;
|
|
@@ -1,35 +1,23 @@
|
|
|
1
1
|
const browser = require('../util/browser');
|
|
2
2
|
const loadImage = require('../util/loader/image');
|
|
3
|
-
const {
|
|
3
|
+
const { calculateKey } = require('./tile_id');
|
|
4
4
|
const RasterTileSource = require('./raster_tile_source');
|
|
5
|
-
|
|
6
|
-
require('../data/dem_data');
|
|
5
|
+
const DEMData = require('../data/dem_data');
|
|
7
6
|
|
|
8
7
|
class RasterDEMTileSource extends RasterTileSource {
|
|
9
|
-
constructor(id, options,
|
|
10
|
-
super(id, options,
|
|
8
|
+
constructor(id, options, eventedParent) {
|
|
9
|
+
super(id, options, eventedParent);
|
|
11
10
|
this.type = 'raster-dem';
|
|
12
11
|
this.maxzoom = 22;
|
|
13
12
|
this._options = Object.assign({}, options);
|
|
14
13
|
this.encoding = options.encoding || 'mapbox';
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
serialize() {
|
|
18
|
-
return {
|
|
19
|
-
type: 'raster-dem',
|
|
20
|
-
url: this.url,
|
|
21
|
-
tileSize: this.tileSize,
|
|
22
|
-
tiles: this.tiles,
|
|
23
|
-
bounds: this.bounds,
|
|
24
|
-
encoding: this.encoding
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
16
|
async loadTile(tile) {
|
|
29
17
|
try {
|
|
30
18
|
tile.abortController = new window.AbortController();
|
|
31
19
|
const data = await this.tiles(tile.tileID.canonical, tile.abortController).catch(() => {});
|
|
32
|
-
tile.neighboringTiles =
|
|
20
|
+
tile.neighboringTiles = getNeighboringTiles(tile.tileID);
|
|
33
21
|
if (!data) {
|
|
34
22
|
const err = new Error('Tile could not be loaded');
|
|
35
23
|
err.status = 404; // will try to use the parent/child tile
|
|
@@ -48,7 +36,7 @@ class RasterDEMTileSource extends RasterTileSource {
|
|
|
48
36
|
rawImageData,
|
|
49
37
|
encoding: this.encoding
|
|
50
38
|
};
|
|
51
|
-
const dem = await
|
|
39
|
+
const dem = await loadDEMTile(params);
|
|
52
40
|
if (dem) {
|
|
53
41
|
tile.dem = dem;
|
|
54
42
|
tile.needsHillshadePrepare = true;
|
|
@@ -65,52 +53,6 @@ class RasterDEMTileSource extends RasterTileSource {
|
|
|
65
53
|
}
|
|
66
54
|
}
|
|
67
55
|
|
|
68
|
-
_getNeighboringTiles(tileID) {
|
|
69
|
-
const canonical = tileID.canonical;
|
|
70
|
-
const dim = 2 ** canonical.z;
|
|
71
|
-
|
|
72
|
-
const px = (canonical.x - 1 + dim) % dim;
|
|
73
|
-
const pxw = canonical.x === 0 ? tileID.wrap - 1 : tileID.wrap;
|
|
74
|
-
const nx = (canonical.x + 1 + dim) % dim;
|
|
75
|
-
const nxw = canonical.x + 1 === dim ? tileID.wrap + 1 : tileID.wrap;
|
|
76
|
-
|
|
77
|
-
const neighboringTiles = {};
|
|
78
|
-
// add adjacent tiles
|
|
79
|
-
neighboringTiles[new OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y).key] = {
|
|
80
|
-
backfilled: false
|
|
81
|
-
};
|
|
82
|
-
neighboringTiles[new OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y).key] = {
|
|
83
|
-
backfilled: false
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// Add upper neighboringTiles
|
|
87
|
-
if (canonical.y > 0) {
|
|
88
|
-
neighboringTiles[new OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y - 1).key] = {
|
|
89
|
-
backfilled: false
|
|
90
|
-
};
|
|
91
|
-
neighboringTiles[
|
|
92
|
-
new OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y - 1).key
|
|
93
|
-
] = { backfilled: false };
|
|
94
|
-
neighboringTiles[new OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y - 1).key] = {
|
|
95
|
-
backfilled: false
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
// Add lower neighboringTiles
|
|
99
|
-
if (canonical.y + 1 < dim) {
|
|
100
|
-
neighboringTiles[new OverscaledTileID(tileID.overscaledZ, pxw, canonical.z, px, canonical.y + 1).key] = {
|
|
101
|
-
backfilled: false
|
|
102
|
-
};
|
|
103
|
-
neighboringTiles[
|
|
104
|
-
new OverscaledTileID(tileID.overscaledZ, tileID.wrap, canonical.z, canonical.x, canonical.y + 1).key
|
|
105
|
-
] = { backfilled: false };
|
|
106
|
-
neighboringTiles[new OverscaledTileID(tileID.overscaledZ, nxw, canonical.z, nx, canonical.y + 1).key] = {
|
|
107
|
-
backfilled: false
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return neighboringTiles;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
56
|
unloadTile(tile) {
|
|
115
57
|
if (tile.demTexture) this.map.painter.saveTileTexture(tile.demTexture);
|
|
116
58
|
if (tile.fbo) {
|
|
@@ -124,4 +66,43 @@ class RasterDEMTileSource extends RasterTileSource {
|
|
|
124
66
|
}
|
|
125
67
|
}
|
|
126
68
|
|
|
69
|
+
// biome-ignore lint/suspicious/useAwait: thread
|
|
70
|
+
async function loadDEMTile({ uid, rawImageData, encoding }) {
|
|
71
|
+
return new DEMData(uid, rawImageData, encoding);
|
|
72
|
+
}
|
|
73
|
+
|
|
127
74
|
module.exports = RasterDEMTileSource;
|
|
75
|
+
|
|
76
|
+
function getNeighboringTiles(tileID) {
|
|
77
|
+
const {
|
|
78
|
+
canonical: { x, y, z },
|
|
79
|
+
wrap,
|
|
80
|
+
overscaledZ
|
|
81
|
+
} = tileID;
|
|
82
|
+
const dim = 2 ** z;
|
|
83
|
+
const px = (x - 1 + dim) % dim;
|
|
84
|
+
const pxw = x === 0 ? wrap - 1 : wrap;
|
|
85
|
+
const nx = (x + 1 + dim) % dim;
|
|
86
|
+
const nxw = x + 1 === dim ? wrap + 1 : wrap;
|
|
87
|
+
|
|
88
|
+
const neighboringTiles = {
|
|
89
|
+
// add adjacent tiles
|
|
90
|
+
[calculateKey(pxw, overscaledZ, px, y)]: { backfilled: false },
|
|
91
|
+
[calculateKey(nxw, overscaledZ, nx, y)]: { backfilled: false }
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Add upper neighboringTiles
|
|
95
|
+
if (y > 0) {
|
|
96
|
+
neighboringTiles[calculateKey(pxw, overscaledZ, px, y - 1)] = { backfilled: false };
|
|
97
|
+
neighboringTiles[calculateKey(wrap, overscaledZ, x, y - 1)] = { backfilled: false };
|
|
98
|
+
neighboringTiles[calculateKey(nxw, overscaledZ, nx, y - 1)] = { backfilled: false };
|
|
99
|
+
}
|
|
100
|
+
// Add lower neighboringTiles
|
|
101
|
+
if (y + 1 < dim) {
|
|
102
|
+
neighboringTiles[calculateKey(pxw, overscaledZ, px, y + 1)] = { backfilled: false };
|
|
103
|
+
neighboringTiles[calculateKey(wrap, overscaledZ, x, y + 1)] = { backfilled: false };
|
|
104
|
+
neighboringTiles[calculateKey(nxw, overscaledZ, nx, y + 1)] = { backfilled: false };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return neighboringTiles;
|
|
108
|
+
}
|
|
@@ -6,10 +6,9 @@ const TileBounds = require('./tile_bounds');
|
|
|
6
6
|
const Texture = require('../render/texture');
|
|
7
7
|
|
|
8
8
|
class RasterTileSource extends Evented {
|
|
9
|
-
constructor(id, options,
|
|
9
|
+
constructor(id, options, eventedParent) {
|
|
10
10
|
super();
|
|
11
11
|
this.id = id;
|
|
12
|
-
this.dispatcher = dispatcher;
|
|
13
12
|
this.setEventedParent(eventedParent);
|
|
14
13
|
|
|
15
14
|
this.type = 'raster';
|
|
@@ -46,10 +45,6 @@ class RasterTileSource extends Evented {
|
|
|
46
45
|
this.load();
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
serialize() {
|
|
50
|
-
return Object.assign({}, this._options);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
48
|
hasTile(tileID) {
|
|
54
49
|
return !this.tileBounds || this.tileBounds.contains(tileID.canonical);
|
|
55
50
|
}
|
|
@@ -4,7 +4,7 @@ module.exports = glyphCache;
|
|
|
4
4
|
|
|
5
5
|
const MAX_GLYPH_ID = 65535;
|
|
6
6
|
|
|
7
|
-
function glyphCache({
|
|
7
|
+
function glyphCache({ loadGlyphRange: loadGlyphRangeFromStyle, parseGlyphs = parseGlyphPBF }) {
|
|
8
8
|
const entries = {};
|
|
9
9
|
|
|
10
10
|
return {
|
|
@@ -56,7 +56,7 @@ function glyphCache({ actor, mapId, parseGlyphs = parseGlyphPBF }) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
async function loadGlyphRange(entry, stack, range) {
|
|
59
|
-
const promise = (entry.requests[range] ??=
|
|
59
|
+
const promise = (entry.requests[range] ??= loadGlyphRangeFromStyle({ stack, range }));
|
|
60
60
|
const data = await promise;
|
|
61
61
|
delete entry.requests[range];
|
|
62
62
|
entry.ranges[range] = true;
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
const makeGlyphs = require('./glyphs');
|
|
2
|
-
const makeImages = require('./images');
|
|
3
2
|
|
|
4
3
|
module.exports = { resources };
|
|
5
4
|
|
|
6
|
-
function resources(
|
|
7
|
-
const glyphs = makeGlyphs(
|
|
8
|
-
const images = makeImages({ actor, mapId });
|
|
5
|
+
function resources(opts) {
|
|
6
|
+
const glyphs = makeGlyphs(opts);
|
|
9
7
|
|
|
10
8
|
return {
|
|
11
9
|
getGlyphs,
|
|
12
|
-
getImages
|
|
10
|
+
getImages: opts.getImages
|
|
13
11
|
};
|
|
14
12
|
|
|
15
13
|
function getGlyphs(params) {
|
|
16
14
|
return glyphs.getGlyphs(params);
|
|
17
15
|
}
|
|
18
|
-
|
|
19
|
-
function getImages(params) {
|
|
20
|
-
return images.getImages(params);
|
|
21
|
-
}
|
|
22
16
|
}
|
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
const
|
|
1
|
+
const dynload = require('dynload');
|
|
2
2
|
const browser = require('../util/browser');
|
|
3
3
|
|
|
4
4
|
let pluginRequested = false;
|
|
5
|
-
let pluginURL
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
const evented = new Evented();
|
|
5
|
+
let pluginURL;
|
|
6
|
+
let loading = false;
|
|
9
7
|
|
|
10
8
|
let _completionCallback;
|
|
9
|
+
const _loadedCallbacks = [];
|
|
10
|
+
|
|
11
|
+
const rtlPlugin = {
|
|
12
|
+
clearRTLTextPlugin, // exported for testing
|
|
13
|
+
loadScript, // exported for testing
|
|
14
|
+
registerForPluginAvailability,
|
|
15
|
+
setRTLTextPlugin
|
|
16
|
+
};
|
|
11
17
|
|
|
12
18
|
function registerForPluginAvailability(callback) {
|
|
13
|
-
if (
|
|
14
|
-
callback(
|
|
15
|
-
|
|
16
|
-
evented.once('pluginAvailable', callback);
|
|
19
|
+
if (plugin.isLoaded()) {
|
|
20
|
+
callback();
|
|
21
|
+
return;
|
|
17
22
|
}
|
|
18
|
-
|
|
23
|
+
_loadedCallbacks.push(callback);
|
|
24
|
+
loadRTLTextPlugin();
|
|
25
|
+
return () => _loadedCallbacks.splice(_loadedCallbacks.indexOf(callback), 1);
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
function clearRTLTextPlugin() {
|
|
29
|
+
_loadedCallbacks.length = 0;
|
|
22
30
|
pluginRequested = false;
|
|
23
|
-
pluginURL =
|
|
31
|
+
pluginURL = undefined;
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
function setRTLTextPlugin(url, callback) {
|
|
@@ -31,35 +39,54 @@ function setRTLTextPlugin(url, callback) {
|
|
|
31
39
|
pluginURL = browser.resolveURL(url);
|
|
32
40
|
_completionCallback = error => {
|
|
33
41
|
if (error) {
|
|
42
|
+
const msg = `RTL Text Plugin failed to load scripts from ${pluginURL}`;
|
|
34
43
|
// Clear loaded state to allow retries
|
|
35
44
|
clearRTLTextPlugin();
|
|
36
45
|
if (callback) {
|
|
37
|
-
callback(
|
|
46
|
+
callback(new Error(msg));
|
|
38
47
|
}
|
|
39
|
-
} else {
|
|
40
|
-
// Called once for each worker
|
|
41
|
-
foregroundLoadComplete = true;
|
|
42
48
|
}
|
|
49
|
+
loading = false;
|
|
50
|
+
_completionCallback = undefined;
|
|
43
51
|
};
|
|
44
|
-
|
|
52
|
+
loadRTLTextPlugin();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function loadRTLTextPlugin() {
|
|
56
|
+
if (pluginURL && !plugin.isLoaded() && _loadedCallbacks.length > 0 && !loading) {
|
|
57
|
+
// needs to be called as exported method for mock testing
|
|
58
|
+
loading = rtlPlugin.loadScript(pluginURL).catch(_completionCallback);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function registerRTLTextPlugin(loadedPlugin) {
|
|
63
|
+
if (plugin.isLoaded()) {
|
|
64
|
+
throw new Error('RTL text plugin already registered.');
|
|
65
|
+
}
|
|
66
|
+
plugin['applyArabicShaping'] = loadedPlugin.applyArabicShaping;
|
|
67
|
+
plugin['processBidirectionalText'] = loadedPlugin.processBidirectionalText;
|
|
68
|
+
plugin['processStyledBidirectionalText'] = loadedPlugin.processStyledBidirectionalText;
|
|
69
|
+
|
|
70
|
+
_completionCallback();
|
|
71
|
+
_loadedCallbacks.forEach(callback => callback());
|
|
72
|
+
_loadedCallbacks.length = 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
globalThis.registerRTLTextPlugin ??= registerRTLTextPlugin;
|
|
76
|
+
|
|
77
|
+
async function loadScript(url) {
|
|
78
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
79
|
+
const s = dynload(url);
|
|
80
|
+
s.onload = () => resolve();
|
|
81
|
+
s.onerror = () => reject(true);
|
|
82
|
+
return promise;
|
|
45
83
|
}
|
|
46
84
|
|
|
47
|
-
const plugin = {
|
|
85
|
+
const plugin = (rtlPlugin.plugin = {
|
|
48
86
|
applyArabicShaping: null,
|
|
49
87
|
processBidirectionalText: null,
|
|
50
88
|
processStyledBidirectionalText: null,
|
|
51
|
-
isLoaded:
|
|
52
|
-
|
|
53
|
-
foregroundLoadComplete || // Foreground: loaded if the completion callback returned successfully
|
|
54
|
-
plugin.applyArabicShaping != null
|
|
55
|
-
); // Background: loaded if the plugin functions have been compiled
|
|
56
|
-
}
|
|
57
|
-
};
|
|
89
|
+
isLoaded: () => plugin.applyArabicShaping != null
|
|
90
|
+
});
|
|
58
91
|
|
|
59
|
-
module.exports =
|
|
60
|
-
registerForPluginAvailability,
|
|
61
|
-
clearRTLTextPlugin,
|
|
62
|
-
setRTLTextPlugin,
|
|
63
|
-
plugin,
|
|
64
|
-
evented
|
|
65
|
-
};
|
|
92
|
+
module.exports = rtlPlugin;
|