isard 1.1.0 → 1.2.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/CHANGELOG.md +33 -0
- package/dist/basemap/basemaps.d.ts +1 -1
- package/dist/basemap/basemaps.js +2 -2
- package/dist/basemap/basemaps.js.map +1 -1
- package/dist/basemap/grid.d.ts +5 -5
- package/dist/basemap/grid.js +59 -65
- package/dist/basemap/grid.js.map +1 -1
- package/dist/basemap/mvt.d.ts +1 -1
- package/dist/basemap/mvt.js +6 -6
- package/dist/basemap/mvt.js.map +1 -1
- package/dist/basemap/pmtiles.d.ts +10 -10
- package/dist/basemap/pmtiles.js +39 -31
- package/dist/basemap/pmtiles.js.map +1 -1
- package/dist/basemap/resample.d.ts +2 -2
- package/dist/basemap/resample.js +16 -14
- package/dist/basemap/resample.js.map +1 -1
- package/dist/basemap/terrain.d.ts +3 -3
- package/dist/basemap/terrain.js +6 -6
- package/dist/basemap/terrain.js.map +1 -1
- package/dist/basemap/vectorstyle.d.ts +12 -10
- package/dist/basemap/vectorstyle.js +128 -110
- package/dist/basemap/vectorstyle.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +11 -11
- package/dist/basemap/vectortiles.js +141 -103
- package/dist/basemap/vectortiles.js.map +1 -1
- package/dist/basemap/wmts.d.ts +3 -3
- package/dist/basemap/wmts.js +16 -11
- package/dist/basemap/wmts.js.map +1 -1
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +14 -13
- package/dist/bind/layers.d.ts +13 -4
- package/dist/bind/layers.js +64 -40
- package/dist/bind/layers.js.map +1 -1
- package/dist/data/crs.d.ts +10 -10
- package/dist/data/crs.js +38 -34
- package/dist/data/crs.js.map +1 -1
- package/dist/data/gpx.d.ts +1 -1
- package/dist/data/gpx.js +20 -20
- package/dist/data/gpx.js.map +1 -1
- package/dist/data/kml.d.ts +1 -1
- package/dist/data/kml.js +42 -39
- package/dist/data/kml.js.map +1 -1
- package/dist/data/topojson.d.ts +1 -1
- package/dist/data/topojson.js +15 -10
- package/dist/data/topojson.js.map +1 -1
- package/dist/data/xml.d.ts +5 -5
- package/dist/data/xml.js +19 -18
- package/dist/data/xml.js.map +1 -1
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +6 -6
- package/dist/engine/decoders.d.ts +2 -2
- package/dist/engine/decoders.js +28 -25
- package/dist/engine/decoders.js.map +1 -1
- package/dist/engine/loader.js +13 -14
- package/dist/engine/loader.js.map +1 -1
- package/dist/engine/requests.d.ts +1 -1
- package/dist/engine/requests.js +19 -16
- package/dist/engine/requests.js.map +1 -1
- package/dist/engine-loader.d.ts +8 -8
- package/dist/engine-loader.js +27 -27
- package/dist/engine-loader.js.map +1 -1
- package/dist/geoplateforme.d.ts +10 -10
- package/dist/geoplateforme.js +22 -20
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_points_bg.wasm +0 -0
- package/dist/layers/extrusions.d.ts +1 -1
- package/dist/layers/extrusions.js +10 -5
- package/dist/layers/extrusions.js.map +1 -1
- package/dist/layers/features.d.ts +10 -10
- package/dist/layers/features.js +41 -42
- package/dist/layers/features.js.map +1 -1
- package/dist/layers/glyphs.d.ts +3 -3
- package/dist/layers/glyphs.js +34 -40
- package/dist/layers/glyphs.js.map +1 -1
- package/dist/layers/icons.d.ts +8 -8
- package/dist/layers/icons.js +76 -68
- package/dist/layers/icons.js.map +1 -1
- package/dist/layers/layers.d.ts +1 -1
- package/dist/layers/layers.js +33 -29
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/panoramas.d.ts +2 -2
- package/dist/layers/panoramas.js +52 -41
- package/dist/layers/panoramas.js.map +1 -1
- package/dist/layers/pointclouds.d.ts +3 -3
- package/dist/layers/pointclouds.js +25 -33
- package/dist/layers/pointclouds.js.map +1 -1
- package/dist/layers/symbols.d.ts +1 -1
- package/dist/layers/symbols.js +68 -71
- package/dist/layers/symbols.js.map +1 -1
- package/dist/map/basemap-layers.d.ts +26 -0
- package/dist/map/basemap-layers.js +61 -0
- package/dist/map/basemap-layers.js.map +1 -0
- package/dist/map/canvas.d.ts +17 -0
- package/dist/map/canvas.js +56 -0
- package/dist/map/canvas.js.map +1 -0
- package/dist/map/checks.d.ts +11 -0
- package/dist/map/checks.js +39 -0
- package/dist/map/checks.js.map +1 -0
- package/dist/map/credits.d.ts +17 -0
- package/dist/map/credits.js +34 -0
- package/dist/map/credits.js.map +1 -0
- package/dist/map/engine-settings.d.ts +15 -0
- package/dist/map/engine-settings.js +45 -0
- package/dist/map/engine-settings.js.map +1 -0
- package/dist/map/engines.d.ts +41 -0
- package/dist/map/engines.js +77 -0
- package/dist/map/engines.js.map +1 -0
- package/dist/map/events.d.ts +14 -0
- package/dist/map/events.js +46 -0
- package/dist/map/events.js.map +1 -0
- package/dist/map/frame-loop.d.ts +61 -0
- package/dist/map/frame-loop.js +139 -0
- package/dist/map/frame-loop.js.map +1 -0
- package/dist/map/hover-pick.d.ts +30 -0
- package/dist/map/hover-pick.js +56 -0
- package/dist/map/hover-pick.js.map +1 -0
- package/dist/map/layer-spec.d.ts +42 -0
- package/dist/map/layer-spec.js +34 -0
- package/dist/map/layer-spec.js.map +1 -0
- package/dist/map/layer-stack.d.ts +36 -0
- package/dist/map/layer-stack.js +101 -0
- package/dist/map/layer-stack.js.map +1 -0
- package/dist/map/overlay-host.d.ts +36 -0
- package/dist/map/overlay-host.js +101 -0
- package/dist/map/overlay-host.js.map +1 -0
- package/dist/map/panorama-host.d.ts +5 -0
- package/dist/map/panorama-host.js +32 -0
- package/dist/map/panorama-host.js.map +1 -0
- package/dist/map/raster-source.d.ts +11 -0
- package/dist/map/raster-source.js +26 -0
- package/dist/map/raster-source.js.map +1 -0
- package/dist/map/symbol-atlases.d.ts +26 -0
- package/dist/map/symbol-atlases.js +59 -0
- package/dist/map/symbol-atlases.js.map +1 -0
- package/dist/map/viewshed.d.ts +5 -0
- package/dist/map/viewshed.js +28 -0
- package/dist/map/viewshed.js.map +1 -0
- package/dist/map/workers.d.ts +46 -0
- package/dist/map/workers.js +73 -0
- package/dist/map/workers.js.map +1 -0
- package/dist/map.d.ts +33 -120
- package/dist/map.js +164 -689
- package/dist/map.js.map +1 -1
- package/dist/react/Control.d.ts +11 -0
- package/dist/react/Control.js +18 -0
- package/dist/react/Control.js.map +1 -0
- package/dist/react/CustomLayer.d.ts +11 -0
- package/dist/react/CustomLayer.js +30 -0
- package/dist/react/CustomLayer.js.map +1 -0
- package/dist/react/IsardMap.d.ts +43 -0
- package/dist/react/IsardMap.js +146 -0
- package/dist/react/IsardMap.js.map +1 -0
- package/dist/react/Layer.d.ts +42 -0
- package/dist/react/Layer.js +74 -0
- package/dist/react/Layer.js.map +1 -0
- package/dist/react/Marker.d.ts +24 -0
- package/dist/react/Marker.js +53 -0
- package/dist/react/Marker.js.map +1 -0
- package/dist/react/Panel.d.ts +11 -0
- package/dist/react/Panel.js +37 -0
- package/dist/react/Panel.js.map +1 -0
- package/dist/react/Popup.d.ts +18 -0
- package/dist/react/Popup.js +60 -0
- package/dist/react/Popup.js.map +1 -0
- package/dist/react/Swipe.d.ts +9 -0
- package/dist/react/Swipe.js +41 -0
- package/dist/react/Swipe.js.map +1 -0
- package/dist/react/Viewshed.d.ts +5 -0
- package/dist/react/Viewshed.js +28 -0
- package/dist/react/Viewshed.js.map +1 -0
- package/dist/react/context.d.ts +32 -0
- package/dist/react/context.js +20 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/index.d.ts +15 -108
- package/dist/react/index.js +10 -397
- package/dist/react/index.js.map +1 -1
- package/dist/settings.d.ts +5 -9
- package/dist/settings.js +17 -15
- package/dist/settings.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.js.map +1 -1
- package/dist/ui/controls.js +6 -4
- package/dist/ui/controls.js.map +1 -1
- package/dist/ui/interaction.d.ts +2 -2
- package/dist/ui/interaction.js +8 -7
- package/dist/ui/interaction.js.map +1 -1
- package/dist/ui/overlay.js +18 -20
- package/dist/ui/overlay.js.map +1 -1
- package/dist/ui/style.d.ts +1 -1
- package/dist/ui/style.js +2 -2
- package/dist/ui/style.js.map +1 -1
- package/dist/util/animation.d.ts +3 -3
- package/dist/util/animation.js +6 -6
- package/dist/util/animation.js.map +1 -1
- package/dist/util/color.d.ts +1 -1
- package/dist/util/color.js +14 -16
- package/dist/util/color.js.map +1 -1
- package/dist/util/geo.d.ts +6 -6
- package/dist/util/geo.js +12 -12
- package/dist/util/geo.js.map +1 -1
- package/dist/util/guards.d.ts +7 -0
- package/dist/util/guards.js +8 -0
- package/dist/util/guards.js.map +1 -0
- package/dist/util/lru.js.map +1 -1
- package/dist/wasm/isard.d.ts +168 -0
- package/dist/wasm/isard.js +146 -0
- package/dist/wasm/isard_core.d.ts +144 -0
- package/dist/wasm/isard_core.js +122 -0
- package/dist/workers/basemap.worker.d.ts +3 -3
- package/dist/workers/basemap.worker.js +94 -83
- package/dist/workers/basemap.worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,14 +17,11 @@ import { setHeaderRules, withHeaders } from "../engine/requests.js";
|
|
|
17
17
|
import { latitude, longitude } from "../util/geo.js";
|
|
18
18
|
import { Lru } from "../util/lru.js";
|
|
19
19
|
/** An image of the sprites and its sheet */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
return undefined;
|
|
27
|
-
}
|
|
20
|
+
const spriteIcon = (r, name) => {
|
|
21
|
+
const sprite = r.sprites.find((sp) => Boolean(sp.icons[name]));
|
|
22
|
+
const icon = sprite?.icons[name];
|
|
23
|
+
return sprite && icon ? { icon, image: sprite.image } : undefined;
|
|
24
|
+
};
|
|
28
25
|
const renderers = new Map();
|
|
29
26
|
/** Decoded tiles kept by the pool, shared among its workers (a vector tile always goes to the same worker): some
|
|
30
27
|
* 2 MB each */
|
|
@@ -32,9 +29,9 @@ const CACHE = 96;
|
|
|
32
29
|
/** Decoded tiles by URL; this worker's share of them, set by the renderers */
|
|
33
30
|
const cache = new Lru(CACHE);
|
|
34
31
|
/** The decoded tiles one worker of `workers` keeps */
|
|
35
|
-
export
|
|
32
|
+
export const cacheShare = (workers) => {
|
|
36
33
|
return Math.max(16, Math.ceil(CACHE / Math.max(1, workers)));
|
|
37
|
-
}
|
|
34
|
+
};
|
|
38
35
|
/** Requests in progress, and those of them aborted (both forgotten once answered) */
|
|
39
36
|
const active = new Set();
|
|
40
37
|
const aborted = new Set();
|
|
@@ -48,7 +45,7 @@ const reprojection = resampler();
|
|
|
48
45
|
* drawn it (they draw without awaiting again) */
|
|
49
46
|
const images = new Lru(64, (evicted) => evicted.then((bitmap) => setTimeout(() => bitmap?.close(), 0), () => undefined));
|
|
50
47
|
/** An image of a raster source (shared by every renderer); undefined where the source has none */
|
|
51
|
-
|
|
48
|
+
const image = (url, priority = 'auto') => {
|
|
52
49
|
const hit = images.get(url);
|
|
53
50
|
if (hit)
|
|
54
51
|
return hit;
|
|
@@ -70,9 +67,9 @@ function image(url, priority = 'auto') {
|
|
|
70
67
|
pending.catch(() => images.delete(url));
|
|
71
68
|
images.set(url, pending);
|
|
72
69
|
return pending;
|
|
73
|
-
}
|
|
70
|
+
};
|
|
74
71
|
/** A vector tile, decoded (shared by every renderer of its URL); the first request's priority fetches it */
|
|
75
|
-
|
|
72
|
+
const tile = (url, priority = 'auto') => {
|
|
76
73
|
const hit = cache.get(url);
|
|
77
74
|
if (hit)
|
|
78
75
|
return hit;
|
|
@@ -100,9 +97,9 @@ function tile(url, priority = 'auto') {
|
|
|
100
97
|
pending.catch(() => cache.delete(url));
|
|
101
98
|
cache.set(url, pending);
|
|
102
99
|
return pending;
|
|
103
|
-
}
|
|
100
|
+
};
|
|
104
101
|
/** The vector tile to draw a raster tile from, and where the raster tile lies in it (tile units) */
|
|
105
|
-
|
|
102
|
+
const source = (r, z, x, y) => {
|
|
106
103
|
const vz = Math.max(0, Math.min(z - 1, r.maxzoom));
|
|
107
104
|
const d = z - vz;
|
|
108
105
|
const n = 2 ** Math.max(0, d);
|
|
@@ -111,7 +108,7 @@ function source(r, z, x, y) {
|
|
|
111
108
|
// Fraction of the vector tile covered, and the offset in it
|
|
112
109
|
const part = 1 / n;
|
|
113
110
|
return { url, vz, vx, vy, part, ox: (x % n) * part, oy: (y % n) * part };
|
|
114
|
-
}
|
|
111
|
+
};
|
|
115
112
|
const value = (layer, group, key, ctx, fallback) => {
|
|
116
113
|
const v = layer[group]?.[key];
|
|
117
114
|
if (v === undefined)
|
|
@@ -121,35 +118,46 @@ const value = (layer, group, key, ctx, fallback) => {
|
|
|
121
118
|
return out === undefined || out === null ? fallback : out;
|
|
122
119
|
};
|
|
123
120
|
/** A color with an opacity, for the canvas */
|
|
124
|
-
|
|
121
|
+
const paint = (c, opacity) => {
|
|
125
122
|
const rgba = color(c) ?? [0, 0, 0, 1];
|
|
126
123
|
return css([rgba[0], rgba[1], rgba[2], rgba[3] * opacity]);
|
|
127
|
-
}
|
|
128
|
-
|
|
124
|
+
};
|
|
125
|
+
const shown = (layer, zoom) => {
|
|
129
126
|
if (layer.layout?.visibility === 'none')
|
|
130
127
|
return false;
|
|
131
128
|
return zoom >= (layer.minzoom ?? 0) && zoom < (layer.maxzoom ?? 24);
|
|
132
|
-
}
|
|
129
|
+
};
|
|
130
|
+
const LINE_CAPS = new Set(['butt', 'round', 'square']);
|
|
131
|
+
const LINE_JOINS = new Set(['bevel', 'miter', 'round']);
|
|
132
|
+
const isLineCap = (value) => LINE_CAPS.has(value);
|
|
133
|
+
const isLineJoin = (value) => LINE_JOINS.has(value);
|
|
134
|
+
/** A style's `line-cap` for the canvas: `butt` if it is none */
|
|
135
|
+
const lineCap = (value) => (isLineCap(value) ? value : 'butt');
|
|
136
|
+
/** A style's `line-join` for the canvas: `miter` if it is none */
|
|
137
|
+
const lineJoin = (value) => (isLineJoin(value) ? value : 'miter');
|
|
133
138
|
/** The image of a fill pattern, cut from the sprite on first use */
|
|
134
|
-
|
|
139
|
+
const patternImage = (r, name) => {
|
|
135
140
|
if (r.patterns.has(name))
|
|
136
141
|
return r.patterns.get(name);
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
const cut = () => {
|
|
143
|
+
const found = spriteIcon(r, name);
|
|
144
|
+
if (!found || !(found.icon.width > 0) || !(found.icon.height > 0))
|
|
145
|
+
return undefined;
|
|
140
146
|
const { icon } = found;
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
const canvas = new OffscreenCanvas(icon.width, icon.height);
|
|
148
|
+
canvas
|
|
143
149
|
.getContext('2d')
|
|
144
150
|
?.drawImage(found.image, icon.x, icon.y, icon.width, icon.height, 0, 0, icon.width, icon.height);
|
|
145
|
-
|
|
151
|
+
return canvas;
|
|
152
|
+
};
|
|
153
|
+
const image = cut();
|
|
146
154
|
r.patterns.set(name, image);
|
|
147
155
|
return image;
|
|
148
|
-
}
|
|
156
|
+
};
|
|
149
157
|
/** Canvases free for the next tiles, by size: one per tile being drawn at most */
|
|
150
158
|
const canvases = new Map();
|
|
151
159
|
/** A blank canvas of `size` pixels and its context, from the free ones if any */
|
|
152
|
-
|
|
160
|
+
const takeCanvas = (size) => {
|
|
153
161
|
const canvas = canvases.get(size)?.pop() ?? new OffscreenCanvas(size, size);
|
|
154
162
|
// A canvas on the CPU: its pixels are read back here, in the worker, not on the main thread at the upload
|
|
155
163
|
const g = canvas.getContext('2d', { willReadFrequently: true });
|
|
@@ -161,24 +169,24 @@ function takeCanvas(size) {
|
|
|
161
169
|
g.setLineDash([]);
|
|
162
170
|
g.clearRect(0, 0, size, size);
|
|
163
171
|
return { canvas, g };
|
|
164
|
-
}
|
|
165
|
-
|
|
172
|
+
};
|
|
173
|
+
const giveCanvas = (canvas) => {
|
|
166
174
|
const free = canvases.get(canvas.width) ?? [];
|
|
167
175
|
canvases.set(canvas.width, free);
|
|
168
176
|
if (free.length < 4)
|
|
169
177
|
free.push(canvas);
|
|
170
|
-
}
|
|
178
|
+
};
|
|
171
179
|
/**
|
|
172
180
|
* The image of a drawn canvas, its alpha straight (the engine blends straight alpha). An opaque tile (a background
|
|
173
181
|
* of full opacity, as a basemap's) is moved out of the canvas as it is, premultiplied and straight being the same
|
|
174
182
|
* there; another one is read back unpremultiplied, copied
|
|
175
183
|
*/
|
|
176
|
-
export
|
|
184
|
+
export const tileImage = (canvas, g, opaque) => {
|
|
177
185
|
if (opaque)
|
|
178
186
|
return Promise.resolve(canvas.transferToImageBitmap());
|
|
179
187
|
return createImageBitmap(g.getImageData(0, 0, canvas.width, canvas.height), { premultiplyAlpha: 'none' });
|
|
180
|
-
}
|
|
181
|
-
async
|
|
188
|
+
};
|
|
189
|
+
const render = async (r, z, x, y, size, id, priority) => {
|
|
182
190
|
const s = source(r, z, x, y);
|
|
183
191
|
const layers = await tile(s.url, priority);
|
|
184
192
|
if (aborted.has(id))
|
|
@@ -190,8 +198,8 @@ async function render(r, z, x, y, size, id, priority) {
|
|
|
190
198
|
finally {
|
|
191
199
|
giveCanvas(canvas);
|
|
192
200
|
}
|
|
193
|
-
}
|
|
194
|
-
async
|
|
201
|
+
};
|
|
202
|
+
const draw = async (r, s, layers, canvas, g, z, x, y, size, id, priority) => {
|
|
195
203
|
const zoom = Math.max(0, z - 1);
|
|
196
204
|
// CSS pixels to canvas pixels: the tile is 256 CSS pixels across at its zoom
|
|
197
205
|
const px = size / 256;
|
|
@@ -258,11 +266,10 @@ async function draw(r, s, layers, canvas, g, z, x, y, size, id, priority) {
|
|
|
258
266
|
// Values that only depend on the zoom are evaluated once for the layer
|
|
259
267
|
const dependent = new Map();
|
|
260
268
|
const get = (group, key, ctx, fallback) => {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
269
|
+
const known = dependent.get(key);
|
|
270
|
+
const d = known ?? isFeatureDependent(layer[group]?.[key]);
|
|
271
|
+
if (known === undefined)
|
|
264
272
|
dependent.set(key, d);
|
|
265
|
-
}
|
|
266
273
|
return value(layer, group, key, d ? ctx : zctx, fallback);
|
|
267
274
|
};
|
|
268
275
|
for (const f of data.features) {
|
|
@@ -281,7 +288,7 @@ async function draw(r, s, layers, canvas, g, z, x, y, size, id, priority) {
|
|
|
281
288
|
const pattern = get('paint', 'fill-pattern', ctx, undefined);
|
|
282
289
|
path(f, true);
|
|
283
290
|
const icon = typeof pattern === 'string' ? spriteIcon(r, pattern)?.icon : undefined;
|
|
284
|
-
const image = icon && patternImage(r, pattern);
|
|
291
|
+
const image = icon && typeof pattern === 'string' && patternImage(r, pattern);
|
|
285
292
|
if (icon && image) {
|
|
286
293
|
const p = g.createPattern(image, 'repeat');
|
|
287
294
|
if (p) {
|
|
@@ -313,8 +320,8 @@ async function draw(r, s, layers, canvas, g, z, x, y, size, id, priority) {
|
|
|
313
320
|
const gap = Number(get('paint', 'line-gap-width', ctx, 0));
|
|
314
321
|
g.strokeStyle = paint(get('paint', 'line-color', ctx, '#000'), Number(get('paint', 'line-opacity', ctx, 1)));
|
|
315
322
|
g.lineWidth = (gap > 0 ? gap + 2 * width : width) * px;
|
|
316
|
-
g.lineCap =
|
|
317
|
-
g.lineJoin =
|
|
323
|
+
g.lineCap = lineCap(get('layout', 'line-cap', ctx, 'butt'));
|
|
324
|
+
g.lineJoin = lineJoin(get('layout', 'line-join', ctx, 'miter'));
|
|
318
325
|
const dash = get('paint', 'line-dasharray', ctx, undefined);
|
|
319
326
|
g.setLineDash(Array.isArray(dash) ? dash.map((d) => Number(d) * width * px) : []);
|
|
320
327
|
path(f, f.type === 3);
|
|
@@ -343,9 +350,9 @@ async function draw(r, s, layers, canvas, g, z, x, y, size, id, priority) {
|
|
|
343
350
|
if (!drawn && !layers)
|
|
344
351
|
return null;
|
|
345
352
|
return tileImage(canvas, g, opaque);
|
|
346
|
-
}
|
|
353
|
+
};
|
|
347
354
|
/** How a layer's text or icon (`prefix`) meets the others: allowed to overlap, ignored by the placement */
|
|
348
|
-
|
|
355
|
+
const overlapOf = (layer, prefix, ctx) => {
|
|
349
356
|
const allow = Boolean(value(layer, 'layout', `${prefix}-allow-overlap`, ctx, false));
|
|
350
357
|
const ignore = Boolean(value(layer, 'layout', `${prefix}-ignore-placement`, ctx, false));
|
|
351
358
|
if (allow && ignore)
|
|
@@ -353,20 +360,28 @@ function overlapOf(layer, prefix, ctx) {
|
|
|
353
360
|
if (allow)
|
|
354
361
|
return 'allow';
|
|
355
362
|
return ignore ? 'ignore' : false;
|
|
356
|
-
}
|
|
363
|
+
};
|
|
357
364
|
/** A pair of numbers of a style value, `fallback` if it is not one */
|
|
358
|
-
|
|
365
|
+
const pair = (v, fallback) => {
|
|
359
366
|
return Array.isArray(v) ? [Number(v[0] ?? fallback[0]), Number(v[1] ?? fallback[1])] : fallback;
|
|
360
|
-
}
|
|
367
|
+
};
|
|
361
368
|
/** Top, right, bottom, left of one to four numbers, as CSS's sides */
|
|
362
|
-
|
|
369
|
+
const sides = (v) => {
|
|
363
370
|
const n = (Array.isArray(v) ? v : [v]).map((x) => Number(x) || 0);
|
|
364
371
|
const [top = 0, right = top, bottom = top, left = right] = n;
|
|
365
372
|
return [top, right, bottom, left];
|
|
366
|
-
}
|
|
373
|
+
};
|
|
374
|
+
/** A label's text in the case of its `text-transform` */
|
|
375
|
+
const cased = (t, transform) => {
|
|
376
|
+
if (transform === 'uppercase')
|
|
377
|
+
return t.toUpperCase();
|
|
378
|
+
if (transform === 'lowercase')
|
|
379
|
+
return t.toLowerCase();
|
|
380
|
+
return t;
|
|
381
|
+
};
|
|
367
382
|
/** Points every `spacing` along a line (tile units, x and y interleaved), the first half a spacing in (the middle of a
|
|
368
383
|
* shorter line): each point and the segment it lies on (x, y, x0, y0, x1, y1) */
|
|
369
|
-
export
|
|
384
|
+
export const lineAnchors = (line, spacing) => {
|
|
370
385
|
let length = 0;
|
|
371
386
|
for (let i = 2; i + 1 < line.length; i += 2) {
|
|
372
387
|
length += Math.hypot((line[i] ?? 0) - (line[i - 2] ?? 0), (line[i + 1] ?? 0) - (line[i - 1] ?? 0));
|
|
@@ -387,14 +402,14 @@ export function lineAnchors(line, spacing) {
|
|
|
387
402
|
walked += d;
|
|
388
403
|
}
|
|
389
404
|
return out;
|
|
390
|
-
}
|
|
405
|
+
};
|
|
391
406
|
/** Longitude and latitude of a point of tile (z, x, y) in tile units */
|
|
392
|
-
|
|
407
|
+
const lonLat = (z, x, y, extent, px, py) => {
|
|
393
408
|
const n = 2 ** z;
|
|
394
409
|
return [longitude((x + px / extent) / n), latitude((y + py / extent) / n)];
|
|
395
|
-
}
|
|
410
|
+
};
|
|
396
411
|
/** The icon of a label: its layer's icon properties for the feature */
|
|
397
|
-
|
|
412
|
+
const iconOf = (layer, image, ctx, placement, sizeOf) => {
|
|
398
413
|
const alignment = value(layer, 'layout', 'icon-rotation-alignment', ctx, 'auto');
|
|
399
414
|
const fit = String(value(layer, 'layout', 'icon-text-fit', ctx, 'none'));
|
|
400
415
|
const padding = value(layer, 'layout', 'icon-text-fit-padding', ctx, [0, 0, 0, 0]);
|
|
@@ -414,8 +429,8 @@ function iconOf(layer, image, ctx, placement, sizeOf) {
|
|
|
414
429
|
color: String(value(layer, 'paint', 'icon-color', ctx, '#000')),
|
|
415
430
|
opacity: Number(value(layer, 'paint', 'icon-opacity', ctx, 1)),
|
|
416
431
|
};
|
|
417
|
-
}
|
|
418
|
-
async
|
|
432
|
+
};
|
|
433
|
+
const labels = async (r, z, x, y, id, priority, zoom = z) => {
|
|
419
434
|
const url = r.tiles.replace('{z}', String(z)).replace('{x}', String(x)).replace('{y}', String(y));
|
|
420
435
|
const layers = await tile(url, priority);
|
|
421
436
|
if (!layers || aborted.has(id))
|
|
@@ -424,23 +439,23 @@ async function labels(r, z, x, y, id, priority, zoom = z) {
|
|
|
424
439
|
// The text size of a layer when it depends on the zoom only: legacy stops as they are, an expression as stops
|
|
425
440
|
const sizes = new Map();
|
|
426
441
|
const sizeOf = (layer) => {
|
|
427
|
-
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
442
|
+
const known = sizes.get(layer);
|
|
443
|
+
if (known !== undefined)
|
|
444
|
+
return known;
|
|
445
|
+
const v = layer.layout?.['text-size'] ?? 16;
|
|
446
|
+
const s = isExpression(v) ? zoomStops(v) : v;
|
|
447
|
+
sizes.set(layer, s);
|
|
433
448
|
return s;
|
|
434
449
|
};
|
|
435
450
|
// The icon size of a layer when it depends on the zoom only, as the text size
|
|
436
451
|
const iconSizes = new Map();
|
|
437
452
|
const iconSizeOf = (layer) => {
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
453
|
+
const known = iconSizes.get(layer);
|
|
454
|
+
if (known !== undefined)
|
|
455
|
+
return known;
|
|
456
|
+
const v = layer.layout?.['icon-size'] ?? 1;
|
|
457
|
+
const s = isExpression(v) ? zoomStops(v) : v;
|
|
458
|
+
iconSizes.set(layer, s);
|
|
444
459
|
return s;
|
|
445
460
|
};
|
|
446
461
|
r.layers.forEach((layer, index) => {
|
|
@@ -459,18 +474,13 @@ async function labels(r, z, x, y, id, priority, zoom = z) {
|
|
|
459
474
|
const ctx = context(f, zoom);
|
|
460
475
|
if (!filter(layer.filter, ctx))
|
|
461
476
|
continue;
|
|
462
|
-
|
|
477
|
+
const field = text(layout['text-field'], ctx).trim();
|
|
463
478
|
const image = text(layout['icon-image'], ctx).trim();
|
|
464
|
-
if (!
|
|
479
|
+
if (!field && !image)
|
|
465
480
|
continue;
|
|
466
|
-
const
|
|
467
|
-
if (transform === 'uppercase')
|
|
468
|
-
t = t.toUpperCase();
|
|
469
|
-
else if (transform === 'lowercase')
|
|
470
|
-
t = t.toLowerCase();
|
|
481
|
+
const t = cased(field, value(layer, 'layout', 'text-transform', ctx, 'none'));
|
|
471
482
|
const fonts = value(layer, 'layout', 'text-font', ctx, ['Noto Sans Regular']);
|
|
472
483
|
const font = labelFont(Array.isArray(fonts) && typeof fonts[0] === 'string' ? fonts[0] : 'Noto Sans Regular');
|
|
473
|
-
const offset = value(layer, 'layout', 'text-offset', ctx, [0, 0]);
|
|
474
484
|
const base = {
|
|
475
485
|
layer: index,
|
|
476
486
|
text: t,
|
|
@@ -483,7 +493,7 @@ async function labels(r, z, x, y, id, priority, zoom = z) {
|
|
|
483
493
|
haloColor: String(value(layer, 'paint', 'text-halo-color', ctx, 'rgba(0,0,0,0)')),
|
|
484
494
|
haloWidth: Number(value(layer, 'paint', 'text-halo-width', ctx, 0)),
|
|
485
495
|
anchor: String(value(layer, 'layout', 'text-anchor', ctx, 'center')),
|
|
486
|
-
offset: (
|
|
496
|
+
offset: pair(value(layer, 'layout', 'text-offset', ctx, [0, 0]), [0, 0]),
|
|
487
497
|
maxWidth: Number(value(layer, 'layout', 'text-max-width', ctx, 10)),
|
|
488
498
|
lineHeight: Number(value(layer, 'layout', 'text-line-height', ctx, 1.2)),
|
|
489
499
|
overlap: overlapOf(layer, 'text', ctx),
|
|
@@ -554,7 +564,7 @@ async function labels(r, z, x, y, id, priority, zoom = z) {
|
|
|
554
564
|
}
|
|
555
565
|
});
|
|
556
566
|
return out;
|
|
557
|
-
}
|
|
567
|
+
};
|
|
558
568
|
const post = (message, transfer = []) => self.postMessage(message, transfer);
|
|
559
569
|
self.onmessage = async ({ data }) => {
|
|
560
570
|
if (data.type === 'headers') {
|
|
@@ -576,8 +586,9 @@ self.onmessage = async ({ data }) => {
|
|
|
576
586
|
}
|
|
577
587
|
if (data.type === 'drop') {
|
|
578
588
|
// Its copy of the sprites
|
|
579
|
-
|
|
589
|
+
renderers.get(data.key)?.sprites.forEach((sprite) => {
|
|
580
590
|
sprite.image.close();
|
|
591
|
+
});
|
|
581
592
|
renderers.delete(data.key);
|
|
582
593
|
return;
|
|
583
594
|
}
|
|
@@ -617,7 +628,7 @@ self.onmessage = async ({ data }) => {
|
|
|
617
628
|
}
|
|
618
629
|
};
|
|
619
630
|
/** A tile of another layer: the altitudes of a relief tile, or a reprojected raster tile */
|
|
620
|
-
async
|
|
631
|
+
const decodeTile = async (data) => {
|
|
621
632
|
const controller = new AbortController();
|
|
622
633
|
controllers.set(data.id, controller);
|
|
623
634
|
try {
|
|
@@ -643,5 +654,5 @@ async function decodeTile(data) {
|
|
|
643
654
|
finally {
|
|
644
655
|
controllers.delete(data.id);
|
|
645
656
|
}
|
|
646
|
-
}
|
|
657
|
+
};
|
|
647
658
|
//# sourceMappingURL=basemap.worker.js.map
|