@nika-js/onlymap 0.6.0 → 0.6.2

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +63 -1
  2. package/README.md +39 -14
  3. package/THIRD-PARTY-LICENSES.md +27 -0
  4. package/dist/{LercDecode.es-fbo6h5rt.js → LercDecode.es-BOJJr6Gx.js} +1 -1
  5. package/dist/{basemap-CprSan9q.js → basemap-BofXgXxy.js} +13 -3
  6. package/dist/basemap.d.ts +10 -1
  7. package/dist/cityjson-D_V5GY8b.js +332 -0
  8. package/dist/clip-box-controller.d.ts +94 -0
  9. package/dist/clip-box.d.ts +109 -0
  10. package/dist/crs-Ciu7Xs7a.js +108 -0
  11. package/dist/crs.d.ts +50 -0
  12. package/dist/ctx.d.ts +8 -1
  13. package/dist/data-layer.d.ts +11 -3
  14. package/dist/draw-controller.d.ts +75 -1
  15. package/dist/draw.d.ts +22 -4
  16. package/dist/elements/om-map.d.ts +45 -2
  17. package/dist/elements/om-overlay.d.ts +13 -1
  18. package/dist/elements/om-widget.d.ts +4 -0
  19. package/dist/feature-colors.d.ts +41 -0
  20. package/dist/geodesy.d.ts +29 -3
  21. package/dist/{geoparquet-Bm8pfxyo.js → geoparquet-DapHATA0.js} +1 -1
  22. package/dist/html-data.d.ts +2 -2
  23. package/dist/ifc-Dc-TdSJr.js +877 -0
  24. package/dist/ifc.d.ts +406 -0
  25. package/dist/{index-Bz-rbmhj.js → index-7B-6Cbzu.js} +31619 -26565
  26. package/dist/{index-DSRIZR81.js → index-BF9iO8Tq.js} +1 -1
  27. package/dist/{index-GOwMjqm6.js → index-BmX6IId3.js} +1 -1
  28. package/dist/{index-UzmNhuS0.js → index-SPJVn_n_.js} +1 -1
  29. package/dist/{index-CCQttJzO.js → index-xmJjZxQJ.js} +2 -2
  30. package/dist/index.d.ts +13 -2
  31. package/dist/ir-snapshot.d.ts +3 -1
  32. package/dist/layer-registry.d.ts +14 -0
  33. package/dist/layers/bim-layer.d.ts +127 -0
  34. package/dist/layers/feature-mesh-layer.d.ts +288 -0
  35. package/dist/layers/gltf-scene-walk.d.ts +55 -0
  36. package/dist/layers/popup-layer.d.ts +13 -0
  37. package/dist/legend-spec.d.ts +1 -1
  38. package/dist/{lerc-CuifOkoA.js → lerc-C6k7EzSN.js} +2 -2
  39. package/dist/license.d.ts +12 -5
  40. package/dist/measure-controller.d.ts +458 -4
  41. package/dist/meshopt_simplifier-Co6uRDDA.js +370 -0
  42. package/dist/onlymap.standalone.js +57077 -50729
  43. package/dist/onlymapjs.js +72 -69
  44. package/dist/parse-manifest.d.ts +3 -0
  45. package/dist/programmatic.d.ts +39 -5
  46. package/dist/{raster-dysYIQ_k.js → raster-Cuzhibe2.js} +2 -2
  47. package/dist/{raster-pipeline-ZdCOGfqV.js → raster-pipeline-DLrnJK8y.js} +1 -1
  48. package/dist/react/om-layer.d.ts +6 -1
  49. package/dist/react/om-overlay.d.ts +9 -0
  50. package/dist/react.js +176 -169
  51. package/dist/region-export-controller.d.ts +37 -0
  52. package/dist/region-export.d.ts +56 -0
  53. package/dist/runtime-core.d.ts +260 -3
  54. package/dist/selection.d.ts +44 -1
  55. package/dist/site-placement.d.ts +107 -0
  56. package/dist/snapping.d.ts +88 -0
  57. package/dist/terrain-heightfield.d.ts +53 -0
  58. package/dist/terrain-sample.d.ts +30 -0
  59. package/dist/terrain.d.ts +6 -1
  60. package/dist/testing.d.ts +6 -2
  61. package/dist/tile3d-metadata.d.ts +185 -0
  62. package/dist/units.d.ts +27 -0
  63. package/dist/version.d.ts +1 -1
  64. package/dist/volumetrics-run.d.ts +13 -0
  65. package/dist/volumetrics-worker.d.ts +1 -0
  66. package/dist/volumetrics.d.ts +201 -0
  67. package/dist/widget-registry.d.ts +11 -0
  68. package/dist/widgets/ifc-clash.d.ts +18 -0
  69. package/dist/widgets/ifc.d.ts +41 -0
  70. package/dist/{zarr-OewK7k2K.js → zarr-CUzEX8fB.js} +79 -66
  71. package/docs/3d-assets.md +48 -0
  72. package/docs/live-data.md +9 -1
  73. package/docs/testing.md +4 -2
  74. package/llms.txt +10 -5
  75. package/onlymapjs.html-data.json +313 -2
  76. package/package.json +6 -2
  77. package/skills/onlymapjs/SKILL.md +14 -2
  78. package/skills/onlymapjs/references/react.md +2 -2
  79. package/skills/onlymapjs/references/syntax.md +314 -15
  80. package/dist/cityjson-urQeujQv.js +0 -407
@@ -1,4 +1,4 @@
1
- import { ag as Be, ah as le, ai as ce, aj as De, ak as Oe, al as ke } from "./index-Bz-rbmhj.js";
1
+ import { ag as Be, ah as le, ai as ce, aj as De, ak as Oe, al as ke } from "./index-7B-6Cbzu.js";
2
2
  import { y as ve, a as he, z as G, R as J, A as ue, C as Fe, F as je, n as xe, S as Ie, E as Ne } from "./recordbatch-Bpc0uxFn.js";
