@fxi/zartigl 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/dist/data/catalog.json +260 -17
- package/dist/index.d.ts +155 -21
- package/dist/zartigl.js +1847 -1496
- package/package.json +5 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { CustomLayerInterface } from 'maplibre-gl';
|
|
|
2
2
|
import { CustomRenderMethodInput } from 'maplibre-gl';
|
|
3
3
|
import { Map as Map_2 } from 'maplibre-gl';
|
|
4
4
|
|
|
5
|
+
export declare type ColorRampInput = string | string[] | Record<number, string>;
|
|
6
|
+
|
|
5
7
|
declare interface CoordArrays {
|
|
6
8
|
time: Float64Array | Float32Array;
|
|
7
9
|
vertical: Float32Array;
|
|
@@ -9,35 +11,107 @@ declare interface CoordArrays {
|
|
|
9
11
|
longitude: Float32Array;
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
export declare interface FieldMeta {
|
|
15
|
+
min: number;
|
|
16
|
+
max: number;
|
|
17
|
+
unit: string;
|
|
18
|
+
time: string;
|
|
19
|
+
depth?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export declare function getPalettes(): PaletteMeta[];
|
|
23
|
+
|
|
24
|
+
declare type LayerEventMap = {
|
|
25
|
+
loading: () => void;
|
|
26
|
+
loaded: (meta: FieldMeta) => void;
|
|
27
|
+
error: (err: Error) => void;
|
|
28
|
+
/** Fired when a time step has been pre-fetched and is ready for instant swap. */
|
|
29
|
+
frameBuffered: (ms: number) => void;
|
|
30
|
+
/** Fired when the frame cache is wiped (viewport changed). */
|
|
31
|
+
cacheInvalidated: () => void;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export declare interface PaletteMeta {
|
|
35
|
+
id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
tags: string[];
|
|
38
|
+
colors: string[];
|
|
39
|
+
}
|
|
40
|
+
|
|
12
41
|
export declare class ParticleLayer implements CustomLayerInterface {
|
|
13
42
|
readonly id: string;
|
|
14
43
|
readonly type: "custom";
|
|
15
|
-
readonly renderingMode: "
|
|
44
|
+
readonly renderingMode: "3d";
|
|
16
45
|
private map;
|
|
17
46
|
private gl;
|
|
18
47
|
private simulation;
|
|
19
48
|
private velocityField;
|
|
20
49
|
private zarrSource;
|
|
21
|
-
private
|
|
50
|
+
private speedFactorParam;
|
|
51
|
+
private fadeOpacityParam;
|
|
52
|
+
private zoomRange;
|
|
53
|
+
private variableU;
|
|
54
|
+
private variableV;
|
|
55
|
+
private time;
|
|
56
|
+
private depth;
|
|
57
|
+
private scalarMode;
|
|
58
|
+
private scalarUnit;
|
|
22
59
|
private initialized;
|
|
23
60
|
private loading;
|
|
24
61
|
private velocityTexUnit;
|
|
62
|
+
private moveStartHandler;
|
|
25
63
|
private moveEndHandler;
|
|
64
|
+
/** Pre-fetched frames keyed by time-ms. Cleared when the viewport changes. */
|
|
65
|
+
private frameCache;
|
|
66
|
+
/** Time-ms values currently being fetched in the background. */
|
|
67
|
+
private inflight;
|
|
68
|
+
private listeners;
|
|
26
69
|
constructor(options: ParticleLayerOptions);
|
|
27
70
|
onAdd(map: Map_2, gl: WebGLRenderingContext): Promise<void>;
|
|
28
71
|
private initAsync;
|
|
72
|
+
private timeToMs;
|
|
73
|
+
private computeFieldMeta;
|
|
74
|
+
/**
|
|
75
|
+
* Fetch and stitch velocity data for the given time without touching GL state.
|
|
76
|
+
* The map's current viewport is used to determine the lat bounds of the request.
|
|
77
|
+
*/
|
|
78
|
+
private fetchVelocityData;
|
|
29
79
|
private loadViewportVelocity;
|
|
30
80
|
render(gl: WebGLRenderingContext, options: CustomRenderMethodInput | number[]): void;
|
|
31
81
|
onRemove(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Interpolate speed and fade per render frame (cheap uniform uploads).
|
|
84
|
+
* t=0 at low zoom (global), t=1 at high zoom (local).
|
|
85
|
+
* For each range [min, max]: min applies at high zoom, max at low zoom.
|
|
86
|
+
*/
|
|
87
|
+
private applyZoomWeighting;
|
|
32
88
|
setTime(time: string | number): void;
|
|
89
|
+
/**
|
|
90
|
+
* Pre-fetch velocity data for a future time step without swapping the active
|
|
91
|
+
* field. Fires `frameBuffered(ms)` when ready so playback can advance
|
|
92
|
+
* immediately without a loading gap.
|
|
93
|
+
*/
|
|
94
|
+
prefetchTime(ms: number): Promise<void>;
|
|
95
|
+
/** True when the frame for the given time (ms) is already in the cache. */
|
|
96
|
+
isFrameCached(ms: number): boolean;
|
|
97
|
+
/** Abort all pending Zarr prefetch fetches and clear the inflight set. */
|
|
98
|
+
cancelPrefetches(): void;
|
|
33
99
|
setDepth(depth: number): void;
|
|
34
|
-
setSpeedFactor(v:
|
|
35
|
-
setFadeOpacity(v:
|
|
100
|
+
setSpeedFactor(v: ZoomWeighted): void;
|
|
101
|
+
setFadeOpacity(v: ZoomWeighted): void;
|
|
36
102
|
setDropRate(v: number): void;
|
|
37
103
|
setDropRateBump(v: number): void;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
setColorRamp(ramp:
|
|
104
|
+
setParticleDensity(density: number): void;
|
|
105
|
+
setZoomRange(range: [number, number]): void;
|
|
106
|
+
setColorRamp(ramp: ColorRampInput): void;
|
|
107
|
+
setRenderMode(mode: RenderMode): void;
|
|
108
|
+
setOpacity(v: number): void;
|
|
109
|
+
setLogScale(v: boolean): void;
|
|
110
|
+
setVibrance(v: number): void;
|
|
111
|
+
setScalarVariable(varName: string): void;
|
|
112
|
+
on<K extends keyof LayerEventMap>(event: K, handler: LayerEventMap[K]): this;
|
|
113
|
+
off<K extends keyof LayerEventMap>(event: K, handler: LayerEventMap[K]): this;
|
|
114
|
+
private emit;
|
|
41
115
|
}
|
|
42
116
|
|
|
43
117
|
export declare interface ParticleLayerOptions {
|
|
@@ -45,15 +119,27 @@ export declare interface ParticleLayerOptions {
|
|
|
45
119
|
source: string;
|
|
46
120
|
variableU?: string;
|
|
47
121
|
variableV?: string;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
122
|
+
/** Particles per screen pixel. Count = clamp(w × h × density, 1, 262144). Default 0.05. */
|
|
123
|
+
particleDensity?: number;
|
|
124
|
+
/** Fixed speed or [atHighZoom, atLowZoom]. */
|
|
125
|
+
speedFactor?: ZoomWeighted;
|
|
126
|
+
/** Fixed fade or [atHighZoom, atLowZoom]. */
|
|
127
|
+
fadeOpacity?: ZoomWeighted;
|
|
51
128
|
dropRate?: number;
|
|
52
129
|
dropRateBump?: number;
|
|
53
|
-
pointSize?: number;
|
|
54
130
|
colorRamp?: Record<number, string>;
|
|
55
131
|
time?: string | number;
|
|
56
132
|
depth?: number;
|
|
133
|
+
/** [lowZoom, highZoom] breakpoints for zoom-weighted params. Default [2, 12]. */
|
|
134
|
+
zoomRange?: [number, number];
|
|
135
|
+
/** Global layer opacity [0, 1]. Default 1.0. */
|
|
136
|
+
opacity?: number;
|
|
137
|
+
/** Logarithmic speed normalization. Default false. */
|
|
138
|
+
logScale?: boolean;
|
|
139
|
+
/** Vibrance adjustment [-1, 1]. Default 0.0. */
|
|
140
|
+
vibrance?: number;
|
|
141
|
+
scalarMode?: boolean;
|
|
142
|
+
scalarUnit?: string;
|
|
57
143
|
}
|
|
58
144
|
|
|
59
145
|
export declare class ParticleSimulation {
|
|
@@ -62,10 +148,12 @@ export declare class ParticleSimulation {
|
|
|
62
148
|
private updateProgram;
|
|
63
149
|
private drawProgram;
|
|
64
150
|
private fadeProgram;
|
|
151
|
+
private gridProgram;
|
|
65
152
|
private particleStateTextures;
|
|
66
153
|
private particleFramebuffers;
|
|
67
|
-
private particleStateRes;
|
|
68
154
|
private particleIndexBuffer;
|
|
155
|
+
private particleIsCurrBuffer;
|
|
156
|
+
/** Active draw count — changes with canvas size / density, no realloc. */
|
|
69
157
|
private numParticles;
|
|
70
158
|
private screenTextures;
|
|
71
159
|
private screenFramebuffers;
|
|
@@ -73,15 +161,18 @@ export declare class ParticleSimulation {
|
|
|
73
161
|
private screenHeight;
|
|
74
162
|
private quadBuffer;
|
|
75
163
|
private colorRampTexture;
|
|
164
|
+
renderMode: RenderMode;
|
|
76
165
|
private updateLocs;
|
|
77
166
|
private drawLocs;
|
|
78
167
|
private fadeLocs;
|
|
168
|
+
private gridLocs;
|
|
79
169
|
constructor(params?: Partial<SimulationParams>);
|
|
80
170
|
init(gl: WebGLRenderingContext): void;
|
|
81
171
|
private getUniforms;
|
|
82
172
|
private initParticleState;
|
|
83
173
|
/**
|
|
84
|
-
* Ensure screen textures match the current canvas size
|
|
174
|
+
* Ensure screen textures match the current canvas size and recompute
|
|
175
|
+
* the active particle count from density × canvas area.
|
|
85
176
|
*/
|
|
86
177
|
resize(width: number, height: number): void;
|
|
87
178
|
/**
|
|
@@ -93,35 +184,51 @@ export declare class ParticleSimulation {
|
|
|
93
184
|
minY: number;
|
|
94
185
|
maxX: number;
|
|
95
186
|
maxY: number;
|
|
96
|
-
}, worldSize: number, geoBounds?: {
|
|
187
|
+
}, worldSize: number, worldCopyOffsets: number[], geoBounds?: {
|
|
97
188
|
west: number;
|
|
98
189
|
south: number;
|
|
99
190
|
east: number;
|
|
100
191
|
north: number;
|
|
101
|
-
}): void;
|
|
192
|
+
}, isGlobe?: boolean): void;
|
|
102
193
|
private drawQuad;
|
|
103
194
|
setSpeedFactor(v: number): void;
|
|
104
195
|
setFadeOpacity(v: number): void;
|
|
105
196
|
setDropRate(v: number): void;
|
|
106
197
|
setDropRateBump(v: number): void;
|
|
107
|
-
|
|
108
|
-
setParticleCount(count: number): void;
|
|
198
|
+
setParticleDensity(density: number): void;
|
|
109
199
|
setColorRamp(ramp: Record<number, string>): void;
|
|
200
|
+
setRenderMode(mode: RenderMode): void;
|
|
201
|
+
setOpacity(v: number): void;
|
|
202
|
+
setLogScale(v: boolean): void;
|
|
203
|
+
setVibrance(v: number): void;
|
|
204
|
+
setScalarMode(v: boolean): void;
|
|
110
205
|
/**
|
|
111
|
-
* Reset all particles to random positions. Call after time/depth change
|
|
206
|
+
* Reset all particles to random positions. Call after time/depth change
|
|
207
|
+
* or map move. Randomises the full state texture and clears trail FBOs.
|
|
112
208
|
*/
|
|
113
209
|
resetParticles(): void;
|
|
210
|
+
/**
|
|
211
|
+
* Clear screen framebuffers to transparent black.
|
|
212
|
+
* Eliminates ghost trails when the viewport shifts.
|
|
213
|
+
*/
|
|
214
|
+
clearState(): void;
|
|
114
215
|
destroy(): void;
|
|
115
216
|
}
|
|
116
217
|
|
|
218
|
+
declare type RenderMode = 'raster' | 'particles' | 'raster+particles';
|
|
219
|
+
|
|
117
220
|
declare interface SimulationParams {
|
|
118
|
-
|
|
221
|
+
/** Particles per screen pixel. Active count = clamp(w * h * density, 1, MAX). */
|
|
222
|
+
particleDensity: number;
|
|
119
223
|
speedFactor: number;
|
|
120
224
|
fadeOpacity: number;
|
|
121
225
|
dropRate: number;
|
|
122
226
|
dropRateBump: number;
|
|
123
|
-
pointSize: number;
|
|
124
227
|
colorRamp?: Record<number, string>;
|
|
228
|
+
opacity: number;
|
|
229
|
+
logScale: boolean;
|
|
230
|
+
vibrance: number;
|
|
231
|
+
scalarMode: boolean;
|
|
125
232
|
}
|
|
126
233
|
|
|
127
234
|
/**
|
|
@@ -135,18 +242,20 @@ export declare function stitchVelocityChunks(uChunks: Array<{
|
|
|
135
242
|
lonStart: number;
|
|
136
243
|
latSize: number;
|
|
137
244
|
lonSize: number;
|
|
245
|
+
lonChunkSize: number;
|
|
138
246
|
}>, vChunks: Array<{
|
|
139
247
|
data: Float32Array;
|
|
140
248
|
latStart: number;
|
|
141
249
|
lonStart: number;
|
|
142
250
|
latSize: number;
|
|
143
251
|
lonSize: number;
|
|
252
|
+
lonChunkSize: number;
|
|
144
253
|
}>, totalLat: number, totalLon: number, geoBounds?: {
|
|
145
254
|
west: number;
|
|
146
255
|
south: number;
|
|
147
256
|
east: number;
|
|
148
257
|
north: number;
|
|
149
|
-
}): VelocityData;
|
|
258
|
+
}, latDescending?: boolean, scalarMode?: boolean): VelocityData;
|
|
150
259
|
|
|
151
260
|
export declare interface VelocityData {
|
|
152
261
|
u: Float32Array;
|
|
@@ -163,6 +272,10 @@ export declare interface VelocityData {
|
|
|
163
272
|
east: number;
|
|
164
273
|
north: number;
|
|
165
274
|
};
|
|
275
|
+
/** True when latitude rows are stored north-to-south (needs GL Y-flip). */
|
|
276
|
+
latDescending?: boolean;
|
|
277
|
+
/** When true: R=scalar_norm, G=128(neutral), V loop skipped. */
|
|
278
|
+
scalarMode?: boolean;
|
|
166
279
|
}
|
|
167
280
|
|
|
168
281
|
/**
|
|
@@ -184,6 +297,8 @@ export declare class VelocityField {
|
|
|
184
297
|
east: number;
|
|
185
298
|
north: number;
|
|
186
299
|
};
|
|
300
|
+
scalarMode: boolean;
|
|
301
|
+
private linearFilter;
|
|
187
302
|
init(gl: WebGLRenderingContext): void;
|
|
188
303
|
/**
|
|
189
304
|
* Upload velocity data as a 2-channel (RG) texture.
|
|
@@ -191,6 +306,8 @@ export declare class VelocityField {
|
|
|
191
306
|
* Stored normalized to [0,1] using uMin/uMax/vMin/vMax.
|
|
192
307
|
*/
|
|
193
308
|
update(data: VelocityData): void;
|
|
309
|
+
/** Switch between bilinear (particles) and nearest-neighbour (raster) sampling. */
|
|
310
|
+
setFilter(linear: boolean): void;
|
|
194
311
|
bind(unit: number): void;
|
|
195
312
|
hasData(): boolean;
|
|
196
313
|
destroy(): void;
|
|
@@ -236,6 +353,7 @@ export declare class ZarrSource {
|
|
|
236
353
|
private meta;
|
|
237
354
|
private coords;
|
|
238
355
|
private verticalName;
|
|
356
|
+
private timeUnits;
|
|
239
357
|
private cache;
|
|
240
358
|
private maxCacheSize;
|
|
241
359
|
private abortControllers;
|
|
@@ -251,6 +369,12 @@ export declare class ZarrSource {
|
|
|
251
369
|
getDimensions(variable: string): string[];
|
|
252
370
|
findNearestIndex(array: Float32Array | Float64Array, value: number): number;
|
|
253
371
|
findTimeIndex(time: string | number): number;
|
|
372
|
+
/**
|
|
373
|
+
* Convert a Unix-ms timestamp to the native time units used by this zarr
|
|
374
|
+
* (read from the time variable's .zattrs "units" field).
|
|
375
|
+
* Falls back to a magnitude heuristic when units are absent or unparseable.
|
|
376
|
+
*/
|
|
377
|
+
private msToZarrTime;
|
|
254
378
|
findDepthIndex(depth: number): number;
|
|
255
379
|
/** Return the actual name of the vertical dimension ("depth" or "elevation"). */
|
|
256
380
|
getVerticalDimName(): string;
|
|
@@ -279,4 +403,14 @@ export declare class ZarrSource {
|
|
|
279
403
|
private loadCoordinates;
|
|
280
404
|
}
|
|
281
405
|
|
|
406
|
+
/**
|
|
407
|
+
* A param that is either a fixed scalar or a zoom-weighted range.
|
|
408
|
+
* When a range [min, max] is given:
|
|
409
|
+
* - min is the value at high zoom (local / detail view)
|
|
410
|
+
* - max is the value at low zoom (global / overview)
|
|
411
|
+
* The layer interpolates between them based on the current map zoom
|
|
412
|
+
* and the configured zoomRange.
|
|
413
|
+
*/
|
|
414
|
+
export declare type ZoomWeighted = number | [min: number, max: number];
|
|
415
|
+
|
|
282
416
|
export { }
|