isard 1.1.0 → 1.3.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 +121 -0
- package/README.md +44 -39
- 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/pmtileslayer.d.ts +33 -0
- package/dist/basemap/pmtileslayer.js +97 -0
- package/dist/basemap/pmtileslayer.js.map +1 -0
- 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/trees.d.ts +26 -0
- package/dist/basemap/trees.js +141 -0
- package/dist/basemap/trees.js.map +1 -0
- package/dist/basemap/vectorstyle.d.ts +22 -10
- package/dist/basemap/vectorstyle.js +163 -110
- package/dist/basemap/vectorstyle.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +70 -47
- package/dist/basemap/vectortiles.js +480 -358
- 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/workerpool.d.ts +17 -0
- package/dist/basemap/workerpool.js +194 -0
- package/dist/basemap/workerpool.js.map +1 -0
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +21 -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 +13 -9
- package/dist/engine-loader.js +38 -28
- package/dist/engine-loader.js.map +1 -1
- package/dist/geoplateforme.d.ts +26 -10
- package/dist/geoplateforme.js +45 -20
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.js +9 -2
- 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/isard_tess_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 +42 -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/layers/vectors.d.ts +60 -0
- package/dist/layers/vectors.js +130 -0
- package/dist/layers/vectors.js.map +1 -0
- 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 +64 -0
- package/dist/map/frame-loop.js +145 -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 +54 -126
- package/dist/map.js +227 -698
- 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 +147 -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 +16 -0
- package/dist/react/Swipe.js +52 -0
- package/dist/react/Swipe.js.map +1 -0
- package/dist/react/VectorGeometry.d.ts +35 -0
- package/dist/react/VectorGeometry.js +82 -0
- package/dist/react/VectorGeometry.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 +33 -0
- package/dist/react/context.js +20 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/index.d.ts +16 -108
- package/dist/react/index.js +11 -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 +27 -4
- 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/minimap.d.ts +25 -0
- package/dist/ui/minimap.js +90 -0
- package/dist/ui/minimap.js.map +1 -0
- package/dist/ui/overlay.js +18 -20
- package/dist/ui/overlay.js.map +1 -1
- package/dist/ui/scale.d.ts +19 -0
- package/dist/ui/scale.js +44 -0
- package/dist/ui/scale.js.map +1 -0
- package/dist/ui/search.d.ts +25 -0
- package/dist/ui/search.js +119 -0
- package/dist/ui/search.js.map +1 -0
- package/dist/ui/style.d.ts +1 -1
- package/dist/ui/style.js +19 -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/util/sun.d.ts +11 -0
- package/dist/util/sun.js +26 -0
- package/dist/util/sun.js.map +1 -0
- package/dist/wasm/isard.d.ts +250 -7
- package/dist/wasm/isard.js +375 -8
- package/dist/wasm/isard_core.d.ts +226 -7
- package/dist/wasm/isard_core.js +351 -8
- package/dist/wasm/isard_tess.d.ts +109 -0
- package/dist/wasm/isard_tess.js +398 -0
- package/dist/workers/basemap/geometry.d.ts +72 -0
- package/dist/workers/basemap/labels.d.ts +8 -0
- package/dist/workers/basemap/raster.d.ts +10 -0
- package/dist/workers/basemap/tiles.d.ts +65 -0
- package/dist/workers/basemap/trees.d.ts +19 -0
- package/dist/workers/basemap.worker.d.ts +126 -22
- package/dist/workers/basemap.worker.js +76 -544
- package/dist/workers/basemap.worker.js.map +1 -1
- package/package.json +5 -4
- package/vite.js +10 -2
|
@@ -7,42 +7,51 @@
|
|
|
7
7
|
* interpolated in RGBA, `{token}` text fields.
|
|
8
8
|
*/
|
|
9
9
|
import { parseCssColor } from "../util/color.js";
|
|
10
|
+
import { isRecord } from "../util/guards.js";
|
|
11
|
+
/** A MapLibre style, as far as the basemap reads it: its sources and its layers (an id and a type each) */
|
|
12
|
+
export const isStyle = (value) => isRecord(value) &&
|
|
13
|
+
isRecord(value.sources) &&
|
|
14
|
+
Object.values(value.sources).every((s) => isRecord(s) && typeof s.type === 'string') &&
|
|
15
|
+
Array.isArray(value.layers) &&
|
|
16
|
+
value.layers.every((l) => isRecord(l) && typeof l.id === 'string' && typeof l.type === 'string');
|
|
10
17
|
const TYPES = ['Unknown', 'Point', 'LineString', 'Polygon'];
|
|
11
|
-
export
|
|
18
|
+
export const context = (feature, zoom) => {
|
|
12
19
|
return { zoom, properties: feature.properties, type: TYPES[feature.type] ?? 'Unknown' };
|
|
13
|
-
}
|
|
20
|
+
};
|
|
14
21
|
// ── Colors ──
|
|
15
22
|
/** A color to RGBA 0-1, undefined if it is not one */
|
|
16
|
-
export
|
|
23
|
+
export const color = (value) => {
|
|
17
24
|
return parseCssColor(value);
|
|
18
|
-
}
|
|
19
|
-
export
|
|
25
|
+
};
|
|
26
|
+
export const css = ([r, g, b, a]) => {
|
|
20
27
|
return `rgba(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)},${a})`;
|
|
21
|
-
}
|
|
28
|
+
};
|
|
22
29
|
// ── Interpolation ──
|
|
23
30
|
/** Factor between two stops: linear, or exponential of `base` */
|
|
24
|
-
|
|
31
|
+
const factor = (x, x0, x1, base = 1) => {
|
|
25
32
|
const d = x1 - x0;
|
|
26
33
|
if (d === 0)
|
|
27
34
|
return 0;
|
|
28
35
|
const t = x - x0;
|
|
29
36
|
return base === 1 ? t / d : (base ** t - 1) / (base ** d - 1);
|
|
30
|
-
}
|
|
31
|
-
|
|
37
|
+
};
|
|
38
|
+
const mix = (a, b, t) => {
|
|
32
39
|
if (typeof a === 'number' && typeof b === 'number')
|
|
33
40
|
return a + (b - a) * t;
|
|
34
41
|
const ca = color(a);
|
|
35
42
|
const cb = color(b);
|
|
36
|
-
if (ca && cb)
|
|
37
|
-
|
|
43
|
+
if (ca && cb) {
|
|
44
|
+
const lerp = (i) => ca[i] + (cb[i] - ca[i]) * t;
|
|
45
|
+
return css([lerp(0), lerp(1), lerp(2), lerp(3)]);
|
|
46
|
+
}
|
|
38
47
|
if (Array.isArray(a) && Array.isArray(b))
|
|
39
48
|
return a.map((v, i) => mix(v, b[i], t));
|
|
40
49
|
return t < 0.5 ? a : b;
|
|
41
|
-
}
|
|
42
|
-
|
|
50
|
+
};
|
|
51
|
+
const isFunction = (v) => {
|
|
43
52
|
return typeof v === 'object' && v !== null && !Array.isArray(v) && Array.isArray(v.stops);
|
|
44
|
-
}
|
|
45
|
-
|
|
53
|
+
};
|
|
54
|
+
const legacy = (f, ctx) => {
|
|
46
55
|
const input = f.property === undefined ? ctx.zoom : ctx.properties[f.property];
|
|
47
56
|
const stops = f.stops;
|
|
48
57
|
const type = f.type ?? (f.property === undefined || typeof stops[0]?.[0] === 'number' ? 'exponential' : 'categorical');
|
|
@@ -53,30 +62,45 @@ function legacy(f, ctx) {
|
|
|
53
62
|
if (typeof input !== 'number' || !stops.length)
|
|
54
63
|
return f.default ?? stops[0]?.[1];
|
|
55
64
|
// Zoom-and-property stops ({ zoom, value } keys) are taken at their zoom only
|
|
56
|
-
const key = (
|
|
65
|
+
const key = ([k]) => {
|
|
66
|
+
if (Array.isArray(k))
|
|
67
|
+
return Number.NaN;
|
|
68
|
+
return isRecord(k) ? Number(k.zoom) : Number(k);
|
|
69
|
+
};
|
|
57
70
|
const first = stops[0];
|
|
58
71
|
if (!first)
|
|
59
72
|
return f.default;
|
|
60
73
|
if (input <= key(first))
|
|
61
74
|
return first[1];
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return stops.at(-1)?.[1];
|
|
73
|
-
}
|
|
75
|
+
const at = stops.findIndex((s1, i) => i > 0 && Boolean(stops[i - 1]) && Boolean(s1) && input < key(s1));
|
|
76
|
+
const [s0, s1] = [stops[at - 1], stops[at]];
|
|
77
|
+
if (at < 0 || !s0 || !s1)
|
|
78
|
+
return stops.at(-1)?.[1];
|
|
79
|
+
if (type === 'interval')
|
|
80
|
+
return s0[1];
|
|
81
|
+
return mix(s0[1], s1[1], factor(input, key(s0), key(s1), f.base ?? 1));
|
|
82
|
+
};
|
|
74
83
|
// ── Expressions ──
|
|
75
|
-
|
|
84
|
+
/** A list of values to look a value up in (any value: `includes` compares with `===`) */
|
|
85
|
+
const labels = (values) => values;
|
|
86
|
+
const ORDERS = {
|
|
87
|
+
'<': (a, b) => a < b,
|
|
88
|
+
'<=': (a, b) => a <= b,
|
|
89
|
+
'>': (a, b) => a > b,
|
|
90
|
+
'>=': (a, b) => a >= b,
|
|
91
|
+
};
|
|
92
|
+
/** A comparison of any two values the way JavaScript's operators make it: two strings (lists and objects as their
|
|
93
|
+
* text) in text order, anything else as numbers */
|
|
94
|
+
const compare = (op, a, b) => {
|
|
95
|
+
const text = (v) => (typeof v === 'object' && v !== null ? String(v) : v);
|
|
96
|
+
const [x, y] = [text(a), text(b)];
|
|
97
|
+
return typeof x === 'string' && typeof y === 'string' ? ORDERS[op](x, y) : ORDERS[op](Number(x), Number(y));
|
|
98
|
+
};
|
|
99
|
+
const get = (ctx, key) => {
|
|
76
100
|
if (key === '$type')
|
|
77
101
|
return ctx.type;
|
|
78
102
|
return typeof key === 'string' ? ctx.properties[key] : undefined;
|
|
79
|
-
}
|
|
103
|
+
};
|
|
80
104
|
/** The operators `evaluate` knows */
|
|
81
105
|
const OPERATORS = new Set([
|
|
82
106
|
'literal',
|
|
@@ -142,13 +166,13 @@ const OPERATORS = new Set([
|
|
|
142
166
|
'e',
|
|
143
167
|
]);
|
|
144
168
|
/** Whether a value is an expression (an array starting with a known operator), not a literal array */
|
|
145
|
-
export
|
|
169
|
+
export const isExpression = (e) => {
|
|
146
170
|
return Array.isArray(e) && typeof e[0] === 'string' && OPERATORS.has(e[0]);
|
|
147
|
-
}
|
|
171
|
+
};
|
|
148
172
|
/** Operators already warned about */
|
|
149
173
|
const warned = new Set();
|
|
150
174
|
const str = (v) => (v === undefined || v === null ? '' : String(v));
|
|
151
|
-
export
|
|
175
|
+
export const evaluate = (e, ctx) => {
|
|
152
176
|
if (isFunction(e))
|
|
153
177
|
return legacy(e, ctx);
|
|
154
178
|
if (!Array.isArray(e))
|
|
@@ -184,13 +208,17 @@ export function evaluate(e, ctx) {
|
|
|
184
208
|
case 'image':
|
|
185
209
|
return ev(0);
|
|
186
210
|
case 'number-format': {
|
|
187
|
-
const options = (args[1]
|
|
211
|
+
const options = isRecord(args[1]) ? args[1] : {};
|
|
212
|
+
const option = (key) => {
|
|
213
|
+
const v = options[key];
|
|
214
|
+
return typeof v === 'number' ? v : undefined;
|
|
215
|
+
};
|
|
188
216
|
const n = num(0);
|
|
189
217
|
if (!Number.isFinite(n))
|
|
190
218
|
return '';
|
|
191
|
-
return n.toLocaleString(options.locale, {
|
|
192
|
-
minimumFractionDigits:
|
|
193
|
-
maximumFractionDigits:
|
|
219
|
+
return n.toLocaleString(typeof options.locale === 'string' ? options.locale : undefined, {
|
|
220
|
+
minimumFractionDigits: option('min-fraction-digits'),
|
|
221
|
+
maximumFractionDigits: option('max-fraction-digits'),
|
|
194
222
|
});
|
|
195
223
|
}
|
|
196
224
|
case 'to-number': {
|
|
@@ -262,13 +290,10 @@ export function evaluate(e, ctx) {
|
|
|
262
290
|
case '!=':
|
|
263
291
|
return ev(0) !== ev(1);
|
|
264
292
|
case '<':
|
|
265
|
-
return ev(0) < ev(1);
|
|
266
293
|
case '<=':
|
|
267
|
-
return ev(0) <= ev(1);
|
|
268
294
|
case '>':
|
|
269
|
-
return ev(0) > ev(1);
|
|
270
295
|
case '>=':
|
|
271
|
-
return ev(0)
|
|
296
|
+
return compare(op, ev(0), ev(1));
|
|
272
297
|
case 'in': {
|
|
273
298
|
const haystack = ev(1);
|
|
274
299
|
const needle = ev(0);
|
|
@@ -277,19 +302,15 @@ export function evaluate(e, ctx) {
|
|
|
277
302
|
return Array.isArray(haystack) && haystack.includes(needle);
|
|
278
303
|
}
|
|
279
304
|
case 'case': {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
return ev(i + 1);
|
|
283
|
-
return ev(args.length - 1);
|
|
305
|
+
const hit = args.findIndex((_, i) => i % 2 === 0 && i + 1 < args.length && Boolean(ev(i)));
|
|
306
|
+
return hit < 0 ? ev(args.length - 1) : ev(hit + 1);
|
|
284
307
|
}
|
|
285
308
|
case 'match': {
|
|
286
309
|
const input = ev(0);
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
return ev(args.length - 1);
|
|
310
|
+
const hit = args.findIndex((label, i) => i % 2 === 1 &&
|
|
311
|
+
i + 1 < args.length &&
|
|
312
|
+
(Array.isArray(label) ? labels(label).includes(input) : label === input));
|
|
313
|
+
return hit < 0 ? ev(args.length - 1) : ev(hit + 1);
|
|
293
314
|
}
|
|
294
315
|
case 'step': {
|
|
295
316
|
const input = num(0);
|
|
@@ -308,20 +329,20 @@ export function evaluate(e, ctx) {
|
|
|
308
329
|
const kind = args[0];
|
|
309
330
|
const input = num(1);
|
|
310
331
|
const base = Array.isArray(kind) && kind[0] === 'exponential' ? Number(kind[1]) : 1;
|
|
311
|
-
const stops = [
|
|
312
|
-
|
|
313
|
-
|
|
332
|
+
const stops = Array.from({ length: Math.floor((args.length - 2) / 2) }, (_, k) => [
|
|
333
|
+
Number(args[2 + 2 * k]),
|
|
334
|
+
args[3 + 2 * k] ?? null,
|
|
335
|
+
]);
|
|
314
336
|
const first = stops[0];
|
|
315
337
|
if (!first)
|
|
316
338
|
return null;
|
|
317
339
|
if (input <= first[0])
|
|
318
340
|
return evaluate(first[1], ctx);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return evaluate(stops.at(-1)?.[1] ?? null, ctx);
|
|
341
|
+
const at = stops.findIndex((s1, i) => i > 0 && input < s1[0]);
|
|
342
|
+
const [s0, s1] = [stops[at - 1], stops[at]];
|
|
343
|
+
if (at < 0 || !s0 || !s1)
|
|
344
|
+
return evaluate(stops.at(-1)?.[1] ?? null, ctx);
|
|
345
|
+
return mix(evaluate(s0[1], ctx), evaluate(s1[1], ctx), factor(input, s0[0], s1[0], base));
|
|
325
346
|
}
|
|
326
347
|
case 'rgb':
|
|
327
348
|
case 'rgba':
|
|
@@ -371,12 +392,26 @@ export function evaluate(e, ctx) {
|
|
|
371
392
|
}
|
|
372
393
|
return null;
|
|
373
394
|
}
|
|
374
|
-
}
|
|
395
|
+
};
|
|
375
396
|
// ── Filters ──
|
|
376
397
|
const LEGACY_COMPARISONS = new Set(['==', '!=', '<', '<=', '>', '>=']);
|
|
398
|
+
/** The kind of geometry a style layer is drawn with as vectors (`vectors()`: backgrounds as fills, extrusions raised
|
|
399
|
+
* into blocks); undefined for the others (symbols, circles, rasters) and for the layers drawn with a pattern (their
|
|
400
|
+
* images are the raster path's) */
|
|
401
|
+
export const vectorKind = (layer) => {
|
|
402
|
+
const paint = layer.paint ?? {};
|
|
403
|
+
if (['fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'background-pattern'].some((k) => k in paint)) {
|
|
404
|
+
return undefined;
|
|
405
|
+
}
|
|
406
|
+
if (layer.type === 'line')
|
|
407
|
+
return 'line';
|
|
408
|
+
if (layer.type === 'fill-extrusion')
|
|
409
|
+
return 'extrusion';
|
|
410
|
+
return layer.type === 'fill' || layer.type === 'background' ? 'fill' : undefined;
|
|
411
|
+
};
|
|
377
412
|
/** Whether a filter (not `all`, `any`, `none`) is in the legacy form: `["==", "key", value]`, `["in", "key", a, b]`,
|
|
378
413
|
* `["has", "key"]`; a key and literal values, as MapLibre tells them from expressions */
|
|
379
|
-
|
|
414
|
+
const isLegacyLeaf = (f) => {
|
|
380
415
|
const [op, a, ...rest] = f;
|
|
381
416
|
if (typeof op !== 'string' || typeof a !== 'string' || rest.some(Array.isArray))
|
|
382
417
|
return false;
|
|
@@ -385,8 +420,8 @@ function isLegacyLeaf(f) {
|
|
|
385
420
|
if (op === 'in')
|
|
386
421
|
return f.length !== 3 || !Array.isArray(f[2]);
|
|
387
422
|
return op === '!in' || op === 'has' || op === '!has';
|
|
388
|
-
}
|
|
389
|
-
|
|
423
|
+
};
|
|
424
|
+
const legacyFilter = (f, ctx) => {
|
|
390
425
|
const [op, key, ...rest] = f;
|
|
391
426
|
const v = get(ctx, key);
|
|
392
427
|
switch (op) {
|
|
@@ -395,17 +430,14 @@ function legacyFilter(f, ctx) {
|
|
|
395
430
|
case '!=':
|
|
396
431
|
return v !== rest[0];
|
|
397
432
|
case '<':
|
|
398
|
-
return v < rest[0];
|
|
399
433
|
case '<=':
|
|
400
|
-
return v <= rest[0];
|
|
401
434
|
case '>':
|
|
402
|
-
return v > rest[0];
|
|
403
435
|
case '>=':
|
|
404
|
-
return v
|
|
436
|
+
return compare(op, v, rest[0]);
|
|
405
437
|
case 'in':
|
|
406
|
-
return rest.includes(v);
|
|
438
|
+
return labels(rest).includes(v);
|
|
407
439
|
case '!in':
|
|
408
|
-
return !rest.includes(v);
|
|
440
|
+
return !labels(rest).includes(v);
|
|
409
441
|
case 'has':
|
|
410
442
|
return v !== undefined;
|
|
411
443
|
case '!has':
|
|
@@ -413,53 +445,53 @@ function legacyFilter(f, ctx) {
|
|
|
413
445
|
default:
|
|
414
446
|
return true;
|
|
415
447
|
}
|
|
416
|
-
}
|
|
448
|
+
};
|
|
417
449
|
/** Compiled filters, by filter object */
|
|
418
450
|
const compiled = new WeakMap();
|
|
419
451
|
/** A filter as a function: `all`, `any`, `none` of their parts, each part legacy or an expression (they may mix) */
|
|
420
|
-
|
|
452
|
+
const compile = (f) => {
|
|
421
453
|
if (!Array.isArray(f))
|
|
422
454
|
return () => Boolean(f);
|
|
423
455
|
const hit = compiled.get(f);
|
|
424
456
|
if (hit)
|
|
425
457
|
return hit;
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
test = (ctx) => Boolean(evaluate(f, ctx));
|
|
442
|
-
}
|
|
458
|
+
const make = () => {
|
|
459
|
+
const op = f[0];
|
|
460
|
+
if (op === 'all' || op === 'any' || op === 'none') {
|
|
461
|
+
const parts = f.slice(1).map(compile);
|
|
462
|
+
if (op === 'all')
|
|
463
|
+
return (ctx) => parts.every((p) => p(ctx));
|
|
464
|
+
if (op === 'any')
|
|
465
|
+
return (ctx) => parts.some((p) => p(ctx));
|
|
466
|
+
return (ctx) => !parts.some((p) => p(ctx));
|
|
467
|
+
}
|
|
468
|
+
if (isLegacyLeaf(f))
|
|
469
|
+
return (ctx) => legacyFilter(f, ctx);
|
|
470
|
+
return (ctx) => Boolean(evaluate(f, ctx));
|
|
471
|
+
};
|
|
472
|
+
const test = make();
|
|
443
473
|
compiled.set(f, test);
|
|
444
474
|
return test;
|
|
445
|
-
}
|
|
446
|
-
export
|
|
475
|
+
};
|
|
476
|
+
export const filter = (f, ctx) => {
|
|
447
477
|
if (f === undefined || f === null)
|
|
448
478
|
return true;
|
|
449
479
|
return compile(f)(ctx);
|
|
450
|
-
}
|
|
480
|
+
};
|
|
481
|
+
/** The operators that read the feature */
|
|
482
|
+
const FEATURE_OPERATORS = new Set(['get', 'has', '!has', 'geometry-type', 'properties', 'id']);
|
|
451
483
|
/** Whether a value depends on the feature (else only on the zoom, evaluated once per tile) */
|
|
452
|
-
export
|
|
484
|
+
export const isFeatureDependent = (e) => {
|
|
453
485
|
if (e !== undefined && isFunction(e))
|
|
454
486
|
return e.property !== undefined;
|
|
455
487
|
if (!Array.isArray(e))
|
|
456
488
|
return false;
|
|
457
|
-
if (
|
|
489
|
+
if (FEATURE_OPERATORS.has(e[0]))
|
|
458
490
|
return true;
|
|
459
491
|
return e.some((x) => isFeatureDependent(x));
|
|
460
|
-
}
|
|
492
|
+
};
|
|
461
493
|
/** A `{token}` text field (or an expression) to the text of a feature */
|
|
462
|
-
export
|
|
494
|
+
export const text = (field, ctx) => {
|
|
463
495
|
if (field === undefined || field === null)
|
|
464
496
|
return '';
|
|
465
497
|
if (typeof field === 'string') {
|
|
@@ -474,45 +506,66 @@ export function text(field, ctx) {
|
|
|
474
506
|
return v.filter((x) => typeof x === 'string').join('');
|
|
475
507
|
}
|
|
476
508
|
return v === undefined || v === null ? '' : String(v);
|
|
477
|
-
}
|
|
509
|
+
};
|
|
478
510
|
/** The font of a label from the first of its `text-font`: a family without its weight takes the regular one */
|
|
479
|
-
export
|
|
511
|
+
export const labelFont = (font) => {
|
|
480
512
|
return /Regular|Bold|Italic|Semibold|Light|Medium|Black/.test(font) ? font : `${font} Regular`;
|
|
481
|
-
}
|
|
513
|
+
};
|
|
482
514
|
/**
|
|
483
515
|
* A value of the zoom only (an expression: `interpolate`, `step` of `["zoom"]`) as stops `[[zoom, value], …]` for the
|
|
484
516
|
* engine, which interpolates them linearly: evaluated at its own stops and at the whole zooms between (an exponential
|
|
485
517
|
* curve followed closely), a step kept sharp just before its threshold
|
|
486
518
|
*/
|
|
487
|
-
export
|
|
519
|
+
export const zoomStops = (e) => {
|
|
488
520
|
const zooms = new Set();
|
|
521
|
+
// The inputs of the stops of an `interpolate` or a `step` (from its fourth argument, one in two)
|
|
522
|
+
const stopInputs = (x) => x.filter((_, i) => i >= 3 && i % 2 === 1).map(Number);
|
|
489
523
|
const walk = (x) => {
|
|
490
524
|
if (!Array.isArray(x))
|
|
491
525
|
return;
|
|
492
526
|
const zoomInput = (input) => Array.isArray(input) && input[0] === 'zoom';
|
|
493
527
|
if ((x[0] === 'interpolate' || x[0] === 'interpolate-hcl' || x[0] === 'interpolate-lab') && zoomInput(x[2])) {
|
|
494
|
-
|
|
495
|
-
zooms.add(
|
|
528
|
+
stopInputs(x).forEach((t) => {
|
|
529
|
+
zooms.add(t);
|
|
530
|
+
});
|
|
496
531
|
}
|
|
497
532
|
else if (x[0] === 'step' && zoomInput(x[1])) {
|
|
498
|
-
|
|
499
|
-
const t = Number(x[i]);
|
|
533
|
+
stopInputs(x).forEach((t) => {
|
|
500
534
|
zooms.add(t);
|
|
501
535
|
zooms.add(t - 0.01);
|
|
502
|
-
}
|
|
536
|
+
});
|
|
503
537
|
}
|
|
504
|
-
|
|
505
|
-
walk(y);
|
|
538
|
+
x.forEach(walk);
|
|
506
539
|
};
|
|
507
540
|
walk(e);
|
|
508
541
|
const finite = [...zooms].filter(Number.isFinite);
|
|
509
542
|
if (finite.length === 0)
|
|
510
543
|
finite.push(0);
|
|
511
544
|
const [lo, hi] = [Math.min(...finite), Math.max(...finite)];
|
|
512
|
-
|
|
513
|
-
finite.push(z);
|
|
545
|
+
finite.push(...Array.from({ length: Math.floor(hi) - Math.ceil(lo) + 1 }, (_, i) => Math.ceil(lo) + i));
|
|
514
546
|
return [...new Set(finite)]
|
|
515
547
|
.sort((a, b) => a - b)
|
|
516
548
|
.map((zoom) => [zoom, Number(evaluate(e, { zoom, properties: {}, type: 'Unknown' }))]);
|
|
517
|
-
}
|
|
549
|
+
};
|
|
550
|
+
/**
|
|
551
|
+
* A paint value as zoom stops when it depends on the zoom only (an expression as `zoomStops` samples it, a legacy zoom
|
|
552
|
+
* function at its stops and the whole zooms between), a number as it is, `fallback` when missing; undefined when it
|
|
553
|
+
* depends on the features
|
|
554
|
+
*/
|
|
555
|
+
export const zoomOnly = (v, fallback) => {
|
|
556
|
+
if (v === undefined || v === null)
|
|
557
|
+
return fallback;
|
|
558
|
+
if (isFeatureDependent(v))
|
|
559
|
+
return undefined;
|
|
560
|
+
if (isExpression(v))
|
|
561
|
+
return zoomStops(v);
|
|
562
|
+
if (!isFunction(v))
|
|
563
|
+
return Number(v);
|
|
564
|
+
const zooms = v.stops.map(([z]) => Number(z)).filter(Number.isFinite);
|
|
565
|
+
const [lo, hi] = [Math.min(...zooms), Math.max(...zooms)];
|
|
566
|
+
const whole = Array.from({ length: Math.max(0, Math.floor(hi) - Math.ceil(lo) + 1) }, (_, i) => Math.ceil(lo) + i);
|
|
567
|
+
return [...new Set([...zooms, ...whole])]
|
|
568
|
+
.sort((a, b) => a - b)
|
|
569
|
+
.map((zoom) => [zoom, Number(evaluate(v, { zoom, properties: {}, type: 'Unknown' }))]);
|
|
570
|
+
};
|
|
518
571
|
//# sourceMappingURL=vectorstyle.js.map
|