@loaders.gl/tiles 5.0.0-alpha.1 → 5.0.0-alpha.3

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.
Files changed (161) hide show
  1. package/LICENSE +14 -3
  2. package/dist/dist.dev.js +17482 -3685
  3. package/dist/dist.min.js +4 -1
  4. package/dist/index.cjs +4594 -422
  5. package/dist/index.cjs.map +3 -4
  6. package/dist/index.d.ts +16 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +7 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/point-cloud/point-cloud-tile.d.ts.map +1 -1
  11. package/dist/point-cloud/point-cloud-tile.js +3 -0
  12. package/dist/point-cloud/point-cloud-tile.js.map +1 -1
  13. package/dist/point-cloud/point-cloud-tileset.d.ts +4 -0
  14. package/dist/point-cloud/point-cloud-tileset.d.ts.map +1 -1
  15. package/dist/point-cloud/point-cloud-tileset.js +54 -12
  16. package/dist/point-cloud/point-cloud-tileset.js.map +1 -1
  17. package/dist/point-cloud/types.d.ts +17 -0
  18. package/dist/point-cloud/types.d.ts.map +1 -1
  19. package/dist/point-cloud/types.js +3 -0
  20. package/dist/point-cloud/types.js.map +1 -1
  21. package/dist/raster-set.d.ts +37 -29
  22. package/dist/raster-set.d.ts.map +1 -1
  23. package/dist/raster-set.js +25 -2
  24. package/dist/raster-set.js.map +1 -1
  25. package/dist/spatial/format-spatial-reference.d.ts +67 -0
  26. package/dist/spatial/format-spatial-reference.d.ts.map +1 -0
  27. package/dist/spatial/format-spatial-reference.js +233 -0
  28. package/dist/spatial/format-spatial-reference.js.map +1 -0
  29. package/dist/spatial/get-spatial-coordinate-frame.d.ts +9 -0
  30. package/dist/spatial/get-spatial-coordinate-frame.d.ts.map +1 -0
  31. package/dist/spatial/get-spatial-coordinate-frame.js +58 -0
  32. package/dist/spatial/get-spatial-coordinate-frame.js.map +1 -0
  33. package/dist/spatial/i3s-elevation.d.ts +20 -0
  34. package/dist/spatial/i3s-elevation.d.ts.map +1 -0
  35. package/dist/spatial/i3s-elevation.js +90 -0
  36. package/dist/spatial/i3s-elevation.js.map +1 -0
  37. package/dist/spatial/i3s-spatial-transformer.d.ts +189 -0
  38. package/dist/spatial/i3s-spatial-transformer.d.ts.map +1 -0
  39. package/dist/spatial/i3s-spatial-transformer.js +686 -0
  40. package/dist/spatial/i3s-spatial-transformer.js.map +1 -0
  41. package/dist/spatial/spatial-coordinate-transformer.d.ts +48 -0
  42. package/dist/spatial/spatial-coordinate-transformer.d.ts.map +1 -0
  43. package/dist/spatial/spatial-coordinate-transformer.js +211 -0
  44. package/dist/spatial/spatial-coordinate-transformer.js.map +1 -0
  45. package/dist/spatial/spatial-resource-registry.d.ts +44 -0
  46. package/dist/spatial/spatial-resource-registry.d.ts.map +1 -0
  47. package/dist/spatial/spatial-resource-registry.js +67 -0
  48. package/dist/spatial/spatial-resource-registry.js.map +1 -0
  49. package/dist/spatial/spatial-types.d.ts +190 -0
  50. package/dist/spatial/spatial-types.d.ts.map +1 -0
  51. package/dist/spatial/spatial-types.js +192 -0
  52. package/dist/spatial/spatial-types.js.map +1 -0
  53. package/dist/tileset-3d/common/tile-3d.d.ts +147 -4
  54. package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -1
  55. package/dist/tileset-3d/common/tile-3d.js +358 -76
  56. package/dist/tileset-3d/common/tile-3d.js.map +1 -1
  57. package/dist/tileset-3d/common/tileset-3d.d.ts +168 -3
  58. package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -1
  59. package/dist/tileset-3d/common/tileset-3d.js +306 -23
  60. package/dist/tileset-3d/common/tileset-3d.js.map +1 -1
  61. package/dist/tileset-3d/common/tileset-cache.d.ts +11 -1
  62. package/dist/tileset-3d/common/tileset-cache.d.ts.map +1 -1
  63. package/dist/tileset-3d/common/tileset-cache.js +11 -3
  64. package/dist/tileset-3d/common/tileset-cache.js.map +1 -1
  65. package/dist/tileset-3d/common/tileset-source.d.ts +32 -0
  66. package/dist/tileset-3d/common/tileset-source.d.ts.map +1 -1
  67. package/dist/tileset-3d/common/tileset-source.js.map +1 -1
  68. package/dist/tileset-3d/common/tileset-traverser.d.ts +19 -1
  69. package/dist/tileset-3d/common/tileset-traverser.d.ts.map +1 -1
  70. package/dist/tileset-3d/common/tileset-traverser.js +39 -7
  71. package/dist/tileset-3d/common/tileset-traverser.js.map +1 -1
  72. package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts +136 -0
  73. package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts.map +1 -0
  74. package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js +384 -0
  75. package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js.map +1 -0
  76. package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts +86 -3
  77. package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts.map +1 -1
  78. package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js +196 -21
  79. package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js.map +1 -1
  80. package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts +36 -0
  81. package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -1
  82. package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js +66 -0
  83. package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js.map +1 -1
  84. package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.d.ts.map +1 -1
  85. package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js +3 -0
  86. package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js.map +1 -1
  87. package/dist/tileset-3d/format-i3s/i3s-source.d.ts +14 -1
  88. package/dist/tileset-3d/format-i3s/i3s-source.d.ts.map +1 -1
  89. package/dist/tileset-3d/format-i3s/i3s-source.js +107 -17
  90. package/dist/tileset-3d/format-i3s/i3s-source.js.map +1 -1
  91. package/dist/tileset-3d/format-i3s/i3s-tile-manager.d.ts.map +1 -1
  92. package/dist/tileset-3d/format-i3s/i3s-tile-manager.js +3 -0
  93. package/dist/tileset-3d/format-i3s/i3s-tile-manager.js.map +1 -1
  94. package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.d.ts.map +1 -1
  95. package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js +3 -0
  96. package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js.map +1 -1
  97. package/dist/tileset-3d/helpers/3d-tiles-options.d.ts.map +1 -1
  98. package/dist/tileset-3d/helpers/3d-tiles-options.js +3 -0
  99. package/dist/tileset-3d/helpers/3d-tiles-options.js.map +1 -1
  100. package/dist/tileset-3d/helpers/bounding-volume.d.ts.map +1 -1
  101. package/dist/tileset-3d/helpers/bounding-volume.js +4 -33
  102. package/dist/tileset-3d/helpers/bounding-volume.js.map +1 -1
  103. package/dist/tileset-3d/helpers/frame-state.d.ts +62 -2
  104. package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -1
  105. package/dist/tileset-3d/helpers/frame-state.js +85 -9
  106. package/dist/tileset-3d/helpers/frame-state.js.map +1 -1
  107. package/dist/tileset-3d/helpers/i3s-lod.d.ts.map +1 -1
  108. package/dist/tileset-3d/helpers/i3s-lod.js +20 -8
  109. package/dist/tileset-3d/helpers/i3s-lod.js.map +1 -1
  110. package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts +61 -9
  111. package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts.map +1 -1
  112. package/dist/tileset-3d/helpers/tiles-3d-lod.js +198 -93
  113. package/dist/tileset-3d/helpers/tiles-3d-lod.js.map +1 -1
  114. package/dist/tileset-3d/helpers/tiles-3d-request-priority.d.ts +134 -0
  115. package/dist/tileset-3d/helpers/tiles-3d-request-priority.d.ts.map +1 -0
  116. package/dist/tileset-3d/helpers/tiles-3d-request-priority.js +179 -0
  117. package/dist/tileset-3d/helpers/tiles-3d-request-priority.js.map +1 -0
  118. package/dist/types.d.ts +5 -0
  119. package/dist/types.d.ts.map +1 -1
  120. package/dist/types.js +3 -0
  121. package/dist/types.js.map +1 -1
  122. package/dist/utils/doubly-linked-list.d.ts.map +1 -1
  123. package/dist/utils/doubly-linked-list.js +1 -0
  124. package/dist/utils/doubly-linked-list.js.map +1 -1
  125. package/dist/utils/managed-array.d.ts.map +1 -1
  126. package/dist/utils/managed-array.js +1 -0
  127. package/dist/utils/managed-array.js.map +1 -1
  128. package/package.json +12 -9
  129. package/src/index.ts +61 -1
  130. package/src/point-cloud/point-cloud-tile.ts +4 -0
  131. package/src/point-cloud/point-cloud-tileset.ts +70 -12
  132. package/src/point-cloud/types.ts +21 -0
  133. package/src/raster-set.ts +118 -45
  134. package/src/spatial/format-spatial-reference.ts +311 -0
  135. package/src/spatial/get-spatial-coordinate-frame.ts +74 -0
  136. package/src/spatial/i3s-elevation.ts +96 -0
  137. package/src/spatial/i3s-spatial-transformer.ts +957 -0
  138. package/src/spatial/spatial-coordinate-transformer.ts +276 -0
  139. package/src/spatial/spatial-resource-registry.ts +79 -0
  140. package/src/spatial/spatial-types.ts +422 -0
  141. package/src/tileset-3d/common/tile-3d.ts +435 -84
  142. package/src/tileset-3d/common/tileset-3d.ts +445 -23
  143. package/src/tileset-3d/common/tileset-cache.ts +15 -7
  144. package/src/tileset-3d/common/tileset-source.ts +36 -0
  145. package/src/tileset-3d/common/tileset-traverser.ts +40 -7
  146. package/src/tileset-3d/format-3d-tiles/implicit-tiling.ts +612 -0
  147. package/src/tileset-3d/format-3d-tiles/tiles-3d-source.ts +254 -21
  148. package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +77 -0
  149. package/src/tileset-3d/format-i3s/i3s-pending-tiles-register.ts +4 -0
  150. package/src/tileset-3d/format-i3s/i3s-source.ts +119 -18
  151. package/src/tileset-3d/format-i3s/i3s-tile-manager.ts +4 -0
  152. package/src/tileset-3d/format-i3s/i3s-tileset-traverser.ts +4 -0
  153. package/src/tileset-3d/helpers/3d-tiles-options.ts +4 -0
  154. package/src/tileset-3d/helpers/bounding-volume.ts +5 -55
  155. package/src/tileset-3d/helpers/frame-state.ts +142 -11
  156. package/src/tileset-3d/helpers/i3s-lod.ts +22 -8
  157. package/src/tileset-3d/helpers/tiles-3d-lod.ts +291 -112
  158. package/src/tileset-3d/helpers/tiles-3d-request-priority.ts +301 -0
  159. package/src/types.ts +9 -0
  160. package/src/utils/doubly-linked-list.ts +2 -0
  161. package/src/utils/managed-array.ts +2 -0
