@nika-js/onlymap 0.5.12 → 0.6.1
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 +19 -0
- package/LICENSE.md +2 -0
- package/README.md +19 -7
- package/THIRD-PARTY-LICENSES.md +27 -0
- package/dist/{LercDecode.es-C97NsRLr.js → LercDecode.es-CJnypw8j.js} +1 -1
- package/dist/{basemap-kc0aQNqr.js → basemap-DrQ0-eyR.js} +1 -1
- package/dist/cityjson-D_V5GY8b.js +332 -0
- package/dist/crs-Ciu7Xs7a.js +108 -0
- package/dist/crs.d.ts +50 -0
- package/dist/ctx.d.ts +8 -1
- package/dist/elements/om-map.d.ts +26 -2
- package/dist/elements/om-overlay.d.ts +1 -1
- package/dist/elements/om-widget.d.ts +4 -0
- package/dist/feature-colors.d.ts +41 -0
- package/dist/{geoparquet-Dn1BypCS.js → geoparquet-Dix4lTNy.js} +1 -1
- package/dist/html-data.d.ts +1 -1
- package/dist/ifc-Dc-TdSJr.js +877 -0
- package/dist/ifc.d.ts +406 -0
- package/dist/{index-aBiHCzy-.js → index-1UgNlfGR.js} +20944 -18922
- package/dist/{index-BoUIm-jd.js → index-BQMjW5w0.js} +1 -1
- package/dist/{index-BcG3m2rF.js → index-B_1PPJgC.js} +1 -1
- package/dist/{index-DA_aop8u.js → index-CAuT5j9Y.js} +2 -2
- package/dist/{index-Dc-ZLLo8.js → index-CXPaeisL.js} +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/layer-registry.d.ts +14 -0
- package/dist/layers/bim-layer.d.ts +104 -0
- package/dist/layers/feature-mesh-layer.d.ts +288 -0
- package/dist/layers/gltf-scene-walk.d.ts +55 -0
- package/dist/{lerc-74-SNPeU.js → lerc-CbTjQ7uI.js} +2 -2
- package/dist/license.d.ts +29 -5
- package/dist/meshopt_simplifier-Co6uRDDA.js +370 -0
- package/dist/onlymap.standalone.js +58057 -54751
- package/dist/onlymapjs.js +69 -67
- package/dist/programmatic.d.ts +22 -2
- package/dist/{raster-VyHCbPXy.js → raster-0b0nSHUh.js} +2 -2
- package/dist/{raster-pipeline-CGQTOUjw.js → raster-pipeline-D8siq7-4.js} +1 -1
- package/dist/react/om-overlay.d.ts +9 -0
- package/dist/react.js +144 -144
- package/dist/runtime-core.d.ts +110 -3
- package/dist/selection.d.ts +33 -0
- package/dist/site-placement.d.ts +85 -0
- package/dist/testing.d.ts +6 -2
- package/dist/tile3d-metadata.d.ts +185 -0
- package/dist/version.d.ts +1 -1
- package/dist/widget-registry.d.ts +11 -0
- package/dist/widgets/ifc-clash.d.ts +18 -0
- package/dist/widgets/ifc.d.ts +41 -0
- package/dist/{zarr-DddHNVim.js → zarr-DCYro_Vs.js} +79 -66
- package/docs/3d-assets.md +3 -3
- package/docs/live-data.md +2 -2
- package/docs/stories.md +1 -1
- package/docs/testing.md +2 -2
- package/llms.txt +3 -3
- package/onlymapjs.html-data.json +152 -0
- package/package.json +7 -2
- package/skills/onlymapjs/SKILL.md +4 -2
- package/skills/onlymapjs/references/react.md +1 -1
- package/skills/onlymapjs/references/syntax.md +299 -12
- package/dist/cityjson-urQeujQv.js +0 -407
|
@@ -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-1UgNlfGR.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 { ag as Be, ah as le, ai as ce, aj as De, ak as Oe, al as ke } from "./index-
|
|
1
|
+
import { ag as Be, ah as le, ai as ce, aj as De, ak as Oe, al as ke } from "./index-1UgNlfGR.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,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-
|
|
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-
|
|
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-1UgNlfGR.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-1UgNlfGR.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,6 +13,8 @@
|
|
|
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";
|
|
17
19
|
import "./elements/om-map";
|
|
18
20
|
import "./elements/om-layer";
|
|
@@ -56,6 +58,12 @@ export { registerTerrain, getTerrain, parseTerrainAttrs } from "./terrain";
|
|
|
56
58
|
export type { TerrainPreset, TerrainIR, ElevationDecoder, LayerTerrainMode } from "./terrain";
|
|
57
59
|
export type { SnapshotOptions } from "./snapshot";
|
|
58
60
|
export { configureTelemetry } from "./telemetry";
|
|
61
|
+
export type { IfcModel, IfcFeature, LoadIfcOptions } from "./ifc";
|
|
62
|
+
export declare function loadIfc(source: ArrayBuffer | Uint8Array | Blob, options?: import("./ifc").LoadIfcOptions): Promise<import("./ifc").IfcModel>;
|
|
63
|
+
/** Point the IFC loader at a self-hosted web-ifc build instead of the default CDN. */
|
|
64
|
+
export declare function configureIfc(options: {
|
|
65
|
+
wasmPath?: string;
|
|
66
|
+
}): Promise<void>;
|
|
59
67
|
export type { TelemetryConfig, TelemetrySnapshot } from "./telemetry";
|
|
60
68
|
export { configureLicense, getEntitlements } from "./license";
|
|
61
69
|
export type { Entitlements } from "./license";
|
package/dist/layer-registry.d.ts
CHANGED
|
@@ -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,104 @@
|
|
|
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 it into the tileset it
|
|
15
|
+
* returns (or falls back honestly when the file declares none) — the
|
|
16
|
+
* attributes exist for OVERRIDING a wrong or missing reading, not for
|
|
17
|
+
* restating what was already computed. (Not wired up in this first pass:
|
|
18
|
+
* an authored `site-origin` on a `BIMLayer` is currently ignored rather
|
|
19
|
+
* than overriding the loader's own placement — an honest, documented gap
|
|
20
|
+
* rather than a half-built override path.)
|
|
21
|
+
* - The outline overlay is automatic. `loadIfc` already returns an
|
|
22
|
+
* `edgesUrl` alongside the tileset; a separate `<om-layer type="PathLayer"
|
|
23
|
+
* data="…/edges.json">` was only ever there because a plain Tile3DLayer
|
|
24
|
+
* has no way to render one itself.
|
|
25
|
+
*
|
|
26
|
+
* The outline overlay follows `isolate-features`/`hide-features` the same way
|
|
27
|
+
* the mesh does: `loadModel` parses the edges blob into memory (it is a
|
|
28
|
+
* same-origin blob URL it just created, not a real network round trip), and
|
|
29
|
+
* `renderLayers` filters those rows with the SAME `matchToken`/
|
|
30
|
+
* `normalizeMatchList` helpers `FeatureMeshLayer` uses for the mesh, keyed on
|
|
31
|
+
* `feature-filter-field`. It does NOT follow `ghost-features` — ghosting only
|
|
32
|
+
* dims the mesh's opacity, never the outline, and that is not a BIMLayer gap:
|
|
33
|
+
* the OLDER two-layer pattern (`ifc-loader`'s own `Tile3DLayer` + companion
|
|
34
|
+
* `<layer-id>-edges` PathLayer, still used by the widget — see
|
|
35
|
+
* src/widgets/ifc.ts) never ghosted its outlines either, since its
|
|
36
|
+
* `filter-category`/`filter-categories` pair is a plain keep-list with no
|
|
37
|
+
* partial-opacity concept. Matching that, not inventing new behaviour.
|
|
38
|
+
*
|
|
39
|
+
* Implementation: a CompositeLayer wrapping a real `Tile3DLayer`, not a
|
|
40
|
+
* Tile3DLayer subclass — `renderLayers` fetches+parses on `src` change, then
|
|
41
|
+
* spreads `this.props` onto the inner Tile3DLayer verbatim (dropping `src`
|
|
42
|
+
* and the runtime's own harmless `data: []` baseline, setting `data` to the
|
|
43
|
+
* resolved tileset URL instead). That spread is load-bearing: the
|
|
44
|
+
* runtime injects `_subLayerProps`/`onTileLoad`/`onTilesetLoad` onto
|
|
45
|
+
* whatever top-level props a `supportsFeaturePicking`/`carriesTileset`
|
|
46
|
+
* layer receives (see runtime-core.ts's `pickFeaturesHook`/`featureTableHook`),
|
|
47
|
+
* and forwarding them unchanged is what makes picking, `feature-styles`,
|
|
48
|
+
* `ctx.features()`, and `om-tileset-load` all keep working without BIMLayer
|
|
49
|
+
* having to know anything about them itself.
|
|
50
|
+
*
|
|
51
|
+
* Other BIM formats: the loader dispatch (currently a straight call to
|
|
52
|
+
* `loadIfc`) is the one seam a future format would extend — nothing else
|
|
53
|
+
* here is IFC-specific.
|
|
54
|
+
*/
|
|
55
|
+
import { CompositeLayer } from "@deck.gl/core";
|
|
56
|
+
import type { Layer } from "@deck.gl/core";
|
|
57
|
+
/** One outline polyline plus the same category fields the mesh filters on — see `readGeoreference`'s edges row shape in `../ifc`. */
|
|
58
|
+
interface EdgeRow {
|
|
59
|
+
path: [number, number, number][];
|
|
60
|
+
[field: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
interface LoadedBim {
|
|
63
|
+
tilesetUrl: string;
|
|
64
|
+
edgeRows: EdgeRow[] | null;
|
|
65
|
+
lonLat: [number, number];
|
|
66
|
+
heading: number;
|
|
67
|
+
scale: number;
|
|
68
|
+
revoke(): void;
|
|
69
|
+
}
|
|
70
|
+
export interface BIMLayerProps {
|
|
71
|
+
/**
|
|
72
|
+
* URL of the BIM source file (an `.ifc` today).
|
|
73
|
+
*
|
|
74
|
+
* Deliberately NOT `data`: deck.gl's own `Layer` base class auto-fetches
|
|
75
|
+
* any string `data` prop through loaders.gl's generic loader registry —
|
|
76
|
+
* fine for a ScatterplotLayer's rows, fatal here ("No valid loader found"
|
|
77
|
+
* for a `.ifc`, confirmed by running this in a real browser). Tile3DLayer
|
|
78
|
+
* avoids this because deck.gl gives Tile3DLayer itself custom handling for
|
|
79
|
+
* `data`; a plain CompositeLayer like this one does not inherit that.
|
|
80
|
+
*/
|
|
81
|
+
src: string;
|
|
82
|
+
[prop: string]: unknown;
|
|
83
|
+
}
|
|
84
|
+
export declare class BIMLayer extends CompositeLayer<BIMLayerProps> {
|
|
85
|
+
static layerName: string;
|
|
86
|
+
static defaultProps: {
|
|
87
|
+
pickFeatures: boolean;
|
|
88
|
+
};
|
|
89
|
+
state: {
|
|
90
|
+
loaded: LoadedBim | null;
|
|
91
|
+
loadingFor: string | null;
|
|
92
|
+
destroyed: boolean;
|
|
93
|
+
abort: AbortController | null;
|
|
94
|
+
};
|
|
95
|
+
initializeState(): void;
|
|
96
|
+
updateState({ props, oldProps }: {
|
|
97
|
+
props: BIMLayerProps;
|
|
98
|
+
oldProps: BIMLayerProps;
|
|
99
|
+
}): void;
|
|
100
|
+
finalizeState(): void;
|
|
101
|
+
private loadModel;
|
|
102
|
+
renderLayers(): Layer[];
|
|
103
|
+
}
|
|
104
|
+
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, number] | readonly [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 {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as a, D as s } from "./raster-
|
|
1
|
+
import { C as a, D as s } from "./raster-0b0nSHUh.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-
|
|
11
|
+
const e = await import("./LercDecode.es-CJnypw8j.js");
|
|
12
12
|
return l || (await e.load(), l = !0), e;
|
|
13
13
|
}
|
|
14
14
|
async function i(e, r) {
|
package/dist/license.d.ts
CHANGED
|
@@ -15,11 +15,20 @@
|
|
|
15
15
|
* basemap-key precedent) — they MAY appear in markup, unlike data
|
|
16
16
|
* credentials.
|
|
17
17
|
*
|
|
18
|
-
* Decisions (spec, RESOLVED 2026-07-14): free tier =
|
|
19
|
-
* per layer / 20 MB fetch; any paid plan hides the
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
18
|
+
* Decisions (spec, RESOLVED 2026-07-14; REVISED 2026-08-05): free tier =
|
|
19
|
+
* 5 layers / 25k rows per layer / 20 MB fetch; any paid plan hides the
|
|
20
|
+
* badge; violations are per-layer hard drops with loud structured errors;
|
|
21
|
+
* no feature is gated at launch. REVISED: caps lift entirely in a DEV
|
|
22
|
+
* context — loopback http(s), any non-http(s) scheme (file://, tauri://,
|
|
23
|
+
* …), or no `location` at all (tests/SSR) — and apply only on hosted
|
|
24
|
+
* http(s). Deliberately NO embedded-runtime sniffing: the commercial /
|
|
25
|
+
* non-commercial boundary is a fact about intent that code cannot observe,
|
|
26
|
+
* so packaged-app enforcement is LEGAL, not technical — LICENSE.md states
|
|
27
|
+
* that the dev exemption is a technical convenience, never a grant, and
|
|
28
|
+
* commercial distribution (hosted OR packaged) requires a key regardless
|
|
29
|
+
* of whether gates fired. The badge stays on in every context (it is the
|
|
30
|
+
* attribution obligation, not a cap). App-identity keys for packaged apps
|
|
31
|
+
* are the onlymap-native roadmap's `apps` claim.
|
|
23
32
|
*
|
|
24
33
|
* Failure semantics: invalid/expired/mismatched keys → free tier + one
|
|
25
34
|
* console warning — never a broken map. While a key verifies (WebCrypto
|
|
@@ -37,6 +46,21 @@ export interface Entitlements {
|
|
|
37
46
|
keyId: string | null;
|
|
38
47
|
}
|
|
39
48
|
export declare const FREE_TIER: Entitlements;
|
|
49
|
+
/** The dev context's entitlements: every cap lifted, badge KEPT (attribution is an obligation, not a cap — and it carries the license pointer into shipped artifacts). */
|
|
50
|
+
export declare const DEV_TIER: Entitlements;
|
|
51
|
+
/**
|
|
52
|
+
* Dev context = not a hosted http(s) page: loopback hosts, any non-http(s)
|
|
53
|
+
* scheme (file://, a desktop webview's custom scheme), or no `location` at
|
|
54
|
+
* all (headless tests, SSR). Computed per call (cheap string checks) so the
|
|
55
|
+
* test seam works; `location` itself never changes within a page.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isDevContext(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* @internal Test seam: the unit suite runs under happy-dom on localhost, so
|
|
60
|
+
* every cap test would silently become vacuous without forcing "hosted".
|
|
61
|
+
* `null` restores real detection.
|
|
62
|
+
*/
|
|
63
|
+
export declare function setHostedContextForTests(hosted: boolean | null): void;
|
|
40
64
|
export declare function getEntitlements(): Readonly<Entitlements>;
|
|
41
65
|
/** True while a key is being verified — gates fail open so a paid page never flashes violations. */
|
|
42
66
|
export declare function licenseSettled(): boolean;
|