@nika-js/onlymap 0.6.2 → 0.6.7
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 +81 -0
- package/README.md +9 -7
- package/dist/{LercDecode.es-BOJJr6Gx.js → LercDecode.es-BzboSQ2U.js} +1 -1
- package/dist/attribute-resolution.d.ts +84 -6
- package/dist/{basemap-BofXgXxy.js → basemap-pWXbFGjp.js} +1 -1
- package/dist/ctx.d.ts +3 -1
- package/dist/data-layer.d.ts +26 -4
- package/dist/declarative-filter.d.ts +14 -5
- package/dist/elements/om-map.d.ts +1 -0
- package/dist/geodesy.d.ts +3 -0
- package/dist/{geoparquet-DapHATA0.js → geoparquet-BPl1T2Or.js} +1 -1
- package/dist/{index-SPJVn_n_.js → index-B9a6f006.js} +1 -1
- package/dist/{index-BF9iO8Tq.js → index-Bgx3CJru.js} +1 -1
- package/dist/{index-7B-6Cbzu.js → index-CAuq7wRs.js} +17565 -16782
- package/dist/{index-xmJjZxQJ.js → index-CqsQz9Bp.js} +2 -2
- package/dist/{index-BmX6IId3.js → index-iVMlGZS9.js} +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/ir-snapshot.d.ts +2 -1
- package/dist/ir.d.ts +47 -9
- package/dist/layer-registry.d.ts +7 -0
- package/dist/layers/marker-icons.d.ts +19 -0
- package/dist/layers/route-layer.d.ts +71 -0
- package/dist/layers/tracking-layer.d.ts +52 -0
- package/dist/{lerc-C6k7EzSN.js → lerc-BgzbFAc7.js} +2 -2
- package/dist/license.d.ts +13 -2
- package/dist/measure-controller.d.ts +28 -4
- package/dist/onlymap.standalone.js +50150 -49367
- package/dist/onlymapjs.js +65 -61
- package/dist/programmatic.d.ts +24 -4
- package/dist/providers.d.ts +48 -0
- package/dist/{raster-Cuzhibe2.js → raster-DtyMY54Z.js} +2 -2
- package/dist/{raster-pipeline-DLrnJK8y.js → raster-pipeline-BmHRCUEb.js} +1 -1
- package/dist/react/om-layer.d.ts +6 -2
- package/dist/react.js +54 -50
- package/dist/tracking-interpolation.d.ts +22 -0
- package/dist/version.d.ts +1 -1
- package/dist/{zarr-CUzEX8fB.js → zarr-CTpFZo_m.js} +2 -2
- package/docs/3d-assets.md +1 -1
- package/docs/live-data.md +17 -0
- package/docs/react.md +9 -1
- package/docs/routing.md +92 -0
- package/llms.txt +6 -5
- package/onlymapjs.html-data.json +61 -3
- package/package.json +1 -1
- package/skills/onlymapjs/SKILL.md +6 -4
- package/skills/onlymapjs/references/react.md +1 -1
- package/skills/onlymapjs/references/syntax.md +83 -5
- package/skills/onlymapjs/references/testing.md +6 -0
package/dist/onlymapjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aA as e, aB as r, aC as t, aD as o, aE as b, aF as i, ap as l, aG as n, aH as S, aI as
|
|
1
|
+
import { aA as e, aB as r, aC as t, aD as o, aE as b, aF as i, ap as l, aG as n, aH as S, aI as g, aJ as c, aK as E, aL as L, aM as T, aN as A, aO as d, aP as p, aQ as m, aR as _, aS as I, aT as u, aU as M, aV as y, aW as D, ao as O, aX as R, aw as f, aY as N, aZ as P, a_ as h, W as F, a$ as B, b0 as C, b1 as v, b2 as G, b3 as U, b4 as W, b5 as w, b6 as x, b7 as Y, b8 as H, b9 as X, ba as k, bb as J, bc as K, bd as V, be as z, bf as Q, bg as Z, bh as $, bi as j, bj as q, bk as aa, bl as sa, bm as ea, bn as ra, bo as ta, bp as oa, bq as ba, br as ia, bs as la, bt as na, bu as Sa, bv as ga, bw as ca, bx as Ea, by as La, bz as Ta, bA as Aa, bB as da, bC as pa, bD as ma, bE as _a, bF as Ia, bG as ua, bH as Ma, bI as ya, bJ as Da, bK as Oa, bL as Ra, bM as fa, bN as Na, bO as Pa, bP as ha, bQ as Fa, bR as Ba, bS as Ca, bT as va, bU as Ga, bV as Ua, bW as Wa, bX as wa, bY as xa, bZ as Ya, b_ as Ha, b$ as Xa, c0 as ka, c1 as Ja, c2 as Ka, c3 as Va, c4 as za, c5 as Qa, c6 as Za } from "./index-CAuq7wRs.js";
|
|
2
2
|
export {
|
|
3
3
|
e as ALL_POSITION_VALUES,
|
|
4
4
|
r as AUDIT_EXEMPTIONS,
|
|
@@ -9,36 +9,36 @@ export {
|
|
|
9
9
|
l as CompositeLayer,
|
|
10
10
|
n as DEFAULT_AUDIT_WIDTHS,
|
|
11
11
|
S as DEFAULT_FOLD_BREAKPOINT_PX,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
g as DRONE_SENSOR_DATABASE,
|
|
13
|
+
c as EDGE_TOLERANCE_PX,
|
|
14
|
+
E as FOLD_HYSTERESIS_PX,
|
|
15
|
+
L as FOLD_SIDES,
|
|
16
|
+
T as GeoJsonLayer,
|
|
17
17
|
A as IconLayer,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
d as LEGACY_POSITION_ALIASES,
|
|
19
|
+
p as LIGHTING_PRESET_NAMES,
|
|
20
|
+
m as Layer,
|
|
21
|
+
_ as LayerExtension,
|
|
22
22
|
I as MANAGED_SLOTS,
|
|
23
|
-
|
|
23
|
+
u as MapController,
|
|
24
24
|
M as OmMap,
|
|
25
|
-
|
|
25
|
+
y as ScatterplotLayer,
|
|
26
26
|
D as ScenegraphLayer,
|
|
27
27
|
O as SimpleMeshLayer,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
R as Tile3DLayer,
|
|
29
|
+
f as TileLayer,
|
|
30
|
+
N as UNIT_SYSTEMS,
|
|
31
31
|
P as WGS84_MEAN_RADIUS_M,
|
|
32
32
|
h as WIDGET_STYLE_KEY_NAMES,
|
|
33
33
|
F as WebMercatorViewport,
|
|
34
34
|
B as arrowTableToColumnar,
|
|
35
35
|
C as asRows,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
v as auditLayout,
|
|
37
|
+
G as compileExpression,
|
|
38
|
+
U as compileFullJsAccessorBlockInSandbox,
|
|
39
|
+
W as computeTimeline,
|
|
40
|
+
w as configureBasemap,
|
|
41
|
+
x as configureData,
|
|
42
42
|
Y as configureIfc,
|
|
43
43
|
H as configureLicense,
|
|
44
44
|
X as configureTelemetry,
|
|
@@ -57,46 +57,50 @@ export {
|
|
|
57
57
|
ea as getEntitlements,
|
|
58
58
|
ra as getLayerSchema,
|
|
59
59
|
ta as getMeasureRadiusMeters,
|
|
60
|
-
oa as
|
|
61
|
-
ba as
|
|
62
|
-
ia as
|
|
63
|
-
la as
|
|
64
|
-
na as
|
|
65
|
-
Sa as
|
|
60
|
+
oa as getRoutingProvider,
|
|
61
|
+
ba as getTerrain,
|
|
62
|
+
ia as isBrowser,
|
|
63
|
+
la as isColumnar,
|
|
64
|
+
na as isStoreToken,
|
|
65
|
+
Sa as lineStringLengthMeters,
|
|
66
|
+
ga as loadIfc,
|
|
67
|
+
ca as loadRasterModule,
|
|
66
68
|
Ea as midpoint,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
La as mountForTest,
|
|
70
|
+
Ta as niceNumber,
|
|
71
|
+
Aa as normalizeData,
|
|
72
|
+
da as parseDurationMs,
|
|
73
|
+
pa as parseTerrainAttrs,
|
|
74
|
+
ma as parseUnitSystem,
|
|
75
|
+
_a as parseWidgetStyle,
|
|
76
|
+
Ia as pathLengthMeters,
|
|
77
|
+
ua as registerAction,
|
|
78
|
+
Ma as registerBasemap,
|
|
77
79
|
ya as registerFormat,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
80
|
+
Da as registerLayer,
|
|
81
|
+
Oa as registerRoutingProvider,
|
|
82
|
+
Ra as registerSource,
|
|
83
|
+
fa as registerTerrain,
|
|
84
|
+
Na as registerWidget,
|
|
85
|
+
Pa as releaseDataOwner,
|
|
86
|
+
ha as resolveFoldBreakpointPx,
|
|
87
|
+
Fa as resolveImageOverlay,
|
|
88
|
+
Ba as resolveLighting,
|
|
89
|
+
Ca as resolveSlot,
|
|
90
|
+
va as ringAreaMeters2,
|
|
91
|
+
Ga as ringEnclosesPole,
|
|
92
|
+
Ua as ringPerimeterMeters,
|
|
93
|
+
Wa as rowAt,
|
|
94
|
+
wa as sandboxHtml,
|
|
95
|
+
xa as scaleBarStep,
|
|
96
|
+
Ya as setMeasureRadiusMeters,
|
|
97
|
+
Ha as settleLayout,
|
|
98
|
+
Xa as shouldFoldAtWidth,
|
|
99
|
+
ka as slotContainerStyle,
|
|
100
|
+
Ja as slotLayout,
|
|
101
|
+
Ka as snapshotDescriptorIR,
|
|
102
|
+
Va as snapshotIR,
|
|
103
|
+
za as solarAzElDegrees,
|
|
104
|
+
Qa as validateManifest,
|
|
105
|
+
Za as validateManifestString
|
|
102
106
|
};
|
package/dist/programmatic.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ import { type TokenStore, type ViewOrigin, type ViewportSnapshot, type DataVersi
|
|
|
22
22
|
import type { LayerIR } from "./ir";
|
|
23
23
|
import { type RuntimeContext } from "./ctx";
|
|
24
24
|
import type { LayerMetaSnapshot } from "./ctx";
|
|
25
|
+
import { type LayerFilterFieldSpec, type LayerCategoryFilterFieldSpec } from "./attribute-resolution";
|
|
26
|
+
import { type DataTransportOwner } from "./data-layer";
|
|
25
27
|
import type { Selection } from "./selection";
|
|
26
28
|
import type { ValidationEntry } from "./validation";
|
|
27
29
|
import type { MapViewport } from "./basemap";
|
|
@@ -49,12 +51,16 @@ export interface LayerDescriptor {
|
|
|
49
51
|
/** Legend metadata (ctx.layers), same as the label/color attributes. */
|
|
50
52
|
label?: string;
|
|
51
53
|
color?: string;
|
|
52
|
-
/** GPU filter (spec: "Filtering") — mirrors filter-field/filter-range/… */
|
|
54
|
+
/** GPU filter (spec: "Filtering") — mirrors filter-field/filter-range/… (single dimension). */
|
|
53
55
|
filterField?: string;
|
|
54
56
|
filterRange?: [number, number];
|
|
55
57
|
filterSoftRange?: [number, number];
|
|
58
|
+
/** Multi-dimension GPU filter (up to 4) — mirrors `filter-fields`. Wins over `filterField`/`filterRange` if both are set. */
|
|
59
|
+
filterFields?: LayerFilterFieldSpec[];
|
|
56
60
|
filterCategoryField?: string;
|
|
57
61
|
filterCategories?: unknown[];
|
|
62
|
+
/** Multi-dimension categorical GPU filter (up to 4) — mirrors `filter-category-fields`. Wins over `filterCategoryField`/`filterCategories` if both are set. */
|
|
63
|
+
filterCategoryFields?: LayerCategoryFilterFieldSpec[];
|
|
58
64
|
/** Dashed lines on a path layer (spec: "PathStyleExtension") — `[dashLength, gapLength]` in line-width units; mirrors the `dash` attribute. */
|
|
59
65
|
dash?: [number, number];
|
|
60
66
|
/** Stretch each segment's dashes to start and end on a dash (deck `dashJustified`); mirrors `dash-justified`. */
|
|
@@ -128,8 +134,18 @@ export interface MapControllerOptions {
|
|
|
128
134
|
/** @internal Stable React-owned hosts that place required chrome in managed slots. */
|
|
129
135
|
chromeHosts?: MandatedChromeHosts;
|
|
130
136
|
}
|
|
131
|
-
/**
|
|
132
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Descriptor → layer IR: the programmatic counterpart of one parse-manifest.ts
|
|
139
|
+
* loop iteration.
|
|
140
|
+
*
|
|
141
|
+
* Pass `owner` (any stable object identity — a host controller, an element) to
|
|
142
|
+
* put a URL-backed descriptor's fetch/poll/socket under descriptor-owned
|
|
143
|
+
* lifetime; `releaseDataOwner(owner)` then stops everything that owner holds.
|
|
144
|
+
* Without one the transport is un-owned: it is still shared by identity and
|
|
145
|
+
* still notifies, but it holds no reference count, so a real owner's release
|
|
146
|
+
* can stop it. `MapController` owns its own transports and does not need this.
|
|
147
|
+
*/
|
|
148
|
+
export declare function descriptorToIR(desc: LayerDescriptor, onDataLoaded: () => void, owner?: DataTransportOwner): LayerIR | null;
|
|
133
149
|
/**
|
|
134
150
|
* Resolve JSON-safe/programmatic descriptors to deterministic snapshots.
|
|
135
151
|
* URL data is represented as an empty pending layer and is never fetched.
|
|
@@ -292,7 +308,11 @@ export declare class MapController {
|
|
|
292
308
|
flyToBounds(bounds: [[number, number], [number, number]], padding?: number, opts?: CameraOptions): void;
|
|
293
309
|
setView(partial: Partial<CameraState>, opts?: CameraOptions): void;
|
|
294
310
|
getViewState(): CameraState;
|
|
295
|
-
/**
|
|
311
|
+
/**
|
|
312
|
+
* Pause descriptor-owned live transports while retaining canonical map state.
|
|
313
|
+
* `retain` because this pause is meant to be reversed: `resume()` repaints the
|
|
314
|
+
* last rows immediately rather than showing an empty map while it reconnects.
|
|
315
|
+
*/
|
|
296
316
|
suspend(): void;
|
|
297
317
|
/** Reacquire current descriptor transports and reconcile after foregrounding. */
|
|
298
318
|
resume(): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing provider registry (spec: "Routing & Tracking", v0.6.7). A
|
|
3
|
+
* `RoutingProvider` computes a route from an origin/destination/waypoints
|
|
4
|
+
* request — kept swappable in code (a plugin registry, the
|
|
5
|
+
* `registerBasemap`/`registerTerrain` precedent) even though v1 ships
|
|
6
|
+
* exactly one concrete adapter (NIKA, below), so a second provider is a
|
|
7
|
+
* registry addition later, not a rewrite.
|
|
8
|
+
*
|
|
9
|
+
* Tracking deliberately has NO separate provider abstraction here: per the
|
|
10
|
+
* design doc, live position updates ride the EXISTING data/source streaming
|
|
11
|
+
* machinery (`OmMap.registerSource`) — a tracking feed is just a
|
|
12
|
+
* `<om-layer type="Tracking">` whose `data` points at a `wss://` URL with a
|
|
13
|
+
* registered `SourcePlugin` decoder, nothing new to build for that half.
|
|
14
|
+
*/
|
|
15
|
+
export interface RouteWaypoint {
|
|
16
|
+
lng: number;
|
|
17
|
+
lat: number;
|
|
18
|
+
stop?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface RouteRequest {
|
|
21
|
+
waypoints: RouteWaypoint[];
|
|
22
|
+
profile?: "driving" | "walking" | "cycling";
|
|
23
|
+
}
|
|
24
|
+
export interface RouteLeg {
|
|
25
|
+
distanceMeters: number;
|
|
26
|
+
durationSec: number;
|
|
27
|
+
}
|
|
28
|
+
/** Normalized route shape every provider returns — GeoJSON end-to-end (v1 ships GeoJSON only; encoded-polyline decoding is a deferred dependency, see the architecture doc). */
|
|
29
|
+
export interface Route {
|
|
30
|
+
geometry: {
|
|
31
|
+
type: "LineString";
|
|
32
|
+
coordinates: [number, number][];
|
|
33
|
+
};
|
|
34
|
+
distanceMeters: number;
|
|
35
|
+
/** `NaN` when no speed model exists to derive it (the direct-`geometry` authoring path) — a provider-computed route always supplies a real value. */
|
|
36
|
+
durationSec: number;
|
|
37
|
+
legs?: RouteLeg[];
|
|
38
|
+
}
|
|
39
|
+
export interface RoutingProvider {
|
|
40
|
+
computeRoute(request: RouteRequest, opts?: {
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
}): Promise<Route>;
|
|
43
|
+
}
|
|
44
|
+
export declare function registerRoutingProvider(name: string, provider: RoutingProvider): void;
|
|
45
|
+
export declare function getRoutingProvider(name: string): RoutingProvider | undefined;
|
|
46
|
+
/** Great-circle length of a LineString, in meters — used both by the direct-`geometry` authoring path (no provider round-trip needed for an already-computed route) and available to any provider adapter that needs it. */
|
|
47
|
+
export declare function lineStringLengthMeters(coordinates: readonly (readonly [number, number])[]): number;
|
|
48
|
+
export declare const nikaRoutingProvider: RoutingProvider;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as re, t as Ae, i as nt, a as Re, s as rt, C as ot, b as it, F as at, A as st, d as lt, R as he, e as ct, p as ut, m as dt, f as ht, g as pt, h as gt } from "./raster-pipeline-
|
|
1
|
+
import { c as re, t as Ae, i as nt, a as Re, s as rt, C as ot, b as it, F as at, A as st, d as lt, R as he, e as ct, p as ut, m as dt, f as ht, g as pt, h as gt } from "./raster-pipeline-BmHRCUEb.js";
|
|
2
2
|
import pe from "./index-CW1n5LdO.js";
|
|
3
3
|
function mt(e, t) {
|
|
4
4
|
const n = e.length / 3, r = new Uint8ClampedArray(n * 4), o = 0, i = n, a = n * 2;
|
|
@@ -1069,7 +1069,7 @@ A.set(m.Zstd, () => import("./zstd-jXobGRcq.js").then((e) => e.decode));
|
|
|
1069
1069
|
A.set(m.Jpeg, () => Promise.resolve(oe));
|
|
1070
1070
|
A.set(m.Jpeg6, () => Promise.resolve(oe));
|
|
1071
1071
|
A.set(m.Webp, () => Promise.resolve(oe));
|
|
1072
|
-
A.set(m.Lerc, () => import("./lerc-
|
|
1072
|
+
A.set(m.Lerc, () => import("./lerc-BgzbFAc7.js").then((e) => e.l).then((e) => e.decode));
|
|
1073
1073
|
async function ie(e, t, n) {
|
|
1074
1074
|
const r = A.get(t);
|
|
1075
1075
|
if (!r)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { w as ae } from "./mgrs-BY9bIvp4.js";
|
|
2
|
-
import { am as ce, an as le, ao as ee, ap as te, aq as ue, b as he, ar as de, l as Z, as as fe, d as pe, at as me, au as ge, av as ve, aw as ne } from "./index-
|
|
2
|
+
import { am as ce, an as le, ao as ee, ap as te, aq as ue, b as he, ar as de, l as Z, as as fe, d as pe, at as me, au as ge, av as ve, aw as ne } from "./index-CAuq7wRs.js";
|
|
3
3
|
function Pe(o, e, t) {
|
|
4
4
|
const { projectedCorners: n } = e, { topLeft: s, topRight: r, bottomRight: a, bottomLeft: i } = n, c = t(s[0], s[1]), u = t(r[0], r[1]), l = t(a[0], a[1]), d = t(i[0], i[1]), f = [
|
|
5
5
|
c,
|
package/dist/react/om-layer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LayerDescriptor, Selection } from "@nika-js/onlymap";
|
|
1
|
+
import type { LayerDescriptor, LayerFilterFieldSpec, LayerCategoryFilterFieldSpec, Selection } from "@nika-js/onlymap";
|
|
2
2
|
export interface OmLayerProps {
|
|
3
3
|
/** Stable identity — same contract as the `id` attribute. */
|
|
4
4
|
id: string;
|
|
@@ -14,12 +14,16 @@ export interface OmLayerProps {
|
|
|
14
14
|
/** Legend metadata (ctx.layers). */
|
|
15
15
|
label?: string;
|
|
16
16
|
color?: string;
|
|
17
|
-
/** GPU filter (DataFilterExtension) — mirrors filter-field/filter-range. */
|
|
17
|
+
/** GPU filter (DataFilterExtension) — mirrors filter-field/filter-range (single dimension). */
|
|
18
18
|
filterField?: string;
|
|
19
19
|
filterRange?: [number, number];
|
|
20
20
|
filterSoftRange?: [number, number];
|
|
21
|
+
/** Multi-dimension GPU filter (up to 4) — mirrors `filter-fields`. Wins over `filterField`/`filterRange` if both are set. */
|
|
22
|
+
filterFields?: LayerFilterFieldSpec[];
|
|
21
23
|
filterCategoryField?: string;
|
|
22
24
|
filterCategories?: unknown[];
|
|
25
|
+
/** Multi-dimension categorical GPU filter (up to 4) — mirrors `filter-category-fields`. Wins over `filterCategoryField`/`filterCategories` if both are set. */
|
|
26
|
+
filterCategoryFields?: LayerCategoryFilterFieldSpec[];
|
|
23
27
|
/** Dashed path styling, mirroring `dash` / `dash-justified`. */
|
|
24
28
|
dash?: [number, number];
|
|
25
29
|
dashJustified?: boolean;
|
package/dist/react.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
var Ee = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var oe = (e, t, s) =>
|
|
2
|
+
var Fe = (e, t, s) => t in e ? Ee(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s;
|
|
3
|
+
var oe = (e, t, s) => Fe(e, typeof t != "symbol" ? t + "" : t, s);
|
|
4
4
|
import { jsxs as X, jsx as O } from "react/jsx-runtime";
|
|
5
|
-
import { createContext as
|
|
6
|
-
import { MANAGED_SLOTS as
|
|
5
|
+
import { createContext as Re, useContext as xe, forwardRef as Ce, useRef as h, useState as j, useId as ce, useCallback as se, useMemo as L, useLayoutEffect as ie, useEffect as R, useImperativeHandle as Te, useSyncExternalStore as de } from "react";
|
|
6
|
+
import { MANAGED_SLOTS as Pe, slotContainerStyle as ke, FOLD_SIDES as A, MapController as Le, parseWidgetStyle as Me, foldToggleSlot as $e, foldToggleStyle as je, foldPanelStyle as De, foldDrawerStyle as _e, resolveFoldBreakpointPx as Ae, shouldFoldAtWidth as Ie, DEFAULT_FOLD_BREAKPOINT_PX as ze, resolveSlot as Ke, foldSideForSlot as He, isStoreToken as Ne } from "@nika-js/onlymap";
|
|
7
7
|
import { createPortal as ue } from "react-dom";
|
|
8
|
-
const fe =
|
|
8
|
+
const fe = Re(null);
|
|
9
9
|
function W(e) {
|
|
10
|
-
const t =
|
|
10
|
+
const t = xe(fe);
|
|
11
11
|
if (!t) throw new Error(`[onlymapjs] ${e} must be rendered inside <OmMap>.`);
|
|
12
12
|
return t;
|
|
13
13
|
}
|
|
@@ -33,7 +33,7 @@ class qe {
|
|
|
33
33
|
this.descriptors.delete(t) && this.controller.setLayers([...this.descriptors.values()]);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
const N =
|
|
36
|
+
const N = Pe, Ve = Object.fromEntries(N.map((e) => [e, ke(e)])), ae = { display: "flex", pointerEvents: "none", order: 2147483647 }, Be = Object.fromEntries(A.map((e) => [e, null]));
|
|
37
37
|
function Je(e) {
|
|
38
38
|
const t = e.querySelector(
|
|
39
39
|
'button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])'
|
|
@@ -43,10 +43,10 @@ function Je(e) {
|
|
|
43
43
|
function Ye(e, t) {
|
|
44
44
|
return Object.entries(t).some(([s, o]) => o !== void 0 && e[s] !== o);
|
|
45
45
|
}
|
|
46
|
-
const nt =
|
|
47
|
-
const { center: o, zoom: i, pitch: m, bearing: c, basemap: l, basemapKey: g, attribution: p, headless: d, widgetStyle:
|
|
46
|
+
const nt = Ce(function(t, s) {
|
|
47
|
+
const { center: o, zoom: i, pitch: m, bearing: c, basemap: l, basemapKey: g, attribution: p, headless: d, widgetStyle: x, widgetsHidden: v, widgetsFold: b = !0, className: y, style: C, children: w } = t, E = h(null), P = h(null), [a, M] = j(null), [k, q] = j(null), [T, D] = j(
|
|
48
48
|
() => Object.fromEntries(N.map((r) => [r, null]))
|
|
49
|
-
), [
|
|
49
|
+
), [F, I] = j(!1), [V, me] = j(Be), [ge, ye] = j(
|
|
50
50
|
() => Object.fromEntries(A.map((r) => [r, 0]))
|
|
51
51
|
), [be, B] = j(null), Z = `om-react-fold-${ce().replaceAll(":", "")}`, he = h(new Map(A.map((r) => [r, /* @__PURE__ */ new Set()]))), ee = d ? JSON.stringify(d) : "", z = h({
|
|
52
52
|
badge: null,
|
|
@@ -88,9 +88,9 @@ const nt = Te(function(t, s) {
|
|
|
88
88
|
if (f(r.getBoundingClientRect().width || (d ? d === !0 ? 800 : d.width ?? 800 : 0)), typeof ResizeObserver > "u") return;
|
|
89
89
|
const S = new ResizeObserver(([_]) => f(_.contentRect.width));
|
|
90
90
|
return S.observe(r), () => S.disconnect();
|
|
91
|
-
}, [b, ee]),
|
|
92
|
-
(!
|
|
93
|
-
}, [
|
|
91
|
+
}, [b, ee]), R(() => {
|
|
92
|
+
(!F || v) && B(null);
|
|
93
|
+
}, [F, v]);
|
|
94
94
|
const re = h({ center: o, zoom: i, pitch: m, bearing: c });
|
|
95
95
|
re.current = { center: o, zoom: i, pitch: m, bearing: c };
|
|
96
96
|
const K = h(t.onReady);
|
|
@@ -103,10 +103,10 @@ const nt = Te(function(t, s) {
|
|
|
103
103
|
J.current = l;
|
|
104
104
|
const Y = h(void 0);
|
|
105
105
|
ie(() => {
|
|
106
|
-
if (!
|
|
106
|
+
if (!P.current) return;
|
|
107
107
|
const r = re.current;
|
|
108
108
|
Y.current = J.current;
|
|
109
|
-
const n = new Le(
|
|
109
|
+
const n = new Le(P.current, {
|
|
110
110
|
center: r.center,
|
|
111
111
|
zoom: r.zoom,
|
|
112
112
|
pitch: r.pitch,
|
|
@@ -132,13 +132,13 @@ const nt = Te(function(t, s) {
|
|
|
132
132
|
}), () => {
|
|
133
133
|
u = !1, M(null), n.destroy();
|
|
134
134
|
};
|
|
135
|
-
}, [ee]),
|
|
135
|
+
}, [ee]), R(() => {
|
|
136
136
|
!a || Y.current === l || (Y.current = l, a.setBasemap(l ?? null));
|
|
137
|
-
}, [a, l]),
|
|
137
|
+
}, [a, l]), Te(s, () => a, [a]), R(() => {
|
|
138
138
|
if (!a) return;
|
|
139
139
|
const r = { longitude: o == null ? void 0 : o[0], latitude: o == null ? void 0 : o[1], zoom: i, pitch: m, bearing: c };
|
|
140
140
|
Ye(a.getViewState(), r) && a.setView(r);
|
|
141
|
-
}, [a, o == null ? void 0 : o[0], o == null ? void 0 : o[1], i, m, c]),
|
|
141
|
+
}, [a, o == null ? void 0 : o[0], o == null ? void 0 : o[1], i, m, c]), R(() => {
|
|
142
142
|
var r;
|
|
143
143
|
if (a)
|
|
144
144
|
return (r = $.current) == null || r.call($, a.getViewState()), a.getStore("viewport").subscribe(() => {
|
|
@@ -153,15 +153,15 @@ const nt = Te(function(t, s) {
|
|
|
153
153
|
zIndex: 20,
|
|
154
154
|
pointerEvents: "none",
|
|
155
155
|
opacity: "var(--om-widget-opacity, 1)",
|
|
156
|
-
...
|
|
156
|
+
...x ? Me(x).properties : void 0
|
|
157
157
|
}),
|
|
158
|
-
[
|
|
158
|
+
[x]
|
|
159
159
|
), G = L(() => a ? new qe(a) : null, [a]), ne = L(
|
|
160
|
-
() => a && G && k ? { controller: a, layers: G, overlayPane: k, corners:
|
|
161
|
-
[a, G, k,
|
|
160
|
+
() => a && G && k ? { controller: a, layers: G, overlayPane: k, corners: T, widgetsHidden: !!v, widgetsFolded: F, foldPanels: V, registerFoldedWidget: te } : null,
|
|
161
|
+
[a, G, k, T, v, F, V, te]
|
|
162
162
|
);
|
|
163
|
-
return /* @__PURE__ */ X("div", { ref: E, className: y, style: { position: "relative", overflow: "hidden", ...
|
|
164
|
-
/* @__PURE__ */ O("div", { ref:
|
|
163
|
+
return /* @__PURE__ */ X("div", { ref: E, className: y, style: { position: "relative", overflow: "hidden", ...C }, children: [
|
|
164
|
+
/* @__PURE__ */ O("div", { ref: P, style: { position: "absolute", inset: 0 } }),
|
|
165
165
|
/* @__PURE__ */ O(
|
|
166
166
|
"div",
|
|
167
167
|
{
|
|
@@ -176,10 +176,10 @@ const nt = Te(function(t, s) {
|
|
|
176
176
|
ref: ve[r],
|
|
177
177
|
style: {
|
|
178
178
|
...Ve[r],
|
|
179
|
-
...
|
|
179
|
+
...F && r === "bottom-end" ? { bottom: "calc(var(--om-widget-inset-y, 12px) + 28px)" } : void 0
|
|
180
180
|
},
|
|
181
181
|
children: [
|
|
182
|
-
|
|
182
|
+
F && A.filter((n) => $e(n) === r && ge[n] > 0).map((n) => {
|
|
183
183
|
const u = be === n;
|
|
184
184
|
return /* @__PURE__ */ X(
|
|
185
185
|
"div",
|
|
@@ -262,8 +262,10 @@ const nt = Te(function(t, s) {
|
|
|
262
262
|
"filterField",
|
|
263
263
|
"filterRange",
|
|
264
264
|
"filterSoftRange",
|
|
265
|
+
"filterFields",
|
|
265
266
|
"filterCategoryField",
|
|
266
267
|
"filterCategories",
|
|
268
|
+
"filterCategoryFields",
|
|
267
269
|
"dash",
|
|
268
270
|
"dashJustified",
|
|
269
271
|
"source",
|
|
@@ -288,8 +290,10 @@ function Ue(e) {
|
|
|
288
290
|
filterField: e.filterField,
|
|
289
291
|
filterRange: e.filterRange,
|
|
290
292
|
filterSoftRange: e.filterSoftRange,
|
|
293
|
+
filterFields: e.filterFields,
|
|
291
294
|
filterCategoryField: e.filterCategoryField,
|
|
292
295
|
filterCategories: e.filterCategories,
|
|
296
|
+
filterCategoryFields: e.filterCategoryFields,
|
|
293
297
|
dash: e.dash,
|
|
294
298
|
dashJustified: e.dashJustified,
|
|
295
299
|
source: e.source,
|
|
@@ -303,13 +307,13 @@ function Ue(e) {
|
|
|
303
307
|
}
|
|
304
308
|
function ot(e) {
|
|
305
309
|
const { controller: t, layers: s } = W("OmLayer"), { id: o } = e, i = Ue(e);
|
|
306
|
-
|
|
310
|
+
R(() => {
|
|
307
311
|
s.upsert(i);
|
|
308
|
-
}),
|
|
312
|
+
}), R(() => () => s.remove(o), [s, o]);
|
|
309
313
|
const m = h(e.onClick);
|
|
310
314
|
m.current = e.onClick;
|
|
311
315
|
const c = h(e.onHover);
|
|
312
|
-
return c.current = e.onHover,
|
|
316
|
+
return c.current = e.onHover, R(
|
|
313
317
|
() => t.watchPicks((l) => {
|
|
314
318
|
var g, p, d;
|
|
315
319
|
if (l === null) {
|
|
@@ -322,14 +326,14 @@ function ot(e) {
|
|
|
322
326
|
), null;
|
|
323
327
|
}
|
|
324
328
|
function st({ position: e = "top-start", order: t, fold: s, className: o, style: i, children: m }) {
|
|
325
|
-
const { corners: c, widgetsHidden: l, widgetsFolded: g, foldPanels: p, registerFoldedWidget: d } = W("OmWidget"),
|
|
326
|
-
if (
|
|
329
|
+
const { corners: c, widgetsHidden: l, widgetsFolded: g, foldPanels: p, registerFoldedWidget: d } = W("OmWidget"), x = ce(), v = Ke(e) ?? "top-start", b = g && v !== "manual" && s !== "never", y = v === "manual" ? null : He(v);
|
|
330
|
+
if (R(() => {
|
|
327
331
|
if (y)
|
|
328
|
-
return d(y,
|
|
329
|
-
}, [y,
|
|
332
|
+
return d(y, x, b), () => d(y, x, !1);
|
|
333
|
+
}, [y, x, b, d]), v === "manual")
|
|
330
334
|
return /* @__PURE__ */ O("div", { className: o, style: { pointerEvents: "auto", ...i }, children: m });
|
|
331
|
-
const
|
|
332
|
-
return
|
|
335
|
+
const C = b && y ? p[y] : c[v];
|
|
336
|
+
return C ? ue(
|
|
333
337
|
/* @__PURE__ */ O(
|
|
334
338
|
"div",
|
|
335
339
|
{
|
|
@@ -345,7 +349,7 @@ function st({ position: e = "top-start", order: t, fold: s, className: o, style:
|
|
|
345
349
|
children: m
|
|
346
350
|
}
|
|
347
351
|
),
|
|
348
|
-
|
|
352
|
+
C
|
|
349
353
|
) : null;
|
|
350
354
|
}
|
|
351
355
|
function le(e, t, s, o) {
|
|
@@ -367,12 +371,12 @@ function it(e) {
|
|
|
367
371
|
m.current = e;
|
|
368
372
|
const c = L(() => {
|
|
369
373
|
const b = t.getStore("selection");
|
|
370
|
-
let y,
|
|
374
|
+
let y, C, w = null;
|
|
371
375
|
return {
|
|
372
376
|
subscribe: b.subscribe,
|
|
373
377
|
getSnapshot: () => {
|
|
374
|
-
const E = b.getSnapshot(), { anchorFrom:
|
|
375
|
-
return (E !== y || k !==
|
|
378
|
+
const E = b.getSnapshot(), { anchorFrom: P, layer: a, selectionType: M } = m.current, k = `${P ?? ""}|${a ?? ""}|${M ?? ""}`;
|
|
379
|
+
return (E !== y || k !== C) && (y = E, C = k, P === "selection" && le(E, a, M, t.getLastPickType()) && (w = E)), w;
|
|
376
380
|
}
|
|
377
381
|
};
|
|
378
382
|
}, [t]), l = de(
|
|
@@ -380,28 +384,28 @@ function it(e) {
|
|
|
380
384
|
c.getSnapshot,
|
|
381
385
|
c.getSnapshot
|
|
382
386
|
);
|
|
383
|
-
|
|
384
|
-
() => t.registerOverlay((b, y,
|
|
387
|
+
R(
|
|
388
|
+
() => t.registerOverlay((b, y, C) => {
|
|
385
389
|
const w = o.current;
|
|
386
390
|
if (!w) return;
|
|
387
|
-
const { anchor: E, anchorFrom:
|
|
388
|
-
let
|
|
389
|
-
if (
|
|
391
|
+
const { anchor: E, anchorFrom: P, layer: a, selectionType: M, visible: k = !0, anchorOffset: q } = m.current;
|
|
392
|
+
let T;
|
|
393
|
+
if (P === "selection" ? (le(y, a, M, C) && (i.current = (y == null ? void 0 : y.coordinate) ?? void 0), T = i.current) : T = E, !k || !T || !b) {
|
|
390
394
|
w.style.visibility = "hidden";
|
|
391
395
|
return;
|
|
392
396
|
}
|
|
393
|
-
const [D,
|
|
394
|
-
if (!(D >= 0 && D <= b.width &&
|
|
397
|
+
const [D, F, I] = b.project([T[0], T[1], T[2] ?? 0]);
|
|
398
|
+
if (!(D >= 0 && D <= b.width && F >= 0 && F <= b.height) || I !== void 0 && I < 0) {
|
|
395
399
|
w.style.visibility = "hidden";
|
|
396
400
|
return;
|
|
397
401
|
}
|
|
398
|
-
w.style.visibility = "visible", w.style.transform = `translate(${D}px, ${
|
|
402
|
+
w.style.visibility = "visible", w.style.transform = `translate(${D}px, ${F}px) ${Xe[q ?? "bottom-center"]}`;
|
|
399
403
|
}),
|
|
400
404
|
[t]
|
|
401
|
-
),
|
|
405
|
+
), R(() => {
|
|
402
406
|
t.refreshOverlays();
|
|
403
407
|
});
|
|
404
|
-
const { children: g, className: p, style: d, interactive:
|
|
408
|
+
const { children: g, className: p, style: d, interactive: x = !0 } = e, v = typeof g == "function" ? g(l) : g;
|
|
405
409
|
return ue(
|
|
406
410
|
/* @__PURE__ */ O(
|
|
407
411
|
"div",
|
|
@@ -415,7 +419,7 @@ function it(e) {
|
|
|
415
419
|
visibility: "hidden",
|
|
416
420
|
// hidden until the first flush positions it — never flashes at the origin
|
|
417
421
|
willChange: "transform",
|
|
418
|
-
pointerEvents:
|
|
422
|
+
pointerEvents: x ? "auto" : "none",
|
|
419
423
|
...d
|
|
420
424
|
},
|
|
421
425
|
children: v
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drives interpolation + follow-camera for `type="Tracking"` layers (spec:
|
|
3
|
+
* "Routing & Tracking"). Deliberately isolated from `RuntimeCore.reconcile`'s
|
|
4
|
+
* own internals — called as one line from that method, reusing the SAME
|
|
5
|
+
* per-frame channel `trace`/`pulse` already ride (`runLayerEffect`/
|
|
6
|
+
* `patchAnimatedProps`, src/effects.ts), not a parallel animation system.
|
|
7
|
+
*
|
|
8
|
+
* Position/bearing come from the layer's OWN already-resolved IR props (the
|
|
9
|
+
* compiled `getPosition` accessor, the `bearingField` name) — no new
|
|
10
|
+
* field-resolution kernel invented for this.
|
|
11
|
+
*/
|
|
12
|
+
import type { RuntimeCore } from "./runtime-core";
|
|
13
|
+
import type { LayerIR } from "./ir";
|
|
14
|
+
/** Shortest-path angle interpolation — a plain lerp on raw degrees would swing the long way around at the 0/360 wrap (350° → 10° should pass through 0°, not backward through 180°). Exported for direct unit testing (the `traceProgress`/`pulseOpacity` precedent in effects.ts — "pure math, unit-testable without a clock"). */
|
|
15
|
+
export declare function lerpAngle(a: number, b: number, t: number): number;
|
|
16
|
+
/**
|
|
17
|
+
* Called once per `reconcile()`, after `RuntimeCore.lastIRs` is updated —
|
|
18
|
+
* needs the PREVIOUS set (passed in explicitly) to detect a genuine new fix
|
|
19
|
+
* vs. an unrelated reconcile (a sibling layer's edit, a story step) that
|
|
20
|
+
* left this layer's `data` reference untouched.
|
|
21
|
+
*/
|
|
22
|
+
export declare function updateTrackingLayers(core: RuntimeCore, previousIRs: readonly LayerIR[], irs: readonly LayerIR[]): void;
|
package/dist/version.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ur, d as lr, R as zt, e as fr, m as dr, p as St, f as hr, g as pr, h as mr } from "./raster-pipeline-
|
|
2
|
-
import { ap as gr } from "./index-
|
|
1
|
+
import { A as ur, d as lr, R as zt, e as fr, m as dr, p as St, f as hr, g as pr, h as mr } from "./raster-pipeline-BmHRCUEb.js";
|
|
2
|
+
import { ap as gr } from "./index-CAuq7wRs.js";
|
|
3
3
|
import $t from "./index-CW1n5LdO.js";
|
|
4
4
|
var Et;
|
|
5
5
|
function h(e, t, n) {
|
package/docs/3d-assets.md
CHANGED
|
@@ -181,7 +181,7 @@ Face counts are long-tailed, so the building count you can fit is not predictabl
|
|
|
181
181
|
|
|
182
182
|
### Visible edges in surfaces mode
|
|
183
183
|
|
|
184
|
-
Surfaces mode is flat-shaded, so adjacent faces at similar heights (e.g. a LoD2.2 hip roof's planes) can be hard to tell apart by color alone. Each row carries an `outline` field — the same face's outer ring, flattened and closed — for exactly this: give a `PathLayer` `get-path="$outline"` and it traces real per-face edges. Always pair one with a surfaces-mode `SolidPolygonLayer`; deck's `wireframe` prop on `SolidPolygonLayer` only builds wireframe geometry when `extruded: true`, so it does nothing in this unextruded mode. Point the `PathLayer` at the same `data` URL (the cache is keyed by URL, so
|
|
184
|
+
Surfaces mode is flat-shaded, so adjacent faces at similar heights (e.g. a LoD2.2 hip roof's planes) can be hard to tell apart by color alone. Each row carries an `outline` field — the same face's outer ring, flattened and closed — for exactly this: give a `PathLayer` `get-path="$outline"` and it traces real per-face edges. Always pair one with a surfaces-mode `SolidPolygonLayer`; deck's `wireframe` prop on `SolidPolygonLayer` only builds wireframe geometry when `extruded: true`, so it does nothing in this unextruded mode. Point the `PathLayer` at the same `data` URL (the cache is keyed by URL plus live-source options, so two plain layers on one URL share a single fetch — give one of them a `refresh`/stream attribute the other lacks and they become separate requests) and mirror the fill layer's `filter-field`/`filter-range` so filtered-out buildings' outlines disappear too.
|
|
185
185
|
|
|
186
186
|
The semantics still do work in both modes: they decide which surfaces count as roof, so these are real roof measurements rather than bounding-box numbers. Derived names win over a same-named source attribute, so manifests can rely on them.
|
|
187
187
|
|
package/docs/live-data.md
CHANGED
|
@@ -86,6 +86,23 @@ handles while preserving descriptors and rendered state;
|
|
|
86
86
|
This is the intended app-background/app-foreground integration for native
|
|
87
87
|
hosts.
|
|
88
88
|
|
|
89
|
+
A transport released by an owner that means to come back leaves its **last rows
|
|
90
|
+
behind as a cold snapshot**, keyed by the same transport identity. Re-acquiring
|
|
91
|
+
it — `resume()`, or re-adding a layer you removed — repaints those rows
|
|
92
|
+
immediately instead of flashing an empty layer while the first fetch or stream
|
|
93
|
+
message arrives; on a 30-second feed that gap would otherwise be 30 seconds of
|
|
94
|
+
blank map after every foreground. A keyed stream also restores its upsert set,
|
|
95
|
+
so the next message merges rather than replacing.
|
|
96
|
+
|
|
97
|
+
Only reversible releases retain. `suspend()` and layer removal/re-pointing keep
|
|
98
|
+
their rows; `MapController.destroy()` and an `<om-map>` leaving the document
|
|
99
|
+
keep nothing, since neither can re-acquire. (Re-parenting a live `<om-map>`
|
|
100
|
+
isn't a teardown at all — the release is deferred a microtask, so the transport
|
|
101
|
+
never stops.) The snapshot is cold, not live: the first real response supersedes
|
|
102
|
+
it, and polling readiness (`om-map-ready`) still waits for that response.
|
|
103
|
+
Nothing is retained for a transport still held by another owner — it was never
|
|
104
|
+
stopped.
|
|
105
|
+
|
|
89
106
|
## Testing live layers
|
|
90
107
|
|
|
91
108
|
In the [headless harness](testing.md), mock the transport: `vi.stubGlobal("fetch", ...)` for polling (readiness waits for your mock), or `vi.stubGlobal("WebSocket", ...)` for streams. The library's own test suites are the reference patterns — including asserting *movement* (fixed entity count, changing coordinates) rather than just presence.
|