@nika-js/onlymap 0.6.25 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +5 -3
- package/dist/{LercDecode.es-DNwkPiJw.js → LercDecode.es-CYOgDeVu.js} +1 -1
- package/dist/{basemap-Da9yotkI.js → basemap-0rGUZkQT.js} +9 -1
- package/dist/basemap.d.ts +4 -0
- package/dist/elements/om-map.d.ts +9 -1
- package/dist/{geoparquet-D8-txekS.js → geoparquet-Cau8fzH7.js} +1 -1
- package/dist/hover-pick.d.ts +53 -0
- package/dist/html-data.d.ts +1 -1
- package/dist/{index-D6SeYdqX.js → index-BF3xZe9d.js} +1 -1
- package/dist/{index-CUnb2y9k.js → index-Bt3U7sbb.js} +1 -1
- package/dist/{index-Z6ZPKbXa.js → index-CpSUZ-J3.js} +1 -1
- package/dist/{index-31e3kTgK.js → index-CriPOt1s.js} +2 -2
- package/dist/{index-CPf0evzb.js → index-CxOS31XG.js} +11725 -11392
- package/dist/index.d.ts +1 -1
- package/dist/layer-registry.d.ts +10 -0
- package/dist/{lerc-CkqppWZk.js → lerc-aeqKo4fK.js} +2 -2
- package/dist/onlymap.standalone.js +29545 -28735
- package/dist/onlymapjs.js +91 -89
- package/dist/programmatic.d.ts +5 -0
- package/dist/{raster-CXPV5d4b.js → raster-D70FrkLt.js} +1049 -790
- package/dist/raster-identify.d.ts +19 -0
- package/dist/{raster-pipeline-CKW1mTzH.js → raster-pipeline-A-zvBnKU.js} +660 -450
- package/dist/raster-pipeline.d.ts +109 -14
- package/dist/raster.d.ts +91 -1
- package/dist/react.js +253 -234
- package/dist/runtime-core.d.ts +44 -0
- package/dist/version.d.ts +1 -1
- package/dist/widget-layout.d.ts +18 -0
- package/dist/{zarr-9YGMeWT7.js → zarr-DmrbmSNx.js} +10 -3
- package/docs/design/cog-v2.md +223 -0
- package/llms.txt +3 -2
- package/onlymapjs.attributes.json +9 -0
- package/onlymapjs.html-data.json +57 -0
- package/package.json +4 -2
- package/skills/onlymapjs/SKILL.md +1 -1
- package/skills/onlymapjs/references/syntax.md +17 -7
|
@@ -4,40 +4,135 @@
|
|
|
4
4
|
* (the GPU modules), NOT on `@developmentseed/deck.gl-geotiff` or `zarrita`, so
|
|
5
5
|
* neither lazy chunk drags the other's decoder in.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* COG v2 (docs/design/cog-v2.md, issue #13): ONE pipeline for single-band and
|
|
8
|
+
* composite sources, built on CompositeBands — per-band `r32float` textures
|
|
9
|
+
* created LAZILY from the retained decode, with an `ivec4 channelMap` uniform
|
|
10
|
+
* routing bands to RGB channels. A single-band source is the degenerate
|
|
11
|
+
* composite (slot 0 replicated to R=G=B), which keeps every styling feature
|
|
12
|
+
* written exactly once. Band switches re-run renderTile on a fresh layer
|
|
13
|
+
* instance; missing band textures are uploaded from the retained array — the
|
|
14
|
+
* tile cache, the HTTP cache, and the decode all survive. Nothing short of a
|
|
15
|
+
* `src` change refetches.
|
|
16
|
+
*
|
|
17
|
+
* Pipeline order (load-bearing): CreateTexture (base-texture insurance for
|
|
18
|
+
* the mesh) → CompositeBands (color = raw band values) → FilterNoDataVal
|
|
19
|
+
* (tests the RAW datum, so it precedes the rescale squash) → LinearRescale →
|
|
20
|
+
* Colormap (single-band only).
|
|
13
21
|
*/
|
|
14
22
|
import type { Device, Texture } from "@luma.gl/core";
|
|
15
23
|
import { type RasterModule } from "@developmentseed/deck.gl-raster/gpu-modules";
|
|
16
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The decoded source a tile retains — structural subset of
|
|
26
|
+
* `@developmentseed/geotiff`'s RasterArray (band-separate carries `bands`,
|
|
27
|
+
* pixel-interleaved carries `data` + `count`), typed here so the pipeline
|
|
28
|
+
* stays decoder-agnostic and tests fabricate it without a TIFF in sight.
|
|
29
|
+
*/
|
|
30
|
+
export interface RasterArrayLike {
|
|
31
|
+
layout: "band-separate" | "pixel-interleaved";
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
bands?: ArrayLike<number>[];
|
|
35
|
+
data?: ArrayLike<number>;
|
|
36
|
+
count?: number;
|
|
37
|
+
}
|
|
38
|
+
/** A styled tile's payload: retained decode + lazily-created band textures. */
|
|
17
39
|
export interface OmTileData {
|
|
18
40
|
width: number;
|
|
19
41
|
height: number;
|
|
20
42
|
byteLength: number;
|
|
21
|
-
|
|
43
|
+
/** The device the tile's textures live on — renderTile receives only the data, so lazy uploads need it here. */
|
|
44
|
+
device: Device;
|
|
45
|
+
/** Decoded source (ALL bands) retained for the tile-cache lifetime — band switches re-upload from it, identify samples it. Null when the source pre-uploads (Zarr) or retention is off. */
|
|
46
|
+
array: RasterArrayLike | null;
|
|
47
|
+
/** 0-based band index → its r32float texture. Lazily filled by ensureBandTextures; fully destroyed by destroyTileTextures. */
|
|
48
|
+
bandTextures: Map<number, Texture>;
|
|
22
49
|
colormapTexture: Texture;
|
|
23
50
|
bandCount: number;
|
|
24
51
|
nodata: number | null;
|
|
25
52
|
}
|
|
26
|
-
/** The
|
|
53
|
+
/** The styling scalars every raster source (COG, Zarr) exposes. */
|
|
27
54
|
export interface RasterStyle {
|
|
28
|
-
/** Rescale window; both default to the 8-bit range when absent. */
|
|
29
|
-
rescaleMin?: number | null;
|
|
30
|
-
rescaleMax?: number | null;
|
|
55
|
+
/** Rescale window; both default to the 8-bit range when absent. A number broadcasts to every selected band; a triple gives per-band windows, positionally matching a `bands` triple (COG v2 decision: per-band ships in 0.7.0). */
|
|
56
|
+
rescaleMin?: number | number[] | null;
|
|
57
|
+
rescaleMax?: number | number[] | null;
|
|
31
58
|
/** Sprite colormap name (single-band sources only). Unknown names warn + fall back to gray. */
|
|
32
59
|
colormap?: string | null;
|
|
60
|
+
/** Reversed colormap (upstream Colormap's own `reversed` prop — the fork the design planned turned out unnecessary). */
|
|
61
|
+
reverse?: boolean | null;
|
|
33
62
|
/** Overrides the source's own nodata sentinel. */
|
|
34
63
|
nodataOverride?: number | null;
|
|
64
|
+
/** 1-based band selection (GDAL convention): a single band (colormap-eligible) or an [r,g,b] triple. Absent = band 1 / first three. */
|
|
65
|
+
bands?: number | number[] | null;
|
|
66
|
+
/** Non-linear stretch applied to the rescaled [0,1] value: linear (default) | log | sqrt. */
|
|
67
|
+
stretch?: string | null;
|
|
68
|
+
/** Power-law exponent > 0 (display gamma); 1 = identity. */
|
|
69
|
+
gamma?: number | null;
|
|
35
70
|
}
|
|
36
71
|
export declare function getColormapTexture(device: Device): Promise<Texture>;
|
|
37
72
|
export declare function resolveColormapIndex(name: string): number;
|
|
38
73
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
74
|
+
* Authored `bands` (1-based) → 0-based indices, validated against the
|
|
75
|
+
* source's band count. A single index means "single-band" (colormap
|
|
76
|
+
* pipeline); a triple means RGB composite. Anything unusable falls back to
|
|
77
|
+
* the source defaults (band 1 / first three) with one warning per shape —
|
|
78
|
+
* the layer renders SOMETHING rather than blanking (structured errors land
|
|
79
|
+
* in phase 6).
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveBands(bands: number | number[] | null | undefined, bandCount: number): number[];
|
|
82
|
+
/** Every band's raw value at one pixel — the identify sampler (no per-band copies; reads the retained layout directly). */
|
|
83
|
+
export declare function sampleAllBands(arr: RasterArrayLike, px: number, py: number, bandCount: number): number[];
|
|
84
|
+
/** One band of a decoded array as Float32 regardless of layout — luma's r32float upload rejects uint8/16 TypedArrays, so non-Float32 sources copy (raw values preserved; that's the contract the rescale window depends on). */
|
|
85
|
+
export declare function extractBand(arr: RasterArrayLike, band: number): Float32Array;
|
|
86
|
+
/**
|
|
87
|
+
* Creates any missing textures for the selected bands from the retained
|
|
88
|
+
* array, and destroys textures for bands no longer selected (VRAM stays at
|
|
89
|
+
* ≤ the selected set). Returns the selected bands' textures in order.
|
|
90
|
+
* A tile whose array was dropped (identify off — phase 4) keeps whatever
|
|
91
|
+
* textures it already has; selections it can't satisfy fall back to the
|
|
92
|
+
* first available texture rather than crashing mid-frame.
|
|
93
|
+
*/
|
|
94
|
+
export declare function ensureBandTextures(tile: OmTileData, bands: number[]): Texture[];
|
|
95
|
+
/** Frees every GPU texture a tile owns and drops the retained decode — the onTileUnload hook (the sprite texture is device-scoped and must NOT be destroyed here). */
|
|
96
|
+
export declare function destroyTileTextures(tile: OmTileData): void;
|
|
97
|
+
/**
|
|
98
|
+
* Per-band rescale windows (design decision: ships in 0.7.0, not a
|
|
99
|
+
* follow-up). Used ONLY when a triple window is authored — scalar windows
|
|
100
|
+
* keep upstream's LinearRescale so existing maps keep their exact shader
|
|
101
|
+
* (the phase-1 SSIM-1.0 parity stays intact).
|
|
102
|
+
*/
|
|
103
|
+
export declare const PerBandRescale: RasterModule["module"];
|
|
104
|
+
/**
|
|
105
|
+
* Non-linear stretch + display gamma, applied AFTER the rescale squash (the
|
|
106
|
+
* value is in [0,1]) and BEFORE the colormap lookup. `log` is the bounded
|
|
107
|
+
* log10 curve `log(1+9x)/log 10` (monotone, hits 0→0 and 1→1, no -inf).
|
|
108
|
+
* Inserted only when non-identity, so linear/γ=1 maps keep their shader.
|
|
109
|
+
*/
|
|
110
|
+
export declare const StretchGamma: RasterModule["module"];
|
|
111
|
+
/** stretch attribute → mode number (0 linear / 1 log / 2 sqrt); unknown warns once and stays linear. */
|
|
112
|
+
export declare function resolveStretchMode(stretch: string | null | undefined): number;
|
|
113
|
+
/** gamma attribute → validated exponent (> 0); anything else warns once and is identity. */
|
|
114
|
+
export declare function resolveGamma(gamma: number | null | undefined): number;
|
|
115
|
+
/**
|
|
116
|
+
* Normalizes the authored window(s) against the selection. Scalars
|
|
117
|
+
* broadcast; a triple pairs positionally with a `bands` triple. Returns
|
|
118
|
+
* either a scalar window (upstream LinearRescale — shader parity for
|
|
119
|
+
* existing maps) or per-band vec3s (PerBandRescale).
|
|
120
|
+
*/
|
|
121
|
+
export declare function resolveWindow(style: RasterStyle, bands: number[]): {
|
|
122
|
+
kind: "scalar";
|
|
123
|
+
min: number;
|
|
124
|
+
max: number;
|
|
125
|
+
} | {
|
|
126
|
+
kind: "per-band";
|
|
127
|
+
minV: [number, number, number];
|
|
128
|
+
maxV: [number, number, number];
|
|
129
|
+
};
|
|
130
|
+
/** channelMap for a selection: single band replicates slot 0 to RGB (gray, colormap-eligible); a triple maps each channel to its band's slot. Alpha is always the shader's opaque -1. */
|
|
131
|
+
export declare function buildChannelMap(bands: number[], slotOf: (band: number) => number): [number, number, number, number];
|
|
132
|
+
/**
|
|
133
|
+
* The styled render pipeline for one tile. One shape for single-band and
|
|
134
|
+
* composite sources (design decision: UNIFY, with the Metal-ANGLE pixel
|
|
135
|
+
* parachute in phase-1 acceptance).
|
|
41
136
|
*/
|
|
42
137
|
export declare function buildRenderPipeline(tile: OmTileData, style: RasterStyle): {
|
|
43
138
|
renderPipeline: RasterModule[];
|
package/dist/raster.d.ts
CHANGED
|
@@ -1,7 +1,45 @@
|
|
|
1
1
|
import { COGLayer } from "@developmentseed/deck.gl-geotiff";
|
|
2
2
|
import { type OmTileData, type RasterStyle } from "./raster-pipeline";
|
|
3
|
-
|
|
3
|
+
import { type RasterIdentifyResult } from "./raster-identify";
|
|
4
|
+
/** COGLayer styling scalars (rescale window, colormap, nodata, bands). Shared with the Zarr layer; re-exported for consumer wrappers. */
|
|
4
5
|
export type OmCOGLayerExtraProps = RasterStyle;
|
|
6
|
+
/** TIFF SampleFormat → readable dtype for the dev notice. */
|
|
7
|
+
export declare function dtypeName(tags: {
|
|
8
|
+
bitsPerSample?: ArrayLike<number>;
|
|
9
|
+
sampleFormat?: ArrayLike<number>;
|
|
10
|
+
}): string;
|
|
11
|
+
export declare function isUint8(tags: {
|
|
12
|
+
bitsPerSample?: ArrayLike<number>;
|
|
13
|
+
sampleFormat?: ArrayLike<number>;
|
|
14
|
+
}): boolean;
|
|
15
|
+
export type AutoWindow = {
|
|
16
|
+
min: number | [number, number, number];
|
|
17
|
+
max: number | [number, number, number];
|
|
18
|
+
source: "stats" | "overview";
|
|
19
|
+
};
|
|
20
|
+
/** Deterministic path: per-band GDAL STATISTICS tags from the header — no pixel pass. Null when any selected band lacks them. */
|
|
21
|
+
export declare function statsWindow(gdalMetadata: unknown, bands: number[]): AutoWindow | null;
|
|
22
|
+
/** Fallback: one small read of the coarsest overview's first tile — data-derived, so the notice warns harder. */
|
|
23
|
+
export declare function overviewWindow(image: {
|
|
24
|
+
fetchTile(x: number, y: number, opts: object): Promise<{
|
|
25
|
+
array: import("./raster-pipeline").RasterArrayLike & {
|
|
26
|
+
nodata?: number | null;
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
}, bands: number[], pool: unknown): Promise<AutoWindow | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Palette legend (COG v2 phase 5, the gl#1014 ask): a paletted GeoTIFF
|
|
32
|
+
* renders through its embedded color table upstream — this derives legend
|
|
33
|
+
* CLASS rows from it when the number of DISTINCT indices actually used
|
|
34
|
+
* (sampled from the coarsest overview tile) is small. Beyond the cap the
|
|
35
|
+
* legend widget's single-swatch fallback stands; TIFF palettes carry no
|
|
36
|
+
* class names, so labels are the palette indices.
|
|
37
|
+
*/
|
|
38
|
+
export declare const PALETTE_LEGEND_MAX_CLASSES = 12;
|
|
39
|
+
export declare function paletteLegendEntries(colorMap: ArrayLike<number>, arr: import("./raster-pipeline").RasterArrayLike): {
|
|
40
|
+
color: string;
|
|
41
|
+
label: string;
|
|
42
|
+
}[] | null;
|
|
5
43
|
type AnyProps = Record<string, unknown>;
|
|
6
44
|
declare const OmCOGLayer_base: new (...props: AnyProps[]) => InstanceType<typeof COGLayer>;
|
|
7
45
|
/**
|
|
@@ -16,7 +54,59 @@ export declare class OmCOGLayer extends OmCOGLayer_base {
|
|
|
16
54
|
rescaleMax: null;
|
|
17
55
|
colormap: null;
|
|
18
56
|
nodataOverride: null;
|
|
57
|
+
bands: null;
|
|
58
|
+
stretch: null;
|
|
59
|
+
gamma: null;
|
|
60
|
+
reverse: null;
|
|
19
61
|
};
|
|
20
62
|
constructor(props: AnyProps);
|
|
63
|
+
/**
|
|
64
|
+
* Upstream's `_parseGeoTIFF` EAGERLY infers a render pipeline at its tail
|
|
65
|
+
* and HARD-THROWS for int/float sources ("Inferring render pipeline for
|
|
66
|
+
* non-unsigned integers not yet supported") — before `state.geotiff` ever
|
|
67
|
+
* lands, which would kill the exact auto-route that exists to serve those
|
|
68
|
+
* sources. Conditional retry: the normal run stays untouched (uint8 infers
|
|
69
|
+
* fine, one header fetch); on the inference throw only, re-run with a
|
|
70
|
+
* props OVERLAY (prototype chain — the real props object is never mutated)
|
|
71
|
+
* whose callback pair suppresses the infer, so state.geotiff lands and the
|
|
72
|
+
* resolvers below route the source through the styled pipeline. The retry
|
|
73
|
+
* costs one extra header fetch, paid only by sources that were a dead
|
|
74
|
+
* layer before this existed.
|
|
75
|
+
*/
|
|
76
|
+
/** Structured runtime errors (phase 6) through the injected onRasterError → core.onRuntimeError channel — the layer stays mounted, the map stays alive. */
|
|
77
|
+
private omReportError;
|
|
78
|
+
_parseGeoTIFF(): Promise<void>;
|
|
79
|
+
private omRetryWithoutInference;
|
|
80
|
+
private omExtra;
|
|
81
|
+
private omAuthoredStyled;
|
|
82
|
+
private omGeotiff;
|
|
83
|
+
/**
|
|
84
|
+
* The bit-depth auto-route (the "my COG is blank" fix): a non-8-bit
|
|
85
|
+
* source with NO styling attrs enters the styled pipeline anyway, with a
|
|
86
|
+
* window from the header. Paletted sources (ColorMap tag) never route —
|
|
87
|
+
* upstream renders the palette.
|
|
88
|
+
*/
|
|
89
|
+
private omAutoWanted;
|
|
90
|
+
/** Resolved auto window, kicking off the one-shot overview sample when stats are absent. Undefined while pending/unavailable. */
|
|
91
|
+
private omAutoWindow;
|
|
92
|
+
/** Feeds the resolved window to the consumer (legend derivation) via the injected onAutoWindow deck prop — the onTilesetLoad compose precedent. */
|
|
93
|
+
private omPublishWindow;
|
|
94
|
+
private omStyledActive;
|
|
95
|
+
/** Authored style + auto window filling any unauthored window end. */
|
|
96
|
+
private omEffectiveStyle;
|
|
97
|
+
/**
|
|
98
|
+
* Pixel identify (COG v2 phase 4): lngLat → source CRS (the descriptor's
|
|
99
|
+
* own projector) → full-res pixel (geotiff.index) → the FINEST currently-
|
|
100
|
+
* loaded tile containing it → all bands sampled from the retained decode.
|
|
101
|
+
* No fetch, no GPU readback; null when the point is outside the image or
|
|
102
|
+
* no covering tile is resident.
|
|
103
|
+
*/
|
|
104
|
+
identify(lngLat: [number, number]): RasterIdentifyResult | null;
|
|
105
|
+
updateState(params: Parameters<InstanceType<typeof COGLayer>["updateState"]>[0]): void;
|
|
106
|
+
/** One-shot palette legend derivation per opened file (phase 5). */
|
|
107
|
+
private omMaybePaletteLegend;
|
|
108
|
+
finalizeState(context: Parameters<InstanceType<typeof COGLayer>["finalizeState"]>[0]): void;
|
|
109
|
+
_getTileDataCallback(): any;
|
|
110
|
+
_renderTileCallback(): any;
|
|
21
111
|
}
|
|
22
112
|
export type { OmTileData };
|