@@ -71,24 +71,32 @@ export class TilesetCache {
71
71
  }
72
72
  }
73
73
 
74
- unloadTiles(tileset, unloadCallback): void {
74
+ /**
75
+ * Unloads least-recently-used tiles until the byte-native cache target is met.
76
+ *
77
+ * Tiles touched after the frame sentinel remain protected, so {@link Tileset3D.cacheBytes} is a
78
+ * soft target rather than a hard cap on the visible working set. Overflow headroom affects
79
+ * memory-adjusted SSE, not eviction of unused tiles.
80
+ *
81
+ * @param tileset - Tileset that owns the cache and reports estimated content memory.
82
+ * @param unloadCallback - Callback that releases content and decrements the memory estimate.
83
+ */
84
+ unloadTiles(
85
+ tileset: Tileset3D,
86
+ unloadCallback?: (tileset: Tileset3D, tile: Tile3D) => void
87
+ ): void {
75
88
  const trimTiles = this._trimTiles;
76
89
  this._trimTiles = false;
77
90
 
78
91
  const list = this._list;
79
92
 
80
- const maximumMemoryUsageInBytes = tileset.maximumMemoryUsage * 1024 * 1024;
81
-
82
93
  // Traverse the list only to the sentinel since tiles/nodes to the
83
94
  // right of the sentinel were used this frame.
84
95
  // The sub-list to the left of the sentinel is ordered from LRU to MRU.
85
96
  const sentinel = this._sentinel;
86
97
  let node = list.head;
87
98
 
88
- while (
89
- node !== sentinel &&
90
- (tileset.gpuMemoryUsageInBytes > maximumMemoryUsageInBytes || trimTiles)
91
- ) {
99
+ while (node !== sentinel && (tileset.gpuMemoryUsageInBytes > tileset.cacheBytes || trimTiles)) {
92
100
  // @ts-expect-error
93
101
  const tile = node.item;
94
102
  // @ts-expect-error
@@ -9,6 +9,7 @@ import type {Tile3D} from './tile-3d';
9
9
  import type {Tileset3D} from './tileset-3d';
10
10
  import type {FrameState} from '../helpers/frame-state';
11
11
  import type {TILESET_TYPE} from '../../constants';
12
+ import type {TilesetSpatialReference} from '../../spatial/spatial-types';
12
13
 
13
14
  /**
14
15
  * Parsed top-level tileset payload consumed by {@link Tileset3D} or a {@link Tileset3DSource}.
@@ -69,8 +70,22 @@ export type TilesetSourceInput = TilesetJSON | TilesetSourceRequest;
69
70
  export type TileContentLoadResult = {
70
71
  /** Whether the tile content request produced usable content. */
71
72
  loaded: boolean;
73
+ /** All payloads loaded for a tile, in source order. */
74
+ contents?: any[];
72
75
  /** Nested tileset metadata to install below the loaded tile, if any. */
73
76
  nestedTileset?: TilesetJSON;
77
+ /** Nested tilesets found among multiple content payloads. */
78
+ nestedTilesets?: TilesetJSON[];
79
+ };
80
+
81
+ /** Result of a source-managed lazy child-header request. */
82
+ export type TileChildrenLoadResult = {
83
+ /** Whether a subtree resource was loaded and installed. */
84
+ loaded: boolean;
85
+ /** Number of available tiles described by the subtree, including its existing root placeholder. */
86
+ tileCount: number;
87
+ /** Number of lazy child-subtree references installed at the new boundary. */
88
+ childSubtreeCount: number;
74
89
  };
75
90
 
76
91
  /**
@@ -118,6 +133,8 @@ export type TilesetSourceMetadata = {
118
133
  lodMetricValue: number;
119
134
  /** Root refinement mode used as fallback by runtime tiles. */
120
135
  refine: string;
136
+ /** Format-discovered coordinate reference system metadata. */
137
+ spatialReference?: TilesetSpatialReference;
121
138
  };
122
139
 
123
140
  /**
@@ -157,6 +174,17 @@ export interface Tileset3DSource {
157
174
  */
158
175
  initialize(): Promise<void>;
159
176
 
177
+ /**
178
+ * Prepares option-dependent asynchronous source state before runtime headers are constructed.
179
+ *
180
+ * I3S uses this hook to sample elevation surfaces for its root bound after `Tileset3D` has
181
+ * applied spatial options. Sources without asynchronous header preparation omit the hook.
182
+ */
183
+ prepareTileset?(tileset: Tileset3D): Promise<void>;
184
+
185
+ /** Releases source-local caches and prevents late asynchronous work from mutating runtime tiles. */
186
+ destroy?(): void;
187
+
160
188
  /**
161
189
  * Returns normalized source metadata after initialization completes.
162
190
  */
@@ -186,6 +214,14 @@ export interface Tileset3DSource {
186
214
  */
187
215
  loadTileContent(tile: Tile3D): Promise<TileContentLoadResult>;
188
216
 
217
+ /**
218
+ * Loads and installs a complete lazy child-header group for a runtime tile.
219
+ *
220
+ * Sources that implement this hook retain ownership of resource parsing, caching, query
221
+ * inheritance, and archive resolution. Traversal calls it only after visibility and LOD checks.
222
+ */
223
+ loadTileChildren?(tile: Tile3D, frameState: FrameState): Promise<TileChildrenLoadResult>;
224
+
189
225
  /**
190
226
  * Resolves a tile-relative path to the final request URL.
191
227
  */
@@ -35,6 +35,8 @@ export class TilesetTraverser {
35
35
  selectedTiles: Record<string, Tile3D> = {};
36
36
  // tiles should be loaded from server
37
37
  requestedTiles: Record<string, Tile3D> = {};
38
+ /** Tiles intentionally held until the camera has remained still for the configured delay. */
39
+ deferredTiles: Record<string, Tile3D> = {};
38
40
  // tiles does not have render content
39
41
  emptyTiles: Record<string, Tile3D> = {};
40
42
 
@@ -73,6 +75,7 @@ export class TilesetTraverser {
73
75
 
74
76
  reset() {
75
77
  this.requestedTiles = {};
78
+ this.deferredTiles = {};
76
79
  this.selectedTiles = {};
77
80
  this.emptyTiles = {};
78
81
  this._traversalStack.reset();
@@ -137,7 +140,9 @@ export class TilesetTraverser {
137
140
  // Always load tiles in the base traversal
138
141
  // Select tiles that can't refine further
139
142
  this.loadTile(tile, frameState);
140
- if (stoppedRefining) {
143
+ // Skip-LOD keeps a ready ancestor selected while descendants stream in. This prevents
144
+ // replacement holes when traversal jumps over one or more hierarchy levels.
145
+ if (stoppedRefining || this.options.skipLevelOfDetail) {
141
146
  this.selectTile(tile, frameState);
142
147
  }
143
148
  }
@@ -225,7 +230,7 @@ export class TilesetTraverser {
225
230
 
226
231
  // tile to render in the browser
227
232
  selectTile(tile: Tile3D, frameState: FrameState): void {
228
- if (this.shouldSelectTile(tile)) {
233
+ if (this.shouldSelectTile(tile, frameState)) {
229
234
  // The tile can be selected right away and does not require traverseAndSelect
230
235
  tile._selectedFrame = frameState.frameNumber;
231
236
  this.selectedTiles[tile.id] = tile;
@@ -235,12 +240,30 @@ export class TilesetTraverser {
235
240
  // tile to load from server
236
241
  loadTile(tile: Tile3D, frameState: FrameState): void {
237
242
  if (this.shouldLoadTile(tile)) {
243
+ if (this.shouldDeferTileRequest(tile)) {
244
+ this.deferredTiles[tile.id] = tile;
245
+ return;
246
+ }
238
247
  tile._requestedFrame = frameState.frameNumber;
239
248
  tile._priority = tile._getPriority();
240
249
  this.requestedTiles[tile.id] = tile;
241
250
  }
242
251
  }
243
252
 
253
+ /**
254
+ * Returns whether an eligible peripheral request should wait for camera motion to settle.
255
+ *
256
+ * Eligibility and the current time window are calculated together when tile visibility updates.
257
+ * Keeping the active state on the tile also lets a queued scheduler callback cancel work that
258
+ * became deferred after its original traversal.
259
+ *
260
+ * @param tile - Tile considered for loading.
261
+ * @returns `true` when the request should be retried after the remaining delay.
262
+ */
263
+ shouldDeferTileRequest(tile: Tile3D): boolean {
264
+ return tile.priorityDeferred;
265
+ }
266
+
244
267
  // cache tile
245
268
  touchTile(tile: Tile3D, frameState: FrameState): void {
246
269
  tile.tileset._cache.touch(tile);
@@ -271,10 +294,13 @@ export class TilesetTraverser {
271
294
  return tile.hasUnloadedContent || tile.contentExpired;
272
295
  }
273
296
 
274
- shouldSelectTile(tile: Tile3D): boolean {
275
- // if select tile is in current frame
276
- // and content available
277
- return tile.contentAvailable && !this.options.skipLevelOfDetail;
297
+ /**
298
+ * Returns whether a tile's content is available and visible for rendering.
299
+ * @param tile Tile considered for rendering.
300
+ * @param frameState Current culling state.
301
+ */
302
+ shouldSelectTile(tile: Tile3D, frameState: FrameState): boolean {
303
+ return tile.contentAvailable && tile.contentVisibility(frameState) !== 'outside';
278
304
  }
279
305
 
280
306
  /** Decide if tile LoD (level of detail) is not sufficient under current viewport */
@@ -323,6 +349,7 @@ export class TilesetTraverser {
323
349
  // Ignores visibility.
324
350
  executeEmptyTraversal(root: Tile3D, frameState: FrameState): boolean {
325
351
  let allDescendantsLoaded = true;
352
+ let hasPendingLazyChildren = false;
326
353
  const stack = this._emptyTraversalStack;
327
354
  stack.push(root);
328
355
 
@@ -331,6 +358,12 @@ export class TilesetTraverser {
331
358
 
332
359
  const traverse = !tile.hasRenderContent && this.canTraverse(tile, frameState);
333
360
  const emptyLeaf = !tile.hasRenderContent && tile.children.length === 0;
361
+ if (tile.header.implicitSubtree) {
362
+ // An unresolved implicit boundary is not a proven empty leaf. Treating it as loaded would
363
+ // allow REPLACE traversal to drop its ancestor before availability and content are known.
364
+ hasPendingLazyChildren = true;
365
+ allDescendantsLoaded = false;
366
+ }
334
367
 
335
368
  // Traversal stops but the tile does not have content yet
336
369
  // There will be holes if the parent tries to refine to its children, so don't refine
@@ -353,6 +386,6 @@ export class TilesetTraverser {
353
386
  }
354
387
  }
355
388
  }
356
- return root.hasEmptyContent || allDescendantsLoaded;
389
+ return (root.hasEmptyContent && !hasPendingLazyChildren) || allDescendantsLoaded;
357
390
  }
358
391
  }