@mapwhit/tilerenderer 1.2.2 → 1.4.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 -1
- package/src/data/array_types.js +115 -64
- package/src/data/bucket/circle_bucket.js +42 -5
- package/src/data/bucket/fill_bucket.js +31 -13
- package/src/data/bucket/fill_extrusion_bucket.js +8 -6
- package/src/data/bucket/line_bucket.js +38 -14
- package/src/data/bucket/symbol_attributes.js +13 -5
- package/src/data/bucket/symbol_bucket.js +87 -33
- package/src/data/bucket/symbol_collision_buffers.js +1 -1
- package/src/data/bucket.js +3 -1
- package/src/data/feature_index.js +24 -11
- package/src/data/segment.js +15 -7
- package/src/render/draw_circle.js +45 -4
- package/src/render/draw_symbol.js +190 -22
- package/src/render/painter.js +1 -1
- package/src/source/geojson_source.js +118 -21
- package/src/source/geojson_source_diff.js +148 -0
- package/src/source/geojson_tiler.js +89 -0
- package/src/source/source.js +16 -5
- package/src/source/source_cache.js +6 -6
- package/src/source/source_state.js +4 -2
- package/src/source/tile.js +5 -3
- package/src/source/vector_tile_source.js +2 -0
- package/src/source/worker_tile.js +4 -2
- package/src/style/pauseable_placement.js +39 -7
- package/src/style/style.js +86 -34
- package/src/style/style_layer/circle_style_layer_properties.js +8 -1
- package/src/style/style_layer/fill_style_layer_properties.js +8 -1
- package/src/style/style_layer/line_style_layer_properties.js +4 -0
- package/src/style/style_layer/symbol_style_layer_properties.js +17 -2
- package/src/style-spec/reference/v8.json +161 -4
- package/src/symbol/one_em.js +4 -0
- package/src/symbol/placement.js +406 -173
- package/src/symbol/projection.js +3 -3
- package/src/symbol/quads.js +1 -6
- package/src/symbol/shaping.js +16 -27
- package/src/symbol/symbol_layout.js +243 -81
- package/src/util/vectortile_to_geojson.js +3 -4
- package/src/source/geojson_worker_source.js +0 -97
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import rewind from '@mapwhit/geojson-rewind';
|
|
2
|
+
import geojsonvt from 'geojson-vt';
|
|
3
|
+
import Supercluster from 'supercluster';
|
|
4
|
+
import FeatureIndex from '../data/feature_index.js';
|
|
5
|
+
import GeoJSONWrapper from './geojson_wrapper.js';
|
|
6
|
+
import { makeSingleSourceLayerWorkerTile as makeWorkerTile } from './worker_tile.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates tiles from GeoJSON data.
|
|
10
|
+
*/
|
|
11
|
+
export default function makeTiler(resources, layerIndex) {
|
|
12
|
+
let geoJSONIndex;
|
|
13
|
+
let createGeoJSONIndex;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Fetches (if appropriate), parses, and index geojson data into tiles. This
|
|
17
|
+
* preparatory method must be called before {@link GeoJSONWorkerSource#loadTile}
|
|
18
|
+
* can correctly serve up tiles.
|
|
19
|
+
*
|
|
20
|
+
* Defers to {@link GeoJSONWorkerSource#loadGeoJSON} for the fetching/parsing,
|
|
21
|
+
* expecting `callback(error, data)` to be called with either an error or a
|
|
22
|
+
* parsed GeoJSON object.
|
|
23
|
+
*
|
|
24
|
+
* @param params
|
|
25
|
+
*/
|
|
26
|
+
function loadData(params) {
|
|
27
|
+
const { cluster, data, geojsonVtOptions, superclusterOptions } = params;
|
|
28
|
+
geoJSONIndex = undefined;
|
|
29
|
+
createGeoJSONIndex = cluster
|
|
30
|
+
? () => {
|
|
31
|
+
rewind(data, true);
|
|
32
|
+
return new Supercluster(superclusterOptions).load(data.features);
|
|
33
|
+
}
|
|
34
|
+
: () => {
|
|
35
|
+
rewind(data, true);
|
|
36
|
+
return geojsonvt(data, geojsonVtOptions);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getTile(tileID) {
|
|
41
|
+
if (!geoJSONIndex) {
|
|
42
|
+
if (!createGeoJSONIndex) {
|
|
43
|
+
return; // we couldn't load the file
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
geoJSONIndex = createGeoJSONIndex();
|
|
48
|
+
} finally {
|
|
49
|
+
createGeoJSONIndex = undefined;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const { z, x, y } = tileID.canonical;
|
|
53
|
+
return geoJSONIndex.getTile(z, x, y);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Returns a single tile.
|
|
58
|
+
*/
|
|
59
|
+
async function loadTile(params) {
|
|
60
|
+
const { tileID, source, promoteId } = params;
|
|
61
|
+
const geoJSONTile = getTile(tileID);
|
|
62
|
+
if (!geoJSONTile) {
|
|
63
|
+
return; // nothing in the given tile
|
|
64
|
+
}
|
|
65
|
+
const sourceLayer = new GeoJSONWrapper(geoJSONTile.features);
|
|
66
|
+
const layerFamilies = layerIndex.familiesBySource.get(source);
|
|
67
|
+
if (!layerFamilies) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
params.featureIndex = new FeatureIndex(tileID, promoteId);
|
|
71
|
+
const { name } = sourceLayer;
|
|
72
|
+
const features = new Array(sourceLayer.length);
|
|
73
|
+
for (let index = 0; index < sourceLayer.length; index++) {
|
|
74
|
+
const feature = sourceLayer.feature(index);
|
|
75
|
+
const id = params.featureIndex.getId(feature, name);
|
|
76
|
+
features[index] = { feature, id, index, sourceLayerIndex: 0 };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const result = await makeWorkerTile(params, features, layerFamilies.get(name), resources);
|
|
80
|
+
|
|
81
|
+
result.vectorTile = sourceLayer;
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
loadData,
|
|
87
|
+
loadTile
|
|
88
|
+
};
|
|
89
|
+
}
|
package/src/source/source.js
CHANGED
|
@@ -25,6 +25,7 @@ import { bindAll } from '../util/object.js';
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import geojson from './geojson_source.js';
|
|
28
|
+
import geojsonTiler from './geojson_tiler.js';
|
|
28
29
|
import image from './image_source.js';
|
|
29
30
|
import rasterDem from './raster_dem_tile_source.js';
|
|
30
31
|
import raster from './raster_tile_source.js';
|
|
@@ -38,6 +39,9 @@ const sourceTypes = {
|
|
|
38
39
|
image
|
|
39
40
|
};
|
|
40
41
|
|
|
42
|
+
const tilerTypes = {
|
|
43
|
+
geojson: geojsonTiler
|
|
44
|
+
};
|
|
41
45
|
/*
|
|
42
46
|
* Creates a tiled data source instance given an options object.
|
|
43
47
|
*
|
|
@@ -48,11 +52,18 @@ const sourceTypes = {
|
|
|
48
52
|
* @returns {Source}
|
|
49
53
|
*/
|
|
50
54
|
export function create(id, specification, eventedParent, { resources, layerIndex, showTileBoundaries }) {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const tiler = tilerTypes[specification.type]?.(resources, layerIndex);
|
|
56
|
+
|
|
57
|
+
const source = new sourceTypes[specification.type](
|
|
58
|
+
id,
|
|
59
|
+
specification,
|
|
60
|
+
eventedParent,
|
|
61
|
+
tiler ?? {
|
|
62
|
+
resources,
|
|
63
|
+
layerIndex,
|
|
64
|
+
showTileBoundaries
|
|
65
|
+
}
|
|
66
|
+
);
|
|
56
67
|
|
|
57
68
|
bindAll(['load', 'abort', 'unload', 'serialize', 'prepare'], source);
|
|
58
69
|
return source;
|
|
@@ -799,27 +799,27 @@ class SourceCache extends Evented {
|
|
|
799
799
|
* Set the value of a particular state for a feature
|
|
800
800
|
* @private
|
|
801
801
|
*/
|
|
802
|
-
setFeatureState(sourceLayer,
|
|
802
|
+
setFeatureState(sourceLayer, featureId, state) {
|
|
803
803
|
sourceLayer = sourceLayer || '_geojsonTileLayer';
|
|
804
|
-
this._state.updateState(sourceLayer,
|
|
804
|
+
this._state.updateState(sourceLayer, featureId, state);
|
|
805
805
|
}
|
|
806
806
|
|
|
807
807
|
/**
|
|
808
808
|
* Resets the value of a particular state key for a feature
|
|
809
809
|
* @private
|
|
810
810
|
*/
|
|
811
|
-
removeFeatureState(sourceLayer,
|
|
811
|
+
removeFeatureState(sourceLayer, featureId, key) {
|
|
812
812
|
sourceLayer = sourceLayer || '_geojsonTileLayer';
|
|
813
|
-
this._state.removeFeatureState(sourceLayer,
|
|
813
|
+
this._state.removeFeatureState(sourceLayer, featureId, key);
|
|
814
814
|
}
|
|
815
815
|
|
|
816
816
|
/**
|
|
817
817
|
* Get the entire state object for a feature
|
|
818
818
|
* @private
|
|
819
819
|
*/
|
|
820
|
-
getFeatureState(sourceLayer,
|
|
820
|
+
getFeatureState(sourceLayer, featureId) {
|
|
821
821
|
sourceLayer = sourceLayer || '_geojsonTileLayer';
|
|
822
|
-
return this._state.getState(sourceLayer,
|
|
822
|
+
return this._state.getState(sourceLayer, featureId);
|
|
823
823
|
}
|
|
824
824
|
}
|
|
825
825
|
|
|
@@ -13,7 +13,8 @@ class SourceFeatureState {
|
|
|
13
13
|
#stateChanges = {};
|
|
14
14
|
#deletedStates = {};
|
|
15
15
|
|
|
16
|
-
updateState(sourceLayer,
|
|
16
|
+
updateState(sourceLayer, featureId, newState) {
|
|
17
|
+
const feature = String(featureId);
|
|
17
18
|
const changes = (this.#stateChanges[sourceLayer] ??= {});
|
|
18
19
|
const featureState = (changes[feature] ??= {});
|
|
19
20
|
Object.assign(featureState, newState);
|
|
@@ -76,7 +77,8 @@ class SourceFeatureState {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
getState(sourceLayer,
|
|
80
|
+
getState(sourceLayer, featureId) {
|
|
81
|
+
const feature = String(featureId);
|
|
80
82
|
const base = this.#state[sourceLayer];
|
|
81
83
|
const changes = this.#stateChanges[sourceLayer];
|
|
82
84
|
const reconciledState = Object.assign({}, base?.[feature], changes?.[feature]);
|
package/src/source/tile.js
CHANGED
|
@@ -191,11 +191,12 @@ class Tile {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
querySourceFeatures(result, params) {
|
|
194
|
-
|
|
194
|
+
const featureIndex = this.latestFeatureIndex;
|
|
195
|
+
if (!featureIndex?.vectorTile) {
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
198
|
|
|
198
|
-
const vtLayers =
|
|
199
|
+
const vtLayers = featureIndex.loadVTLayers();
|
|
199
200
|
|
|
200
201
|
const sourceLayer = params ? params.sourceLayer : '';
|
|
201
202
|
const layer = vtLayers._geojsonTileLayer || vtLayers[sourceLayer];
|
|
@@ -211,7 +212,8 @@ class Tile {
|
|
|
211
212
|
for (let i = 0; i < layer.length; i++) {
|
|
212
213
|
const feature = layer.feature(i);
|
|
213
214
|
if (filter(new EvaluationParameters(this.tileID.overscaledZ), feature)) {
|
|
214
|
-
const
|
|
215
|
+
const id = featureIndex.getId(feature, sourceLayer);
|
|
216
|
+
const geojsonFeature = new GeoJSONFeature(feature, z, x, y, id);
|
|
215
217
|
geojsonFeature.tile = coord;
|
|
216
218
|
result.push(geojsonFeature);
|
|
217
219
|
}
|
|
@@ -22,6 +22,7 @@ class VectorTileSource extends Evented {
|
|
|
22
22
|
this.url = options.url;
|
|
23
23
|
this.scheme = options.scheme ?? 'xyz';
|
|
24
24
|
this.tileSize = options.tileSize ?? 512;
|
|
25
|
+
this.promoteId = options.promoteId;
|
|
25
26
|
|
|
26
27
|
if (this.tileSize !== 512) {
|
|
27
28
|
throw new Error('vector tile sources must have a tileSize of 512');
|
|
@@ -93,6 +94,7 @@ class VectorTileSource extends Evented {
|
|
|
93
94
|
source: this.id,
|
|
94
95
|
pixelRatio: browser.devicePixelRatio,
|
|
95
96
|
showCollisionBoxes: this.map.showCollisionBoxes,
|
|
97
|
+
promoteId: this.promoteId,
|
|
96
98
|
painter: this.map.painter
|
|
97
99
|
};
|
|
98
100
|
tile.workerID ??= true;
|
|
@@ -27,7 +27,9 @@ async function makeWorkerTile(params, { layers }, layerIndex, resources) {
|
|
|
27
27
|
const sourceLayerIndex = sourceLayerCoder.encode(sourceLayerId);
|
|
28
28
|
const features = new Array(sourceLayer.length);
|
|
29
29
|
for (let index = 0; index < sourceLayer.length; index++) {
|
|
30
|
-
|
|
30
|
+
const feature = sourceLayer.feature(index);
|
|
31
|
+
const id = options.featureIndex.getId(feature, sourceLayerId);
|
|
32
|
+
features[index] = { feature, id, index, sourceLayerIndex };
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
makeBucketsForSourceLayer(sourceLayerFamilies, sourceLayerIndex, features, params, options);
|
|
@@ -47,7 +49,7 @@ export async function makeSingleSourceLayerWorkerTile(params, features, sourceLa
|
|
|
47
49
|
function initializeBucketsOptions(params) {
|
|
48
50
|
const tileID = createTileID(params);
|
|
49
51
|
|
|
50
|
-
const featureIndex = new FeatureIndex(tileID);
|
|
52
|
+
const featureIndex = params.featureIndex ?? new FeatureIndex(tileID, params.promoteId);
|
|
51
53
|
featureIndex.bucketLayerIDs = [];
|
|
52
54
|
|
|
53
55
|
return {
|
|
@@ -2,27 +2,59 @@ import { Placement } from '../symbol/placement.js';
|
|
|
2
2
|
import browser from '../util/browser.js';
|
|
3
3
|
|
|
4
4
|
class LayerPlacement {
|
|
5
|
-
constructor() {
|
|
5
|
+
constructor(styleLayer) {
|
|
6
|
+
this._sortAcrossTiles =
|
|
7
|
+
styleLayer._layout.get('symbol-z-order') !== 'viewport-y' &&
|
|
8
|
+
styleLayer._layout.get('symbol-sort-key').constantOr(1) !== undefined;
|
|
9
|
+
|
|
6
10
|
this._currentTileIndex = 0;
|
|
11
|
+
this._currentPartIndex = 0;
|
|
7
12
|
this._seenCrossTileIDs = {};
|
|
13
|
+
this._bucketParts = [];
|
|
8
14
|
}
|
|
9
15
|
|
|
10
16
|
continuePlacement(tiles, placement, showCollisionBoxes, styleLayer, shouldPausePlacement) {
|
|
17
|
+
const bucketParts = this._bucketParts;
|
|
18
|
+
|
|
11
19
|
while (this._currentTileIndex < tiles.length) {
|
|
12
20
|
const tile = tiles[this._currentTileIndex];
|
|
13
|
-
placement.
|
|
21
|
+
placement.getBucketParts(bucketParts, styleLayer, tile, this._sortAcrossTiles);
|
|
14
22
|
|
|
15
23
|
this._currentTileIndex++;
|
|
16
24
|
if (shouldPausePlacement()) {
|
|
17
25
|
return true;
|
|
18
26
|
}
|
|
19
27
|
}
|
|
28
|
+
|
|
29
|
+
if (this._sortAcrossTiles) {
|
|
30
|
+
this._sortAcrossTiles = false;
|
|
31
|
+
bucketParts.sort((a, b) => a.sortKey - b.sortKey);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
while (this._currentPartIndex < bucketParts.length) {
|
|
35
|
+
const bucketPart = bucketParts[this._currentPartIndex];
|
|
36
|
+
placement.placeLayerBucketPart(bucketPart, this._seenCrossTileIDs, showCollisionBoxes);
|
|
37
|
+
|
|
38
|
+
this._currentPartIndex++;
|
|
39
|
+
if (shouldPausePlacement()) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
20
44
|
}
|
|
21
45
|
}
|
|
22
46
|
|
|
23
47
|
class PauseablePlacement {
|
|
24
|
-
constructor(
|
|
25
|
-
|
|
48
|
+
constructor(
|
|
49
|
+
transform,
|
|
50
|
+
maxIndex,
|
|
51
|
+
forceFullPlacement,
|
|
52
|
+
showCollisionBoxes,
|
|
53
|
+
fadeDuration,
|
|
54
|
+
crossSourceCollisions,
|
|
55
|
+
prevPlacement
|
|
56
|
+
) {
|
|
57
|
+
this.placement = new Placement(transform, fadeDuration, crossSourceCollisions, prevPlacement);
|
|
26
58
|
this._currentPlacementIndex = maxIndex;
|
|
27
59
|
this._forceFullPlacement = forceFullPlacement;
|
|
28
60
|
this._showCollisionBoxes = showCollisionBoxes;
|
|
@@ -50,7 +82,7 @@ class PauseablePlacement {
|
|
|
50
82
|
(!layer.maxzoom || layer.maxzoom > placementZoom)
|
|
51
83
|
) {
|
|
52
84
|
if (!this._inProgressLayer) {
|
|
53
|
-
this._inProgressLayer = new LayerPlacement();
|
|
85
|
+
this._inProgressLayer = new LayerPlacement(layer);
|
|
54
86
|
}
|
|
55
87
|
|
|
56
88
|
const pausePlacement = this._inProgressLayer.continuePlacement(
|
|
@@ -77,8 +109,8 @@ class PauseablePlacement {
|
|
|
77
109
|
this._done = true;
|
|
78
110
|
}
|
|
79
111
|
|
|
80
|
-
commit(
|
|
81
|
-
this.placement.commit(
|
|
112
|
+
commit(now) {
|
|
113
|
+
this.placement.commit(now);
|
|
82
114
|
return this.placement;
|
|
83
115
|
}
|
|
84
116
|
}
|
package/src/style/style.js
CHANGED
|
@@ -41,6 +41,7 @@ class Style extends Evented {
|
|
|
41
41
|
loadGlyphRange: this.loadGlyphRange.bind(this)
|
|
42
42
|
});
|
|
43
43
|
#layerIndex = new StyleLayerIndex();
|
|
44
|
+
#opsQueue = [];
|
|
44
45
|
|
|
45
46
|
constructor(map, options = {}) {
|
|
46
47
|
super();
|
|
@@ -89,7 +90,10 @@ class Style extends Evented {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
setGlobalStateProperty(name, value) {
|
|
92
|
-
this.
|
|
93
|
+
if (!this._loaded) {
|
|
94
|
+
this.#opsQueue.push(() => this.setGlobalStateProperty(name, value));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
93
97
|
|
|
94
98
|
const newValue = value === null ? (this.stylesheet.state?.[name]?.default ?? null) : value;
|
|
95
99
|
|
|
@@ -107,7 +111,10 @@ class Style extends Evented {
|
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
setGlobalState(newStylesheetState) {
|
|
110
|
-
this.
|
|
114
|
+
if (!this._loaded) {
|
|
115
|
+
this.#opsQueue.push(() => this.setGlobalState(newStylesheetState));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
111
118
|
|
|
112
119
|
const changedGlobalStateRefs = [];
|
|
113
120
|
|
|
@@ -225,6 +232,9 @@ class Style extends Evented {
|
|
|
225
232
|
this.light = this.stylesheet.light;
|
|
226
233
|
this._light = new Light(this.light);
|
|
227
234
|
|
|
235
|
+
this.#opsQueue.forEach(op => op());
|
|
236
|
+
this.#opsQueue = [];
|
|
237
|
+
|
|
228
238
|
this.fire(new Event('data', { dataType: 'style' }));
|
|
229
239
|
this.fire(new Event('style.load'));
|
|
230
240
|
}
|
|
@@ -301,12 +311,6 @@ class Style extends Evented {
|
|
|
301
311
|
return false;
|
|
302
312
|
}
|
|
303
313
|
|
|
304
|
-
_checkLoaded() {
|
|
305
|
-
if (!this._loaded) {
|
|
306
|
-
throw new Error('Style is not done loading');
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
314
|
/**
|
|
311
315
|
* Apply queued style updates in a batch and recalculate zoom-dependent paint properties.
|
|
312
316
|
*/
|
|
@@ -390,13 +394,18 @@ class Style extends Evented {
|
|
|
390
394
|
}
|
|
391
395
|
|
|
392
396
|
listImages() {
|
|
393
|
-
this.
|
|
397
|
+
if (!this._loaded) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
394
400
|
|
|
395
401
|
return this.imageManager.listImages();
|
|
396
402
|
}
|
|
397
403
|
|
|
398
404
|
addSource(id, source) {
|
|
399
|
-
this.
|
|
405
|
+
if (!this._loaded) {
|
|
406
|
+
this.#opsQueue.push(() => this.addSource(id, source));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
400
409
|
|
|
401
410
|
if (this._sources[id] !== undefined) {
|
|
402
411
|
throw new Error('There is already a source with this ID');
|
|
@@ -432,7 +441,10 @@ class Style extends Evented {
|
|
|
432
441
|
* @throws {Error} if no source is found with the given ID
|
|
433
442
|
*/
|
|
434
443
|
removeSource(id) {
|
|
435
|
-
this.
|
|
444
|
+
if (!this._loaded) {
|
|
445
|
+
this.#opsQueue.push(() => this.removeSource(id));
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
436
448
|
|
|
437
449
|
if (this._sources[id] === undefined) {
|
|
438
450
|
throw new Error('There is no source with this ID');
|
|
@@ -464,7 +476,10 @@ class Style extends Evented {
|
|
|
464
476
|
* @param {GeoJSON|string} data GeoJSON source
|
|
465
477
|
*/
|
|
466
478
|
setGeoJSONSourceData(id, data) {
|
|
467
|
-
this.
|
|
479
|
+
if (!this._loaded) {
|
|
480
|
+
this.#opsQueue.push(() => this.setGeoJSONSourceData(id, data));
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
468
483
|
|
|
469
484
|
assert(this._sources[id] !== undefined, 'There is no source with this ID');
|
|
470
485
|
const geojsonSource = this._sources[id].getSource();
|
|
@@ -519,7 +534,10 @@ class Style extends Evented {
|
|
|
519
534
|
* @param {string} [before] ID of an existing layer to insert before
|
|
520
535
|
*/
|
|
521
536
|
addLayer(layerObject, before) {
|
|
522
|
-
this.
|
|
537
|
+
if (!this._loaded) {
|
|
538
|
+
this.#opsQueue.push(() => this.addLayer(layerObject, before));
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
523
541
|
|
|
524
542
|
const id = layerObject.id;
|
|
525
543
|
|
|
@@ -568,7 +586,10 @@ class Style extends Evented {
|
|
|
568
586
|
* @param {string} [before] ID of an existing layer to insert before
|
|
569
587
|
*/
|
|
570
588
|
moveLayer(id, before) {
|
|
571
|
-
this.
|
|
589
|
+
if (!this._loaded) {
|
|
590
|
+
this.#opsQueue.push(() => this.moveLayer(id, before));
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
572
593
|
this._changed = true;
|
|
573
594
|
|
|
574
595
|
const layer = this._layers.get(id);
|
|
@@ -593,7 +614,10 @@ class Style extends Evented {
|
|
|
593
614
|
* @fires error
|
|
594
615
|
*/
|
|
595
616
|
removeLayer(id) {
|
|
596
|
-
this.
|
|
617
|
+
if (!this._loaded) {
|
|
618
|
+
this.#opsQueue.push(() => this.removeLayer(id));
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
597
621
|
|
|
598
622
|
const layer = this._layers.get(id);
|
|
599
623
|
if (!layer) {
|
|
@@ -624,7 +648,10 @@ class Style extends Evented {
|
|
|
624
648
|
}
|
|
625
649
|
|
|
626
650
|
setLayerZoomRange(layerId, minzoom, maxzoom) {
|
|
627
|
-
this.
|
|
651
|
+
if (!this._loaded) {
|
|
652
|
+
this.#opsQueue.push(() => this.setLayerZoomRange(layerId, minzoom, maxzoom));
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
628
655
|
|
|
629
656
|
const layer = this.getLayer(layerId);
|
|
630
657
|
if (!layer) {
|
|
@@ -646,7 +673,10 @@ class Style extends Evented {
|
|
|
646
673
|
}
|
|
647
674
|
|
|
648
675
|
setFilter(layerId, filter) {
|
|
649
|
-
this.
|
|
676
|
+
if (!this._loaded) {
|
|
677
|
+
this.#opsQueue.push(() => this.setFilter(layerId, filter));
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
650
680
|
|
|
651
681
|
const layer = this.getLayer(layerId);
|
|
652
682
|
if (!layer) {
|
|
@@ -680,7 +710,10 @@ class Style extends Evented {
|
|
|
680
710
|
}
|
|
681
711
|
|
|
682
712
|
setLayoutProperty(layerId, name, value) {
|
|
683
|
-
this.
|
|
713
|
+
if (!this._loaded) {
|
|
714
|
+
this.#opsQueue.push(() => this.setLayoutProperty(layerId, name, value));
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
684
717
|
|
|
685
718
|
const layer = this.getLayer(layerId);
|
|
686
719
|
if (!layer) {
|
|
@@ -713,7 +746,10 @@ class Style extends Evented {
|
|
|
713
746
|
}
|
|
714
747
|
|
|
715
748
|
setPaintProperty(layerId, name, value) {
|
|
716
|
-
this.
|
|
749
|
+
if (!this._loaded) {
|
|
750
|
+
this.#opsQueue.push(() => this.setPaintProperty(layerId, name, value));
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
717
753
|
|
|
718
754
|
const layer = this.getLayer(layerId);
|
|
719
755
|
if (!layer) {
|
|
@@ -748,10 +784,13 @@ class Style extends Evented {
|
|
|
748
784
|
return this.getLayer(layer).getPaintProperty(name);
|
|
749
785
|
}
|
|
750
786
|
|
|
751
|
-
setFeatureState(
|
|
752
|
-
this.
|
|
753
|
-
|
|
754
|
-
|
|
787
|
+
setFeatureState(target, state) {
|
|
788
|
+
if (!this._loaded) {
|
|
789
|
+
this.#opsQueue.push(() => this.setFeatureState(target, state));
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
const sourceId = target.source;
|
|
793
|
+
const sourceLayer = target.sourceLayer;
|
|
755
794
|
const sourceCache = this._sources[sourceId];
|
|
756
795
|
|
|
757
796
|
if (sourceCache === undefined) {
|
|
@@ -767,16 +806,19 @@ class Style extends Evented {
|
|
|
767
806
|
this.fire(new ErrorEvent(new Error('The sourceLayer parameter must be provided for vector source types.')));
|
|
768
807
|
return;
|
|
769
808
|
}
|
|
770
|
-
if (
|
|
809
|
+
if (target.id === undefined) {
|
|
771
810
|
this.fire(new ErrorEvent(new Error('The feature id parameter must be provided.')));
|
|
772
811
|
return;
|
|
773
812
|
}
|
|
774
813
|
|
|
775
|
-
sourceCache.setFeatureState(sourceLayer,
|
|
814
|
+
sourceCache.setFeatureState(sourceLayer, target.id, state);
|
|
776
815
|
}
|
|
777
816
|
|
|
778
817
|
removeFeatureState(target, key) {
|
|
779
|
-
this.
|
|
818
|
+
if (!this._loaded) {
|
|
819
|
+
this.#opsQueue.push(() => this.removeFeatureState(target, key));
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
780
822
|
const sourceId = target.source;
|
|
781
823
|
const sourceCache = this._sources[sourceId];
|
|
782
824
|
|
|
@@ -801,10 +843,12 @@ class Style extends Evented {
|
|
|
801
843
|
sourceCache.removeFeatureState(sourceLayer, target.id, key);
|
|
802
844
|
}
|
|
803
845
|
|
|
804
|
-
getFeatureState(
|
|
805
|
-
this.
|
|
806
|
-
|
|
807
|
-
|
|
846
|
+
getFeatureState(target) {
|
|
847
|
+
if (!this._loaded) {
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
const sourceId = target.source;
|
|
851
|
+
const sourceLayer = target.sourceLayer;
|
|
808
852
|
const sourceCache = this._sources[sourceId];
|
|
809
853
|
|
|
810
854
|
if (sourceCache === undefined) {
|
|
@@ -817,7 +861,11 @@ class Style extends Evented {
|
|
|
817
861
|
return;
|
|
818
862
|
}
|
|
819
863
|
|
|
820
|
-
|
|
864
|
+
if (target.id === undefined) {
|
|
865
|
+
this.fire(new ErrorEvent(new Error('The feature id parameter must be provided.')));
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
return sourceCache.getFeatureState(sourceLayer, target.id);
|
|
821
869
|
}
|
|
822
870
|
|
|
823
871
|
getTransition() {
|
|
@@ -962,7 +1010,10 @@ class Style extends Evented {
|
|
|
962
1010
|
}
|
|
963
1011
|
|
|
964
1012
|
setLight(lightOptions) {
|
|
965
|
-
this.
|
|
1013
|
+
if (!this._loaded) {
|
|
1014
|
+
this.#opsQueue.push(() => this.setLight(lightOptions));
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
966
1017
|
|
|
967
1018
|
const light = this._light.getLight();
|
|
968
1019
|
let _update = false;
|
|
@@ -1070,7 +1121,8 @@ class Style extends Evented {
|
|
|
1070
1121
|
forceFullPlacement,
|
|
1071
1122
|
showCollisionBoxes,
|
|
1072
1123
|
fadeDuration,
|
|
1073
|
-
crossSourceCollisions
|
|
1124
|
+
crossSourceCollisions,
|
|
1125
|
+
this.placement
|
|
1074
1126
|
);
|
|
1075
1127
|
this._layerOrderChanged = false;
|
|
1076
1128
|
}
|
|
@@ -1085,7 +1137,7 @@ class Style extends Evented {
|
|
|
1085
1137
|
this.pauseablePlacement.continuePlacement(Array.from(this._layers.values()), layerTiles);
|
|
1086
1138
|
|
|
1087
1139
|
if (this.pauseablePlacement.isDone()) {
|
|
1088
|
-
this.placement = this.pauseablePlacement.commit(
|
|
1140
|
+
this.placement = this.pauseablePlacement.commit(browser.now());
|
|
1089
1141
|
placementCommitted = true;
|
|
1090
1142
|
}
|
|
1091
1143
|
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { DataConstantProperty, DataDrivenProperty, Properties } from '../properties.js';
|
|
4
4
|
|
|
5
|
+
const layout = new Properties({
|
|
6
|
+
'circle-sort-key': new DataDrivenProperty({
|
|
7
|
+
type: 'number',
|
|
8
|
+
expression: { parameters: ['zoom', 'feature'] }
|
|
9
|
+
})
|
|
10
|
+
});
|
|
11
|
+
|
|
5
12
|
const paint = new Properties({
|
|
6
13
|
'circle-radius': new DataDrivenProperty({
|
|
7
14
|
type: 'number',
|
|
@@ -73,4 +80,4 @@ const paint = new Properties({
|
|
|
73
80
|
})
|
|
74
81
|
});
|
|
75
82
|
|
|
76
|
-
export default { paint };
|
|
83
|
+
export default { paint, layout };
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { CrossFadedDataDrivenProperty, DataConstantProperty, DataDrivenProperty, Properties } from '../properties.js';
|
|
4
4
|
|
|
5
|
+
const layout = new Properties({
|
|
6
|
+
'fill-sort-key': new DataDrivenProperty({
|
|
7
|
+
type: 'number',
|
|
8
|
+
expression: { parameters: ['zoom', 'feature'] }
|
|
9
|
+
})
|
|
10
|
+
});
|
|
11
|
+
|
|
5
12
|
const paint = new Properties({
|
|
6
13
|
'fill-antialias': new DataConstantProperty({ type: 'boolean', default: true, expression: { parameters: ['zoom'] } }),
|
|
7
14
|
'fill-opacity': new DataDrivenProperty({
|
|
@@ -42,4 +49,4 @@ const paint = new Properties({
|
|
|
42
49
|
})
|
|
43
50
|
});
|
|
44
51
|
|
|
45
|
-
export default { paint };
|
|
52
|
+
export default { paint, layout };
|
|
@@ -31,6 +31,10 @@ const layout = new Properties({
|
|
|
31
31
|
type: 'number',
|
|
32
32
|
default: 1.05,
|
|
33
33
|
expression: { interpolated: true, parameters: ['zoom'] }
|
|
34
|
+
}),
|
|
35
|
+
'line-sort-key': new DataDrivenProperty({
|
|
36
|
+
type: 'number',
|
|
37
|
+
expression: { parameters: ['zoom', 'feature'] }
|
|
34
38
|
})
|
|
35
39
|
});
|
|
36
40
|
const paint = new Properties({
|