3
3
  import { g as V, a as fe, b as Le, c as Ue, d as Me, e as qe, m as Ve } from "./table-accessors-CYWTzpQI.js";
4
4
  import { c as $e } from "./convert-arrow-schema-DrAihRf9.js";
@@ -1,4 +1,4 @@
1
- import { ak as Bt, ax as Xt, ay as Yt, az as Us } from "./index-Bz-rbmhj.js";
1
+ import { ak as Bt, ax as Xt, ay as Yt, az as Us } from "./index-7B-6Cbzu.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";
@@ -1,4 +1,4 @@
1
- import { ae as _t, af as Ct } from "./index-Bz-rbmhj.js";
1
+ import { ae as _t, af as Ct } from "./index-7B-6Cbzu.js";
2
2
  function Yt(e, r, t = 2, i, o = "xy") {
3
3
  const s = r && r.length, l = s ? r[0] * t : e.length;
4
4
  let c = Ut(e, 0, l, t, !0, i && i[0], o);
@@ -1,5 +1,5 @@
1
- import { i as E, j as S, k as R, o as N, p as h, q as w, s as O, t as W, v as x, w as I, x as B, y as _, A as P, B as k, E as $, F as z, H as v, I as F, J as C, K as U, N as p, O as M } from "./index-Bz-rbmhj.js";
2
- import { P as $e, R as ze, _ as ve, Q as Ce, S as Ue, T as Me, U as je, X as De, Y as Je, Z as qe, $ as He, a0 as Ve, a1 as Ge, a2 as Ke, a3 as Qe, a4 as Xe, a5 as Ye, a6 as Ze, a7 as et, a8 as tt, a9 as nt, aa as rt, ab as at, ac as st, ad as ot } from "./index-Bz-rbmhj.js";
1
+ import { i as E, j as S, k as R, o as N, p as h, q as w, s as O, t as W, v as x, w as I, x as B, y as _, A as P, B as k, E as $, F as z, H as v, I as F, J as C, K as U, N as p, O as M } from "./index-7B-6Cbzu.js";
2
+ import { P as $e, R as ze, _ as ve, Q as Ce, S as Ue, T as Me, U as je, X as De, Y as Je, Z as qe, $ as He, a0 as Ve, a1 as Ge, a2 as Ke, a3 as Qe, a4 as Xe, a5 as Ye, a6 as Ze, a7 as et, a8 as tt, a9 as nt, aa as rt, ab as at, ac as st, ad as ot } from "./index-7B-6Cbzu.js";
3
3
  import { g as j, i as D } from "./table-accessors-CYWTzpQI.js";
4
4
  async function J(t, e, n = {}, r = {}) {
5
5
  const a = E(t), s = S.getWorkerFarm(n), { source: o } = n, c = { name: a, source: o };
package/dist/index.d.ts CHANGED
@@ -13,7 +13,10 @@
13
13
  * renderer against an empty registry and never picks up the built-in.
14
14
  */
15
15
  import "./widgets/built-in";
16
+ import "./widgets/ifc";
17
+ import "./widgets/ifc-clash";
16
18
  import "./measure-controller";
19
+ import "./region-export-controller";
17
20
  import "./elements/om-map";
18
21
  import "./elements/om-layer";
19
22
  import "./elements/om-widget";
@@ -33,6 +36,7 @@ import { configureTelemetry } from "./telemetry";
33
36
  import { configureLicense } from "./license";
34
37
  import { validateManifestString } from "./validation";
35
38
  import { snapshotIR } from "./ir-snapshot";
39
+ import { snapshotDescriptorIR } from "./programmatic";
36
40
  import { resolveImageOverlay } from "./image-overlay";
37
41
  export { registerLayer, getLayerSchema } from "./layer-registry";
38
42
  export type { LayerSchema, PropDescriptor, PropKind } from "./layer-registry";
@@ -56,11 +60,17 @@ export { registerTerrain, getTerrain, parseTerrainAttrs } from "./terrain";
56
60
  export type { TerrainPreset, TerrainIR, ElevationDecoder, LayerTerrainMode } from "./terrain";
57
61
  export type { SnapshotOptions } from "./snapshot";
58
62
  export { configureTelemetry } from "./telemetry";
63
+ export type { IfcModel, IfcFeature, LoadIfcOptions } from "./ifc";
64
+ export declare function loadIfc(source: ArrayBuffer | Uint8Array | Blob, options?: import("./ifc").LoadIfcOptions): Promise<import("./ifc").IfcModel>;
65
+ /** Point the IFC loader at a self-hosted web-ifc build instead of the default CDN. */
66
+ export declare function configureIfc(options: {
67
+ wasmPath?: string;
68
+ }): Promise<void>;
59
69
  export type { TelemetryConfig, TelemetrySnapshot } from "./telemetry";
60
70
  export { configureLicense, getEntitlements } from "./license";
61
- export type { Entitlements } from "./license";
71
+ export type { Entitlements, LicenseIdentity } from "./license";
62
72
  export type { RuntimeContext } from "./ctx";
63
- export { MapController, descriptorToIR } from "./programmatic";
73
+ export { MapController, descriptorToIR, snapshotDescriptorIR } from "./programmatic";
64
74
  export type { LayerDescriptor, MapControllerOptions, CameraState, OverlayPositioner, PickListener } from "./programmatic";
65
75
  export { MANAGED_SLOTS, LEGACY_POSITION_ALIASES, ALL_POSITION_VALUES, FOLD_SIDES, resolveSlot, slotLayout, slotContainerStyle, foldSideForSlot, foldToggleSlot, foldDrawerStyle, foldPanelStyle, foldToggleStyle, resolveFoldBreakpointPx, shouldFoldAtWidth, DEFAULT_FOLD_BREAKPOINT_PX, FOLD_HYSTERESIS_PX, parseWidgetStyle, WIDGET_STYLE_KEY_NAMES, } from "./widget-layout";
66
76
  export type { ManagedSlot, WidgetSlot, FoldSide, SlotLayout, WidgetStyleParse } from "./widget-layout";
@@ -119,6 +129,7 @@ export declare const OmMap: {
119
129
  configureLicense: typeof configureLicense;
120
130
  validate: typeof validateManifestString;
121
131
  snapshotIR: typeof snapshotIR;
132
+ snapshotDescriptorIR: typeof snapshotDescriptorIR;
122
133
  resolveImageOverlay: typeof resolveImageOverlay;
123
134
  loadRasterModule: typeof loadRasterModule;
124
135
  };
@@ -22,7 +22,7 @@
22
22
  * (snapshots are side-effect-free; a URL-backed layer shows the same empty
23
23
  * placeholder the live Q6 pre-fetch state has).
24
24
  */
25
- import type { LayerMeta, LayerFilter, LayerAssetState } from "./ir";
25
+ import type { LayerIR, LayerMeta, LayerFilter, LayerAssetState } from "./ir";
26
26
  import type { Shape } from "./expr";
27
27
  export interface LayerIRSnapshot {
28
28
  id: string;
@@ -49,6 +49,8 @@ export interface LayerIRSnapshot {
49
49
  props: Record<string, unknown>;
50
50
  updateTriggers: Record<string, string>;
51
51
  }
52
+ /** Convert one already-resolved layer IR to the public deterministic JSON-safe form. */
53
+ export declare function snapshotLayerIR(ir: LayerIR): LayerIRSnapshot;
52
54
  /**
53
55
  * Resolves a manifest to JSON-safe layer IR snapshots.
54
56
  *
@@ -50,6 +50,20 @@ export interface LayerSchema {
50
50
  * `compact`/`neverHides` widget-flag precedent — one source of truth).
51
51
  */
52
52
  carriesTileset?: boolean;
53
+ /**
54
+ * BIM feature-picking epic, Phase 2 (design pending). Supports
55
+ * `pick-features`/`feature-id-property` — the runtime injects the
56
+ * `_subLayerProps` sublayer-class swap (to `FeatureMeshLayer`) only into
57
+ * these types, same one-source-of-truth reasoning as `carriesTileset`.
58
+ */
59
+ supportsFeaturePicking?: boolean;
60
+ /**
61
+ * Loads its own georeferencing from the source file (spec: "auto-terrain
62
+ * for georeferenced BIM") and supports the `onGeoreference` deck prop —
63
+ * the runtime injects that hook only into these types, same
64
+ * one-source-of-truth reasoning as `carriesTileset`.
65
+ */
66
+ carriesGeoreference?: boolean;
53
67
  /** Layer-owned async asset resolver; keeps parse/runtime branching registry-driven rather than name-matched. */
54
68
  assetResolver?: "image-overlay";
55
69
  }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * BIMLayer — a Tile3DLayer for BIM SOURCE files, not pre-baked tilesets.
3
+ *
4
+ * `<om-layer type="Tile3DLayer" tileset="…/tileset.json">` expects a 3D Tiles
5
+ * root someone already produced (by hand, by `dev/tools/gen-ifc-fixture.ts`,
6
+ * by any other converter). `BIMLayer` takes the BIM file itself — today an
7
+ * `.ifc` — and runs it through `loadIfc` (the SAME parser the BIM workbench's
8
+ * `ifc-loader` widget uses) the moment it loads, so a page never needs a
9
+ * separate conversion step or a pre-built tileset checked into the repo.
10
+ *
11
+ * Two things fall out of using the loader rather than a static tileset:
12
+ *
13
+ * - No `site-origin`/`site-heading`/`site-scale` needed. `loadIfc` already
14
+ * reads the file's own georeference and bakes the HORIZONTAL placement
15
+ * (eastings/northings/heading/scale) into the tileset it returns (or
16
+ * falls back honestly when the file declares none). `site-origin` itself
17
+ * is NOT wired up on `BIMLayer` (an authored one is ignored) — it rides
18
+ * runtime-core.ts's `tilesetBakedFrame`/`tilesetPlacementMatrix`
19
+ * machinery, which reads a tileset.json's baked root transform
20
+ * SYNCHRONOUSLY off the layer's `data` prop at construction time, and
21
+ * BIMLayer's tileset is an in-browser blob URL that doesn't exist until
22
+ * `loadIfc` resolves asynchronously inside `updateState` below — an
23
+ * honest, documented gap rather than a half-built override path.
24
+ * - The VERTICAL placement, by contrast, IS automatic — matching how the
25
+ * BIM workbench's `ifc-loader` WIDGET already behaves, not a separate
26
+ * opt-in. `IfcMapConversion`'s `OrthogonalHeight` (this model's real
27
+ * absolute elevation) is computed by `loadIfc` but left out of the
28
+ * tileset's own baked transform (see that field's doc comment in
29
+ * src/ifc.ts) — correct on a flat, no-`terrain` basemap (a local Z≈0
30
+ * model sits right on a Z=0 ground plane), wrong once a REAL terrain
31
+ * surface is active (whose elevation at any inhabited location is
32
+ * essentially never 0 — the model ends up buried inside the mesh).
33
+ * `runtime-core.ts` reports whether terrain is active via a
34
+ * `terrainActive` prop (the same `carriesGeoreference`-gated channel
35
+ * `onGeoreference` already rides); `renderLayers` below applies
36
+ * `OrthogonalHeight` as an ENU re-placement AT the model's own already-
37
+ * correct lon/lat (same site point, just a non-zero height component)
38
+ * only when that prop is true — reusing `tilesetPlacementMatrix`, the
39
+ * exact mechanism `ifc-loader`'s own manual `site-origin` override rides,
40
+ * just triggered automatically instead of requiring the author (or a
41
+ * widget) to compute and restate a number that's already known.
42
+ * - The outline overlay is automatic. `loadIfc` already returns an
43
+ * `edgesUrl` alongside the tileset; a separate `<om-layer type="PathLayer"
44
+ * data="…/edges.json">` was only ever there because a plain Tile3DLayer
45
+ * has no way to render one itself.
46
+ *
47
+ * The outline overlay follows `isolate-features`/`hide-features` the same way
48
+ * the mesh does: `loadModel` parses the edges blob into memory (it is a
49
+ * same-origin blob URL it just created, not a real network round trip), and
50
+ * `renderLayers` filters those rows with the SAME `matchToken`/
51
+ * `normalizeMatchList` helpers `FeatureMeshLayer` uses for the mesh, keyed on
52
+ * `feature-filter-field`. It does NOT follow `ghost-features` — ghosting only
53
+ * dims the mesh's opacity, never the outline, and that is not a BIMLayer gap:
54
+ * the OLDER two-layer pattern (`ifc-loader`'s own `Tile3DLayer` + companion
55
+ * `<layer-id>-edges` PathLayer, still used by the widget — see
56
+ * src/widgets/ifc.ts) never ghosted its outlines either, since its
57
+ * `filter-category`/`filter-categories` pair is a plain keep-list with no
58
+ * partial-opacity concept. Matching that, not inventing new behaviour.
59
+ *
60
+ * Implementation: a CompositeLayer wrapping a real `Tile3DLayer`, not a
61
+ * Tile3DLayer subclass — `renderLayers` fetches+parses on `src` change, then
62
+ * spreads `this.props` onto the inner Tile3DLayer verbatim (dropping `src`
63
+ * and the runtime's own harmless `data: []` baseline, setting `data` to the
64
+ * resolved tileset URL instead). That spread is load-bearing: the
65
+ * runtime injects `_subLayerProps`/`onTileLoad`/`onTilesetLoad` onto
66
+ * whatever top-level props a `supportsFeaturePicking`/`carriesTileset`
67
+ * layer receives (see runtime-core.ts's `pickFeaturesHook`/`featureTableHook`),
68
+ * and forwarding them unchanged is what makes picking, `feature-styles`,
69
+ * `ctx.features()`, and `om-tileset-load` all keep working without BIMLayer
70
+ * having to know anything about them itself.
71
+ *
72
+ * Other BIM formats: the loader dispatch (currently a straight call to
73
+ * `loadIfc`) is the one seam a future format would extend — nothing else
74
+ * here is IFC-specific.
75
+ */
76
+ import { CompositeLayer } from "@deck.gl/core";
77
+ import type { Layer } from "@deck.gl/core";
78
+ /** One outline polyline plus the same category fields the mesh filters on — see `readGeoreference`'s edges row shape in `../ifc`. */
79
+ interface EdgeRow {
80
+ path: [number, number, number][];
81
+ [field: string]: unknown;
82
+ }
83
+ interface LoadedBim {
84
+ tilesetUrl: string;
85
+ edgeRows: EdgeRow[] | null;
86
+ lonLat: [number, number];
87
+ heading: number;
88
+ scale: number;
89
+ /** The file's own `IfcMapConversion.OrthogonalHeight`, undefined when it never declared one — see renderLayers' `terrainActive` handling. */
90
+ orthogonalHeight?: number;
91
+ revoke(): void;
92
+ }
93
+ export interface BIMLayerProps {
94
+ /**
95
+ * URL of the BIM source file (an `.ifc` today).
96
+ *
97
+ * Deliberately NOT `data`: deck.gl's own `Layer` base class auto-fetches
98
+ * any string `data` prop through loaders.gl's generic loader registry —
99
+ * fine for a ScatterplotLayer's rows, fatal here ("No valid loader found"
100
+ * for a `.ifc`, confirmed by running this in a real browser). Tile3DLayer
101
+ * avoids this because deck.gl gives Tile3DLayer itself custom handling for
102
+ * `data`; a plain CompositeLayer like this one does not inherit that.
103
+ */
104
+ src: string;
105
+ [prop: string]: unknown;
106
+ }
107
+ export declare class BIMLayer extends CompositeLayer<BIMLayerProps> {
108
+ static layerName: string;
109
+ static defaultProps: {
110
+ pickFeatures: boolean;
111
+ };
112
+ state: {
113
+ loaded: LoadedBim | null;
114
+ loadingFor: string | null;
115
+ destroyed: boolean;
116
+ abort: AbortController | null;
117
+ };
118
+ initializeState(): void;
119
+ updateState({ props, oldProps }: {
120
+ props: BIMLayerProps;
121
+ oldProps: BIMLayerProps;
122
+ }): void;
123
+ finalizeState(): void;
124
+ private loadModel;
125
+ renderLayers(): Layer[];
126
+ }
127
+ export {};
@@ -0,0 +1,288 @@
1
+ import { type ShaderModule } from "@luma.gl/shadertools";
2
+ import { Model, Geometry } from "@luma.gl/engine";
3
+ import { Matrix4 } from "@math.gl/core";
4
+ import { SimpleMeshLayer, ScenegraphLayer, type SimpleMeshLayerProps } from "@deck.gl/mesh-layers";
5
+ import { CompositeLayer, type DefaultProps, type UpdateParameters } from "@deck.gl/core";
6
+ import { type GltfExtStructuralMetadata } from "../tile3d-metadata";
7
+ import { type FeatureColorMapping } from "../feature-colors";
8
+ /**
9
+ * A primitive whose POSITION accessor did not resolve (unsupported
10
+ * componentType, a missing buffer, `loadBuffers` off, a corrupt bufferView —
11
+ * `toLumaGeometry` silently omits the key rather than fabricating one) has
12
+ * nothing to draw at all, so this can't degrade to a partially-rendered mesh
13
+ * the way a missing property table degrades to "no properties" — there is no
14
+ * useful "unstyled but visible" state for zero vertices. What it CAN do is
15
+ * fail with a message that says why, instead of the opaque "Cannot read
16
+ * properties of undefined (reading 'length')" a non-null assertion produced
17
+ * here previously — deck.gl's LayerManager already catches a layer update
18
+ * throwing (this doesn't crash the page), so the only actual regression from
19
+ * throwing plainly is a worse error message, which this fixes.
20
+ */
21
+ export declare function validateGeometryAttributes(attributes: Record<string, {
22
+ value: ArrayLike<number>;
23
+ } | undefined>): void;
24
+ /** Loose shape of the `tile` prop Tile3DLayer's `_make3DModelLayer` passes through. `featureIdPropertyTableIndex` is set by the outer `FeatureMeshLayer` composite below, during its own `renderLayers()`, right before constructing this inner layer — not by a separate async step. */
25
+ interface FeatureTileProp {
26
+ content?: {
27
+ gltf?: {
28
+ extensions?: {
29
+ EXT_structural_metadata?: GltfExtStructuralMetadata;
30
+ };
31
+ };
32
+ featureIdPropertyTableIndex?: number;
33
+ };
34
+ }
35
+ /**
36
+ * One row of the per-feature style table, keyed by feature ID (the array index
37
+ * IS the feature ID). Every field is optional; an omitted or absent row leaves
38
+ * that feature rendered exactly as it would be unstyled.
39
+ */
40
+ export interface FeatureStyle {
41
+ /** Tint colour, `[r, g, b]` 0-255. */
42
+ color?: [number, number, number];
43
+ /** How strongly `color` replaces the lit colour, 0-1. Defaults to 1 when a colour is given, 0 otherwise. */
44
+ strength?: number;
45
+ /** Alpha multiplier, 0-1. Defaults to 1 (opaque). */
46
+ opacity?: number;
47
+ }
48
+ /** The extra props this layer adds on top of SimpleMeshLayer's own (mesh/getPosition/getColor/…). */
49
+ interface FeatureMeshLayerExtraProps {
50
+ pbrMaterial: Record<string, unknown> | null;
51
+ /** Per-vertex feature ID for the single primitive `FeatureMeshLayer` resolved — see this file's module doc. */
52
+ featureIds?: ArrayLike<number> | null;
53
+ /** Per-feature style table indexed by feature ID — see featureStyleUniforms. Null/empty renders unstyled. */
54
+ featureStyles?: FeatureStyle[] | null;
55
+ /** Raw feature-ID texture image, when the dataset carries IDs per texel. Enables the per-fragment path. */
56
+ featureIdImage?: unknown;
57
+ /** Which RGBA channels compose the ID, low byte first — the extension's own `channels` array. */
58
+ featureIdChannels?: number[] | null;
59
+ /** EXT_mesh_features' "belongs to no feature" sentinel — a pick of this ID reports as no feature. */
60
+ featureIdNull?: number | null;
61
+ tile?: FeatureTileProp;
62
+ }
63
+ /**
64
+ * Turns the extension's `channels` array into the four per-channel byte
65
+ * weights the shader multiplies by — channels[i] names an RGBA channel and its
66
+ * position sets its significance, so [0,1] means R is the low byte and G the
67
+ * next (weights 1 and 256).
68
+ */
69
+ export declare function featureIdChannelWeights(channels: number[] | null | undefined): [number, number, number, number];
70
+ /** 0-1 style fraction → a 0-255 texel byte (the tables are rgba8unorm). */
71
+ export declare const styleByte: (value: number) => number;
72
+ /** Builds the two `count x 1` RGBA lookup tables described in featureStyleUniforms' doc. */
73
+ export declare function encodeFeatureStyleTables(styles: FeatureStyle[]): {
74
+ tint: Uint8Array;
75
+ opacity: Uint8Array;
76
+ };
77
+ /** True when any row asks for transparency — the layer must then enable blending. */
78
+ export declare function hasTranslucentFeature(styles: FeatureStyle[] | null | undefined): boolean;
79
+ type DrawParams = Parameters<InstanceType<typeof SimpleMeshLayer>["draw"]>[0];
80
+ type MeshParam = Parameters<InstanceType<typeof SimpleMeshLayer>["getModel"]>[0];
81
+ type PickingInfoParams = Parameters<InstanceType<typeof SimpleMeshLayer>["getPickingInfo"]>[0];
82
+ declare class SinglePrimitiveFeatureLayer extends SimpleMeshLayer<unknown, FeatureMeshLayerExtraProps> {
83
+ static layerName: string;
84
+ static defaultProps: DefaultProps<SimpleMeshLayerProps<unknown> & FeatureMeshLayerExtraProps>;
85
+ getShaders(): {
86
+ vs: string;
87
+ fs: string;
88
+ modules: ShaderModule[];
89
+ defines?: Record<string, unknown>;
90
+ };
91
+ initializeState(): void;
92
+ /** Registers the per-vertex feature-ID attributes exactly once — callable late, from the texture-failure fallback. */
93
+ private registerFeatureIdAttributes;
94
+ updateState(params: UpdateParameters<this>): void;
95
+ /**
96
+ * Uploads the feature-ID texture once per tile and keeps it — this is the
97
+ * cache. The image itself is already cached upstream by loaders.gl for the
98
+ * tile's lifetime, so the only per-tile cost here is the single upload, and
99
+ * it replaces what was previously one CPU texture sample per vertex.
100
+ */
101
+ private updateFeatureIdTexture;
102
+ /** Rebuilds both style lookup textures. Cheap enough to redo wholesale on any style change — each table is `featureCount x 1` texels. */
103
+ private updateFeatureStyleTexture;
104
+ draw(opts: DrawParams): void;
105
+ protected getModel(mesh: MeshParam): Model;
106
+ private updatePbrMaterialUniforms;
107
+ private parseMaterial;
108
+ private calculateFeatureIdsPickingColors;
109
+ private calculateFeatureIdValues;
110
+ finalizeState(context: Parameters<InstanceType<typeof SimpleMeshLayer>["finalizeState"]>[0]): void;
111
+ getPickingInfo(params: PickingInfoParams): {
112
+ color: Uint8Array | null;
113
+ layer: import("@deck.gl/core").Layer | null;
114
+ sourceLayer?: import("@deck.gl/core").Layer | null;
115
+ viewport?: import("@deck.gl/core").Viewport;
116
+ index: number;
117
+ picked: boolean;
118
+ object?: any;
119
+ x: number;
120
+ y: number;
121
+ pixel?: [number, number];
122
+ coordinate?: number[];
123
+ devicePixel?: [number, number];
124
+ pixelRatio: number;
125
+ } & {
126
+ featureId?: number;
127
+ properties?: Record<string, unknown>;
128
+ class?: string | null;
129
+ guid?: string | null;
130
+ };
131
+ }
132
+ /** The extra props `_make3DModelLayer` passes that this composite wrapper reads directly (everything else is forwarded to the fallback ScenegraphLayer verbatim). */
133
+ interface FeatureMeshLayerOuterExtraProps {
134
+ scenegraph?: unknown;
135
+ tile?: FeatureTileProp;
136
+ featureIdProperty?: string;
137
+ /** Per-feature style table, forwarded to the picking-aware sublayer. Ignored on the ScenegraphLayer fallback, which has no feature IDs to key on. */
138
+ featureStyles?: FeatureStyle[] | null;
139
+ /**
140
+ * The GLOBAL colour mapping (feature-color-by / feature-color-scale),
141
+ * applied to THIS tile's own property rows in composeFeatureStyles —
142
+ * feature IDs are tile-local, so the style table must be built per tile
143
+ * from per-tile rows (a shared globally-indexed table was only ever
144
+ * correct for the first tile). Identity is memoized upstream
145
+ * (runtime-core.featureColorMappingFor), which keeps the derived table —
146
+ * and its GPU textures — stable across reconciles and animation frames.
147
+ */
148
+ featureColorMapping?: FeatureColorMapping | null;
149
+ /** Property-table field the three visibility lists below match against. */
150
+ featureFilterField?: string | null;
151
+ /** Show ONLY features whose field matches; everything else is hidden. */
152
+ isolateFeatures?: unknown[] | null;
153
+ hideFeatures?: unknown[] | null;
154
+ ghostFeatures?: unknown[] | null;
155
+ ghostOpacity?: number;
156
+ }
157
+ /**
158
+ * Property values are compared as strings so a manifest can write
159
+ * `hide-features='["Windows"]'` or `'[3]'` without caring whether the column
160
+ * decoded to strings, numbers or booleans — an attribute is text either way.
161
+ */
162
+ export declare function matchToken(value: unknown): string;
163
+ /** Normalizes an attribute list to a lookup set, or null when there is nothing to match. */
164
+ export declare function normalizeMatchList(values: unknown[] | null | undefined): Set<string> | null;
165
+ /** See this file's module doc — dispatches between the per-vertex feature-picking single-primitive path and a plain ScenegraphLayer fallback. */
166
+ export declare class FeatureMeshLayer extends CompositeLayer<FeatureMeshLayerOuterExtraProps> {
167
+ static layerName: string;
168
+ static defaultProps: DefaultProps<FeatureMeshLayerOuterExtraProps>;
169
+ /**
170
+ * Resolves the primitive, builds its Geometry and locates its feature-ID
171
+ * image ONCE, whenever the glTF itself changes — never per render.
172
+ *
173
+ * Doing this inside renderLayers (as an earlier version did) handed
174
+ * SimpleMeshLayer a brand-new Geometry instance every time ANY prop changed.
175
+ * A `mesh` identity change makes it destroy and rebuild its Model, so simply
176
+ * switching style mode re-uploaded every visible tile's vertex buffers at
177
+ * once and the model blanked out until something forced another redraw —
178
+ * which is why it only reappeared after a pan or zoom.
179
+ */
180
+ updateState({ props, oldProps, changeFlags }: UpdateParameters<this>): void;
181
+ /**
182
+ * Folds the declarative `isolate-features`/`hide-features`/`ghost-features`
183
+ * lists onto the author's own `feature-styles` table.
184
+ *
185
+ * Precedence is deliberate: the authored table supplies COLOUR, the
186
+ * declarative lists supply VISIBILITY, and visibility wins on `opacity`.
187
+ * That means switching a colour scheme never silently un-hides anything, and
188
+ * isolating never discards the colouring — the two are orthogonal, which is
189
+ * what makes them composable in a story or an undo step.
190
+ *
191
+ * `isolate` is evaluated first and is exclusive: anything not named is
192
+ * hidden outright, so it is a scope, not another kind of hide.
193
+ */
194
+ private composeFeatureStyles;
195
+ private resolvePrimitives;
196
+ renderLayers(): SinglePrimitiveFeatureLayer[] | ScenegraphLayer<any, {
197
+ data: string | {
198
+ length: number;
199
+ attributes?: Record<string, import("@math.gl/types").TypedArray | import("@luma.gl/core").Buffer | import("@deck.gl/core").BinaryAttribute>;
200
+ } | Iterable<unknown> | AsyncIterable<unknown[]> | Promise<import("@deck.gl/core").LayerData<unknown>> | null;
201
+ mesh: string | import("@loaders.gl/schema").MeshAttributes | Geometry | {
202
+ attributes: import("@loaders.gl/schema").MeshAttributes;
203
+ indices?: import("@loaders.gl/schema").MeshAttribute;
204
+ } | Promise<import("@loaders.gl/schema").MeshAttributes | Geometry | {
205
+ attributes: import("@loaders.gl/schema").MeshAttributes;
206
+ indices?: import("@loaders.gl/schema").MeshAttribute;
207
+ }> | null;
208
+ texture: string | HTMLCanvasElement | import("@luma.gl/core").Texture | import("@luma.gl/core").TextureProps | HTMLImageElement | ImageData | HTMLVideoElement | ImageBitmap | Promise<import("@deck.gl/core").TextureSource>;
209
+ textureParameters: import("@luma.gl/core").SamplerProps | null;
210
+ getPosition: readonly [number, number] | readonly [number, number, number] | Readonly<Float32Array<ArrayBufferLike>> | Readonly<Float64Array<ArrayBufferLike>> | import("@deck.gl/core").AccessorFunction<unknown, import("@deck.gl/core").Position>;
211
+ getColor: readonly [number, number, number] | readonly [number, number, number, number] | Readonly<Uint8Array<ArrayBufferLike>> | Readonly<Uint8ClampedArray<ArrayBufferLike>> | import("@deck.gl/core").AccessorFunction<unknown, import("@deck.gl/core").Color>;
212
+ getOrientation: readonly [number, number, number] | import("@deck.gl/core").AccessorFunction<unknown, readonly [number, number, number]>;
213
+ getScale: readonly [number, number, number] | import("@deck.gl/core").AccessorFunction<unknown, readonly [number, number, number]>;
214
+ getTranslation: readonly [number, number, number] | import("@deck.gl/core").AccessorFunction<unknown, readonly [number, number, number]>;
215
+ getTransformMatrix: number[] | import("@deck.gl/core").AccessorFunction<unknown, number[]>;
216
+ sizeScale: number;
217
+ _instanced: boolean;
218
+ wireframe: boolean;
219
+ material: import("@deck.gl/core").Material;
220
+ id: string;
221
+ dataComparator: (<LayerDataT = import("@deck.gl/core").LayerData<unknown>>(newData: LayerDataT, oldData?: LayerDataT) => boolean) | null;
222
+ _dataDiff: (<LayerDataT = import("@deck.gl/core").LayerData<unknown>>(newData: LayerDataT, oldData?: LayerDataT) => {
223
+ startRow: number;
224
+ endRow?: number;
225
+ }[]) | null;
226
+ dataTransform: (<LayerDataT = import("@deck.gl/core").LayerData<unknown>>(data: unknown, previousData?: LayerDataT) => LayerDataT) | null;
227
+ fetch: (url: string, context: {
228
+ propName: string;
229
+ layer: import("@deck.gl/core").Layer;
230
+ loaders?: import("@loaders.gl/loader-utils").Loader[];
231
+ loadOptions?: any;
232
+ signal?: AbortSignal;
233
+ }) => any;
234
+ updateTriggers: Record<string, any>;
235
+ operation: "terrain" | "draw" | "mask" | "terrain+terrain" | "terrain+draw" | "terrain+mask" | "draw+terrain" | "draw+draw" | "draw+mask" | "mask+terrain" | "mask+draw" | "mask+mask";
236
+ visible: boolean;
237
+ pickable: boolean | "3d";
238
+ opacity: number;
239
+ coordinateSystem: "default" | "lnglat" | "meter-offsets" | "lnglat-offsets" | "cartesian";
240
+ coordinateOrigin: [number, number, number];
241
+ modelMatrix: Matrix4 | Int8Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint32Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | import("@math.gl/types").NumberArray16 | null;
242
+ wrapLongitude: boolean;
243
+ positionFormat: "XYZ" | "XY";
244
+ colorFormat: "RGBA" | "RGB";
245
+ parameters: {
246
+ cullMode?: import("@luma.gl/core").CullMode;
247
+ frontFace?: import("@luma.gl/core").FrontFace;
248
+ depthBias?: number;
249
+ depthBiasSlopeScale?: number;
250
+ depthBiasClamp?: number;
251
+ unclippedDepth?: boolean;
252
+ provokingVertex?: "first" | "last";
253
+ polygonMode?: "fill" | "line";
254
+ polygonOffsetLine?: boolean;
255
+ clipDistance0?: boolean;
256
+ clipDistance1?: boolean;
257
+ clipDistance2?: boolean;
258
+ clipDistance3?: boolean;
259
+ clipDistance4?: boolean;
260
+ clipDistance5?: boolean;
261
+ clipDistance6?: boolean;
262
+ clipDistance7?: boolean;
263
+ } & import("@luma.gl/core").DepthStencilParameters & import("@luma.gl/core").ColorParameters & import("@luma.gl/core").MultisampleParameters;
264
+ transitions: Record<string, any> | null;
265
+ extensions: import("@deck.gl/core").LayerExtension[];
266
+ loaders: import("@loaders.gl/loader-utils").Loader[];
267
+ loadOptions: any;
268
+ getPolygonOffset: ((params: {
269
+ layerIndex: number;
270
+ }) => [number, number]) | null;
271
+ autoHighlight: boolean;
272
+ highlightedObjectIndex: number | null;
273
+ highlightColor: number[] | ((pickingInfo: import("@deck.gl/core").PickingInfo) => number[]);
274
+ onDataLoad: (<LayerDataT = import("@deck.gl/core").LayerData<unknown>>(data: LayerDataT, context: {
275
+ propName: string;
276
+ layer: import("@deck.gl/core").Layer;
277
+ }) => void) | null;
278
+ onError: ((error: Error) => boolean | void) | null;
279
+ onHover: ((pickingInfo: import("@deck.gl/core").PickingInfo, event: import("mjolnir.js").MjolnirEvent) => boolean | void) | null;
280
+ onClick: ((pickingInfo: import("@deck.gl/core").PickingInfo, event: import("mjolnir.js").MjolnirEvent) => boolean | void) | null;
281
+ onDragStart: ((pickingInfo: import("@deck.gl/core").PickingInfo, event: import("mjolnir.js").MjolnirEvent) => boolean | void) | null;
282
+ onDrag: ((pickingInfo: import("@deck.gl/core").PickingInfo, event: import("mjolnir.js").MjolnirEvent) => boolean | void) | null;
283
+ onDragEnd: ((pickingInfo: import("@deck.gl/core").PickingInfo, event: import("mjolnir.js").MjolnirEvent) => boolean | void) | null;
284
+ numInstances: number | null;
285
+ startIndices: number[] | Int8Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint32Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | null;
286
+ }> | null;
287
+ }
288
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * BIM feature-picking epic, Phase 2 — glTF scene-graph walk. `ScenegraphLayer`
3
+ * (via the undocumented `@luma.gl/gltf` `createScenegraphsFromGLTF`) is what
4
+ * actually renders 3D-Tiles glTF/glb/b3dm/i3dm content in this repo — NOT
5
+ * the I3S-only `MeshLayer`/`content.featureIds` path (verified against
6
+ * `@loaders.gl/3d-tiles`'s `getTileType()`: gltf/glb/b3dm/i3dm all map to
7
+ * `TILE_TYPE.SCENEGRAPH`, and `@loaders.gl/i3s` isn't even installed here).
8
+ * `pick-features` therefore only fast-paths the realistic single-element
9
+ * case — one node, one mesh, one primitive — and walks that node's actual
10
+ * transform (glTF node placement is independent of the tile's own 3D-Tiles
11
+ * transform); anything else falls back to a plain, unmodified
12
+ * `ScenegraphLayer` with zero rendering regression.
13
+ */
14
+ import { Matrix4 } from "@math.gl/core";
15
+ interface GltfNode {
16
+ mesh?: {
17
+ primitives?: unknown[];
18
+ };
19
+ children?: GltfNode[];
20
+ matrix?: number[];
21
+ translation?: [number, number, number];
22
+ rotation?: [number, number, number, number];
23
+ scale?: [number, number, number];
24
+ }
25
+ interface GltfScene {
26
+ nodes?: GltfNode[];
27
+ }
28
+ interface GltfLike {
29
+ scene?: number | GltfScene;
30
+ scenes?: GltfScene[];
31
+ }
32
+ export interface ResolvedSinglePrimitive {
33
+ primitive: unknown;
34
+ /** This node's transform composed down from the scene root — glTF-internal placement, independent of the tile's own 3D-Tiles transform. */
35
+ worldMatrix: Matrix4;
36
+ }
37
+ /**
38
+ * Walks the glTF's node hierarchy (starting at its default/only scene) and
39
+ * returns EVERY {primitive, worldMatrix} pair, each carrying its own node's
40
+ * transform composed down from the scene root.
41
+ *
42
+ * Multi-primitive content is the norm, not the exception: glTF allows exactly
43
+ * one material per primitive, so a mesh with five materials is five
44
+ * primitives. Real IFC exports split much further still — the Building-
45
+ * Architecture sample converts to 14 nodes/14 primitives. Only single-material
46
+ * content (photogrammetry tiles, for instance) resolves to one.
47
+ */
48
+ export declare function resolvePrimitiveNodes(gltf: GltfLike): ResolvedSinglePrimitive[];
49
+ /**
50
+ * The single-primitive special case, kept as its own entry point because
51
+ * "exactly one primitive" is still a meaningful question (a caller that cannot
52
+ * fan out wants to know). Returns null for anything more complex.
53
+ */
54
+ export declare function resolveSinglePrimitiveNode(gltf: GltfLike): ResolvedSinglePrimitive | null;
55
+ export {};
@@ -31,6 +31,19 @@ export interface PopupLayerProps {
31
31
  getSubtext?: ((d: unknown) => string) | null;
32
32
  getColor?: unknown;
33
33
  getSize?: unknown;
34
+ /**
35
+ * Overrides the layout's default `[x, y]` screen-pixel offset. Not
36
+ * attribute-exposed (an internal escape hatch, set via `patchAnimatedProps`
37
+ * — same non-string-prop-injection precedent as a SimpleMeshLayer's
38
+ * `mesh`) — the volume gizmo's elevation tooltip uses this so it clears
39
+ * the gizmo mesh by a CONSTANT pixel gap at every zoom, which a world-space
40
+ * (meters) offset can't do: at low zoom a fixed meter offset shrinks to
41
+ * fewer pixels than the badge itself needs, causing exactly the overlap a
42
+ * real user reported.
43
+ */
44
+ pixelOffset?: [number, number];
45
+ /** Raw WebGL/GPU state passthrough (e.g. `{ depthTest: false }`) — same internal escape hatch as `pixelOffset`, not attribute-exposed. */
46
+ parameters?: Record<string, unknown>;
34
47
  updateTriggers?: Record<string, unknown>;
35
48
  }
36
49
  export declare class PopupLayer extends CompositeLayer<PopupLayerProps> {
@@ -45,7 +45,7 @@ export type LegendSpec = {
45
45
  * THE LEGEND, not the map (the map samples the GPU sprite; a 1-D CSS
46
46
  * gradient bar only needs a few stops and the eye fills in the rest).
47
47
  * Matplotlib reference colors at 0/.25/.5/.75/1. The sprite ships ~107
48
- * colormaps; this curated dozen covers the ones worth suggesting — an
48
+ * colormaps; this curated set covers the ones worth suggesting — an
49
49
  * authored name outside it still RENDERS (sprite lookup), it just gets the
50
50
  * single-swatch legend fallback.
51
51
  */
@@ -1,4 +1,4 @@
1
- import { C as a, D as s } from "./raster-dysYIQ_k.js";
1
+ import { C as a, D as s } from "./raster-Cuzhibe2.js";
2
2
  const D = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3
3
  __proto__: null
4
4
  }, Symbol.toStringTag, { value: "Module" }));
@@ -8,7 +8,7 @@ var t;
8
8
  })(t || (t = {}));
9
9
  let l = !1;
10
10
  async function d() {
11
- const e = await import("./LercDecode.es-fbo6h5rt.js");
11
+ const e = await import("./LercDecode.es-BOJJr6Gx.js");
12
12
  return l || (await e.load(), l = !0), e;
13
13
  }
14
14
  async function i(e, r) {