bruce-models 7.1.87 → 7.1.89
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/dist/bruce-models.es5.js +2482 -176
- package/dist/bruce-models.es5.js.map +1 -1
- package/dist/bruce-models.umd.js +2475 -180
- package/dist/bruce-models.umd.js.map +1 -1
- package/dist/lib/bruce-models.js +3 -1
- package/dist/lib/bruce-models.js.map +1 -1
- package/dist/lib/client-file/client-file-value-map.js +197 -0
- package/dist/lib/client-file/client-file-value-map.js.map +1 -0
- package/dist/lib/client-file/client-file.js +0 -76
- package/dist/lib/client-file/client-file.js.map +1 -1
- package/dist/lib/client-file/value-map-grid.js +298 -0
- package/dist/lib/client-file/value-map-grid.js.map +1 -0
- package/dist/lib/client-file/value-map-metadata.js +362 -0
- package/dist/lib/client-file/value-map-metadata.js.map +1 -0
- package/dist/lib/client-file/value-map-reader.js +1547 -0
- package/dist/lib/client-file/value-map-reader.js.map +1 -0
- package/dist/lib/export/export-nsx.js +32 -0
- package/dist/lib/export/export-nsx.js.map +1 -0
- package/dist/types/bruce-models.d.ts +3 -1
- package/dist/types/client-file/client-file-value-map.d.ts +186 -0
- package/dist/types/client-file/client-file.d.ts +1 -14
- package/dist/types/client-file/value-map-grid.d.ts +108 -0
- package/dist/types/client-file/value-map-metadata.d.ts +176 -0
- package/dist/types/client-file/value-map-reader.d.ts +520 -0
- package/dist/types/export/export-nsx.d.ts +16 -0
- package/package.json +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { ClientFileValueMap } from "./client-file-value-map";
|
|
2
|
+
/**
|
|
3
|
+
* Reading what a published value map declares, without decoding a single pixel.
|
|
4
|
+
*/
|
|
5
|
+
export declare namespace ValueMapMetadata {
|
|
6
|
+
type IMetadata = ClientFileValueMap.IMetadata;
|
|
7
|
+
type ILayer = ClientFileValueMap.ILayer;
|
|
8
|
+
type IBinaryTile = ClientFileValueMap.IBinaryTile;
|
|
9
|
+
type IBinaryRange = ClientFileValueMap.IBinaryRange;
|
|
10
|
+
type IExtent = ClientFileValueMap.IExtent;
|
|
11
|
+
export const SUPPORTED_VERSION = 3;
|
|
12
|
+
export const LAYOUT_TILES = "tiles";
|
|
13
|
+
export const LAYOUT_SINGLE = "single";
|
|
14
|
+
export const FORMAT_U8 = "u8";
|
|
15
|
+
export const FORMAT_RG16 = "rg16";
|
|
16
|
+
export const FORMAT_MASK = "mask";
|
|
17
|
+
export const ENCODING_ABSOLUTE = "absolute";
|
|
18
|
+
export const LAYER_VALUE = "Value";
|
|
19
|
+
export const LAYER_VALUE_MIN = "ValueMin";
|
|
20
|
+
export const LAYER_VALUE_MAX = "ValueMax";
|
|
21
|
+
export const LAYER_BASELINE = "Baseline";
|
|
22
|
+
export const LAYER_VALUE_SHIFT = "ValueShift";
|
|
23
|
+
export const NO_DATA = 0;
|
|
24
|
+
export const DATUM_ELLIPSOIDAL = "WGS84";
|
|
25
|
+
export const DATUMS_ELLIPSOIDAL: string[];
|
|
26
|
+
/**
|
|
27
|
+
* The published block on a Client File record, or undefined when it carries none.
|
|
28
|
+
*/
|
|
29
|
+
export function Of(file: any): IMetadata | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Whether a record is a value map this library can read.
|
|
32
|
+
*/
|
|
33
|
+
export function IsReadable(metadata: IMetadata | undefined): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Why an archive cannot be read, or null when it can.
|
|
36
|
+
*
|
|
37
|
+
* Returned rather than thrown so a renderer can warn and draw nothing while an analysis caller
|
|
38
|
+
* turns the same sentence into an error. Both then say the same thing.
|
|
39
|
+
*/
|
|
40
|
+
export function Unreadable(metadata: IMetadata | undefined): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* The tiles coarsest first, which is the order a reader has to composite them in.
|
|
43
|
+
*
|
|
44
|
+
* Tiles overlap and the finer one is the better answer, so assigning coarse first leaves the
|
|
45
|
+
* finest tile holding each texel it covers.
|
|
46
|
+
*/
|
|
47
|
+
export function TilesOf(metadata: IMetadata | undefined): IBinaryTile[];
|
|
48
|
+
/**
|
|
49
|
+
* One layer's declaration, or undefined when the archive does not carry it.
|
|
50
|
+
*/
|
|
51
|
+
export function LayerOf(metadata: IMetadata | undefined, name: string): ILayer | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* The range one layer was quantised between, or null for a mask and for a layer that is absent.
|
|
54
|
+
*
|
|
55
|
+
* A statistics layer is encoded over the true data range rather than over the frames' own, so
|
|
56
|
+
* reading it with the frame range is a plausible wrong answer.
|
|
57
|
+
*/
|
|
58
|
+
export function LayerRange(metadata: IMetadata | undefined, name: string): {
|
|
59
|
+
Min: number;
|
|
60
|
+
Max: number;
|
|
61
|
+
} | null;
|
|
62
|
+
/**
|
|
63
|
+
* The values a reading out of this archive falls between, in its delivered units.
|
|
64
|
+
*/
|
|
65
|
+
export function ValueRange(metadata: IMetadata | undefined): {
|
|
66
|
+
Min: number;
|
|
67
|
+
Max: number;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* The values the source's own numbers fall between, or null where nothing was transformed.
|
|
71
|
+
*/
|
|
72
|
+
export function SourceRange(metadata: IMetadata | undefined): {
|
|
73
|
+
Min: number;
|
|
74
|
+
Max: number;
|
|
75
|
+
} | null;
|
|
76
|
+
/**
|
|
77
|
+
* What was applied to the source's numbers to get the delivered ones, empty for nothing.
|
|
78
|
+
*/
|
|
79
|
+
export function TransformOf(metadata: IMetadata | undefined): string;
|
|
80
|
+
/**
|
|
81
|
+
* Whether a delivered reading differs from what the source's own data said.
|
|
82
|
+
*
|
|
83
|
+
* Both halves are needed: the transform names what happened, and the ValueShift layer is the
|
|
84
|
+
* only thing that can undo it per texel.
|
|
85
|
+
*/
|
|
86
|
+
export function IsTransformed(metadata: IMetadata | undefined): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* What a picture should be ramped over where the source suggests one, which is not a bound on the data.
|
|
89
|
+
*/
|
|
90
|
+
export function ColorBarRange(metadata: IMetadata | undefined): {
|
|
91
|
+
Min: number;
|
|
92
|
+
Max: number;
|
|
93
|
+
} | null;
|
|
94
|
+
/**
|
|
95
|
+
* When each frame was sampled. Authoritative, unlike Series.Increment.
|
|
96
|
+
*/
|
|
97
|
+
export function TimesOf(metadata: IMetadata | undefined): string[];
|
|
98
|
+
/**
|
|
99
|
+
* Whether the archive holds every timestep that was asked for.
|
|
100
|
+
*
|
|
101
|
+
* A short archive is otherwise indistinguishable from a short series, and the failure it hides
|
|
102
|
+
* is a skipped timestep in the middle of the event rather than a shorter one.
|
|
103
|
+
*/
|
|
104
|
+
export function IsComplete(metadata: IMetadata | undefined): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Says so when an archive's heights are not on the ellipsoid they will be drawn against.
|
|
107
|
+
*
|
|
108
|
+
* Returned rather than logged, so the renderer keeps its console warning and an analysis caller
|
|
109
|
+
* can put the same sentence in a report.
|
|
110
|
+
*/
|
|
111
|
+
export function UnshiftedWarning(metadata: IMetadata | undefined): string | null;
|
|
112
|
+
/**
|
|
113
|
+
* Where one tile's copy of a layer sits in the blob, or null when it holds none.
|
|
114
|
+
*
|
|
115
|
+
* A per-time layer holds one entry per Series.Times element, and a zero length means the tile
|
|
116
|
+
* held nothing at that time, so the indices stay aligned with the series.
|
|
117
|
+
*/
|
|
118
|
+
export function BytesOf(tile: IBinaryTile | undefined, name: string, index?: number): IBinaryRange | null;
|
|
119
|
+
export const MAX_READ_GAP = 131072;
|
|
120
|
+
/**
|
|
121
|
+
* The span of the blob a set of byte ranges covers, or null for an empty set.
|
|
122
|
+
*/
|
|
123
|
+
export function SpanOf(ranges: (IBinaryRange | null | undefined)[]): IBinaryRange | null;
|
|
124
|
+
/**
|
|
125
|
+
* The rectangle the archive's raster covers, or null when the block does not place it.
|
|
126
|
+
*/
|
|
127
|
+
export function ExtentOf(metadata: IMetadata | undefined): IExtent | null;
|
|
128
|
+
/**
|
|
129
|
+
* Whether frames carry a 16 bit value packed across R and G.
|
|
130
|
+
*
|
|
131
|
+
* Worth asking by name: taking R alone from a packed frame yields a plausible surface quantised
|
|
132
|
+
* to 255 steps of the full range rather than an obvious failure.
|
|
133
|
+
*/
|
|
134
|
+
export function IsPacked(metadata: IMetadata | undefined): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* A value in the attribute's own units as the 0 to 1 position a ramp is indexed by.
|
|
137
|
+
*
|
|
138
|
+
* Stops are authored in real units, since "hide anything under 0.1 m" is the sentence a user
|
|
139
|
+
* actually has, and the archive's published range is what makes that expressible.
|
|
140
|
+
*/
|
|
141
|
+
export function Normalise(value: number, range: {
|
|
142
|
+
Min: number;
|
|
143
|
+
Max: number;
|
|
144
|
+
}): number;
|
|
145
|
+
/**
|
|
146
|
+
* A 0 to 1 position back in the attribute's own units.
|
|
147
|
+
*/
|
|
148
|
+
export function Denormalise(position: number, range: {
|
|
149
|
+
Min: number;
|
|
150
|
+
Max: number;
|
|
151
|
+
}): number;
|
|
152
|
+
/**
|
|
153
|
+
* The packed number at one texel, straight out of the channels, whatever the format.
|
|
154
|
+
*/
|
|
155
|
+
export function PackedAt(pixels: Uint8Array | Uint8ClampedArray, at: number, format: string): number;
|
|
156
|
+
/**
|
|
157
|
+
* The 0 to 1 reading at one texel, for a caller indexing a ramp rather than reporting a number.
|
|
158
|
+
*/
|
|
159
|
+
export function NormalisedAt(pixels: Uint8Array | Uint8ClampedArray, at: number, format: string): number;
|
|
160
|
+
/**
|
|
161
|
+
* The reads that cover a set of byte ranges, adjacent ones merged and distant ones left apart.
|
|
162
|
+
*
|
|
163
|
+
* What stops a caller having to choose between one round trip per entry and one download of
|
|
164
|
+
* everything between the first entry and the last.
|
|
165
|
+
*/
|
|
166
|
+
export function PlanReads(ranges: (IBinaryRange | null | undefined)[], maxGap?: number): IBinaryRange[];
|
|
167
|
+
/**
|
|
168
|
+
* A packed channel reading as the number it stands for.
|
|
169
|
+
* value = Min + packed / fullScale * (Max - Min), where packed is R at 8 bits and R * 256 + G at 16.
|
|
170
|
+
*/
|
|
171
|
+
export function Decode(packed: number, format: string, range: {
|
|
172
|
+
Min: number;
|
|
173
|
+
Max: number;
|
|
174
|
+
}): number;
|
|
175
|
+
export {};
|
|
176
|
+
}
|
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
import { Geometry } from "../common/geometry";
|
|
2
|
+
import { BruceApi } from "../api/bruce-api";
|
|
3
|
+
import { ClientFile } from "./client-file";
|
|
4
|
+
import type { ClientFileValueMap } from "./client-file-value-map";
|
|
5
|
+
import { ValueMapGrid } from "./value-map-grid";
|
|
6
|
+
/**
|
|
7
|
+
* Reads a generated value map: its frames, the values in them, and the shapes those values make.
|
|
8
|
+
*/
|
|
9
|
+
export declare namespace ValueMapReader {
|
|
10
|
+
interface IRaster {
|
|
11
|
+
Width: number;
|
|
12
|
+
Height: number;
|
|
13
|
+
Data: Uint8Array | Uint8ClampedArray;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Turns one PNG's bytes into its pixels.
|
|
17
|
+
*/
|
|
18
|
+
type TDecoder = (bytes: Uint8Array) => Promise<IRaster>;
|
|
19
|
+
/**
|
|
20
|
+
* Hands back a slice of the archive blob.
|
|
21
|
+
*/
|
|
22
|
+
type TByteSource = (offset: number, length: number) => Promise<Uint8Array>;
|
|
23
|
+
interface IField {
|
|
24
|
+
Width: number;
|
|
25
|
+
Height: number;
|
|
26
|
+
Values: Float64Array | null;
|
|
27
|
+
Covered: Uint8Array;
|
|
28
|
+
}
|
|
29
|
+
interface IMask {
|
|
30
|
+
Width: number;
|
|
31
|
+
Height: number;
|
|
32
|
+
Bits: Uint8Array;
|
|
33
|
+
}
|
|
34
|
+
interface IReading {
|
|
35
|
+
Longitude: number;
|
|
36
|
+
Latitude: number;
|
|
37
|
+
Frame: number;
|
|
38
|
+
Time: string | null;
|
|
39
|
+
Units: string | null;
|
|
40
|
+
Texel: ValueMapGrid.ITexel | null;
|
|
41
|
+
Covered: boolean;
|
|
42
|
+
Value: number | null;
|
|
43
|
+
SourceValue: number | null;
|
|
44
|
+
}
|
|
45
|
+
interface IDetails extends IReading {
|
|
46
|
+
Attribute: string | null;
|
|
47
|
+
Label: string | null;
|
|
48
|
+
Dataset: string | null;
|
|
49
|
+
Frames: number;
|
|
50
|
+
Transform: string | null;
|
|
51
|
+
VerticalDatum: string | null;
|
|
52
|
+
Tile: {
|
|
53
|
+
Level: number;
|
|
54
|
+
TexelMetres: number;
|
|
55
|
+
ResolutionX: number;
|
|
56
|
+
ResolutionY: number;
|
|
57
|
+
West: number;
|
|
58
|
+
East: number;
|
|
59
|
+
South: number;
|
|
60
|
+
North: number;
|
|
61
|
+
};
|
|
62
|
+
TileTexel: ValueMapGrid.ITexel | null;
|
|
63
|
+
ValueMin: number | null;
|
|
64
|
+
ValueMax: number | null;
|
|
65
|
+
Shift: number | null;
|
|
66
|
+
Baseline: boolean;
|
|
67
|
+
}
|
|
68
|
+
interface ISummary {
|
|
69
|
+
Frame: number;
|
|
70
|
+
Time: string | null;
|
|
71
|
+
Units: string | null;
|
|
72
|
+
Texels: number;
|
|
73
|
+
Covered: number;
|
|
74
|
+
Peak: number | null;
|
|
75
|
+
Mean: number | null;
|
|
76
|
+
SourcePeak: number | null;
|
|
77
|
+
SourceMean: number | null;
|
|
78
|
+
}
|
|
79
|
+
interface IAdded {
|
|
80
|
+
Frame: number;
|
|
81
|
+
Time: string | null;
|
|
82
|
+
NewTexels: number;
|
|
83
|
+
Shapes: Geometry.IGeometry[];
|
|
84
|
+
New: IMask;
|
|
85
|
+
Cumulative: IMask;
|
|
86
|
+
}
|
|
87
|
+
const MIN_TEXELS = 8;
|
|
88
|
+
const SIMPLIFY_TOLERANCE = 0.25;
|
|
89
|
+
const ONSET_FRACTION = 0.5;
|
|
90
|
+
const LEVELS = 256;
|
|
91
|
+
const MAX_COMPOSITE_TEXELS = 2048;
|
|
92
|
+
const FRAME_CACHE = 16;
|
|
93
|
+
const TILE_CACHE = 32;
|
|
94
|
+
const MAX_READ_GAP = 131072;
|
|
95
|
+
/**
|
|
96
|
+
* One generated value map, read from its Client File.
|
|
97
|
+
*
|
|
98
|
+
* const map = await ClientFileValueMap.Open({ api, fileId });
|
|
99
|
+
* const frame = await map.Frame(0);
|
|
100
|
+
* for (const shape of await map.ShapesAbove({ threshold: 1.25 })) { ... }
|
|
101
|
+
*
|
|
102
|
+
* Every reading is in the archive's delivered units. Where a transform was applied, ask for the
|
|
103
|
+
* source values instead to get the customer's own numbers.
|
|
104
|
+
*/
|
|
105
|
+
interface IReaderParams {
|
|
106
|
+
file: ClientFile.IFile;
|
|
107
|
+
bytes: TByteSource;
|
|
108
|
+
decoder?: TDecoder;
|
|
109
|
+
maxCompositeTexels?: number;
|
|
110
|
+
extent?: ClientFileValueMap.IExtent;
|
|
111
|
+
}
|
|
112
|
+
class Reader {
|
|
113
|
+
readonly File: ClientFile.IFile;
|
|
114
|
+
readonly Metadata: ClientFileValueMap.IMetadata;
|
|
115
|
+
readonly Tiles: ClientFileValueMap.IBinaryTile[];
|
|
116
|
+
readonly Grid: ValueMapGrid.Grid;
|
|
117
|
+
readonly Extent: ClientFileValueMap.IExtent;
|
|
118
|
+
private readonly decoder;
|
|
119
|
+
private readonly bytes;
|
|
120
|
+
private readonly frames;
|
|
121
|
+
private readonly tileLayers;
|
|
122
|
+
private readonly statistics;
|
|
123
|
+
private readonly thresholds;
|
|
124
|
+
private baseline;
|
|
125
|
+
private unchanging;
|
|
126
|
+
constructor(params: IReaderParams);
|
|
127
|
+
/**
|
|
128
|
+
* The attribute this value map was generated from.
|
|
129
|
+
*/
|
|
130
|
+
get Attribute(): string | null;
|
|
131
|
+
/**
|
|
132
|
+
* What the attribute is called for a reader, where the source names it.
|
|
133
|
+
*/
|
|
134
|
+
get Label(): string | null;
|
|
135
|
+
/**
|
|
136
|
+
* The dataset the values came from, since one account holds several over the same mesh.
|
|
137
|
+
*/
|
|
138
|
+
get Dataset(): string | null;
|
|
139
|
+
/**
|
|
140
|
+
* The Entity Type Source this was generated from.
|
|
141
|
+
*/
|
|
142
|
+
get EntityTypeSourceID(): number | null;
|
|
143
|
+
/**
|
|
144
|
+
* When the archive was written, which is what tells two generations of it apart.
|
|
145
|
+
*/
|
|
146
|
+
get Generated(): string | null;
|
|
147
|
+
get Revision(): number | null;
|
|
148
|
+
/**
|
|
149
|
+
* The units a reading is in, where the source states them.
|
|
150
|
+
*/
|
|
151
|
+
get Units(): string | null;
|
|
152
|
+
/**
|
|
153
|
+
* How a frame's number is packed: one channel or two.
|
|
154
|
+
*/
|
|
155
|
+
get Format(): string;
|
|
156
|
+
/**
|
|
157
|
+
* The values a reading out of this value map falls between, in its own units.
|
|
158
|
+
*/
|
|
159
|
+
get ValueRange(): {
|
|
160
|
+
Min: number;
|
|
161
|
+
Max: number;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* The values the source's own numbers fall between, or null where nothing was transformed.
|
|
165
|
+
*/
|
|
166
|
+
get SourceRange(): {
|
|
167
|
+
Min: number;
|
|
168
|
+
Max: number;
|
|
169
|
+
} | null;
|
|
170
|
+
/**
|
|
171
|
+
* What the source's own heights are measured from, when the archive says.
|
|
172
|
+
* A thickness declares none, and an untransformed elevation declares one with no transform.
|
|
173
|
+
*/
|
|
174
|
+
get VerticalDatum(): string | null;
|
|
175
|
+
/**
|
|
176
|
+
* What was applied to the source's numbers to get the delivered ones, empty for nothing.
|
|
177
|
+
*/
|
|
178
|
+
get Transform(): string;
|
|
179
|
+
/**
|
|
180
|
+
* Whether a reading differs from what the source's own data said.
|
|
181
|
+
*/
|
|
182
|
+
get IsTransformed(): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* What the source suggests a picture be ramped over, which is not a bound on the data.
|
|
185
|
+
*/
|
|
186
|
+
get ColorBarRange(): {
|
|
187
|
+
Min: number;
|
|
188
|
+
Max: number;
|
|
189
|
+
} | null;
|
|
190
|
+
/**
|
|
191
|
+
* The largest movement any one texel made over the series.
|
|
192
|
+
*/
|
|
193
|
+
get MovingRangeMax(): number | null;
|
|
194
|
+
/**
|
|
195
|
+
* How many timesteps the generator set out to write.
|
|
196
|
+
*/
|
|
197
|
+
get RequestedFrames(): number;
|
|
198
|
+
/**
|
|
199
|
+
* How many it actually wrote.
|
|
200
|
+
*/
|
|
201
|
+
get WrittenFrames(): number;
|
|
202
|
+
/**
|
|
203
|
+
* Whether the archive holds every timestep that was asked for.
|
|
204
|
+
*/
|
|
205
|
+
get IsComplete(): boolean;
|
|
206
|
+
/**
|
|
207
|
+
* When each frame was sampled. Authoritative, unlike the series increment.
|
|
208
|
+
*/
|
|
209
|
+
get Times(): string[];
|
|
210
|
+
/**
|
|
211
|
+
* How many frames the archive holds.
|
|
212
|
+
*/
|
|
213
|
+
get Length(): number;
|
|
214
|
+
/**
|
|
215
|
+
* Says so when the archive's heights are not on the ellipsoid, or null when they are.
|
|
216
|
+
*/
|
|
217
|
+
Warning(): string | null;
|
|
218
|
+
/**
|
|
219
|
+
* One layer's declaration, or undefined when the archive does not carry it.
|
|
220
|
+
*/
|
|
221
|
+
Layer(name: string): ClientFileValueMap.ILayer | undefined;
|
|
222
|
+
/**
|
|
223
|
+
* One frame's values and a mask of which texels were sampled.
|
|
224
|
+
*/
|
|
225
|
+
Frame(index?: number, source?: boolean): Promise<IField>;
|
|
226
|
+
/**
|
|
227
|
+
* Each texel's lowest value over the series and where that is known, or null.
|
|
228
|
+
*/
|
|
229
|
+
ValueMin(): Promise<IField | null>;
|
|
230
|
+
/**
|
|
231
|
+
* Each texel's highest value over the series and where that is known, or null.
|
|
232
|
+
*/
|
|
233
|
+
ValueMax(): Promise<IField | null>;
|
|
234
|
+
/**
|
|
235
|
+
* The per-texel correction applied to the source's own numbers, or null where none was.
|
|
236
|
+
*
|
|
237
|
+
* sourceValue = value - shift, which is what makes the transform reversible per texel rather
|
|
238
|
+
* than only describable in prose.
|
|
239
|
+
*/
|
|
240
|
+
ValueShift(): Promise<IField | null>;
|
|
241
|
+
/**
|
|
242
|
+
* The texels flagged as permanently at their own minimum, or null when none were published.
|
|
243
|
+
*
|
|
244
|
+
* A caller measuring change subtracts these rather than reporting ground that never moved.
|
|
245
|
+
*/
|
|
246
|
+
Baseline(): Promise<IMask | null>;
|
|
247
|
+
/**
|
|
248
|
+
* The texels holding one value for the whole series, or null for a single frame archive.
|
|
249
|
+
*/
|
|
250
|
+
Unchanging(): Promise<IMask | null>;
|
|
251
|
+
/**
|
|
252
|
+
* Every texel a change in the series cannot be read from, or null when there are none.
|
|
253
|
+
*
|
|
254
|
+
* The published baseline and the texels measured as unchanging, since neither describes
|
|
255
|
+
* anything the series does and a caller asking what moved wants both gone.
|
|
256
|
+
*/
|
|
257
|
+
Ignored(): Promise<IMask | null>;
|
|
258
|
+
/**
|
|
259
|
+
* The level the series itself separates on, for a caller who cannot name one.
|
|
260
|
+
*/
|
|
261
|
+
NaturalThreshold(source?: boolean): Promise<number>;
|
|
262
|
+
/**
|
|
263
|
+
* The level to measure against, read off the series when the caller names none.
|
|
264
|
+
*/
|
|
265
|
+
Resolve(threshold: number | null | undefined, source?: boolean): Promise<number>;
|
|
266
|
+
/**
|
|
267
|
+
* The texels in one frame whose value is over a threshold.
|
|
268
|
+
*
|
|
269
|
+
* Ask for source to compare against the customer's own numbers, so a level stated against
|
|
270
|
+
* their data means what they think it means.
|
|
271
|
+
*/
|
|
272
|
+
MaskAbove(params?: {
|
|
273
|
+
threshold?: number;
|
|
274
|
+
frame?: number;
|
|
275
|
+
excludeBaseline?: boolean;
|
|
276
|
+
source?: boolean;
|
|
277
|
+
}): Promise<IMask>;
|
|
278
|
+
/**
|
|
279
|
+
* The texels over a threshold in every frame, or null for an archive with no frames.
|
|
280
|
+
*
|
|
281
|
+
* Measured rather than read off the first frame, so a tide that is out at the start does
|
|
282
|
+
* not get counted as ground the event flooded.
|
|
283
|
+
*/
|
|
284
|
+
AlwaysAbove(params?: {
|
|
285
|
+
threshold?: number;
|
|
286
|
+
excludeBaseline?: boolean;
|
|
287
|
+
source?: boolean;
|
|
288
|
+
}): Promise<IMask | null>;
|
|
289
|
+
/**
|
|
290
|
+
* One frame's mask with anything below the noise floor already removed.
|
|
291
|
+
*
|
|
292
|
+
* Built from the components so the floor is applied once, which is what lets two frames be
|
|
293
|
+
* compared as sets that already agree on what counts.
|
|
294
|
+
*/
|
|
295
|
+
CoveredMask(params?: {
|
|
296
|
+
threshold?: number;
|
|
297
|
+
frame?: number;
|
|
298
|
+
minTexels?: number;
|
|
299
|
+
excludeBaseline?: boolean;
|
|
300
|
+
source?: boolean;
|
|
301
|
+
}): Promise<IMask>;
|
|
302
|
+
/**
|
|
303
|
+
* How many texels are over the threshold in each frame.
|
|
304
|
+
*
|
|
305
|
+
* Decoding is local, so the whole series is read without a request and the frames worth
|
|
306
|
+
* querying can be found rather than guessed at.
|
|
307
|
+
*/
|
|
308
|
+
Profile(params?: {
|
|
309
|
+
threshold?: number;
|
|
310
|
+
minTexels?: number;
|
|
311
|
+
excludeBaseline?: boolean;
|
|
312
|
+
source?: boolean;
|
|
313
|
+
}): Promise<number[]>;
|
|
314
|
+
/**
|
|
315
|
+
* The frames that characterise an event: it arriving, its worst, and it passing.
|
|
316
|
+
*
|
|
317
|
+
* Read off the series rather than named by the caller, since a frame number that suits one
|
|
318
|
+
* archive is quietly wrong for the next and finding the worst is usually the question.
|
|
319
|
+
*/
|
|
320
|
+
FramesOfInterest(params?: {
|
|
321
|
+
threshold?: number;
|
|
322
|
+
fraction?: number;
|
|
323
|
+
excludeBaseline?: boolean;
|
|
324
|
+
source?: boolean;
|
|
325
|
+
}): Promise<number[]>;
|
|
326
|
+
/**
|
|
327
|
+
* Each area of one frame over a threshold, as a Bruce geometry ready to query with.
|
|
328
|
+
* Holes are dropped unless asked for.
|
|
329
|
+
*/
|
|
330
|
+
ShapesAbove(params?: {
|
|
331
|
+
threshold?: number;
|
|
332
|
+
frame?: number;
|
|
333
|
+
minTexels?: number;
|
|
334
|
+
keepHoles?: boolean;
|
|
335
|
+
excludeBaseline?: boolean;
|
|
336
|
+
tolerance?: number;
|
|
337
|
+
source?: boolean;
|
|
338
|
+
}): Promise<Geometry.IGeometry[]>;
|
|
339
|
+
/**
|
|
340
|
+
* Each area of any mask as a Bruce geometry, for a caller who built the mask itself.
|
|
341
|
+
*/
|
|
342
|
+
ShapesOf(mask: IMask, params?: {
|
|
343
|
+
minTexels?: number;
|
|
344
|
+
keepHoles?: boolean;
|
|
345
|
+
tolerance?: number;
|
|
346
|
+
}): Geometry.IGeometry[];
|
|
347
|
+
/**
|
|
348
|
+
* One area's outer ring and its holes, as positions.
|
|
349
|
+
*
|
|
350
|
+
* The longest ring is the outer one, since a hole is enclosed by what surrounds it. Pass a
|
|
351
|
+
* tolerance of 0 to keep every traced vertex.
|
|
352
|
+
*/
|
|
353
|
+
RingsOf(members: ValueMapGrid.ITexel[], tolerance?: number): {
|
|
354
|
+
Outer: ValueMapGrid.IPoint[];
|
|
355
|
+
Holes: ValueMapGrid.IPoint[][];
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* Walks the series in order, reporting only the ground each frame adds.
|
|
359
|
+
* Most frames add nothing, so onProgress is called for every frame while only the ones that grew come back.
|
|
360
|
+
*/
|
|
361
|
+
NewAreas(params?: {
|
|
362
|
+
threshold?: number;
|
|
363
|
+
minTexels?: number;
|
|
364
|
+
excludeBaseline?: boolean;
|
|
365
|
+
tolerance?: number;
|
|
366
|
+
source?: boolean;
|
|
367
|
+
onProgress?: (at: {
|
|
368
|
+
Frame: number;
|
|
369
|
+
Frames: number;
|
|
370
|
+
Time: string | null;
|
|
371
|
+
NewTexels: number;
|
|
372
|
+
Added: boolean;
|
|
373
|
+
}) => void;
|
|
374
|
+
}): Promise<IAdded[]>;
|
|
375
|
+
/**
|
|
376
|
+
* The texels an Entity covers, from where its record says it is.
|
|
377
|
+
*
|
|
378
|
+
* The raster does not move, so this holds for the whole series and a caller reading every
|
|
379
|
+
* frame works it out once.
|
|
380
|
+
*
|
|
381
|
+
* Ask for geometry to use the Entity's own outline rather than the box around it.
|
|
382
|
+
*/
|
|
383
|
+
TexelsOf(entity: any, useGeometry?: boolean): ValueMapGrid.ITexel[];
|
|
384
|
+
/**
|
|
385
|
+
* Every value a frame holds over a set of texels, skipping the texels it never sampled.
|
|
386
|
+
*
|
|
387
|
+
* An unsampled texel decodes to the bottom of the archive's range, which reads as a real
|
|
388
|
+
* measurement rather than as an absence, so the coverage mask decides what is reported.
|
|
389
|
+
*/
|
|
390
|
+
ReadingsAt(texels: ValueMapGrid.ITexel[], frame: IField): number[];
|
|
391
|
+
/**
|
|
392
|
+
* The highest value a frame holds over a set of texels, or null where it holds nothing.
|
|
393
|
+
*
|
|
394
|
+
* The highest rather than the middle one, because something spanning more than one texel is
|
|
395
|
+
* described by its worst part.
|
|
396
|
+
*/
|
|
397
|
+
PeakAt(texels: ValueMapGrid.ITexel[], frame?: number, source?: boolean): Promise<number | null>;
|
|
398
|
+
/**
|
|
399
|
+
* The average value a frame holds over a set of texels, or null where it holds nothing.
|
|
400
|
+
* What something spanning several texels experienced overall, as against the worst part.
|
|
401
|
+
*/
|
|
402
|
+
MeanAt(texels: ValueMapGrid.ITexel[], frame?: number, source?: boolean): Promise<number | null>;
|
|
403
|
+
/**
|
|
404
|
+
* How the values over a mask are spread, for a caller reporting on an area.
|
|
405
|
+
*/
|
|
406
|
+
ValuesAt(mask: IMask, frame: IField): {
|
|
407
|
+
Texels: number;
|
|
408
|
+
Peak?: number;
|
|
409
|
+
Mean?: number;
|
|
410
|
+
Median?: number;
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* The finest tile covering a position, or null when it falls outside every one of them.
|
|
414
|
+
*
|
|
415
|
+
* Tiles overlap, and the finer one is the better answer, so the last match wins over a list
|
|
416
|
+
* that is already sorted coarse first.
|
|
417
|
+
*/
|
|
418
|
+
TileAt(longitude: number, latitude: number): ClientFileValueMap.IBinaryTile | null;
|
|
419
|
+
/**
|
|
420
|
+
* One reading at one place, in both the delivered numbers and the source's own.
|
|
421
|
+
*
|
|
422
|
+
* Reads the single tile the position falls in rather than compositing the whole grid, which
|
|
423
|
+
* is what makes charting one point over a long series cheap.
|
|
424
|
+
*/
|
|
425
|
+
SampleAt(longitude: number, latitude: number, frame?: number): Promise<IReading | null>;
|
|
426
|
+
/**
|
|
427
|
+
* Everything the archive knows about one place, for a caller inspecting a single point.
|
|
428
|
+
*/
|
|
429
|
+
DetailsAt(longitude: number, latitude: number, frame?: number): Promise<IDetails | null>;
|
|
430
|
+
/**
|
|
431
|
+
* Every reading at one place over the whole series, in the order the times run.
|
|
432
|
+
*/
|
|
433
|
+
SeriesAt(longitude: number, latitude: number): Promise<IReading[]>;
|
|
434
|
+
/**
|
|
435
|
+
* What one frame holds over an Entity, in both the delivered numbers and the source's own.
|
|
436
|
+
*/
|
|
437
|
+
SampleOf(entity: any, frame?: number, useGeometry?: boolean): Promise<ISummary>;
|
|
438
|
+
/**
|
|
439
|
+
* What every frame holds over one Entity, for a caller charting a record through an event.
|
|
440
|
+
*/
|
|
441
|
+
SeriesOf(entity: any, useGeometry?: boolean): Promise<ISummary[]>;
|
|
442
|
+
private identity;
|
|
443
|
+
private position;
|
|
444
|
+
private statistic;
|
|
445
|
+
private composite;
|
|
446
|
+
private paste;
|
|
447
|
+
private tileLayer;
|
|
448
|
+
private tileReading;
|
|
449
|
+
private tileFlag;
|
|
450
|
+
private tileSeries;
|
|
451
|
+
private decodeAll;
|
|
452
|
+
private packing;
|
|
453
|
+
private range;
|
|
454
|
+
private toSource;
|
|
455
|
+
private missingShift;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* A value map read from a Client File.
|
|
459
|
+
*/
|
|
460
|
+
interface IOpenParams {
|
|
461
|
+
api?: BruceApi.Api;
|
|
462
|
+
fileId?: string;
|
|
463
|
+
file?: ClientFile.IFile;
|
|
464
|
+
blob?: ArrayBuffer | Uint8Array;
|
|
465
|
+
bytes?: TByteSource;
|
|
466
|
+
decoder?: TDecoder;
|
|
467
|
+
maxCompositeTexels?: number;
|
|
468
|
+
extent?: ClientFileValueMap.IExtent;
|
|
469
|
+
}
|
|
470
|
+
function Open(params: IOpenParams): Promise<Reader>;
|
|
471
|
+
/**
|
|
472
|
+
* Where an archive's bytes come from: a blob already held, or ranged reads of the file's URL.
|
|
473
|
+
*/
|
|
474
|
+
function SourceFor(file: ClientFile.IFile, blob?: ArrayBuffer | Uint8Array, api?: BruceApi.Api): TByteSource;
|
|
475
|
+
/**
|
|
476
|
+
* Decodes a PNG where the runtime has an image decoder of its own.
|
|
477
|
+
*
|
|
478
|
+
* A browser has one. Node does not, and rather than pull an image library into a client library
|
|
479
|
+
* that mostly does not decode anything, a caller there passes their own.
|
|
480
|
+
*/
|
|
481
|
+
const DefaultDecoder: TDecoder;
|
|
482
|
+
const MIN_RING_POINTS = 4;
|
|
483
|
+
/**
|
|
484
|
+
* The disconnected areas in a mask, as 4-connected groups of texels.
|
|
485
|
+
*/
|
|
486
|
+
function Components(mask: IMask, minTexels?: number): ValueMapGrid.ITexel[][];
|
|
487
|
+
/**
|
|
488
|
+
* The closed rings bounding a group of texels, in texel corner coordinates.
|
|
489
|
+
*/
|
|
490
|
+
function Trace(members: ValueMapGrid.ITexel[]): {
|
|
491
|
+
X: number;
|
|
492
|
+
Y: number;
|
|
493
|
+
}[][];
|
|
494
|
+
/**
|
|
495
|
+
* A ring with its texel staircase reduced, by Ramer-Douglas-Peucker.
|
|
496
|
+
*/
|
|
497
|
+
function Simplify(ring: {
|
|
498
|
+
X: number;
|
|
499
|
+
Y: number;
|
|
500
|
+
}[], tolerance: number): {
|
|
501
|
+
X: number;
|
|
502
|
+
Y: number;
|
|
503
|
+
}[];
|
|
504
|
+
/**
|
|
505
|
+
* How many texels a mask holds.
|
|
506
|
+
*/
|
|
507
|
+
function Count(mask: IMask): number;
|
|
508
|
+
/**
|
|
509
|
+
* Two masks merged texel by texel.
|
|
510
|
+
*/
|
|
511
|
+
function Combine(left: IMask, right: IMask, rule: (a: boolean, b: boolean) => boolean): IMask;
|
|
512
|
+
/**
|
|
513
|
+
* A polygon geometry from an outer ring and its holes, ready to query Bruce with.
|
|
514
|
+
*/
|
|
515
|
+
function Polygon(outer: ValueMapGrid.IPoint[], holes: ValueMapGrid.IPoint[][]): Geometry.IGeometry;
|
|
516
|
+
/**
|
|
517
|
+
* An Entity's polygon rings, or nothing when its record carries no outline.
|
|
518
|
+
*/
|
|
519
|
+
function RingsOfEntity(entity: any): ValueMapGrid.IPoint[][];
|
|
520
|
+
}
|