@loaders.gl/tiles 5.0.0-alpha.1 → 5.0.0-alpha.10
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/LICENSE +14 -3
- package/README.md +26 -0
- package/dist/dist.dev.js +20271 -5055
- package/dist/dist.min.js +3 -1
- package/dist/index.cjs +7849 -2081
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +25 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/point-cloud/point-cloud-tile.d.ts.map +1 -1
- package/dist/point-cloud/point-cloud-tile.js +3 -0
- package/dist/point-cloud/point-cloud-tile.js.map +1 -1
- package/dist/point-cloud/point-cloud-tileset.d.ts +4 -0
- package/dist/point-cloud/point-cloud-tileset.d.ts.map +1 -1
- package/dist/point-cloud/point-cloud-tileset.js +54 -12
- package/dist/point-cloud/point-cloud-tileset.js.map +1 -1
- package/dist/point-cloud/types.d.ts +17 -0
- package/dist/point-cloud/types.d.ts.map +1 -1
- package/dist/point-cloud/types.js +3 -0
- package/dist/point-cloud/types.js.map +1 -1
- package/dist/raster-set.d.ts +48 -31
- package/dist/raster-set.d.ts.map +1 -1
- package/dist/raster-set.js +104 -24
- package/dist/raster-set.js.map +1 -1
- package/dist/spatial/format-spatial-reference.d.ts +68 -0
- package/dist/spatial/format-spatial-reference.d.ts.map +1 -0
- package/dist/spatial/format-spatial-reference.js +291 -0
- package/dist/spatial/format-spatial-reference.js.map +1 -0
- package/dist/spatial/get-spatial-coordinate-frame.d.ts +20 -0
- package/dist/spatial/get-spatial-coordinate-frame.d.ts.map +1 -0
- package/dist/spatial/get-spatial-coordinate-frame.js +139 -0
- package/dist/spatial/get-spatial-coordinate-frame.js.map +1 -0
- package/dist/spatial/i3s-elevation.d.ts +20 -0
- package/dist/spatial/i3s-elevation.d.ts.map +1 -0
- package/dist/spatial/i3s-elevation.js +90 -0
- package/dist/spatial/i3s-elevation.js.map +1 -0
- package/dist/spatial/i3s-spatial-transformer.d.ts +189 -0
- package/dist/spatial/i3s-spatial-transformer.d.ts.map +1 -0
- package/dist/spatial/i3s-spatial-transformer.js +686 -0
- package/dist/spatial/i3s-spatial-transformer.js.map +1 -0
- package/dist/spatial/normalize-crs-identifier.d.ts +15 -0
- package/dist/spatial/normalize-crs-identifier.d.ts.map +1 -0
- package/dist/spatial/normalize-crs-identifier.js +22 -0
- package/dist/spatial/normalize-crs-identifier.js.map +1 -0
- package/dist/spatial/spatial-coordinate-transformer.d.ts +52 -0
- package/dist/spatial/spatial-coordinate-transformer.d.ts.map +1 -0
- package/dist/spatial/spatial-coordinate-transformer.js +295 -0
- package/dist/spatial/spatial-coordinate-transformer.js.map +1 -0
- package/dist/spatial/spatial-resource-registry.d.ts +44 -0
- package/dist/spatial/spatial-resource-registry.d.ts.map +1 -0
- package/dist/spatial/spatial-resource-registry.js +67 -0
- package/dist/spatial/spatial-resource-registry.js.map +1 -0
- package/dist/spatial/spatial-types.d.ts +190 -0
- package/dist/spatial/spatial-types.d.ts.map +1 -0
- package/dist/spatial/spatial-types.js +192 -0
- package/dist/spatial/spatial-types.js.map +1 -0
- package/dist/spatial/tiles-3d-spatial-transformer.d.ts +32 -0
- package/dist/spatial/tiles-3d-spatial-transformer.d.ts.map +1 -0
- package/dist/spatial/tiles-3d-spatial-transformer.js +175 -0
- package/dist/spatial/tiles-3d-spatial-transformer.js.map +1 -0
- package/dist/tileset-2d/adapter.d.ts +2 -3
- package/dist/tileset-2d/adapter.d.ts.map +1 -1
- package/dist/tileset-2d/tileset-2d.d.ts +2 -3
- package/dist/tileset-2d/tileset-2d.d.ts.map +1 -1
- package/dist/tileset-2d/tileset-2d.js.map +1 -1
- package/dist/tileset-3d/common/indexed-archive-tileset-source.d.ts +3 -3
- package/dist/tileset-3d/common/indexed-archive-tileset-source.d.ts.map +1 -1
- package/dist/tileset-3d/common/indexed-archive-tileset-source.js +9 -4
- package/dist/tileset-3d/common/indexed-archive-tileset-source.js.map +1 -1
- package/dist/tileset-3d/common/tile-3d-contracts.d.ts +63 -0
- package/dist/tileset-3d/common/tile-3d-contracts.d.ts.map +1 -0
- package/dist/tileset-3d/common/tile-3d-contracts.js +51 -0
- package/dist/tileset-3d/common/tile-3d-contracts.js.map +1 -0
- package/dist/tileset-3d/common/tile-3d.d.ts +176 -5
- package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tile-3d.js +523 -89
- package/dist/tileset-3d/common/tile-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.d.ts +192 -9
- package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.js +303 -23
- package/dist/tileset-3d/common/tileset-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-cache.d.ts +11 -1
- package/dist/tileset-3d/common/tileset-cache.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-cache.js +11 -3
- package/dist/tileset-3d/common/tileset-cache.js.map +1 -1
- package/dist/tileset-3d/common/tileset-content-traversal.d.ts +37 -0
- package/dist/tileset-3d/common/tileset-content-traversal.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-content-traversal.js +80 -0
- package/dist/tileset-3d/common/tileset-content-traversal.js.map +1 -0
- package/dist/tileset-3d/common/tileset-observability.d.ts +60 -0
- package/dist/tileset-3d/common/tileset-observability.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-observability.js +39 -0
- package/dist/tileset-3d/common/tileset-observability.js.map +1 -0
- package/dist/tileset-3d/common/tileset-source.d.ts +51 -9
- package/dist/tileset-3d/common/tileset-source.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-source.js.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.d.ts +33 -1
- package/dist/tileset-3d/common/tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.js +59 -11
- package/dist/tileset-3d/common/tileset-traverser.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts +182 -0
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js +681 -0
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts +127 -6
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js +485 -27
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts +103 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js +278 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js +3 -0
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts +23 -6
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-source.js +176 -25
- package/dist/tileset-3d/format-i3s/i3s-source.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.js +3 -0
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js +4 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js.map +1 -1
- package/dist/tileset-3d/helpers/3d-tiles-options.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/3d-tiles-options.js +3 -0
- package/dist/tileset-3d/helpers/3d-tiles-options.js.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.d.ts +7 -3
- package/dist/tileset-3d/helpers/bounding-volume.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.js +20 -91
- package/dist/tileset-3d/helpers/bounding-volume.js.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.d.ts +67 -2
- package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.js +92 -10
- package/dist/tileset-3d/helpers/frame-state.js.map +1 -1
- package/dist/tileset-3d/helpers/i3s-lod.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/i3s-lod.js +20 -8
- package/dist/tileset-3d/helpers/i3s-lod.js.map +1 -1
- package/dist/tileset-3d/helpers/s2-bounding-volume.d.ts +17 -0
- package/dist/tileset-3d/helpers/s2-bounding-volume.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/s2-bounding-volume.js +20 -0
- package/dist/tileset-3d/helpers/s2-bounding-volume.js.map +1 -0
- package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts +61 -9
- package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/tiles-3d-lod.js +198 -93
- package/dist/tileset-3d/helpers/tiles-3d-lod.js.map +1 -1
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.d.ts +134 -0
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.js +179 -0
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/doubly-linked-list.d.ts.map +1 -1
- package/dist/utils/doubly-linked-list.js +1 -0
- package/dist/utils/doubly-linked-list.js.map +1 -1
- package/dist/utils/managed-array.d.ts.map +1 -1
- package/dist/utils/managed-array.js +1 -0
- package/dist/utils/managed-array.js.map +1 -1
- package/package.json +12 -10
- package/src/index.ts +78 -1
- package/src/point-cloud/point-cloud-tile.ts +4 -0
- package/src/point-cloud/point-cloud-tileset.ts +70 -12
- package/src/point-cloud/types.ts +21 -0
- package/src/raster-set.ts +197 -67
- package/src/spatial/format-spatial-reference.ts +385 -0
- package/src/spatial/get-spatial-coordinate-frame.ts +169 -0
- package/src/spatial/i3s-elevation.ts +96 -0
- package/src/spatial/i3s-spatial-transformer.ts +957 -0
- package/src/spatial/normalize-crs-identifier.ts +26 -0
- package/src/spatial/spatial-coordinate-transformer.ts +376 -0
- package/src/spatial/spatial-resource-registry.ts +79 -0
- package/src/spatial/spatial-types.ts +422 -0
- package/src/spatial/tiles-3d-spatial-transformer.ts +206 -0
- package/src/tileset-2d/adapter.ts +2 -3
- package/src/tileset-2d/tileset-2d.ts +2 -3
- package/src/tileset-3d/common/indexed-archive-tileset-source.ts +13 -13
- package/src/tileset-3d/common/tile-3d-contracts.ts +115 -0
- package/src/tileset-3d/common/tile-3d.ts +629 -98
- package/src/tileset-3d/common/tileset-3d.ts +459 -29
- package/src/tileset-3d/common/tileset-cache.ts +15 -7
- package/src/tileset-3d/common/tileset-content-traversal.ts +114 -0
- package/src/tileset-3d/common/tileset-observability.ts +100 -0
- package/src/tileset-3d/common/tileset-source.ts +63 -13
- package/src/tileset-3d/common/tileset-traverser.ts +71 -11
- package/src/tileset-3d/format-3d-tiles/implicit-tiling.ts +1059 -0
- package/src/tileset-3d/format-3d-tiles/tiles-3d-source.ts +674 -28
- package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +316 -0
- package/src/tileset-3d/format-i3s/i3s-pending-tiles-register.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-source.ts +220 -29
- package/src/tileset-3d/format-i3s/i3s-tile-manager.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-tileset-traverser.ts +6 -1
- package/src/tileset-3d/helpers/3d-tiles-options.ts +4 -0
- package/src/tileset-3d/helpers/bounding-volume.ts +31 -114
- package/src/tileset-3d/helpers/frame-state.ts +152 -13
- package/src/tileset-3d/helpers/i3s-lod.ts +22 -8
- package/src/tileset-3d/helpers/s2-bounding-volume.ts +35 -0
- package/src/tileset-3d/helpers/tiles-3d-lod.ts +291 -112
- package/src/tileset-3d/helpers/tiles-3d-request-priority.ts +301 -0
- package/src/types.ts +11 -0
- package/src/utils/doubly-linked-list.ts +2 -0
- package/src/utils/managed-array.ts +2 -0
package/src/raster-set.ts
CHANGED
|
@@ -1,66 +1,89 @@
|
|
|
1
1
|
// loaders.gl
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Copyright (c) vis.gl contributors
|
|
3
|
+
// SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import type {
|
|
6
6
|
GetRasterParameters,
|
|
7
|
+
NumericRasterData,
|
|
7
8
|
RasterData,
|
|
8
9
|
RasterSource,
|
|
9
10
|
RasterSourceMetadata
|
|
10
11
|
} from '@loaders.gl/loader-utils';
|
|
12
|
+
import {waitForPromiseWithSignals} from '@loaders.gl/loader-utils';
|
|
11
13
|
|
|
12
14
|
/** Accepted raster request currently retained by {@link RasterSet}. */
|
|
13
|
-
export type RasterSetRequest<
|
|
15
|
+
export type RasterSetRequest<
|
|
16
|
+
DataT extends NumericRasterData = RasterData,
|
|
17
|
+
ParametersT extends object = GetRasterParameters
|
|
18
|
+
> = {
|
|
14
19
|
/** Unique request id assigned by the manager. */
|
|
15
20
|
requestId: number;
|
|
16
21
|
/** Raster request parameters that produced the accepted raster payload. */
|
|
17
|
-
parameters:
|
|
22
|
+
parameters: ParametersT;
|
|
18
23
|
/** Raster retained as the current output. */
|
|
19
24
|
raster: DataT;
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
/** Arguments supplied to {@link RasterSetBaseProps.shouldRefetch}. */
|
|
23
|
-
export type RasterSetShouldRefetchArgs<
|
|
28
|
+
export type RasterSetShouldRefetchArgs<
|
|
29
|
+
DataT extends NumericRasterData = RasterData,
|
|
30
|
+
ParametersT extends object = GetRasterParameters,
|
|
31
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
32
|
+
> = {
|
|
24
33
|
/** Current accepted request retained by the raster manager, if any. */
|
|
25
|
-
currentRequest: RasterSetRequest<DataT> | null;
|
|
34
|
+
currentRequest: RasterSetRequest<DataT, ParametersT> | null;
|
|
26
35
|
/** Source metadata resolved by {@link RasterSet.loadMetadata}, if available. */
|
|
27
|
-
metadata:
|
|
36
|
+
metadata: MetadataT | null;
|
|
28
37
|
/** Candidate raster request parameters under evaluation. */
|
|
29
|
-
nextParameters:
|
|
38
|
+
nextParameters: ParametersT;
|
|
30
39
|
};
|
|
31
40
|
|
|
32
41
|
/** Configuration shared by all {@link RasterSet} instances. */
|
|
33
|
-
export type RasterSetBaseProps<
|
|
42
|
+
export type RasterSetBaseProps<
|
|
43
|
+
DataT extends NumericRasterData = RasterData,
|
|
44
|
+
ParametersT extends object = GetRasterParameters,
|
|
45
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
46
|
+
> = {
|
|
34
47
|
/** Callback used to load source metadata. */
|
|
35
|
-
getMetadata: (
|
|
48
|
+
getMetadata: (options?: {
|
|
49
|
+
/** Metadata request cancellation. */ signal?: AbortSignal;
|
|
50
|
+
}) => Promise<MetadataT>;
|
|
36
51
|
/** Callback used to load raster data for a viewport-derived request. */
|
|
37
|
-
getRaster: (parameters:
|
|
52
|
+
getRaster: (parameters: ParametersT) => Promise<DataT>;
|
|
38
53
|
/** Debounce interval applied before issuing raster requests. */
|
|
39
54
|
debounceTime?: number;
|
|
40
55
|
/** Optional policy callback that can skip redundant raster requests. */
|
|
41
|
-
shouldRefetch?: (args: RasterSetShouldRefetchArgs<DataT>) => boolean;
|
|
56
|
+
shouldRefetch?: (args: RasterSetShouldRefetchArgs<DataT, ParametersT, MetadataT>) => boolean;
|
|
42
57
|
};
|
|
43
58
|
|
|
44
59
|
/** Options for creating a {@link RasterSet}. */
|
|
45
|
-
export type RasterSetProps<
|
|
60
|
+
export type RasterSetProps<
|
|
61
|
+
DataT extends NumericRasterData = RasterData,
|
|
62
|
+
ParametersT extends object = GetRasterParameters,
|
|
63
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
64
|
+
> = Partial<RasterSetBaseProps<DataT, ParametersT, MetadataT>> & {
|
|
46
65
|
/** Optional loaders.gl raster source backing this manager. */
|
|
47
|
-
rasterSource?: RasterSource | null;
|
|
66
|
+
rasterSource?: RasterSource<DataT, ParametersT & GetRasterParameters, MetadataT> | null;
|
|
48
67
|
};
|
|
49
68
|
|
|
50
69
|
/** Subscription callbacks emitted by {@link RasterSet}. */
|
|
51
|
-
export type RasterSetListener<
|
|
70
|
+
export type RasterSetListener<
|
|
71
|
+
DataT extends NumericRasterData = RasterData,
|
|
72
|
+
ParametersT extends object = GetRasterParameters,
|
|
73
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
74
|
+
> = {
|
|
52
75
|
/** Fired when metadata/raster loading starts or stops. */
|
|
53
76
|
onLoadingStateChange?: (isLoading: boolean) => void;
|
|
54
77
|
/** Fired when source metadata resolves successfully. */
|
|
55
|
-
onMetadataLoad?: (metadata:
|
|
78
|
+
onMetadataLoad?: (metadata: MetadataT) => void;
|
|
56
79
|
/** Fired when metadata loading fails. */
|
|
57
80
|
onMetadataLoadError?: (error: Error) => void;
|
|
58
81
|
/** Fired when a new raster request is issued. */
|
|
59
|
-
onRasterLoadStart?: (requestId: number, parameters:
|
|
82
|
+
onRasterLoadStart?: (requestId: number, parameters: ParametersT) => void;
|
|
60
83
|
/** Fired when a raster request resolves and becomes current. */
|
|
61
|
-
onRasterLoad?: (request: RasterSetRequest<DataT>) => void;
|
|
84
|
+
onRasterLoad?: (request: RasterSetRequest<DataT, ParametersT>) => void;
|
|
62
85
|
/** Fired when a raster request fails. */
|
|
63
|
-
onRasterLoadError?: (requestId: number, error: Error, parameters:
|
|
86
|
+
onRasterLoadError?: (requestId: number, error: Error, parameters: ParametersT) => void;
|
|
64
87
|
/** Fired when metadata or the current raster changes. */
|
|
65
88
|
onUpdate?: () => void;
|
|
66
89
|
};
|
|
@@ -84,23 +107,38 @@ const DEFAULT_RASTERSET_PROPS: Required<Omit<RasterSetProps, 'rasterSource'>> =
|
|
|
84
107
|
shouldRefetch: () => true
|
|
85
108
|
};
|
|
86
109
|
|
|
87
|
-
/**
|
|
88
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Shared raster request manager used by viewport-driven raster examples and layers.
|
|
112
|
+
*
|
|
113
|
+
* @typeParam DataT Raster payload retained by the manager.
|
|
114
|
+
* @typeParam ParametersT Request parameters accepted by the source.
|
|
115
|
+
* @typeParam MetadataT Metadata returned by the source.
|
|
116
|
+
*/
|
|
117
|
+
export class RasterSet<
|
|
118
|
+
DataT extends NumericRasterData = RasterData,
|
|
119
|
+
ParametersT extends object = GetRasterParameters,
|
|
120
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
121
|
+
> {
|
|
89
122
|
/** Cached metadata returned by the backing source, if any. */
|
|
90
|
-
metadata:
|
|
123
|
+
metadata: MetadataT | null = null;
|
|
91
124
|
|
|
92
|
-
private _opts: Required<RasterSetProps<DataT>>;
|
|
93
|
-
private _listeners = new Set<RasterSetListener<DataT>>();
|
|
94
|
-
private _currentRequest: RasterSetRequest<DataT> | null = null;
|
|
95
|
-
private _lastAcceptedRequestId = -1;
|
|
125
|
+
private _opts: Required<RasterSetProps<DataT, ParametersT, MetadataT>>;
|
|
126
|
+
private _listeners = new Set<RasterSetListener<DataT, ParametersT, MetadataT>>();
|
|
127
|
+
private _currentRequest: RasterSetRequest<DataT, ParametersT> | null = null;
|
|
96
128
|
private _nextRequestId = 0;
|
|
97
129
|
private _loadCounter = 0;
|
|
98
130
|
private _timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
99
131
|
private _abortController: AbortController | null = null;
|
|
132
|
+
/** Controller owned by the newest metadata request. */
|
|
133
|
+
private _metadataAbortController: AbortController | null = null;
|
|
100
134
|
private _finalized = false;
|
|
135
|
+
/** Generation invalidates metadata from replaced sources. */
|
|
136
|
+
private _sourceGeneration = 0;
|
|
137
|
+
/** Monotonic metadata request identity. */
|
|
138
|
+
private _metadataRequestId = 0;
|
|
101
139
|
|
|
102
140
|
/** Creates a raster manager from a source or direct callbacks. */
|
|
103
|
-
constructor(opts: RasterSetProps<DataT>) {
|
|
141
|
+
constructor(opts: RasterSetProps<DataT, ParametersT, MetadataT>) {
|
|
104
142
|
this._opts = this._normalizeOptions(opts);
|
|
105
143
|
if (!this._opts.rasterSource && (!opts.getRaster || !opts.getMetadata)) {
|
|
106
144
|
throw new Error(
|
|
@@ -110,11 +148,29 @@ export class RasterSet<DataT = RasterData> {
|
|
|
110
148
|
}
|
|
111
149
|
|
|
112
150
|
/** Convenience factory for wrapping a loaders.gl {@link RasterSource}. */
|
|
113
|
-
static fromRasterSource<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
151
|
+
static fromRasterSource<
|
|
152
|
+
DataT extends NumericRasterData = RasterData,
|
|
153
|
+
ParametersT extends GetRasterParameters = GetRasterParameters,
|
|
154
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
155
|
+
>(
|
|
156
|
+
rasterSource: RasterSource<DataT, ParametersT, MetadataT>,
|
|
157
|
+
opts: Omit<
|
|
158
|
+
RasterSetProps<DataT, ParametersT, MetadataT>,
|
|
159
|
+
'rasterSource' | 'getRaster' | 'getMetadata'
|
|
160
|
+
> = {}
|
|
161
|
+
): RasterSet<DataT, ParametersT, MetadataT> {
|
|
162
|
+
return new RasterSet<DataT, ParametersT, MetadataT>({...opts, rasterSource});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Convenience factory for sources whose requests are not viewport-shaped. */
|
|
166
|
+
static fromCallbacks<
|
|
167
|
+
DataT extends NumericRasterData = RasterData,
|
|
168
|
+
ParametersT extends object = GetRasterParameters,
|
|
169
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
170
|
+
>(
|
|
171
|
+
opts: RasterSetBaseProps<DataT, ParametersT, MetadataT>
|
|
172
|
+
): RasterSet<DataT, ParametersT, MetadataT> {
|
|
173
|
+
return new RasterSet<DataT, ParametersT, MetadataT>(opts);
|
|
118
174
|
}
|
|
119
175
|
|
|
120
176
|
/** Whether the manager has no requests in flight and a current raster. */
|
|
@@ -128,25 +184,30 @@ export class RasterSet<DataT = RasterData> {
|
|
|
128
184
|
}
|
|
129
185
|
|
|
130
186
|
/** Current accepted request and raster payload, if any. */
|
|
131
|
-
get currentRequest(): RasterSetRequest<DataT> | null {
|
|
187
|
+
get currentRequest(): RasterSetRequest<DataT, ParametersT> | null {
|
|
132
188
|
return this._currentRequest;
|
|
133
189
|
}
|
|
134
190
|
|
|
135
191
|
/** Backing raster source when constructed from one. */
|
|
136
|
-
get rasterSource(): RasterSource | null {
|
|
192
|
+
get rasterSource(): RasterSource<DataT, ParametersT & GetRasterParameters, MetadataT> | null {
|
|
137
193
|
return this._opts.rasterSource;
|
|
138
194
|
}
|
|
139
195
|
|
|
140
196
|
/** Subscribes to metadata and raster lifecycle events. */
|
|
141
|
-
subscribe(listener: RasterSetListener<DataT>): () => void {
|
|
197
|
+
subscribe(listener: RasterSetListener<DataT, ParametersT, MetadataT>): () => void {
|
|
142
198
|
this._listeners.add(listener);
|
|
143
199
|
return () => this._listeners.delete(listener);
|
|
144
200
|
}
|
|
145
201
|
|
|
146
202
|
/** Updates source callbacks or debounce settings, resetting state when the source changes. */
|
|
147
|
-
setOptions(opts: RasterSetProps<DataT>): void {
|
|
203
|
+
setOptions(opts: RasterSetProps<DataT, ParametersT, MetadataT>): void {
|
|
148
204
|
const previousRasterSource = this._opts.rasterSource;
|
|
149
|
-
const
|
|
205
|
+
const mergedOptions: RasterSetProps<DataT, ParametersT, MetadataT> = {...this._opts, ...opts};
|
|
206
|
+
if (opts.rasterSource && opts.rasterSource !== previousRasterSource) {
|
|
207
|
+
mergedOptions.getRaster = opts.getRaster;
|
|
208
|
+
mergedOptions.getMetadata = opts.getMetadata;
|
|
209
|
+
}
|
|
210
|
+
const nextOptions = this._normalizeOptions(mergedOptions);
|
|
150
211
|
const sourceChanged =
|
|
151
212
|
previousRasterSource !== nextOptions.rasterSource ||
|
|
152
213
|
this._opts.getRaster !== nextOptions.getRaster ||
|
|
@@ -156,20 +217,42 @@ export class RasterSet<DataT = RasterData> {
|
|
|
156
217
|
|
|
157
218
|
if (sourceChanged) {
|
|
158
219
|
this._cancelScheduledRaster();
|
|
220
|
+
this._abortActiveRequest();
|
|
221
|
+
this._metadataAbortController?.abort();
|
|
222
|
+
this._sourceGeneration++;
|
|
159
223
|
this.metadata = null;
|
|
160
224
|
this._currentRequest = null;
|
|
161
|
-
|
|
162
|
-
this._nextRequestId = 0;
|
|
225
|
+
|
|
163
226
|
this._emitUpdate();
|
|
164
227
|
}
|
|
165
228
|
}
|
|
166
229
|
|
|
167
230
|
/** Loads metadata from the current raster source or callbacks. */
|
|
168
|
-
async loadMetadata(
|
|
169
|
-
|
|
231
|
+
async loadMetadata(
|
|
232
|
+
options: {/** Caller cancellation for metadata. */ signal?: AbortSignal} = {}
|
|
233
|
+
): Promise<MetadataT> {
|
|
234
|
+
if (this._finalized) throw new Error('RasterSet is finalized');
|
|
235
|
+
options.signal?.throwIfAborted();
|
|
236
|
+
this._metadataAbortController?.abort();
|
|
237
|
+
const abortController = new AbortController();
|
|
238
|
+
this._metadataAbortController = abortController;
|
|
239
|
+
const abortFromCaller = () => abortController.abort(options.signal?.reason);
|
|
240
|
+
options.signal?.addEventListener('abort', abortFromCaller, {once: true});
|
|
241
|
+
const metadataRequestId = ++this._metadataRequestId;
|
|
242
|
+
const generation = this._sourceGeneration;
|
|
170
243
|
try {
|
|
171
|
-
|
|
172
|
-
|
|
244
|
+
this._startLoading();
|
|
245
|
+
abortController.signal.throwIfAborted();
|
|
246
|
+
const metadata = await waitForPromiseWithSignals(
|
|
247
|
+
signal => this._opts.getMetadata({signal}),
|
|
248
|
+
[abortController.signal]
|
|
249
|
+
);
|
|
250
|
+
abortController.signal.throwIfAborted();
|
|
251
|
+
if (
|
|
252
|
+
this._finalized ||
|
|
253
|
+
generation !== this._sourceGeneration ||
|
|
254
|
+
metadataRequestId !== this._metadataRequestId
|
|
255
|
+
) {
|
|
173
256
|
return metadata;
|
|
174
257
|
}
|
|
175
258
|
this.metadata = metadata;
|
|
@@ -179,26 +262,39 @@ export class RasterSet<DataT = RasterData> {
|
|
|
179
262
|
this._emitUpdate();
|
|
180
263
|
return metadata;
|
|
181
264
|
} catch (error) {
|
|
265
|
+
if (abortController.signal.aborted) throw abortController.signal.reason;
|
|
266
|
+
if (isAbortError(error)) throw error;
|
|
182
267
|
const normalizedError = normalizeRasterSetError(error, 'Raster metadata request failed');
|
|
183
|
-
if (
|
|
268
|
+
if (
|
|
269
|
+
!this._finalized &&
|
|
270
|
+
generation === this._sourceGeneration &&
|
|
271
|
+
metadataRequestId === this._metadataRequestId
|
|
272
|
+
) {
|
|
184
273
|
for (const listener of this._listeners) {
|
|
185
274
|
listener.onMetadataLoadError?.(normalizedError);
|
|
186
275
|
}
|
|
187
276
|
}
|
|
188
277
|
throw normalizedError;
|
|
189
278
|
} finally {
|
|
279
|
+
options.signal?.removeEventListener('abort', abortFromCaller);
|
|
280
|
+
if (this._metadataAbortController === abortController) this._metadataAbortController = null;
|
|
190
281
|
this._finishLoading();
|
|
191
282
|
}
|
|
192
283
|
}
|
|
193
284
|
|
|
194
285
|
/** Debounces and issues a new raster request for the supplied parameters. */
|
|
195
|
-
requestRaster(parameters:
|
|
286
|
+
requestRaster(parameters: ParametersT, debounceTime = this._opts.debounceTime): number {
|
|
287
|
+
if (this._finalized) return -1;
|
|
196
288
|
if (!this.shouldRefetchRaster(parameters)) {
|
|
289
|
+
this._cancelScheduledRaster();
|
|
290
|
+
this._abortActiveRequest();
|
|
291
|
+
this._nextRequestId++;
|
|
197
292
|
return this._currentRequest?.requestId ?? -1;
|
|
198
293
|
}
|
|
199
294
|
|
|
200
295
|
const requestId = this._nextRequestId++;
|
|
201
296
|
this._cancelScheduledRaster();
|
|
297
|
+
this._abortActiveRequest();
|
|
202
298
|
|
|
203
299
|
if (debounceTime > 0) {
|
|
204
300
|
this._timeoutId = setTimeout(() => {
|
|
@@ -213,7 +309,7 @@ export class RasterSet<DataT = RasterData> {
|
|
|
213
309
|
}
|
|
214
310
|
|
|
215
311
|
/** Returns `true` when the supplied parameters warrant a new raster fetch. */
|
|
216
|
-
shouldRefetchRaster(parameters:
|
|
312
|
+
shouldRefetchRaster(parameters: ParametersT): boolean {
|
|
217
313
|
return this._opts.shouldRefetch({
|
|
218
314
|
currentRequest: this._currentRequest,
|
|
219
315
|
metadata: this.metadata,
|
|
@@ -226,33 +322,41 @@ export class RasterSet<DataT = RasterData> {
|
|
|
226
322
|
this._finalized = true;
|
|
227
323
|
this._cancelScheduledRaster();
|
|
228
324
|
this._abortActiveRequest();
|
|
325
|
+
this._metadataAbortController?.abort();
|
|
326
|
+
this._metadataAbortController = null;
|
|
327
|
+
this._loadCounter = 0;
|
|
229
328
|
this._listeners.clear();
|
|
230
329
|
}
|
|
231
330
|
|
|
232
331
|
/** Loads a raster immediately and accepts it only if it is the newest completed request. */
|
|
233
|
-
private async _loadRaster(requestId: number, parameters:
|
|
332
|
+
private async _loadRaster(requestId: number, parameters: ParametersT): Promise<void> {
|
|
234
333
|
if (this._finalized) {
|
|
235
334
|
return;
|
|
236
335
|
}
|
|
237
336
|
|
|
337
|
+
const callerSignal = (parameters as {signal?: AbortSignal}).signal;
|
|
338
|
+
if (callerSignal?.aborted) return;
|
|
339
|
+
const abortController = new AbortController();
|
|
340
|
+
this._abortController = abortController;
|
|
341
|
+
const abortFromCaller = () => abortController.abort(callerSignal?.reason);
|
|
342
|
+
callerSignal?.addEventListener('abort', abortFromCaller, {once: true});
|
|
238
343
|
this._startLoading();
|
|
239
|
-
for (const listener of this._listeners) {
|
|
240
|
-
listener.onRasterLoadStart?.(requestId, parameters);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
344
|
try {
|
|
244
|
-
|
|
245
|
-
this.
|
|
246
|
-
|
|
345
|
+
abortController.signal.throwIfAborted();
|
|
346
|
+
for (const listener of this._listeners) listener.onRasterLoadStart?.(requestId, parameters);
|
|
347
|
+
abortController.signal.throwIfAborted();
|
|
348
|
+
const raster = await waitForPromiseWithSignals(
|
|
349
|
+
signal => this._opts.getRaster(withAbortSignal(parameters, signal)),
|
|
350
|
+
[abortController.signal]
|
|
351
|
+
);
|
|
247
352
|
if (
|
|
248
353
|
this._finalized ||
|
|
249
354
|
abortController.signal.aborted ||
|
|
250
|
-
requestId
|
|
355
|
+
requestId !== this._nextRequestId - 1
|
|
251
356
|
) {
|
|
252
357
|
return;
|
|
253
358
|
}
|
|
254
359
|
|
|
255
|
-
this._lastAcceptedRequestId = requestId;
|
|
256
360
|
this._currentRequest = {requestId, parameters, raster};
|
|
257
361
|
|
|
258
362
|
for (const listener of this._listeners) {
|
|
@@ -260,23 +364,26 @@ export class RasterSet<DataT = RasterData> {
|
|
|
260
364
|
}
|
|
261
365
|
this._emitUpdate();
|
|
262
366
|
} catch (error) {
|
|
263
|
-
if (isAbortError(error)) {
|
|
367
|
+
if (abortController.signal.aborted || isAbortError(error)) {
|
|
264
368
|
return;
|
|
265
369
|
}
|
|
266
370
|
const normalizedError = normalizeRasterSetError(error, 'Raster request failed');
|
|
267
|
-
if (!this._finalized) {
|
|
371
|
+
if (!this._finalized && requestId === this._nextRequestId - 1) {
|
|
268
372
|
for (const listener of this._listeners) {
|
|
269
373
|
listener.onRasterLoadError?.(requestId, normalizedError, parameters);
|
|
270
374
|
}
|
|
271
375
|
}
|
|
272
376
|
} finally {
|
|
273
|
-
|
|
377
|
+
callerSignal?.removeEventListener('abort', abortFromCaller);
|
|
378
|
+
if (this._abortController === abortController) this._abortController = null;
|
|
274
379
|
this._finishLoading();
|
|
275
380
|
}
|
|
276
381
|
}
|
|
277
382
|
|
|
278
383
|
/** Resolves current options from either a source or direct callbacks. */
|
|
279
|
-
private _normalizeOptions(
|
|
384
|
+
private _normalizeOptions(
|
|
385
|
+
opts: RasterSetProps<DataT, ParametersT, MetadataT>
|
|
386
|
+
): Required<RasterSetProps<DataT, ParametersT, MetadataT>> {
|
|
280
387
|
const rasterSource = opts.rasterSource || null;
|
|
281
388
|
return {
|
|
282
389
|
...DEFAULT_RASTERSET_PROPS,
|
|
@@ -284,32 +391,35 @@ export class RasterSet<DataT = RasterData> {
|
|
|
284
391
|
rasterSource,
|
|
285
392
|
getMetadata:
|
|
286
393
|
opts.getMetadata ||
|
|
287
|
-
(
|
|
394
|
+
(options => {
|
|
288
395
|
if (rasterSource) {
|
|
289
|
-
return rasterSource.getMetadata();
|
|
396
|
+
return rasterSource.getMetadata(options);
|
|
290
397
|
}
|
|
291
|
-
return DEFAULT_RASTERSET_PROPS.getMetadata()
|
|
398
|
+
return DEFAULT_RASTERSET_PROPS.getMetadata() as Promise<MetadataT>;
|
|
292
399
|
}),
|
|
293
400
|
getRaster:
|
|
294
401
|
opts.getRaster ||
|
|
295
|
-
((parameters:
|
|
402
|
+
((parameters: ParametersT) => {
|
|
296
403
|
if (rasterSource) {
|
|
297
|
-
return rasterSource.getRaster(parameters
|
|
404
|
+
return rasterSource.getRaster(parameters as ParametersT & GetRasterParameters);
|
|
298
405
|
}
|
|
299
|
-
return DEFAULT_RASTERSET_PROPS.getRaster(
|
|
406
|
+
return DEFAULT_RASTERSET_PROPS.getRaster(
|
|
407
|
+
parameters as GetRasterParameters
|
|
408
|
+
) as Promise<DataT>;
|
|
300
409
|
}),
|
|
301
410
|
debounceTime: opts.debounceTime ?? DEFAULT_RASTERSET_PROPS.debounceTime,
|
|
302
411
|
shouldRefetch:
|
|
303
412
|
(opts.shouldRefetch as
|
|
304
|
-
| ((args: RasterSetShouldRefetchArgs<DataT>) => boolean)
|
|
413
|
+
| ((args: RasterSetShouldRefetchArgs<DataT, ParametersT, MetadataT>) => boolean)
|
|
305
414
|
| undefined) ||
|
|
306
|
-
((args: RasterSetShouldRefetchArgs<DataT>) =>
|
|
415
|
+
((args: RasterSetShouldRefetchArgs<DataT, ParametersT, MetadataT>) =>
|
|
307
416
|
DEFAULT_RASTERSET_PROPS.shouldRefetch(args as RasterSetShouldRefetchArgs))
|
|
308
417
|
};
|
|
309
418
|
}
|
|
310
419
|
|
|
311
420
|
/** Emits one generic update notification to all subscribers. */
|
|
312
421
|
private _emitUpdate(): void {
|
|
422
|
+
if (this._finalized) return;
|
|
313
423
|
for (const listener of this._listeners) {
|
|
314
424
|
listener.onUpdate?.();
|
|
315
425
|
}
|
|
@@ -317,6 +427,7 @@ export class RasterSet<DataT = RasterData> {
|
|
|
317
427
|
|
|
318
428
|
/** Emits one loading-state transition to all subscribers. */
|
|
319
429
|
private _emitLoadingStateChange(isLoading: boolean): void {
|
|
430
|
+
if (this._finalized) return;
|
|
320
431
|
for (const listener of this._listeners) {
|
|
321
432
|
listener.onLoadingStateChange?.(isLoading);
|
|
322
433
|
}
|
|
@@ -357,6 +468,25 @@ export class RasterSet<DataT = RasterData> {
|
|
|
357
468
|
}
|
|
358
469
|
}
|
|
359
470
|
|
|
471
|
+
/** Adds cancellation to a request while preserving its array/prototype shape. */
|
|
472
|
+
function withAbortSignal<ParametersT extends object>(
|
|
473
|
+
parameters: ParametersT,
|
|
474
|
+
signal: AbortSignal
|
|
475
|
+
): ParametersT {
|
|
476
|
+
const descriptors = Object.getOwnPropertyDescriptors(parameters);
|
|
477
|
+
delete descriptors.signal;
|
|
478
|
+
const request = Array.isArray(parameters)
|
|
479
|
+
? Object.defineProperties(parameters.slice(), descriptors)
|
|
480
|
+
: Object.create(Object.getPrototypeOf(parameters), descriptors);
|
|
481
|
+
Object.defineProperty(request, 'signal', {
|
|
482
|
+
configurable: true,
|
|
483
|
+
enumerable: true,
|
|
484
|
+
value: signal,
|
|
485
|
+
writable: true
|
|
486
|
+
});
|
|
487
|
+
return request as ParametersT;
|
|
488
|
+
}
|
|
489
|
+
|
|
360
490
|
/** Normalizes arbitrary thrown values to `Error` instances for raster-set callbacks. */
|
|
361
491
|
function normalizeRasterSetError(error: unknown, message: string): Error {
|
|
362
492
|
if (error instanceof Error) {
|