@loaders.gl/tiles 4.5.3 → 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 +136 -1
- package/dist/dist.dev.js +22570 -4947
- package/dist/dist.min.js +3 -1
- package/dist/image-set.d.ts +94 -0
- package/dist/image-set.d.ts.map +1 -0
- package/dist/image-set.js +243 -0
- package/dist/image-set.js.map +1 -0
- package/dist/index.cjs +10171 -2117
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +50 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -8
- package/dist/index.js.map +1 -1
- package/dist/point-cloud/point-cloud-tile.d.ts +47 -0
- package/dist/point-cloud/point-cloud-tile.d.ts.map +1 -0
- package/dist/point-cloud/point-cloud-tile.js +70 -0
- package/dist/point-cloud/point-cloud-tile.js.map +1 -0
- package/dist/point-cloud/point-cloud-tileset.d.ts +135 -0
- package/dist/point-cloud/point-cloud-tileset.d.ts.map +1 -0
- package/dist/point-cloud/point-cloud-tileset.js +549 -0
- package/dist/point-cloud/point-cloud-tileset.js.map +1 -0
- package/dist/point-cloud/types.d.ts +81 -0
- package/dist/point-cloud/types.d.ts.map +1 -0
- package/dist/point-cloud/types.js +5 -0
- package/dist/point-cloud/types.js.map +1 -0
- package/dist/raster-set.d.ts +124 -0
- package/dist/raster-set.d.ts.map +1 -0
- package/dist/raster-set.js +348 -0
- package/dist/raster-set.js.map +1 -0
- 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 +37 -0
- package/dist/tileset-2d/adapter.d.ts.map +1 -0
- package/dist/tileset-2d/adapter.js +5 -0
- package/dist/tileset-2d/adapter.js.map +1 -0
- package/dist/tileset-2d/index.d.ts +7 -0
- package/dist/tileset-2d/index.d.ts.map +1 -0
- package/dist/tileset-2d/index.js +6 -0
- package/dist/tileset-2d/index.js.map +1 -0
- package/dist/tileset-2d/tile-2d-header.d.ts +68 -0
- package/dist/tileset-2d/tile-2d-header.d.ts.map +1 -0
- package/dist/tileset-2d/tile-2d-header.js +181 -0
- package/dist/tileset-2d/tile-2d-header.js.map +1 -0
- package/dist/tileset-2d/tileset-2d.d.ts +200 -0
- package/dist/tileset-2d/tileset-2d.d.ts.map +1 -0
- package/dist/tileset-2d/tileset-2d.js +532 -0
- package/dist/tileset-2d/tileset-2d.js.map +1 -0
- package/dist/tileset-2d/types.d.ts +44 -0
- package/dist/tileset-2d/types.d.ts.map +1 -0
- package/dist/tileset-2d/types.js +5 -0
- package/dist/tileset-2d/types.js.map +1 -0
- package/dist/tileset-2d.d.ts +2 -0
- package/dist/tileset-2d.d.ts.map +1 -0
- package/dist/tileset-2d.js +5 -0
- package/dist/tileset-2d.js.map +1 -0
- package/dist/tileset-3d/common/indexed-archive-tileset-source.d.ts +60 -0
- package/dist/tileset-3d/common/indexed-archive-tileset-source.d.ts.map +1 -0
- package/dist/tileset-3d/common/indexed-archive-tileset-source.js +130 -0
- package/dist/tileset-3d/common/indexed-archive-tileset-source.js.map +1 -0
- 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 +410 -0
- package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -0
- package/dist/tileset-3d/common/tile-3d.js +1056 -0
- package/dist/tileset-3d/common/tile-3d.js.map +1 -0
- package/dist/tileset-3d/common/tileset-3d.d.ts +360 -0
- package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-3d.js +846 -0
- package/dist/tileset-3d/common/tileset-3d.js.map +1 -0
- package/dist/tileset-3d/common/tileset-cache.d.ts +29 -0
- package/dist/tileset-3d/common/tileset-cache.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d/common}/tileset-cache.js +12 -4
- package/dist/tileset-3d/common/tileset-cache.js.map +1 -0
- 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 +228 -0
- package/dist/tileset-3d/common/tileset-source.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-source.js +17 -0
- package/dist/tileset-3d/common/tileset-source.js.map +1 -0
- package/dist/{tileset → tileset-3d/common}/tileset-traverser.d.ts +35 -3
- package/dist/tileset-3d/common/tileset-traverser.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d/common}/tileset-traverser.js +61 -13
- package/dist/tileset-3d/common/tileset-traverser.js.map +1 -0
- 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 +221 -0
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js +770 -0
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts +110 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js +331 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js.map +1 -0
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/format-i3s/i3s-pending-tiles-register.js +3 -0
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js.map +1 -0
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts +116 -0
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts.map +1 -0
- package/dist/tileset-3d/format-i3s/i3s-source.js +450 -0
- package/dist/tileset-3d/format-i3s/i3s-source.js.map +1 -0
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/format-i3s/i3s-tile-manager.js +5 -2
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.js.map +1 -0
- package/dist/{tileset → tileset-3d}/format-i3s/i3s-tileset-traverser.d.ts +2 -2
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/format-i3s/i3s-tileset-traverser.js +17 -23
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/3d-tiles-options.d.ts +1 -1
- package/dist/tileset-3d/helpers/3d-tiles-options.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/3d-tiles-options.js +3 -0
- package/dist/tileset-3d/helpers/3d-tiles-options.js.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/bounding-volume.d.ts +7 -3
- package/dist/tileset-3d/helpers/bounding-volume.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/bounding-volume.js +20 -91
- package/dist/tileset-3d/helpers/bounding-volume.js.map +1 -0
- package/dist/tileset-3d/helpers/frame-state.d.ts +93 -0
- package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/frame-state.js +92 -10
- package/dist/tileset-3d/helpers/frame-state.js.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/i3s-lod.d.ts +1 -1
- package/dist/tileset-3d/helpers/i3s-lod.d.ts.map +1 -0
- package/dist/{tileset → tileset-3d}/helpers/i3s-lod.js +21 -9
- package/dist/tileset-3d/helpers/i3s-lod.js.map +1 -0
- 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 +72 -0
- package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/tiles-3d-lod.js +257 -0
- package/dist/tileset-3d/helpers/tiles-3d-lod.js.map +1 -0
- 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/{tileset → tileset-3d}/helpers/transform-utils.d.ts +1 -1
- package/dist/tileset-3d/helpers/transform-utils.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/transform-utils.js.map +1 -0
- package/dist/tileset-3d/helpers/zoom.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/zoom.js.map +1 -0
- package/dist/types.d.ts +14 -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 -9
- package/src/image-set.ts +328 -0
- package/src/index.ts +157 -9
- package/src/point-cloud/point-cloud-tile.ts +80 -0
- package/src/point-cloud/point-cloud-tileset.ts +767 -0
- package/src/point-cloud/types.ts +99 -0
- package/src/raster-set.ts +504 -0
- 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 +46 -0
- package/src/tileset-2d/index.ts +33 -0
- package/src/tileset-2d/tile-2d-header.ts +224 -0
- package/src/tileset-2d/tileset-2d.ts +715 -0
- package/src/tileset-2d/types.ts +39 -0
- package/src/tileset-2d.ts +5 -0
- package/src/tileset-3d/common/indexed-archive-tileset-source.ts +205 -0
- package/src/tileset-3d/common/tile-3d-contracts.ts +115 -0
- package/src/tileset-3d/common/tile-3d.ts +1310 -0
- package/src/tileset-3d/common/tileset-3d.ts +1166 -0
- package/src/{tileset → tileset-3d/common}/tileset-cache.ts +16 -8
- 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 +284 -0
- package/src/{tileset → tileset-3d/common}/tileset-traverser.ts +74 -14
- package/src/tileset-3d/format-3d-tiles/implicit-tiling.ts +1059 -0
- package/src/tileset-3d/format-3d-tiles/tiles-3d-source.ts +1025 -0
- package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +379 -0
- package/src/{tileset → tileset-3d}/format-i3s/i3s-pending-tiles-register.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-source.ts +557 -0
- package/src/{tileset → tileset-3d}/format-i3s/i3s-tile-manager.ts +6 -2
- package/src/{tileset → tileset-3d}/format-i3s/i3s-tileset-traverser.ts +20 -24
- package/src/{tileset → tileset-3d}/helpers/3d-tiles-options.ts +5 -1
- package/src/{tileset → tileset-3d}/helpers/bounding-volume.ts +31 -114
- package/src/tileset-3d/helpers/frame-state.ts +322 -0
- package/src/{tileset → tileset-3d}/helpers/i3s-lod.ts +24 -10
- package/src/tileset-3d/helpers/s2-bounding-volume.ts +35 -0
- package/src/tileset-3d/helpers/tiles-3d-lod.ts +370 -0
- package/src/tileset-3d/helpers/tiles-3d-request-priority.ts +301 -0
- package/src/{tileset → tileset-3d}/helpers/transform-utils.ts +1 -1
- package/src/types.ts +18 -0
- package/src/utils/doubly-linked-list.ts +2 -0
- package/src/utils/managed-array.ts +2 -0
- package/dist/tileset/format-3d-tiles/tileset-3d-traverser.d.ts +0 -7
- package/dist/tileset/format-3d-tiles/tileset-3d-traverser.d.ts.map +0 -1
- package/dist/tileset/format-3d-tiles/tileset-3d-traverser.js +0 -53
- package/dist/tileset/format-3d-tiles/tileset-3d-traverser.js.map +0 -1
- package/dist/tileset/format-i3s/i3s-pending-tiles-register.d.ts.map +0 -1
- package/dist/tileset/format-i3s/i3s-pending-tiles-register.js.map +0 -1
- package/dist/tileset/format-i3s/i3s-tile-manager.d.ts.map +0 -1
- package/dist/tileset/format-i3s/i3s-tile-manager.js.map +0 -1
- package/dist/tileset/format-i3s/i3s-tileset-traverser.d.ts.map +0 -1
- package/dist/tileset/format-i3s/i3s-tileset-traverser.js.map +0 -1
- package/dist/tileset/helpers/3d-tiles-options.d.ts.map +0 -1
- package/dist/tileset/helpers/3d-tiles-options.js.map +0 -1
- package/dist/tileset/helpers/bounding-volume.d.ts.map +0 -1
- package/dist/tileset/helpers/bounding-volume.js.map +0 -1
- package/dist/tileset/helpers/frame-state.d.ts +0 -28
- package/dist/tileset/helpers/frame-state.d.ts.map +0 -1
- package/dist/tileset/helpers/frame-state.js.map +0 -1
- package/dist/tileset/helpers/i3s-lod.d.ts.map +0 -1
- package/dist/tileset/helpers/i3s-lod.js.map +0 -1
- package/dist/tileset/helpers/tiles-3d-lod.d.ts +0 -8
- package/dist/tileset/helpers/tiles-3d-lod.d.ts.map +0 -1
- package/dist/tileset/helpers/tiles-3d-lod.js +0 -113
- package/dist/tileset/helpers/tiles-3d-lod.js.map +0 -1
- package/dist/tileset/helpers/transform-utils.d.ts.map +0 -1
- package/dist/tileset/helpers/transform-utils.js.map +0 -1
- package/dist/tileset/helpers/zoom.d.ts.map +0 -1
- package/dist/tileset/helpers/zoom.js.map +0 -1
- package/dist/tileset/tile-3d.d.ts +0 -230
- package/dist/tileset/tile-3d.d.ts.map +0 -1
- package/dist/tileset/tile-3d.js +0 -631
- package/dist/tileset/tile-3d.js.map +0 -1
- package/dist/tileset/tileset-3d.d.ts +0 -284
- package/dist/tileset/tileset-3d.d.ts.map +0 -1
- package/dist/tileset/tileset-3d.js +0 -814
- package/dist/tileset/tileset-3d.js.map +0 -1
- package/dist/tileset/tileset-cache.d.ts +0 -19
- package/dist/tileset/tileset-cache.d.ts.map +0 -1
- package/dist/tileset/tileset-cache.js.map +0 -1
- package/dist/tileset/tileset-traverser.d.ts.map +0 -1
- package/dist/tileset/tileset-traverser.js.map +0 -1
- package/src/tileset/format-3d-tiles/tileset-3d-traverser.ts +0 -63
- package/src/tileset/helpers/frame-state.ts +0 -183
- package/src/tileset/helpers/tiles-3d-lod.ts +0 -149
- package/src/tileset/tile-3d.ts +0 -788
- package/src/tileset/tileset-3d.ts +0 -1037
- /package/dist/{tileset → tileset-3d}/format-i3s/i3s-pending-tiles-register.d.ts +0 -0
- /package/dist/{tileset → tileset-3d}/format-i3s/i3s-tile-manager.d.ts +0 -0
- /package/dist/{tileset → tileset-3d}/helpers/transform-utils.js +0 -0
- /package/dist/{tileset → tileset-3d}/helpers/zoom.d.ts +0 -0
- /package/dist/{tileset → tileset-3d}/helpers/zoom.js +0 -0
- /package/src/{tileset → tileset-3d}/helpers/zoom.ts +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {DataSource, DataSourceOptions} from '@loaders.gl/loader-utils';
|
|
6
|
+
import type {MeshArrowTable} from '@loaders.gl/schema';
|
|
7
|
+
import type {TilesetSpatialReference} from '../spatial/spatial-types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An accessor-like description for point cloud attributes.
|
|
11
|
+
*/
|
|
12
|
+
export type PointCloudAttribute = {
|
|
13
|
+
value: ArrayBufferView;
|
|
14
|
+
size: number;
|
|
15
|
+
normalized?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* deck.gl coordinate system string values accepted by point cloud tile content.
|
|
20
|
+
*/
|
|
21
|
+
export type PointCloudCoordinateSystem =
|
|
22
|
+
| 'default'
|
|
23
|
+
| 'lnglat'
|
|
24
|
+
| 'meter-offsets'
|
|
25
|
+
| 'lnglat-offsets'
|
|
26
|
+
| 'cartesian';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A normalized point cloud tile content payload.
|
|
30
|
+
*/
|
|
31
|
+
export type PointCloudTileContent = {
|
|
32
|
+
data: MeshArrowTable;
|
|
33
|
+
pointCount: number;
|
|
34
|
+
cartographicOrigin: number[];
|
|
35
|
+
coordinateSystem: PointCloudCoordinateSystem;
|
|
36
|
+
constantRGBA?: number[];
|
|
37
|
+
modelMatrix?: number[] | Float32Array;
|
|
38
|
+
/** Spatial descriptor for returned points, origins, and bounds. */
|
|
39
|
+
spatialReference?: TilesetSpatialReference;
|
|
40
|
+
/** Content bound expressed in the selected spatial output frame. */
|
|
41
|
+
spatialBoundingVolume?: PointCloudBoundingVolume;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A cartographic bounding volume for a point cloud tile.
|
|
46
|
+
*/
|
|
47
|
+
export type PointCloudBoundingVolume = {
|
|
48
|
+
cartographicBounds: [min: number[], max: number[]];
|
|
49
|
+
/** True when the longitude interval crosses the antimeridian. */
|
|
50
|
+
wrapsDateline?: boolean;
|
|
51
|
+
/** True when the longitude interval covers the full globe. */
|
|
52
|
+
coversFullLongitude?: boolean;
|
|
53
|
+
center: number[];
|
|
54
|
+
radius: number;
|
|
55
|
+
/** Broad coordinate frame of `center` and `cartographicBounds`. */
|
|
56
|
+
coordinateFrame?: 'geographic' | 'cartesian';
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A source-owned tile header used by the point cloud tileset.
|
|
61
|
+
*/
|
|
62
|
+
export type PointCloudTileHeader = {
|
|
63
|
+
id: string;
|
|
64
|
+
level: number;
|
|
65
|
+
pointCount: number;
|
|
66
|
+
geometricError: number;
|
|
67
|
+
boundingVolume: PointCloudBoundingVolume;
|
|
68
|
+
/** Bound expressed in the selected content/output frame; traversal retains geographic bounds. */
|
|
69
|
+
spatialBoundingVolume?: PointCloudBoundingVolume;
|
|
70
|
+
/** I3S LOD metric used to decide whether this node refines. */
|
|
71
|
+
lodSelectionMetricType?: 'maxScreenThresholdSQ' | 'density-threshold';
|
|
72
|
+
/** Source-provided LOD threshold for density or screen metrics. */
|
|
73
|
+
lodThreshold?: number;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Optional tileset view metadata.
|
|
78
|
+
*/
|
|
79
|
+
export type PointCloudTilesetViewState = {
|
|
80
|
+
cartographicCenter?: number[];
|
|
81
|
+
zoom?: number;
|
|
82
|
+
boundingVolume?: PointCloudBoundingVolume;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Structural contract for point cloud sources that can back a PointCloudTileset.
|
|
87
|
+
*/
|
|
88
|
+
export type PointCloudTilesetSource<
|
|
89
|
+
DataT = unknown,
|
|
90
|
+
OptionsT extends DataSourceOptions = DataSourceOptions
|
|
91
|
+
> = DataSource<DataT, OptionsT> & {
|
|
92
|
+
isReady: boolean;
|
|
93
|
+
initialize(): Promise<void>;
|
|
94
|
+
getMetadata?(): Promise<unknown>;
|
|
95
|
+
getRootTile(): Promise<PointCloudTileHeader>;
|
|
96
|
+
getChildren(tile: PointCloudTileHeader): Promise<PointCloudTileHeader[]>;
|
|
97
|
+
loadTileContent(tile: PointCloudTileHeader): Promise<PointCloudTileContent | null>;
|
|
98
|
+
getViewState?(): Promise<PointCloudTilesetViewState> | PointCloudTilesetViewState;
|
|
99
|
+
};
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
GetRasterParameters,
|
|
7
|
+
NumericRasterData,
|
|
8
|
+
RasterData,
|
|
9
|
+
RasterSource,
|
|
10
|
+
RasterSourceMetadata
|
|
11
|
+
} from '@loaders.gl/loader-utils';
|
|
12
|
+
import {waitForPromiseWithSignals} from '@loaders.gl/loader-utils';
|
|
13
|
+
|
|
14
|
+
/** Accepted raster request currently retained by {@link RasterSet}. */
|
|
15
|
+
export type RasterSetRequest<
|
|
16
|
+
DataT extends NumericRasterData = RasterData,
|
|
17
|
+
ParametersT extends object = GetRasterParameters
|
|
18
|
+
> = {
|
|
19
|
+
/** Unique request id assigned by the manager. */
|
|
20
|
+
requestId: number;
|
|
21
|
+
/** Raster request parameters that produced the accepted raster payload. */
|
|
22
|
+
parameters: ParametersT;
|
|
23
|
+
/** Raster retained as the current output. */
|
|
24
|
+
raster: DataT;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Arguments supplied to {@link RasterSetBaseProps.shouldRefetch}. */
|
|
28
|
+
export type RasterSetShouldRefetchArgs<
|
|
29
|
+
DataT extends NumericRasterData = RasterData,
|
|
30
|
+
ParametersT extends object = GetRasterParameters,
|
|
31
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
32
|
+
> = {
|
|
33
|
+
/** Current accepted request retained by the raster manager, if any. */
|
|
34
|
+
currentRequest: RasterSetRequest<DataT, ParametersT> | null;
|
|
35
|
+
/** Source metadata resolved by {@link RasterSet.loadMetadata}, if available. */
|
|
36
|
+
metadata: MetadataT | null;
|
|
37
|
+
/** Candidate raster request parameters under evaluation. */
|
|
38
|
+
nextParameters: ParametersT;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Configuration shared by all {@link RasterSet} instances. */
|
|
42
|
+
export type RasterSetBaseProps<
|
|
43
|
+
DataT extends NumericRasterData = RasterData,
|
|
44
|
+
ParametersT extends object = GetRasterParameters,
|
|
45
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
46
|
+
> = {
|
|
47
|
+
/** Callback used to load source metadata. */
|
|
48
|
+
getMetadata: (options?: {
|
|
49
|
+
/** Metadata request cancellation. */ signal?: AbortSignal;
|
|
50
|
+
}) => Promise<MetadataT>;
|
|
51
|
+
/** Callback used to load raster data for a viewport-derived request. */
|
|
52
|
+
getRaster: (parameters: ParametersT) => Promise<DataT>;
|
|
53
|
+
/** Debounce interval applied before issuing raster requests. */
|
|
54
|
+
debounceTime?: number;
|
|
55
|
+
/** Optional policy callback that can skip redundant raster requests. */
|
|
56
|
+
shouldRefetch?: (args: RasterSetShouldRefetchArgs<DataT, ParametersT, MetadataT>) => boolean;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Options for creating a {@link RasterSet}. */
|
|
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>> & {
|
|
65
|
+
/** Optional loaders.gl raster source backing this manager. */
|
|
66
|
+
rasterSource?: RasterSource<DataT, ParametersT & GetRasterParameters, MetadataT> | null;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Subscription callbacks emitted by {@link RasterSet}. */
|
|
70
|
+
export type RasterSetListener<
|
|
71
|
+
DataT extends NumericRasterData = RasterData,
|
|
72
|
+
ParametersT extends object = GetRasterParameters,
|
|
73
|
+
MetadataT extends RasterSourceMetadata = RasterSourceMetadata
|
|
74
|
+
> = {
|
|
75
|
+
/** Fired when metadata/raster loading starts or stops. */
|
|
76
|
+
onLoadingStateChange?: (isLoading: boolean) => void;
|
|
77
|
+
/** Fired when source metadata resolves successfully. */
|
|
78
|
+
onMetadataLoad?: (metadata: MetadataT) => void;
|
|
79
|
+
/** Fired when metadata loading fails. */
|
|
80
|
+
onMetadataLoadError?: (error: Error) => void;
|
|
81
|
+
/** Fired when a new raster request is issued. */
|
|
82
|
+
onRasterLoadStart?: (requestId: number, parameters: ParametersT) => void;
|
|
83
|
+
/** Fired when a raster request resolves and becomes current. */
|
|
84
|
+
onRasterLoad?: (request: RasterSetRequest<DataT, ParametersT>) => void;
|
|
85
|
+
/** Fired when a raster request fails. */
|
|
86
|
+
onRasterLoadError?: (requestId: number, error: Error, parameters: ParametersT) => void;
|
|
87
|
+
/** Fired when metadata or the current raster changes. */
|
|
88
|
+
onUpdate?: () => void;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const DEFAULT_RASTERSET_PROPS: Required<Omit<RasterSetProps, 'rasterSource'>> = {
|
|
92
|
+
getMetadata: async () => ({
|
|
93
|
+
width: 0,
|
|
94
|
+
height: 0,
|
|
95
|
+
bandCount: 0,
|
|
96
|
+
dtype: 'uint8'
|
|
97
|
+
}),
|
|
98
|
+
getRaster: async () =>
|
|
99
|
+
({
|
|
100
|
+
data: new Uint8Array(0),
|
|
101
|
+
width: 0,
|
|
102
|
+
height: 0,
|
|
103
|
+
bandCount: 0,
|
|
104
|
+
dtype: 'uint8'
|
|
105
|
+
}) as never,
|
|
106
|
+
debounceTime: 0,
|
|
107
|
+
shouldRefetch: () => true
|
|
108
|
+
};
|
|
109
|
+
|
|
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
|
+
> {
|
|
122
|
+
/** Cached metadata returned by the backing source, if any. */
|
|
123
|
+
metadata: MetadataT | null = null;
|
|
124
|
+
|
|
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;
|
|
128
|
+
private _nextRequestId = 0;
|
|
129
|
+
private _loadCounter = 0;
|
|
130
|
+
private _timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
131
|
+
private _abortController: AbortController | null = null;
|
|
132
|
+
/** Controller owned by the newest metadata request. */
|
|
133
|
+
private _metadataAbortController: AbortController | null = null;
|
|
134
|
+
private _finalized = false;
|
|
135
|
+
/** Generation invalidates metadata from replaced sources. */
|
|
136
|
+
private _sourceGeneration = 0;
|
|
137
|
+
/** Monotonic metadata request identity. */
|
|
138
|
+
private _metadataRequestId = 0;
|
|
139
|
+
|
|
140
|
+
/** Creates a raster manager from a source or direct callbacks. */
|
|
141
|
+
constructor(opts: RasterSetProps<DataT, ParametersT, MetadataT>) {
|
|
142
|
+
this._opts = this._normalizeOptions(opts);
|
|
143
|
+
if (!this._opts.rasterSource && (!opts.getRaster || !opts.getMetadata)) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
'RasterSet requires either `rasterSource` or both `getRaster` and `getMetadata`.'
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Convenience factory for wrapping a loaders.gl {@link RasterSource}. */
|
|
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);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Whether the manager has no requests in flight and a current raster. */
|
|
177
|
+
get isLoaded(): boolean {
|
|
178
|
+
return this._loadCounter === 0 && Boolean(this._currentRequest);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Current accepted raster, if any. */
|
|
182
|
+
get raster(): DataT | null {
|
|
183
|
+
return this._currentRequest?.raster || null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Current accepted request and raster payload, if any. */
|
|
187
|
+
get currentRequest(): RasterSetRequest<DataT, ParametersT> | null {
|
|
188
|
+
return this._currentRequest;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Backing raster source when constructed from one. */
|
|
192
|
+
get rasterSource(): RasterSource<DataT, ParametersT & GetRasterParameters, MetadataT> | null {
|
|
193
|
+
return this._opts.rasterSource;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Subscribes to metadata and raster lifecycle events. */
|
|
197
|
+
subscribe(listener: RasterSetListener<DataT, ParametersT, MetadataT>): () => void {
|
|
198
|
+
this._listeners.add(listener);
|
|
199
|
+
return () => this._listeners.delete(listener);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Updates source callbacks or debounce settings, resetting state when the source changes. */
|
|
203
|
+
setOptions(opts: RasterSetProps<DataT, ParametersT, MetadataT>): void {
|
|
204
|
+
const previousRasterSource = this._opts.rasterSource;
|
|
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);
|
|
211
|
+
const sourceChanged =
|
|
212
|
+
previousRasterSource !== nextOptions.rasterSource ||
|
|
213
|
+
this._opts.getRaster !== nextOptions.getRaster ||
|
|
214
|
+
this._opts.getMetadata !== nextOptions.getMetadata;
|
|
215
|
+
|
|
216
|
+
this._opts = nextOptions;
|
|
217
|
+
|
|
218
|
+
if (sourceChanged) {
|
|
219
|
+
this._cancelScheduledRaster();
|
|
220
|
+
this._abortActiveRequest();
|
|
221
|
+
this._metadataAbortController?.abort();
|
|
222
|
+
this._sourceGeneration++;
|
|
223
|
+
this.metadata = null;
|
|
224
|
+
this._currentRequest = null;
|
|
225
|
+
|
|
226
|
+
this._emitUpdate();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Loads metadata from the current raster source or callbacks. */
|
|
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;
|
|
243
|
+
try {
|
|
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
|
+
) {
|
|
256
|
+
return metadata;
|
|
257
|
+
}
|
|
258
|
+
this.metadata = metadata;
|
|
259
|
+
for (const listener of this._listeners) {
|
|
260
|
+
listener.onMetadataLoad?.(metadata);
|
|
261
|
+
}
|
|
262
|
+
this._emitUpdate();
|
|
263
|
+
return metadata;
|
|
264
|
+
} catch (error) {
|
|
265
|
+
if (abortController.signal.aborted) throw abortController.signal.reason;
|
|
266
|
+
if (isAbortError(error)) throw error;
|
|
267
|
+
const normalizedError = normalizeRasterSetError(error, 'Raster metadata request failed');
|
|
268
|
+
if (
|
|
269
|
+
!this._finalized &&
|
|
270
|
+
generation === this._sourceGeneration &&
|
|
271
|
+
metadataRequestId === this._metadataRequestId
|
|
272
|
+
) {
|
|
273
|
+
for (const listener of this._listeners) {
|
|
274
|
+
listener.onMetadataLoadError?.(normalizedError);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
throw normalizedError;
|
|
278
|
+
} finally {
|
|
279
|
+
options.signal?.removeEventListener('abort', abortFromCaller);
|
|
280
|
+
if (this._metadataAbortController === abortController) this._metadataAbortController = null;
|
|
281
|
+
this._finishLoading();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** Debounces and issues a new raster request for the supplied parameters. */
|
|
286
|
+
requestRaster(parameters: ParametersT, debounceTime = this._opts.debounceTime): number {
|
|
287
|
+
if (this._finalized) return -1;
|
|
288
|
+
if (!this.shouldRefetchRaster(parameters)) {
|
|
289
|
+
this._cancelScheduledRaster();
|
|
290
|
+
this._abortActiveRequest();
|
|
291
|
+
this._nextRequestId++;
|
|
292
|
+
return this._currentRequest?.requestId ?? -1;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const requestId = this._nextRequestId++;
|
|
296
|
+
this._cancelScheduledRaster();
|
|
297
|
+
this._abortActiveRequest();
|
|
298
|
+
|
|
299
|
+
if (debounceTime > 0) {
|
|
300
|
+
this._timeoutId = setTimeout(() => {
|
|
301
|
+
this._timeoutId = null;
|
|
302
|
+
void this._loadRaster(requestId, parameters);
|
|
303
|
+
}, debounceTime);
|
|
304
|
+
} else {
|
|
305
|
+
void this._loadRaster(requestId, parameters);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return requestId;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** Returns `true` when the supplied parameters warrant a new raster fetch. */
|
|
312
|
+
shouldRefetchRaster(parameters: ParametersT): boolean {
|
|
313
|
+
return this._opts.shouldRefetch({
|
|
314
|
+
currentRequest: this._currentRequest,
|
|
315
|
+
metadata: this.metadata,
|
|
316
|
+
nextParameters: parameters
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Clears timers and listeners held by the manager. */
|
|
321
|
+
finalize(): void {
|
|
322
|
+
this._finalized = true;
|
|
323
|
+
this._cancelScheduledRaster();
|
|
324
|
+
this._abortActiveRequest();
|
|
325
|
+
this._metadataAbortController?.abort();
|
|
326
|
+
this._metadataAbortController = null;
|
|
327
|
+
this._loadCounter = 0;
|
|
328
|
+
this._listeners.clear();
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** Loads a raster immediately and accepts it only if it is the newest completed request. */
|
|
332
|
+
private async _loadRaster(requestId: number, parameters: ParametersT): Promise<void> {
|
|
333
|
+
if (this._finalized) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
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});
|
|
343
|
+
this._startLoading();
|
|
344
|
+
try {
|
|
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
|
+
);
|
|
352
|
+
if (
|
|
353
|
+
this._finalized ||
|
|
354
|
+
abortController.signal.aborted ||
|
|
355
|
+
requestId !== this._nextRequestId - 1
|
|
356
|
+
) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
this._currentRequest = {requestId, parameters, raster};
|
|
361
|
+
|
|
362
|
+
for (const listener of this._listeners) {
|
|
363
|
+
listener.onRasterLoad?.(this._currentRequest);
|
|
364
|
+
}
|
|
365
|
+
this._emitUpdate();
|
|
366
|
+
} catch (error) {
|
|
367
|
+
if (abortController.signal.aborted || isAbortError(error)) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const normalizedError = normalizeRasterSetError(error, 'Raster request failed');
|
|
371
|
+
if (!this._finalized && requestId === this._nextRequestId - 1) {
|
|
372
|
+
for (const listener of this._listeners) {
|
|
373
|
+
listener.onRasterLoadError?.(requestId, normalizedError, parameters);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
} finally {
|
|
377
|
+
callerSignal?.removeEventListener('abort', abortFromCaller);
|
|
378
|
+
if (this._abortController === abortController) this._abortController = null;
|
|
379
|
+
this._finishLoading();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Resolves current options from either a source or direct callbacks. */
|
|
384
|
+
private _normalizeOptions(
|
|
385
|
+
opts: RasterSetProps<DataT, ParametersT, MetadataT>
|
|
386
|
+
): Required<RasterSetProps<DataT, ParametersT, MetadataT>> {
|
|
387
|
+
const rasterSource = opts.rasterSource || null;
|
|
388
|
+
return {
|
|
389
|
+
...DEFAULT_RASTERSET_PROPS,
|
|
390
|
+
...opts,
|
|
391
|
+
rasterSource,
|
|
392
|
+
getMetadata:
|
|
393
|
+
opts.getMetadata ||
|
|
394
|
+
(options => {
|
|
395
|
+
if (rasterSource) {
|
|
396
|
+
return rasterSource.getMetadata(options);
|
|
397
|
+
}
|
|
398
|
+
return DEFAULT_RASTERSET_PROPS.getMetadata() as Promise<MetadataT>;
|
|
399
|
+
}),
|
|
400
|
+
getRaster:
|
|
401
|
+
opts.getRaster ||
|
|
402
|
+
((parameters: ParametersT) => {
|
|
403
|
+
if (rasterSource) {
|
|
404
|
+
return rasterSource.getRaster(parameters as ParametersT & GetRasterParameters);
|
|
405
|
+
}
|
|
406
|
+
return DEFAULT_RASTERSET_PROPS.getRaster(
|
|
407
|
+
parameters as GetRasterParameters
|
|
408
|
+
) as Promise<DataT>;
|
|
409
|
+
}),
|
|
410
|
+
debounceTime: opts.debounceTime ?? DEFAULT_RASTERSET_PROPS.debounceTime,
|
|
411
|
+
shouldRefetch:
|
|
412
|
+
(opts.shouldRefetch as
|
|
413
|
+
| ((args: RasterSetShouldRefetchArgs<DataT, ParametersT, MetadataT>) => boolean)
|
|
414
|
+
| undefined) ||
|
|
415
|
+
((args: RasterSetShouldRefetchArgs<DataT, ParametersT, MetadataT>) =>
|
|
416
|
+
DEFAULT_RASTERSET_PROPS.shouldRefetch(args as RasterSetShouldRefetchArgs))
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/** Emits one generic update notification to all subscribers. */
|
|
421
|
+
private _emitUpdate(): void {
|
|
422
|
+
if (this._finalized) return;
|
|
423
|
+
for (const listener of this._listeners) {
|
|
424
|
+
listener.onUpdate?.();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** Emits one loading-state transition to all subscribers. */
|
|
429
|
+
private _emitLoadingStateChange(isLoading: boolean): void {
|
|
430
|
+
if (this._finalized) return;
|
|
431
|
+
for (const listener of this._listeners) {
|
|
432
|
+
listener.onLoadingStateChange?.(isLoading);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/** Increments the active load count and emits loading-state transitions. */
|
|
437
|
+
private _startLoading(): void {
|
|
438
|
+
const wasLoading = this._loadCounter > 0;
|
|
439
|
+
this._loadCounter++;
|
|
440
|
+
if (!wasLoading) {
|
|
441
|
+
this._emitLoadingStateChange(true);
|
|
442
|
+
this._emitUpdate();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/** Decrements the active load count and emits loading-state transitions. */
|
|
447
|
+
private _finishLoading(): void {
|
|
448
|
+
const wasLoading = this._loadCounter > 0;
|
|
449
|
+
this._loadCounter = Math.max(0, this._loadCounter - 1);
|
|
450
|
+
if (wasLoading && this._loadCounter === 0) {
|
|
451
|
+
this._emitLoadingStateChange(false);
|
|
452
|
+
this._emitUpdate();
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** Clears any pending debounced raster request before it hits the network. */
|
|
457
|
+
private _cancelScheduledRaster(): void {
|
|
458
|
+
if (this._timeoutId !== null) {
|
|
459
|
+
clearTimeout(this._timeoutId);
|
|
460
|
+
this._timeoutId = null;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/** Aborts the currently active raster request, if one exists. */
|
|
465
|
+
private _abortActiveRequest(): void {
|
|
466
|
+
this._abortController?.abort();
|
|
467
|
+
this._abortController = null;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
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
|
+
|
|
490
|
+
/** Normalizes arbitrary thrown values to `Error` instances for raster-set callbacks. */
|
|
491
|
+
function normalizeRasterSetError(error: unknown, message: string): Error {
|
|
492
|
+
if (error instanceof Error) {
|
|
493
|
+
return error;
|
|
494
|
+
}
|
|
495
|
+
if (typeof error === 'string') {
|
|
496
|
+
return new Error(error);
|
|
497
|
+
}
|
|
498
|
+
return new Error(message);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/** Returns true when an error came from an aborted request. */
|
|
502
|
+
function isAbortError(error: unknown): boolean {
|
|
503
|
+
return error instanceof Error && error.name === 'AbortError';
|
|
504
|
+
}
|