@nika-js/onlymap 0.6.1 → 0.6.4
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 +106 -1
- package/README.md +28 -15
- package/dist/{LercDecode.es-CJnypw8j.js → LercDecode.es-D5in29tf.js} +1 -1
- package/dist/{basemap-DrQ0-eyR.js → basemap-C0pFT3AO.js} +13 -3
- package/dist/basemap.d.ts +10 -1
- package/dist/clip-box-controller.d.ts +94 -0
- package/dist/clip-box.d.ts +109 -0
- package/dist/data-layer.d.ts +34 -4
- package/dist/draw-controller.d.ts +75 -1
- package/dist/draw.d.ts +22 -4
- package/dist/elements/om-map.d.ts +20 -0
- package/dist/elements/om-overlay.d.ts +12 -0
- package/dist/geodesy.d.ts +32 -3
- package/dist/{geoparquet-Dix4lTNy.js → geoparquet-By98JVB0.js} +1 -1
- package/dist/html-data.d.ts +2 -2
- package/dist/{index-BQMjW5w0.js → index-Bx9GFkrn.js} +1 -1
- package/dist/{index-CXPaeisL.js → index-CqC4sW_k.js} +1 -1
- package/dist/{index-1UgNlfGR.js → index-Cxo9mCw_.js} +30947 -27785
- package/dist/{index-B_1PPJgC.js → index-olfncHIq.js} +1 -1
- package/dist/{index-CAuT5j9Y.js → index-tnlYDALL.js} +2 -2
- package/dist/index.d.ts +8 -3
- package/dist/ir-snapshot.d.ts +3 -1
- package/dist/layers/bim-layer.d.ts +30 -7
- package/dist/layers/feature-mesh-layer.d.ts +1 -1
- package/dist/layers/popup-layer.d.ts +13 -0
- package/dist/legend-spec.d.ts +1 -1
- package/dist/{lerc-CbTjQ7uI.js → lerc-gKDDtc69.js} +2 -2
- package/dist/license.d.ts +25 -4
- package/dist/measure-controller.d.ts +482 -4
- package/dist/onlymap.standalone.js +53976 -50804
- package/dist/onlymapjs.js +42 -40
- package/dist/parse-manifest.d.ts +3 -0
- package/dist/programmatic.d.ts +34 -5
- package/dist/{raster-0b0nSHUh.js → raster-Cl5m3KsC.js} +2 -2
- package/dist/{raster-pipeline-D8siq7-4.js → raster-pipeline-hJGxIwYx.js} +1 -1
- package/dist/react/om-layer.d.ts +6 -1
- package/dist/react.js +167 -160
- package/dist/region-export-controller.d.ts +37 -0
- package/dist/region-export.d.ts +56 -0
- package/dist/runtime-core.d.ts +150 -0
- package/dist/selection.d.ts +11 -1
- package/dist/site-placement.d.ts +22 -0
- package/dist/snapping.d.ts +88 -0
- package/dist/terrain-heightfield.d.ts +53 -0
- package/dist/terrain-sample.d.ts +30 -0
- package/dist/terrain.d.ts +6 -1
- package/dist/units.d.ts +27 -0
- package/dist/version.d.ts +1 -1
- package/dist/volumetrics-run.d.ts +13 -0
- package/dist/volumetrics-worker.d.ts +1 -0
- package/dist/volumetrics.d.ts +201 -0
- package/dist/{zarr-DCYro_Vs.js → zarr-hRDavRGV.js} +2 -2
- package/docs/3d-assets.md +49 -1
- package/docs/live-data.md +26 -1
- package/docs/react.md +9 -1
- package/docs/testing.md +2 -0
- package/llms.txt +10 -5
- package/onlymapjs.html-data.json +161 -2
- package/package.json +4 -2
- package/skills/onlymapjs/SKILL.md +11 -1
- package/skills/onlymapjs/references/react.md +2 -2
- package/skills/onlymapjs/references/syntax.md +20 -8
- package/skills/onlymapjs/references/testing.md +6 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clip box (spec: issue #34 §"Cutting / Clipping", tier 2 — the geometric
|
|
3
|
+
* complement to issue #26's clip PLANE). A real oriented... well, AXIS-
|
|
4
|
+
* ALIGNED (v1 scope, confirmed explicitly — rotation is a documented
|
|
5
|
+
* follow-up, not this) 3D box: geometry outside it is discarded (or, in
|
|
6
|
+
* `highlight` mode, dimmed rather than removed — "non-destructive"), so a
|
|
7
|
+
* dense scene (a BIM model, a point cloud, a city block) can be cut open to
|
|
8
|
+
* see what's inside.
|
|
9
|
+
*
|
|
10
|
+
* Map-level scene state (spec: `<om-map clip-box-min="..." clip-box-max="..."
|
|
11
|
+
* clip-box-invert clip-box-highlight>`), same architecture as `lighting`/
|
|
12
|
+
* `terrain`: attribute-backed, undoable, live-editable, applied to every
|
|
13
|
+
* layer by default with a per-layer `clip="off"` escape hatch — see
|
|
14
|
+
* `applyClipBox`'s own doc comment for why that default (not opt-in) is
|
|
15
|
+
* the right one here specifically.
|
|
16
|
+
*
|
|
17
|
+
* Three corrections from the original design review, all reflected below:
|
|
18
|
+
* 1. "Outside the box" is `!inside` (De Morgan's law on the AND of 6
|
|
19
|
+
* half-spaces) — NOT a literal OR of 6 flipped half-space tests, which
|
|
20
|
+
* would (incorrectly) require re-deriving 6 new inequalities; negating
|
|
21
|
+
* the single boolean `inside` result is simpler and exactly equivalent.
|
|
22
|
+
* 2. Plane/box bounds are expressed in deck's COMMON SPACE (via
|
|
23
|
+
* `Layer#projectPosition`, the SAME mechanism the built-in `ClipExtension`
|
|
24
|
+
* uses for its own 2D bounds) — never raw lng/lat — so one authored box
|
|
25
|
+
* clips layers in different coordinate systems (geographic, meter-offset
|
|
26
|
+
* BIM placements, etc.) correctly.
|
|
27
|
+
* 3. Picking (including the `pickable:'3d'` depth pass) is covered for
|
|
28
|
+
* free: `discard` inside `fs:DECKGL_FILTER_COLOR` is the SAME shader
|
|
29
|
+
* stage deck's own picking pass reuses — no separate picking-specific
|
|
30
|
+
* code needed, confirmed by the built-in `ClipExtension` doing nothing
|
|
31
|
+
* extra for picking either.
|
|
32
|
+
*/
|
|
33
|
+
import { LayerExtension } from "@deck.gl/core";
|
|
34
|
+
import type { Layer } from "@deck.gl/core";
|
|
35
|
+
import type { LayerIR } from "./ir";
|
|
36
|
+
export interface ClipBoxIR {
|
|
37
|
+
/** [lng, lat, elevationMeters] — one corner. Order vs. `max` doesn't matter; both get componentwise min/max'd after projecting. */
|
|
38
|
+
min: [number, number, number];
|
|
39
|
+
max: [number, number, number];
|
|
40
|
+
/** Show OUTSIDE the box instead of inside. */
|
|
41
|
+
invert: boolean;
|
|
42
|
+
/** Dim clipped-out geometry instead of discarding it — "non-destructive": nothing disappears, it just de-emphasizes. */
|
|
43
|
+
highlight: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** `<om-map clip-box-min="[...]" clip-box-max="[...]" clip-box-invert clip-box-highlight>` → `ClipBoxIR`, or `null` when min/max aren't both present/valid (no box = no clipping, not a broken one). */
|
|
46
|
+
export declare function parseClipBoxAttrs(getAttr: (name: string) => string | null): ClipBoxIR | null;
|
|
47
|
+
export interface ClipBoxExtensionProps {
|
|
48
|
+
clipBoxMin?: [number, number, number];
|
|
49
|
+
clipBoxMax?: [number, number, number];
|
|
50
|
+
clipBoxInvert?: boolean;
|
|
51
|
+
clipBoxHighlight?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Fragment-level box clip (targets extruded/mesh geometry — GeoJsonLayer extrusions, Tile3DLayer/BIMLayer triangles — not point/icon anchors, unlike the built-in ClipExtension's dual vertex/fragment modes; this library's clip-box use case is "cut into a 3D scene," not "hide points outside a rect"). */
|
|
54
|
+
export declare class ClipBoxExtension extends LayerExtension {
|
|
55
|
+
static extensionName: string;
|
|
56
|
+
static defaultProps: {
|
|
57
|
+
clipBoxMin: number[];
|
|
58
|
+
clipBoxMax: number[];
|
|
59
|
+
clipBoxInvert: boolean;
|
|
60
|
+
clipBoxHighlight: boolean;
|
|
61
|
+
};
|
|
62
|
+
getShaders(): {
|
|
63
|
+
modules: {
|
|
64
|
+
readonly name: "clipBox";
|
|
65
|
+
readonly fs: "\nlayout(std140) uniform clipBoxUniforms {\n vec3 boxMin;\n vec3 boxMax;\n float invert;\n float highlight;\n vec4 highlightTint;\n} clipBox;\n\nbool clipBox_isInside(vec3 commonPos) {\n return commonPos.x >= clipBox.boxMin.x && commonPos.x <= clipBox.boxMax.x\n && commonPos.y >= clipBox.boxMin.y && commonPos.y <= clipBox.boxMax.y\n && commonPos.z >= clipBox.boxMin.z && commonPos.z <= clipBox.boxMax.z;\n}\n";
|
|
66
|
+
readonly uniformTypes: {
|
|
67
|
+
readonly boxMin: "vec3<f32>";
|
|
68
|
+
readonly boxMax: "vec3<f32>";
|
|
69
|
+
readonly invert: "f32";
|
|
70
|
+
readonly highlight: "f32";
|
|
71
|
+
readonly highlightTint: "vec4<f32>";
|
|
72
|
+
};
|
|
73
|
+
}[];
|
|
74
|
+
inject: {
|
|
75
|
+
"vs:#decl": string;
|
|
76
|
+
"vs:DECKGL_FILTER_GL_POSITION": string;
|
|
77
|
+
"fs:#decl": string;
|
|
78
|
+
"fs:DECKGL_FILTER_COLOR": string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
draw(this: Layer<Required<ClipBoxExtensionProps>>): void;
|
|
82
|
+
}
|
|
83
|
+
export interface ClipBoxLayerPatch {
|
|
84
|
+
/**
|
|
85
|
+
* The deck-layer id to construct with. Suffixed `#c<generation>` while a
|
|
86
|
+
* box is active and this layer is opted in: adding/removing an extension
|
|
87
|
+
* on a LIVE (already-mounted) layer corrupts DataFilterExtension's
|
|
88
|
+
* attribute state for some layer types (ColumnLayer, Tile3DLayer/BIMLayer
|
|
89
|
+
* sublayers — empirically verified: a box present from the FIRST render
|
|
90
|
+
* works fine, but toggling one on live on an already-mounted filtered
|
|
91
|
+
* layer silently blanks it, with no console error) — the exact same
|
|
92
|
+
* "birth-stable extension set" issue `applyTerrain`'s own `deckId`
|
|
93
|
+
* suffixing already works around. A fresh id forces clean teardown +
|
|
94
|
+
* rebuild instead of a live prop update.
|
|
95
|
+
*/
|
|
96
|
+
deckId: string;
|
|
97
|
+
extraProps: Record<string, unknown>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Per-layer clip-box patches, PURE — mirrors `applyTerrain`'s exact shape
|
|
101
|
+
* (same file this gets merged alongside in runtime-core.ts's `buildLayers`).
|
|
102
|
+
* Default is APPLIED (every layer gets clipped once a box is configured),
|
|
103
|
+
* unlike terrain's per-layer OPT-IN default — the clip box's whole point is
|
|
104
|
+
* cutting into "the scene," and requiring every single layer to opt in
|
|
105
|
+
* individually would make the common case ("cut through everything, show me
|
|
106
|
+
* what's inside") the awkward one; `clip="off"` is the escape hatch for the
|
|
107
|
+
* layers that shouldn't be touched (a basemap, most often).
|
|
108
|
+
*/
|
|
109
|
+
export declare function applyClipBox(irs: readonly LayerIR[], clipBox: ClipBoxIR | null, generation: number): Map<string, ClipBoxLayerPatch>;
|
package/dist/data-layer.d.ts
CHANGED
|
@@ -90,6 +90,28 @@ export interface DataFormat {
|
|
|
90
90
|
export declare function rowsToColumnar(rows: Record<string, unknown>[]): ColumnarData | undefined;
|
|
91
91
|
/** `OmMap.registerFormat(format)` — plug in a parser for a format the library doesn't ship (spec: "v0.2 / Tier 1"). */
|
|
92
92
|
export declare function registerFormat(format: DataFormat): void;
|
|
93
|
+
/** Opaque controller/element identity used to reference-count data transports. */
|
|
94
|
+
export type DataTransportOwner = object;
|
|
95
|
+
/** Start one descriptor reconciliation transaction for an owner. */
|
|
96
|
+
export declare function beginDataOwnerUpdate(owner: DataTransportOwner): void;
|
|
97
|
+
/**
|
|
98
|
+
* Release transports no longer named by the owner's complete descriptor
|
|
99
|
+
* document. Retains their rows: a layer removed or re-pointed is a routine
|
|
100
|
+
* edit, and re-adding it (or undoing the edit) should repaint, not blink.
|
|
101
|
+
*/
|
|
102
|
+
export declare function endDataOwnerUpdate(owner: DataTransportOwner): void;
|
|
103
|
+
/**
|
|
104
|
+
* Release every fetch/poller/socket held by an owner.
|
|
105
|
+
*
|
|
106
|
+
* Defaults to a permanent teardown — dispose, unmount, an <om-map> leaving the
|
|
107
|
+
* document — which drops the rows too, because an owner that cannot come back
|
|
108
|
+
* has nothing to repaint. Pass `{ retain: true }` for a pause the owner intends
|
|
109
|
+
* to reverse (`MapController.suspend()`), and resuming repaints the last rows
|
|
110
|
+
* while the reopened transport catches up.
|
|
111
|
+
*/
|
|
112
|
+
export declare function releaseDataOwner(owner: DataTransportOwner, opts?: {
|
|
113
|
+
retain?: boolean;
|
|
114
|
+
}): void;
|
|
93
115
|
/**
|
|
94
116
|
* A source plugin supplies domain decoding (and optionally a subscription
|
|
95
117
|
* handshake); the transport (WebSocket, reconnect, flush) is generic.
|
|
@@ -128,7 +150,7 @@ export interface DataRequestConfig {
|
|
|
128
150
|
}
|
|
129
151
|
export declare function configureData(config: DataRequestConfig): void;
|
|
130
152
|
/** @internal Shared request-policy chokepoint for non-row assets (ImageOverlay); not re-exported from the package root. */
|
|
131
|
-
export declare function fetchConfiguredResource(url: string): Promise<Response>;
|
|
153
|
+
export declare function fetchConfiguredResource(url: string, signal?: AbortSignal): Promise<Response>;
|
|
132
154
|
/** @internal Shared Content-Length license backstop for row and non-row sources. */
|
|
133
155
|
export declare function assertFetchSizeWithinEntitlement(response: Response): void;
|
|
134
156
|
/** `data="draw:sketch"` — the reserved scheme for a widget-fed sketch layer (never collides with http/ws/inline). */
|
|
@@ -162,9 +184,17 @@ export declare function getDrawData(url: string): LayerData;
|
|
|
162
184
|
* call for a given URL, and invokes `onLoaded` on every resolution/flush (the
|
|
163
185
|
* caller re-reconciles from there).
|
|
164
186
|
*/
|
|
165
|
-
export declare function getData(url: string, onLoaded: () => void, opts?: StreamOptions): LayerData;
|
|
166
|
-
/**
|
|
167
|
-
|
|
187
|
+
export declare function getData(url: string, onLoaded: () => void, opts?: StreamOptions, owner?: DataTransportOwner): LayerData;
|
|
188
|
+
/**
|
|
189
|
+
* Is a fetch for this URL still in flight? Feeds the `om-map-ready` signal —
|
|
190
|
+
* errored fetches count as settled (readiness must not hang on a bad URL).
|
|
191
|
+
*
|
|
192
|
+
* With an owner this asks only about that owner's OWN transports: a map must
|
|
193
|
+
* never wait on — or be released by — a sibling map's fetch. An owner with no
|
|
194
|
+
* acquired identities has nothing pending by definition, so a missing state is
|
|
195
|
+
* an empty set, not "match anything".
|
|
196
|
+
*/
|
|
197
|
+
export declare function isPendingData(url: string, owner?: DataTransportOwner): boolean;
|
|
168
198
|
/**
|
|
169
199
|
* Minimal feature-shape detection (spec: "Feature Field Resolution & Data
|
|
170
200
|
* Shape" — full per-layer caching/registry treatment is a later phase; this
|
|
@@ -22,6 +22,49 @@ export declare class DrawController {
|
|
|
22
22
|
private readonly autosaveKeys;
|
|
23
23
|
private readonly observers;
|
|
24
24
|
private active;
|
|
25
|
+
/**
|
|
26
|
+
* rAF handle coalescing hover-driven preview updates (spec: "Cut/fill
|
|
27
|
+
* volume measurement" — found debugging click-reliability in standalone
|
|
28
|
+
* mode). `point()` used to call `renderPreview()` (which patches the
|
|
29
|
+
* per-frame channel and rebuilds every deck.gl layer) SYNCHRONOUSLY on
|
|
30
|
+
* every raw mousemove — far more often than the "per-frame" name implies,
|
|
31
|
+
* since mousemove fires at native pointer-event rate, not rAF rate. That
|
|
32
|
+
* rebuild storm intermittently corrupted deck.gl's own click/pick pipeline
|
|
33
|
+
* (mjolnir gesture recognition losing a click shortly after a hover-driven
|
|
34
|
+
* rebuild) — confirmed by disabling hover-triggered rebuilds entirely and
|
|
35
|
+
* watching the click-loss disappear. Coalescing to one rebuild per actual
|
|
36
|
+
* animation frame is what `patchAnimatedProps`'s own doc comment already
|
|
37
|
+
* describes as "the deck-idiomatic rAF pattern" — this was a gap between
|
|
38
|
+
* that intent and this call site, not a design change.
|
|
39
|
+
*/
|
|
40
|
+
private hoverRaf;
|
|
41
|
+
/**
|
|
42
|
+
* The coordinate `commit()` just used to close a shape (its live cursor
|
|
43
|
+
* position at that moment), or null. The native `dblclick` DOM event
|
|
44
|
+
* (which drives `commit()`) fires as soon as the second tap's mouseup
|
|
45
|
+
* lands — but deck.gl's own click-gesture recognition is independently
|
|
46
|
+
* delayed (Hammer's Tap recognizer defers confirming a "click" until it's
|
|
47
|
+
* sure a second tap isn't coming, per its `requireFailure`/`interval`
|
|
48
|
+
* mechanics). One of the double-click's own two taps can therefore still
|
|
49
|
+
* arrive here as a late, ordinary "click" a few ms *after* commit() already
|
|
50
|
+
* ran, at ~that same coordinate — with pending now empty, session.click's
|
|
51
|
+
* own same-spot dedup (see `point()`'s click branch) has nothing to
|
|
52
|
+
* compare against, so it silently starts a fresh one-vertex shape at the
|
|
53
|
+
* spot the user just finished closing.
|
|
54
|
+
*
|
|
55
|
+
* Guarding on position (not a time window) is what keeps this from
|
|
56
|
+
* swallowing a genuinely new, deliberate click that happens to follow
|
|
57
|
+
* immediately after a commit — e.g. redrawing a second shape back-to-back
|
|
58
|
+
* in a test with no elapsed wall-clock time — since that click lands at a
|
|
59
|
+
* different coordinate and passes straight through. The match is a small
|
|
60
|
+
* PIXEL-radius tolerance (see `point()`), not exact equality: a real
|
|
61
|
+
* double-click's two taps are two independent physical presses and rarely
|
|
62
|
+
* land at the bit-identical screen pixel, let alone the bit-identical
|
|
63
|
+
* unprojected lng/lat — exact equality let real hand jitter slip past the
|
|
64
|
+
* guard even though a synthetic, pixel-perfect test wouldn't reveal that.
|
|
65
|
+
* Consumed (cleared) by the very next click regardless of whether it matched.
|
|
66
|
+
*/
|
|
67
|
+
private lastClosePos;
|
|
25
68
|
constructor(mapEl: Element, core: RuntimeCore);
|
|
26
69
|
/** A draw tool is active — om-map routes points here and suppresses selection. */
|
|
27
70
|
isCapturing(): boolean;
|
|
@@ -32,14 +75,45 @@ export declare class DrawController {
|
|
|
32
75
|
* geodesic readouts + labels live off the shared draw stack. `null` unsubs.
|
|
33
76
|
*/
|
|
34
77
|
setObserver(target: string, cb: ((session: DrawSession) => void) | null): void;
|
|
78
|
+
/** This map's own committed-feature count for `target` (spec: "Cut/fill volume measurement") — see DrawSession.count's doc comment for why this beats reading the shared getDrawData mirror. */
|
|
79
|
+
featureCount(target: string): number;
|
|
35
80
|
private notify;
|
|
36
|
-
/** Enable localStorage autosave for a target and restore any saved sketch (draw-config action). */
|
|
81
|
+
/** Enable localStorage autosave for a target and restore any saved sketch, and/or an auto-styled committed-geometry layer (draw-config action). */
|
|
37
82
|
configure(target: string, opts: {
|
|
38
83
|
autosave?: string;
|
|
84
|
+
fillColor?: number[];
|
|
85
|
+
lineColor?: number[];
|
|
39
86
|
}): void;
|
|
87
|
+
/**
|
|
88
|
+
* Opt-in committed-geometry visualization (spec: issue #34's region-export
|
|
89
|
+
* demo surfaced this — a closed shape with no author-added layer is
|
|
90
|
+
* indistinguishable from "double-click didn't work," since the ONLY
|
|
91
|
+
* built-in visual is the in-progress preview, which clears the instant a
|
|
92
|
+
* shape commits). Bound directly to the SAME reactive `draw:<target>` data
|
|
93
|
+
* URL an author's own manual layer would use — this is pure convenience
|
|
94
|
+
* layered on top, not a replacement; an author who wants custom styling
|
|
95
|
+
* (or a non-GeoJsonLayer rendering) still adds their own layer instead,
|
|
96
|
+
* and both can coexist. One committed layer per TARGET (not a singleton
|
|
97
|
+
* like `PREVIEW_ID`), since multiple draw targets can exist on one map.
|
|
98
|
+
*
|
|
99
|
+
* `depthTest: false` (patched, not attribute-expressible — same non-
|
|
100
|
+
* string-prop precedent as the volume gizmo's `mesh`): a flat 2D ring has
|
|
101
|
+
* no z of its own, so on a page with 3D content (the exact case this was
|
|
102
|
+
* built for — outlining a footprint over a BIM building to export) it can
|
|
103
|
+
* sit at an elevation UNDER opaque building geometry, fully occluded from
|
|
104
|
+
* a normal camera angle — the identical depth-occlusion class already
|
|
105
|
+
* fixed for the measure tool's cut-prism guides. This is a SELECTION
|
|
106
|
+
* indicator, not real in-world geometry, so it's correct for it to always
|
|
107
|
+
* read on top regardless of what 3D content surrounds it.
|
|
108
|
+
*/
|
|
109
|
+
private ensureCommittedLayer;
|
|
40
110
|
setMode(target: string, mode: DrawMode | null): void;
|
|
41
111
|
private deactivate;
|
|
42
112
|
point(coord: [number, number] | null, kind: "click" | "hover"): void;
|
|
113
|
+
/** Drop a queued hover-coalesced render (a following immediate render already supersedes it). */
|
|
114
|
+
private cancelHoverRaf;
|
|
115
|
+
/** `CLOSE_GUARD_PIXELS` converted to real meters at the current zoom/latitude (standard Web Mercator meters-per-pixel). */
|
|
116
|
+
private closeGuardMeters;
|
|
43
117
|
/** Close the in-progress line/polygon — from the double-click DOM event or Enter. */
|
|
44
118
|
commit(): void;
|
|
45
119
|
cancel(): void;
|
package/dist/draw.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export interface DrawSessionOpts {
|
|
|
50
50
|
/** Fired whenever the COMMITTED feature set changes (commit / delete / clear / seed) — D2 wires this to the store push. */
|
|
51
51
|
onChange?: (fc: FeatureCollection) => void;
|
|
52
52
|
}
|
|
53
|
+
export declare function samePoint(a: Position, b: Position): boolean;
|
|
53
54
|
/**
|
|
54
55
|
* One sketch session. Owns the committed features and the single in-progress
|
|
55
56
|
* shape. Every mutation that changes the committed set fires `onChange` once.
|
|
@@ -74,10 +75,16 @@ export declare class DrawSession {
|
|
|
74
75
|
/** Cursor moved — updates the rubber-band target. No committed-set change. */
|
|
75
76
|
move(pos: Position): void;
|
|
76
77
|
/**
|
|
77
|
-
* Finalize the in-progress line/polygon (from double-click / Enter).
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
78
|
+
* Finalize the in-progress line/polygon (from double-click / Enter). The
|
|
79
|
+
* two clicks that make up a double-click are individually unreliable —
|
|
80
|
+
* deck.gl's click/dblclick gesture disambiguation can drop either or both
|
|
81
|
+
* of them depending on exact timing — so rather than depend on them having
|
|
82
|
+
* landed in `pending`, the closing vertex is the live cursor position
|
|
83
|
+
* (already updated by the hover that preceded the double-click, via a
|
|
84
|
+
* separate, non-gesture-gated code path). A trailing duplicate — the
|
|
85
|
+
* cursor exactly repeating the last real vertex — is dropped. No-op (shape
|
|
86
|
+
* kept pending) if there aren't enough distinct vertices yet. Returns the
|
|
87
|
+
* committed feature or null.
|
|
81
88
|
*/
|
|
82
89
|
commit(): DrawFeature | null;
|
|
83
90
|
/** Esc — discard the in-progress shape, keep the tool active. */
|
|
@@ -93,6 +100,17 @@ export declare class DrawSession {
|
|
|
93
100
|
features?: unknown;
|
|
94
101
|
} | null | undefined): void;
|
|
95
102
|
toFeatureCollection(): FeatureCollection;
|
|
103
|
+
/**
|
|
104
|
+
* Committed-feature count for THIS session object (spec: "Cut/fill volume
|
|
105
|
+
* measurement"). Distinct from reading the shared `getDrawData` store
|
|
106
|
+
* mirror: that mirror is a module-global `Map` keyed by URL string with no
|
|
107
|
+
* per-map/per-session isolation, so it can carry a PRIOR session's data
|
|
108
|
+
* (a different `<om-map>` sharing the same runtime-internal target id, or —
|
|
109
|
+
* the case that surfaced this — a freshly re-mounted map in a test) until
|
|
110
|
+
* this session's own first commit overwrites it. This reads `this.features`
|
|
111
|
+
* directly, which always starts empty for a genuinely new session.
|
|
112
|
+
*/
|
|
113
|
+
count(): number;
|
|
96
114
|
/** The in-progress shape for the preview layer, or null when nothing is pending. */
|
|
97
115
|
preview(): DrawPreview | null;
|
|
98
116
|
private finalize;
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { HTMLElementBase } from "../env";
|
|
21
21
|
import { type RuntimeContext } from "../ctx";
|
|
22
22
|
import { type LightingIR } from "../scene-lighting";
|
|
23
|
+
import { type ClipBoxIR } from "../clip-box";
|
|
23
24
|
import { type TerrainIR } from "../terrain";
|
|
24
25
|
import { type WidgetSlot } from "../widget-layout";
|
|
25
26
|
import { type SnapshotOptions } from "../snapshot";
|
|
@@ -44,10 +45,13 @@ export declare class OmMapElement extends HTMLElementBase {
|
|
|
44
45
|
private observer;
|
|
45
46
|
private history;
|
|
46
47
|
private keydownHandler?;
|
|
48
|
+
private keyupHandler?;
|
|
47
49
|
private dblclickHandler?;
|
|
48
50
|
private contextmenuHandler?;
|
|
49
51
|
private mount;
|
|
50
52
|
private reconcilePending;
|
|
53
|
+
private readonly dataOwner;
|
|
54
|
+
private dataReleasePending;
|
|
51
55
|
/** Decoded property tables per pick-features layer — see RuntimeCoreCallbacks.onFeatureTable. */
|
|
52
56
|
private featureTables;
|
|
53
57
|
private layerIRs;
|
|
@@ -257,6 +261,20 @@ export declare class OmMapElement extends HTMLElementBase {
|
|
|
257
261
|
* Fires at pointer rate on hover (no debounce — vertex capture needs
|
|
258
262
|
* every point); heavy listeners should throttle their own work. */
|
|
259
263
|
private handleMapPoint;
|
|
264
|
+
/**
|
|
265
|
+
* XY snapping's snap-tip (spec: issue #34 Part A — "a snap tip shows
|
|
266
|
+
* which agent fired on which layer, otherwise users can't tell why a
|
|
267
|
+
* vertex jumped"). A SEPARATE runtime overlay from the shared
|
|
268
|
+
* `show-tooltip` singleton (`actions.ts`'s `getOrCreateTooltipOverlay`):
|
|
269
|
+
* that one is `anchor-from="selection"` (tied to `ctx.selection`) and
|
|
270
|
+
* shared across every `show-tooltip` behavior a page authors (this
|
|
271
|
+
* page's own z-tooltip, for one) — reusing it here would fight over the
|
|
272
|
+
* same element on every hover. This one anchors at a plain, static
|
|
273
|
+
* `anchor="[lng,lat]"` instead, since a snap position has nothing to do
|
|
274
|
+
* with whatever `ctx.selection` currently holds.
|
|
275
|
+
*/
|
|
276
|
+
private ensureSnapTipOverlay;
|
|
277
|
+
private handleSnapPoint;
|
|
260
278
|
/** Harness map-point injection (spec: "Consumer Testing Surface") — the
|
|
261
279
|
* same path a real deck click/hover coordinate takes, so the om-map-point
|
|
262
280
|
* event and custom capture tools are testable without a GPU. */
|
|
@@ -285,6 +303,8 @@ export declare class OmMapElement extends HTMLElementBase {
|
|
|
285
303
|
getLightingInternal(): LightingIR | null;
|
|
286
304
|
/** Resolved terrain IR (headless test inspection) — null = no surface. */
|
|
287
305
|
getTerrainInternal(): TerrainIR | null;
|
|
306
|
+
/** Resolved clip-box IR (headless test inspection) — null = no active box. */
|
|
307
|
+
getClipBoxInternal(): ClipBoxIR | null;
|
|
288
308
|
/**
|
|
289
309
|
* Canvas-only scene snapshot (spec: "Snapshot API") — basemap + deck
|
|
290
310
|
* composited at device pixels. DOM widgets/overlays/badge/attribution are
|
|
@@ -36,7 +36,19 @@ export declare class OmOverlayElement extends HTMLElementBase {
|
|
|
36
36
|
* simply doesn't update this remembered anchor; only a matching
|
|
37
37
|
* selection moves it, and only an explicit `visible="false"` hides it.
|
|
38
38
|
*/
|
|
39
|
+
/**
|
|
40
|
+
* A 3rd (z) component survives here specifically for the projection at
|
|
41
|
+
* the bottom of `updatePosition` — a selection's real elevation (a depth
|
|
42
|
+
* pick against terrain/3D content, see `Selection.coordinate`'s own doc
|
|
43
|
+
* comment) matters for WHERE on screen the anchor lands under a pitched
|
|
44
|
+
* camera, even though this class only ever positions in 2D. Dropping it
|
|
45
|
+
* (projecting at an implied z=0) put a tooltip over an elevated pick tens
|
|
46
|
+
* to hundreds of pixels from the actual cursor — the anchor was correct
|
|
47
|
+
* in lng/lat, just projected as if the picked surface were at sea level.
|
|
48
|
+
*/
|
|
39
49
|
private lastAnchor;
|
|
50
|
+
/** Cached [w, h] for `clip-to-map` (offsetWidth forces layout; flushes run per pointer move) — invalidated by setContent. */
|
|
51
|
+
private clipSizeCache;
|
|
40
52
|
/** Memoized feature anchor — recomputed only when the layer's data reference or the target id changes (live layers swap data). */
|
|
41
53
|
private featureAnchorCache;
|
|
42
54
|
connectedCallback(): void;
|
package/dist/geodesy.d.ts
CHANGED
|
@@ -23,6 +23,25 @@ export type LngLat = [number, number];
|
|
|
23
23
|
export declare function distanceMeters(a: LngLat, b: LngLat, radius?: number): number;
|
|
24
24
|
/** Total haversine length of a polyline in meters (0 for < 2 points). */
|
|
25
25
|
export declare function pathLengthMeters(points: LngLat[], radius?: number): number;
|
|
26
|
+
export interface PathSample {
|
|
27
|
+
position: LngLat;
|
|
28
|
+
/** Cumulative distance (m) from the path's start. */
|
|
29
|
+
distance: number;
|
|
30
|
+
/** Index into the ORIGINAL input points when this sample IS one of them (see `resamplePathWithVertices`); absent for interpolated samples. */
|
|
31
|
+
vertexIndex?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `count` evenly-spaced points along a multi-segment polyline, by cumulative
|
|
35
|
+
* distance (spec item E — elevation-profile samples). Walks the segment
|
|
36
|
+
* lengths to find which segment each target distance falls in, then
|
|
37
|
+
* `intermediate()`s within it — a straight generalization of that function
|
|
38
|
+
* from "interpolate one segment" to "interpolate a whole path." `count=1`
|
|
39
|
+
* returns just the start point; `points.length < 2` returns each input point
|
|
40
|
+
* at distance 0 (nothing to interpolate); a zero-length path (every point
|
|
41
|
+
* coincident) returns `count` copies of the start point at distance 0.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resamplePath(points: LngLat[], count: number): PathSample[];
|
|
44
|
+
export declare function resamplePathWithVertices(points: LngLat[], count: number): PathSample[];
|
|
26
45
|
/**
|
|
27
46
|
* Spherical polygon area in m² via the Chamberlain–Duquette line integral (the
|
|
28
47
|
* exact index form Turf's `ringArea` uses, so results match Turf's fixtures).
|
|
@@ -40,8 +59,18 @@ export declare function ringPerimeterMeters(ring: LngLat[], radius?: number): nu
|
|
|
40
59
|
*/
|
|
41
60
|
export declare function ringEnclosesPole(ring: LngLat[]): boolean;
|
|
42
61
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
62
|
+
* Point a `fraction` of the way from `a` to `b` along the great-circle path
|
|
63
|
+
* (spherical slerp) — spec item E's evenly-spaced elevation-profile samples
|
|
64
|
+
* need this; only the f=0.5 special case (`midpoint`) existed before.
|
|
65
|
+
* Antimeridian-safe (interpolates the Cartesian unit vectors, not lng/lat
|
|
66
|
+
* directly, so a segment crossing ±180° doesn't wrap the wrong way).
|
|
67
|
+
* `f=0` returns `a`, `f=1` returns `b`. Returns [lng (normalized to
|
|
68
|
+
* (−180, 180]), lat].
|
|
69
|
+
*/
|
|
70
|
+
export declare function intermediate(a: LngLat, b: LngLat, fraction: number): LngLat;
|
|
71
|
+
/**
|
|
72
|
+
* Great-circle midpoint of a segment — `intermediate(a, b, 0.5)`, kept as its
|
|
73
|
+
* own name since "the point halfway along a segment" is the common case
|
|
74
|
+
* (badge label anchors) and reads better than a bare 0.5 at every call site.
|
|
46
75
|
*/
|
|
47
76
|
export declare function midpoint(a: LngLat, b: LngLat): LngLat;
|
package/dist/html-data.d.ts
CHANGED
|
@@ -15,9 +15,9 @@ interface TagData {
|
|
|
15
15
|
}[];
|
|
16
16
|
}
|
|
17
17
|
/** Hand-authored action list — validated against hasAction() in html-data.test.ts. */
|
|
18
|
-
export declare const BUILTIN_ACTIONS: readonly ["toggle-layer", "zoom-in", "zoom-out", "filter-layer", "highlight-feature", "fade", "pulse", "populate", "trace", "story-play", "story-pause", "story-seek", "fly-to", "zoom-to-feature", "show-overlay", "hide-overlay", "show-tooltip", "hide-tooltip", "draw-mode", "draw-commit", "draw-cancel", "draw-delete", "draw-clear", "draw-config", "draw-save", "measure-mode", "measure-clear", "measure-units", "set-basemap", "set-lighting", "set-terrain", "set-widgets-visible", "undo", "redo"];
|
|
18
|
+
export declare const BUILTIN_ACTIONS: readonly ["toggle-layer", "zoom-in", "zoom-out", "filter-layer", "highlight-feature", "fade", "pulse", "populate", "trace", "story-play", "story-pause", "story-seek", "fly-to", "zoom-to-feature", "show-overlay", "hide-overlay", "show-tooltip", "hide-tooltip", "draw-mode", "draw-commit", "draw-cancel", "draw-delete", "draw-clear", "draw-config", "draw-save", "export-region-3d", "measure-mode", "measure-clear", "measure-units", "set-basemap", "set-lighting", "set-terrain", "set-clip-box", "clip-box-edit", "set-widgets-visible", "undo", "redo"];
|
|
19
19
|
/** Hand-authored widget types — validated against the widget registry in html-data.test.ts. */
|
|
20
|
-
export declare const BUILTIN_WIDGETS: readonly ["legend", "layer-switcher", "zoom-controls", "scale-bar", "attribution", "filter", "vega-lite", "player", "draw", "measure", "basemap-switcher", "lighting", "undo-redo", "widgets-toggle", "ifc-browser", "ifc-legend", "feature-inspector", "ifc-inspector", "ifc-loader", "ifc-clash"];
|
|
20
|
+
export declare const BUILTIN_WIDGETS: readonly ["legend", "layer-switcher", "zoom-controls", "scale-bar", "attribution", "filter", "vega-lite", "dynamic-chart", "player", "draw", "measure", "basemap-switcher", "lighting", "clip-box", "undo-redo", "widgets-toggle", "ifc-browser", "ifc-legend", "feature-inspector", "ifc-inspector", "ifc-loader", "ifc-clash"];
|
|
21
21
|
export declare function buildHtmlCustomData(): {
|
|
22
22
|
version: number;
|
|
23
23
|
tags: TagData[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ak as Bt, ax as Xt, ay as Yt, az as Us } from "./index-
|
|
1
|
+
import { ak as Bt, ax as Xt, ay as Yt, az as Us } from "./index-Cxo9mCw_.js";
|
|
2
2
|
import { w as gs, t as Hs, f as Ws, m as Qs } from "./mgrs-BY9bIvp4.js";
|
|
3
3
|
import { c as Xs } from "./convert-arrow-schema-DrAihRf9.js";
|
|
4
4
|
import { y as Ys, A as bt, a as Ks, z as Vs, R as Zs } from "./recordbatch-Bpc0uxFn.js";
|