@loaders.gl/tiles 3.4.0-alpha.4 → 3.4.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -1
- package/dist/dist.min.js +171 -151
- package/dist/es5/constants.js.map +1 -1
- package/dist/es5/tileset/helpers/3d-tiles-options.js.map +1 -1
- package/dist/es5/tileset/tile-3d.js +41 -71
- package/dist/es5/tileset/tile-3d.js.map +1 -1
- package/dist/es5/tileset/tileset-3d.js +68 -102
- package/dist/es5/tileset/tileset-3d.js.map +1 -1
- package/dist/es5/tileset/tileset-cache.js +4 -7
- package/dist/es5/tileset/tileset-cache.js.map +1 -1
- package/dist/es5/tileset/tileset-traverser.js +12 -22
- package/dist/es5/tileset/tileset-traverser.js.map +1 -1
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/tileset/helpers/3d-tiles-options.js.map +1 -1
- package/dist/esm/tileset/tile-3d.js +39 -71
- package/dist/esm/tileset/tile-3d.js.map +1 -1
- package/dist/esm/tileset/tileset-3d.js +64 -94
- package/dist/esm/tileset/tileset-3d.js.map +1 -1
- package/dist/esm/tileset/tileset-cache.js +4 -7
- package/dist/esm/tileset/tileset-cache.js.map +1 -1
- package/dist/esm/tileset/tileset-traverser.js +9 -19
- package/dist/esm/tileset/tileset-traverser.js.map +1 -1
- package/dist/tileset/helpers/3d-tiles-options.d.ts +3 -2
- package/dist/tileset/helpers/3d-tiles-options.d.ts.map +1 -1
- package/dist/tileset/tile-3d.d.ts +36 -21
- package/dist/tileset/tile-3d.d.ts.map +1 -1
- package/dist/tileset/tile-3d.js +58 -43
- package/dist/tileset/tileset-3d.d.ts +90 -43
- package/dist/tileset/tileset-3d.d.ts.map +1 -1
- package/dist/tileset/tileset-3d.js +108 -127
- package/dist/tileset/tileset-cache.d.ts +5 -4
- package/dist/tileset/tileset-cache.d.ts.map +1 -1
- package/dist/tileset/tileset-cache.js +4 -10
- package/dist/tileset/tileset-traverser.d.ts +32 -21
- package/dist/tileset/tileset-traverser.d.ts.map +1 -1
- package/dist/tileset/tileset-traverser.js +23 -35
- package/package.json +4 -4
- package/src/constants.ts +18 -0
- package/src/tileset/helpers/3d-tiles-options.ts +3 -1
- package/src/tileset/tile-3d.ts +70 -109
- package/src/tileset/tileset-3d.ts +178 -216
- package/src/tileset/tileset-cache.ts +20 -15
- package/src/tileset/tileset-traverser.ts +52 -68
|
@@ -3,58 +3,18 @@
|
|
|
3
3
|
// This file is derived from the Cesium code base under Apache 2 license
|
|
4
4
|
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
5
5
|
|
|
6
|
-
/*
|
|
7
|
-
|
|
8
|
-
The Tileset loading and rendering flow is as below,
|
|
9
|
-
A rendered (i.e. deck.gl `Tile3DLayer`) triggers `tileset.update()` after a `tileset` is loaded
|
|
10
|
-
`tileset` starts traversing the tile tree and update `requestTiles` (tiles of which content need
|
|
11
|
-
to be fetched) and `selectedTiles` (tiles ready for rendering under the current viewport).
|
|
12
|
-
`Tile3DLayer` will update rendering based on `selectedTiles`.
|
|
13
|
-
`Tile3DLayer` also listens to `onTileLoad` callback and trigger another round of `update and then traversal`
|
|
14
|
-
when new tiles are loaded.
|
|
15
|
-
|
|
16
|
-
As I3S tileset have stored `tileHeader` file (metadata) and tile content files (geometry, texture, ...) separately.
|
|
17
|
-
During each traversal, it issues `tilHeader` requests if that `tileHeader` is not yet fetched,
|
|
18
|
-
after the tile header is fulfilled, it will resume the traversal starting from the tile just fetched (not root).
|
|
19
|
-
|
|
20
|
-
Tile3DLayer
|
|
21
|
-
|
|
|
22
|
-
await load(tileset)
|
|
23
|
-
|
|
|
24
|
-
tileset.update()
|
|
25
|
-
| async load tileHeader
|
|
26
|
-
tileset.traverse() -------------------------- Queued
|
|
27
|
-
| resume traversal after fetched |
|
|
28
|
-
|----------------------------------------|
|
|
29
|
-
|
|
|
30
|
-
| async load tile content
|
|
31
|
-
tilset.requestedTiles ----------------------------- RequestScheduler
|
|
32
|
-
|
|
|
33
|
-
tilset.selectedTiles (ready for rendering) |
|
|
34
|
-
| Listen to |
|
|
35
|
-
Tile3DLayer ----------- onTileLoad ----------------------|
|
|
36
|
-
| | notify new tile is available
|
|
37
|
-
updateLayers |
|
|
38
|
-
tileset.update // trigger another round of update
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
6
|
import {Matrix4, Vector3} from '@math.gl/core';
|
|
42
7
|
import {Ellipsoid} from '@math.gl/geospatial';
|
|
43
8
|
import {Stats} from '@probe.gl/stats';
|
|
44
|
-
import {
|
|
45
|
-
RequestScheduler,
|
|
46
|
-
assert,
|
|
47
|
-
path,
|
|
48
|
-
LoaderWithParser,
|
|
49
|
-
LoaderOptions
|
|
50
|
-
} from '@loaders.gl/loader-utils';
|
|
9
|
+
import {RequestScheduler, path, LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
51
10
|
import {TilesetCache} from './tileset-cache';
|
|
52
11
|
import {calculateTransformProps} from './helpers/transform-utils';
|
|
53
12
|
import {FrameState, getFrameState, limitSelectedTiles} from './helpers/frame-state';
|
|
54
13
|
import {getZoomFromBoundingVolume, getZoomFromExtent, getZoomFromFullExtent} from './helpers/zoom';
|
|
14
|
+
|
|
15
|
+
import type {GeospatialViewport, Viewport} from '../types';
|
|
55
16
|
import {Tile3D} from './tile-3d';
|
|
56
17
|
import {TILESET_TYPE} from '../constants';
|
|
57
|
-
import {GeospatialViewport, Viewport} from '../types';
|
|
58
18
|
|
|
59
19
|
import {TilesetTraverser} from './tileset-traverser';
|
|
60
20
|
|
|
@@ -62,6 +22,27 @@ import {TilesetTraverser} from './tileset-traverser';
|
|
|
62
22
|
import {Tileset3DTraverser} from './format-3d-tiles/tileset-3d-traverser';
|
|
63
23
|
import {I3STilesetTraverser} from './format-i3s/i3s-tileset-traverser';
|
|
64
24
|
|
|
25
|
+
export type TilesetJSON = any;
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
export type TilesetJSON = {
|
|
29
|
+
loader;
|
|
30
|
+
// could be 3d tiles, i3s
|
|
31
|
+
type: 'I3S' | '3DTILES';
|
|
32
|
+
/** The url to the top level tileset JSON file. *
|
|
33
|
+
url: string;
|
|
34
|
+
basePath?: string;
|
|
35
|
+
// Geometric error when the tree is not rendered at all
|
|
36
|
+
lodMetricType: string;
|
|
37
|
+
lodMetricValue: number;
|
|
38
|
+
root: {
|
|
39
|
+
refine: string;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
},
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
};
|
|
44
|
+
*/
|
|
45
|
+
|
|
65
46
|
export type Tileset3DProps = {
|
|
66
47
|
// loading
|
|
67
48
|
throttleRequests?: boolean;
|
|
@@ -98,83 +79,63 @@ export type Tileset3DProps = {
|
|
|
98
79
|
type Props = {
|
|
99
80
|
description: string;
|
|
100
81
|
ellipsoid: object;
|
|
82
|
+
/** A 4x4 transformation matrix this transforms the entire tileset. */
|
|
101
83
|
modelMatrix: Matrix4;
|
|
84
|
+
/** Set to false to disable network request throttling */
|
|
102
85
|
throttleRequests: boolean;
|
|
86
|
+
/** Number of simultaneous requsts, if throttleRequests is true */
|
|
87
|
+
maxRequests: number;
|
|
103
88
|
maximumMemoryUsage: number;
|
|
89
|
+
/** Maximum number limit of tiles selected for show. 0 means no limit */
|
|
104
90
|
maximumTilesSelected: number;
|
|
91
|
+
/** Delay time before the tileset traversal. It prevents traversal requests spam.*/
|
|
105
92
|
debounceTime: number;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
/** Callback. Indicates this a tile's content was loaded */
|
|
94
|
+
onTileLoad: (tile: Tile3D) => void;
|
|
95
|
+
/** Callback. Indicates this a tile's content was unloaded (cache full) */
|
|
96
|
+
onTileUnload: (tile: Tile3D) => void;
|
|
97
|
+
/** Callback. Indicates this a tile's content failed to load */
|
|
98
|
+
onTileError: (tile: Tile3D, message: string, url: string) => void;
|
|
99
|
+
/** Callback. Allows post-process selectedTiles right after traversal. */
|
|
109
100
|
onTraversalComplete: (selectedTiles: Tile3D[]) => Tile3D[];
|
|
101
|
+
/** The maximum screen space error used to drive level of detail refinement. */
|
|
110
102
|
maximumScreenSpaceError: number;
|
|
111
|
-
viewportTraversersMap: any;
|
|
103
|
+
viewportTraversersMap: Record<string, any> | null;
|
|
112
104
|
attributions: string[];
|
|
113
|
-
maxRequests: number;
|
|
114
105
|
loadTiles: boolean;
|
|
115
106
|
loadOptions: LoaderOptions;
|
|
116
107
|
updateTransforms: boolean;
|
|
108
|
+
/** View distance scale modifier */
|
|
117
109
|
viewDistanceScale: number;
|
|
118
110
|
basePath: string;
|
|
111
|
+
/** Optional async tile content loader */
|
|
119
112
|
contentLoader?: (tile: Tile3D) => Promise<void>;
|
|
120
|
-
|
|
113
|
+
/** @todo I3S specific knowledge should be moved to I3S module */
|
|
114
|
+
i3s: Record<string, any>;
|
|
121
115
|
};
|
|
122
116
|
|
|
123
117
|
const DEFAULT_PROPS: Props = {
|
|
124
118
|
description: '',
|
|
125
|
-
|
|
126
119
|
ellipsoid: Ellipsoid.WGS84,
|
|
127
|
-
// A 4x4 transformation matrix this transforms the entire tileset.
|
|
128
120
|
modelMatrix: new Matrix4(),
|
|
129
|
-
|
|
130
|
-
// Set to false to disable network request throttling
|
|
131
121
|
throttleRequests: true,
|
|
132
|
-
|
|
133
|
-
// Number of simultaneous requsts, if throttleRequests is true
|
|
134
122
|
maxRequests: 64,
|
|
135
|
-
|
|
136
123
|
maximumMemoryUsage: 32,
|
|
137
|
-
/** Maximum number limit of tiles selected for show. 0 means no limit */
|
|
138
124
|
maximumTilesSelected: 0,
|
|
139
|
-
/** Delay time before the tileset traversal. It prevents traversal requests spam.*/
|
|
140
125
|
debounceTime: 0,
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Callback. Indicates this a tile's content was loaded
|
|
144
|
-
* @param tile {TileHeader}
|
|
145
|
-
*/
|
|
146
126
|
onTileLoad: () => {},
|
|
147
|
-
/**
|
|
148
|
-
* Callback. Indicates this a tile's content was unloaded
|
|
149
|
-
* @param tile {TileHeader}
|
|
150
|
-
*/
|
|
151
127
|
onTileUnload: () => {},
|
|
152
128
|
onTileError: () => {},
|
|
153
|
-
/**
|
|
154
|
-
* Callback. Allows post-process selectedTiles right after traversal.
|
|
155
|
-
* @param selectedTiles {TileHeader[]}
|
|
156
|
-
* @returns TileHeader[] - output array of tiles to return to deck.gl
|
|
157
|
-
*/
|
|
158
129
|
onTraversalComplete: (selectedTiles: Tile3D[]) => selectedTiles,
|
|
159
|
-
|
|
160
|
-
// Optional async tile content loader
|
|
161
130
|
contentLoader: undefined,
|
|
162
|
-
|
|
163
|
-
// View distance scale modifier
|
|
164
131
|
viewDistanceScale: 1.0,
|
|
165
|
-
|
|
166
|
-
// The maximum screen space error used to drive level of detail refinement.
|
|
167
132
|
maximumScreenSpaceError: 8,
|
|
168
|
-
|
|
169
133
|
loadTiles: true,
|
|
170
134
|
updateTransforms: true,
|
|
171
135
|
viewportTraversersMap: null,
|
|
172
|
-
|
|
173
136
|
loadOptions: {fetch: {}},
|
|
174
|
-
|
|
175
137
|
attributions: [],
|
|
176
138
|
basePath: '',
|
|
177
|
-
|
|
178
139
|
i3s: {}
|
|
179
140
|
};
|
|
180
141
|
|
|
@@ -190,13 +151,46 @@ const TILES_LOAD_FAILED = 'Failed Tile Loads';
|
|
|
190
151
|
const POINTS_COUNT = 'Points/Vertices';
|
|
191
152
|
const TILES_GPU_MEMORY = 'Tile Memory Use';
|
|
192
153
|
|
|
154
|
+
/**
|
|
155
|
+
* The Tileset loading and rendering flow is as below,
|
|
156
|
+
* A rendered (i.e. deck.gl `Tile3DLayer`) triggers `tileset.update()` after a `tileset` is loaded
|
|
157
|
+
* `tileset` starts traversing the tile tree and update `requestTiles` (tiles of which content need
|
|
158
|
+
* to be fetched) and `selectedTiles` (tiles ready for rendering under the current viewport).
|
|
159
|
+
* `Tile3DLayer` will update rendering based on `selectedTiles`.
|
|
160
|
+
* `Tile3DLayer` also listens to `onTileLoad` callback and trigger another round of `update and then traversal`
|
|
161
|
+
* when new tiles are loaded.
|
|
162
|
+
|
|
163
|
+
* As I3S tileset have stored `tileHeader` file (metadata) and tile content files (geometry, texture, ...) separately.
|
|
164
|
+
* During each traversal, it issues `tilHeader` requests if that `tileHeader` is not yet fetched,
|
|
165
|
+
* after the tile header is fulfilled, it will resume the traversal starting from the tile just fetched (not root).
|
|
166
|
+
|
|
167
|
+
* Tile3DLayer
|
|
168
|
+
* |
|
|
169
|
+
* await load(tileset)
|
|
170
|
+
* |
|
|
171
|
+
* tileset.update()
|
|
172
|
+
* | async load tileHeader
|
|
173
|
+
* tileset.traverse() -------------------------- Queued
|
|
174
|
+
* | resume traversal after fetched |
|
|
175
|
+
* |----------------------------------------|
|
|
176
|
+
* |
|
|
177
|
+
* | async load tile content
|
|
178
|
+
* tilset.requestedTiles ----------------------------- RequestScheduler
|
|
179
|
+
* |
|
|
180
|
+
* tilset.selectedTiles (ready for rendering) |
|
|
181
|
+
* | Listen to |
|
|
182
|
+
* Tile3DLayer ----------- onTileLoad ----------------------|
|
|
183
|
+
* | | notify new tile is available
|
|
184
|
+
* updateLayers |
|
|
185
|
+
* tileset.update // trigger another round of update
|
|
186
|
+
*/
|
|
193
187
|
export class Tileset3D {
|
|
194
188
|
// props: Tileset3DProps;
|
|
195
189
|
options: Props;
|
|
196
|
-
loadOptions:
|
|
190
|
+
loadOptions: LoaderOptions;
|
|
197
191
|
|
|
198
192
|
type: string;
|
|
199
|
-
tileset:
|
|
193
|
+
tileset: TilesetJSON;
|
|
200
194
|
loader: LoaderWithParser;
|
|
201
195
|
url: string;
|
|
202
196
|
basePath: string;
|
|
@@ -205,60 +199,71 @@ export class Tileset3D {
|
|
|
205
199
|
lodMetricType: string;
|
|
206
200
|
lodMetricValue: number;
|
|
207
201
|
refine: string;
|
|
208
|
-
root: Tile3D | null;
|
|
209
|
-
roots:
|
|
210
|
-
|
|
202
|
+
root: Tile3D | null = null;
|
|
203
|
+
roots: Record<string, Tile3D> = {};
|
|
204
|
+
/** @todo any->unknown */
|
|
205
|
+
asset: Record<string, any> = {};
|
|
211
206
|
|
|
212
|
-
|
|
207
|
+
// Metadata for the entire tileset
|
|
208
|
+
description: string = '';
|
|
213
209
|
properties: any;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
210
|
+
|
|
211
|
+
extras: any = null;
|
|
212
|
+
attributions: any = {};
|
|
213
|
+
credits: any = {};
|
|
217
214
|
|
|
218
215
|
stats: Stats;
|
|
219
216
|
|
|
220
217
|
/** flags that contain information about data types in nested tiles */
|
|
221
218
|
contentFormats = {draco: false, meshopt: false, dds: false, ktx2: false};
|
|
222
219
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
220
|
+
// view props
|
|
221
|
+
cartographicCenter: Vector3 | null = null;
|
|
222
|
+
cartesianCenter: Vector3 | null = null;
|
|
223
|
+
zoom: number = 1;
|
|
224
|
+
boundingVolume: any = null;
|
|
228
225
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
zoom: number;
|
|
232
|
-
boundingVolume: any;
|
|
226
|
+
/** Updated based on the camera position and direction */
|
|
227
|
+
dynamicScreenSpaceErrorComputedDensity: number = 0.0;
|
|
233
228
|
|
|
234
229
|
// METRICS
|
|
235
|
-
// The maximum amount of GPU memory (in MB) that may be used to cache tiles.
|
|
236
|
-
// Tiles not in view are unloaded to enforce private
|
|
237
|
-
// The total amount of GPU memory in bytes used by the tileset.
|
|
238
|
-
gpuMemoryUsageInBytes: any;
|
|
239
|
-
dynamicScreenSpaceErrorComputedDensity: any;
|
|
240
230
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
231
|
+
/**
|
|
232
|
+
* The maximum amount of GPU memory (in MB) that may be used to cache tiles
|
|
233
|
+
* Tiles not in view are unloaded to enforce private
|
|
234
|
+
*/
|
|
235
|
+
maximumMemoryUsage: number = 32;
|
|
245
236
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
private _queryParams: any;
|
|
249
|
-
private _extensionsUsed: any;
|
|
250
|
-
private _tiles: {[id: string]: Tile3D};
|
|
237
|
+
/** The total amount of GPU memory in bytes used by the tileset. */
|
|
238
|
+
gpuMemoryUsageInBytes: number = 0;
|
|
251
239
|
|
|
252
|
-
|
|
253
|
-
|
|
240
|
+
/** Update tracker. increase in each update cycle. */
|
|
241
|
+
_frameNumber: number = 0;
|
|
242
|
+
private _queryParams: Record<string, string> = {};
|
|
243
|
+
private _extensionsUsed: string[] = [];
|
|
244
|
+
private _tiles: Record<string, Tile3D> = {};
|
|
254
245
|
|
|
255
|
-
|
|
256
|
-
private
|
|
257
|
-
private _requestedTiles: any;
|
|
258
|
-
private _emptyTiles: any;
|
|
259
|
-
private frameStateData: any;
|
|
246
|
+
/** counter for tracking tiles requests */
|
|
247
|
+
private _pendingCount: number = 0;
|
|
260
248
|
|
|
261
|
-
|
|
249
|
+
/** Hold traversal results */
|
|
250
|
+
selectedTiles: Tile3D[] = [];
|
|
251
|
+
|
|
252
|
+
// TRAVERSAL
|
|
253
|
+
traverseCounter: number = 0;
|
|
254
|
+
geometricError: number = 0;
|
|
255
|
+
private lastUpdatedVieports: Viewport[] | Viewport | null = null;
|
|
256
|
+
private _requestedTiles: Tile3D[] = [];
|
|
257
|
+
private _emptyTiles: Tile3D[] = [];
|
|
258
|
+
private frameStateData: any = {};
|
|
259
|
+
|
|
260
|
+
_traverser: TilesetTraverser;
|
|
261
|
+
_cache = new TilesetCache();
|
|
262
|
+
_requestScheduler: RequestScheduler;
|
|
263
|
+
|
|
264
|
+
// Promise tracking
|
|
265
|
+
private updatePromise: Promise<number> | null = null;
|
|
266
|
+
tilesetInitializationPromise: Promise<void>;
|
|
262
267
|
|
|
263
268
|
/**
|
|
264
269
|
* Create a new Tileset3D
|
|
@@ -266,83 +271,40 @@ export class Tileset3D {
|
|
|
266
271
|
* @param props
|
|
267
272
|
*/
|
|
268
273
|
// eslint-disable-next-line max-statements
|
|
269
|
-
constructor(
|
|
270
|
-
assert(json);
|
|
271
|
-
|
|
274
|
+
constructor(tileset: TilesetJSON, options?: Tileset3DProps) {
|
|
272
275
|
// PUBLIC MEMBERS
|
|
273
276
|
this.options = {...DEFAULT_PROPS, ...options};
|
|
274
277
|
// raw data
|
|
275
|
-
this.tileset =
|
|
276
|
-
this.loader =
|
|
278
|
+
this.tileset = tileset;
|
|
279
|
+
this.loader = tileset.loader;
|
|
277
280
|
// could be 3d tiles, i3s
|
|
278
|
-
this.type =
|
|
281
|
+
this.type = tileset.type;
|
|
279
282
|
// The url to a tileset JSON file.
|
|
280
|
-
this.url =
|
|
281
|
-
this.basePath =
|
|
283
|
+
this.url = tileset.url;
|
|
284
|
+
this.basePath = tileset.basePath || path.dirname(this.url);
|
|
282
285
|
this.modelMatrix = this.options.modelMatrix;
|
|
283
286
|
this.ellipsoid = this.options.ellipsoid;
|
|
284
287
|
|
|
285
288
|
// Geometric error when the tree is not rendered at all
|
|
286
|
-
this.lodMetricType =
|
|
287
|
-
this.lodMetricValue =
|
|
288
|
-
this.refine =
|
|
289
|
+
this.lodMetricType = tileset.lodMetricType;
|
|
290
|
+
this.lodMetricValue = tileset.lodMetricValue;
|
|
291
|
+
this.refine = tileset.root.refine;
|
|
289
292
|
|
|
290
293
|
this.loadOptions = this.options.loadOptions || {};
|
|
291
294
|
|
|
292
|
-
this.root = null;
|
|
293
|
-
this.roots = {};
|
|
294
|
-
// view props
|
|
295
|
-
this.cartographicCenter = null;
|
|
296
|
-
this.cartesianCenter = null;
|
|
297
|
-
this.zoom = 1;
|
|
298
|
-
this.boundingVolume = null;
|
|
299
|
-
|
|
300
295
|
// TRAVERSAL
|
|
301
|
-
this.traverseCounter = 0;
|
|
302
|
-
this.geometricError = 0;
|
|
303
296
|
this._traverser = this._initializeTraverser();
|
|
304
|
-
this._cache = new TilesetCache();
|
|
305
297
|
this._requestScheduler = new RequestScheduler({
|
|
306
298
|
throttleRequests: this.options.throttleRequests,
|
|
307
299
|
maxRequests: this.options.maxRequests
|
|
308
300
|
});
|
|
309
|
-
// update tracker
|
|
310
|
-
// increase in each update cycle
|
|
311
|
-
this._frameNumber = 0;
|
|
312
|
-
|
|
313
|
-
// counter for tracking tiles requests
|
|
314
|
-
this._pendingCount = 0;
|
|
315
|
-
|
|
316
|
-
// HOLD TRAVERSAL RESULTS
|
|
317
|
-
this._tiles = {};
|
|
318
|
-
this.selectedTiles = [];
|
|
319
|
-
this._emptyTiles = [];
|
|
320
|
-
this._requestedTiles = [];
|
|
321
|
-
this.frameStateData = {};
|
|
322
|
-
this.lastUpdatedVieports = null;
|
|
323
|
-
|
|
324
|
-
this._queryParams = {};
|
|
325
|
-
this._queryParamsString = '';
|
|
326
301
|
|
|
327
302
|
// METRICS
|
|
328
|
-
// The maximum amount of GPU memory (in MB) that may be used to cache tiles.
|
|
329
|
-
// Tiles not in view are unloaded to enforce this.
|
|
330
|
-
this.maximumMemoryUsage = this.options.maximumMemoryUsage || 32;
|
|
331
303
|
// The total amount of GPU memory in bytes used by the tileset.
|
|
332
|
-
this.gpuMemoryUsageInBytes = 0;
|
|
333
304
|
this.stats = new Stats({id: this.url});
|
|
334
305
|
this._initializeStats();
|
|
335
306
|
|
|
336
|
-
|
|
337
|
-
this._extensionsUsed = undefined;
|
|
338
|
-
this.dynamicScreenSpaceErrorComputedDensity = 0.0; // Updated based on the camera position and direction
|
|
339
|
-
// Metadata for the entire tileset
|
|
340
|
-
this.extras = null;
|
|
341
|
-
this.asset = {};
|
|
342
|
-
this.credits = {};
|
|
343
|
-
this.description = this.options.description || '';
|
|
344
|
-
|
|
345
|
-
this.tilesetInitializationPromise = this._initializeTileSet(json);
|
|
307
|
+
this.tilesetInitializationPromise = this._initializeTileSet(tileset);
|
|
346
308
|
}
|
|
347
309
|
|
|
348
310
|
/** Release resources */
|
|
@@ -365,10 +327,8 @@ export class Tileset3D {
|
|
|
365
327
|
}
|
|
366
328
|
|
|
367
329
|
get queryParams(): string {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
return this._queryParamsString;
|
|
330
|
+
const search = new URLSearchParams(this._queryParams).toString();
|
|
331
|
+
return search ? `?${search}` : '';
|
|
372
332
|
}
|
|
373
333
|
|
|
374
334
|
setProps(props: Tileset3DProps): void {
|
|
@@ -389,12 +349,12 @@ export class Tileset3D {
|
|
|
389
349
|
if (isDataUrl) {
|
|
390
350
|
return tilePath;
|
|
391
351
|
}
|
|
392
|
-
return `${tilePath}${this.queryParams}`;
|
|
352
|
+
return `${tilePath}${tilePath.includes('?') ? '&' : '?'}${this.queryParams}`;
|
|
393
353
|
}
|
|
394
354
|
|
|
395
355
|
// TODO CESIUM specific
|
|
396
356
|
hasExtension(extensionName: string): boolean {
|
|
397
|
-
return Boolean(this._extensionsUsed
|
|
357
|
+
return Boolean(this._extensionsUsed.indexOf(extensionName) > -1);
|
|
398
358
|
}
|
|
399
359
|
|
|
400
360
|
/**
|
|
@@ -559,7 +519,7 @@ export class Tileset3D {
|
|
|
559
519
|
this._updateStats();
|
|
560
520
|
}
|
|
561
521
|
|
|
562
|
-
_tilesChanged(oldSelectedTiles, selectedTiles) {
|
|
522
|
+
_tilesChanged(oldSelectedTiles: Tile3D[], selectedTiles: Tile3D[]): boolean {
|
|
563
523
|
if (oldSelectedTiles.length !== selectedTiles.length) {
|
|
564
524
|
return true;
|
|
565
525
|
}
|
|
@@ -570,7 +530,7 @@ export class Tileset3D {
|
|
|
570
530
|
return changed;
|
|
571
531
|
}
|
|
572
532
|
|
|
573
|
-
_loadTiles() {
|
|
533
|
+
_loadTiles(): void {
|
|
574
534
|
// Sort requests by priority before making any requests.
|
|
575
535
|
// This makes it less likely this requests will be cancelled after being issued.
|
|
576
536
|
// requestedTiles.sort((a, b) => a._priority - b._priority);
|
|
@@ -582,12 +542,12 @@ export class Tileset3D {
|
|
|
582
542
|
}
|
|
583
543
|
}
|
|
584
544
|
|
|
585
|
-
_unloadTiles() {
|
|
545
|
+
_unloadTiles(): void {
|
|
586
546
|
// unload tiles from cache when hit maximumMemoryUsage
|
|
587
547
|
this._cache.unloadTiles(this, (tileset, tile) => tileset._unloadTile(tile));
|
|
588
548
|
}
|
|
589
549
|
|
|
590
|
-
_updateStats() {
|
|
550
|
+
_updateStats(): void {
|
|
591
551
|
let tilesRenderable = 0;
|
|
592
552
|
let pointsRenderable = 0;
|
|
593
553
|
for (const tile of this.selectedTiles) {
|
|
@@ -607,7 +567,7 @@ export class Tileset3D {
|
|
|
607
567
|
this.stats.get(POINTS_COUNT).count = pointsRenderable;
|
|
608
568
|
}
|
|
609
569
|
|
|
610
|
-
async _initializeTileSet(tilesetJson) {
|
|
570
|
+
async _initializeTileSet(tilesetJson: TilesetJSON): Promise<void> {
|
|
611
571
|
if (this.type === TILESET_TYPE.I3S) {
|
|
612
572
|
this.calculateViewPropsI3S();
|
|
613
573
|
tilesetJson.root = await tilesetJson.root;
|
|
@@ -630,7 +590,7 @@ export class Tileset3D {
|
|
|
630
590
|
* For I3S there is extent (<1.8 version) or fullExtent (>=1.8 version) to calculate view props
|
|
631
591
|
* @returns
|
|
632
592
|
*/
|
|
633
|
-
private calculateViewPropsI3S() {
|
|
593
|
+
private calculateViewPropsI3S(): void {
|
|
634
594
|
// for I3S 1.8 try to calculate with fullExtent
|
|
635
595
|
const fullExtent = this.tileset.fullExtent;
|
|
636
596
|
if (fullExtent) {
|
|
@@ -674,7 +634,6 @@ export class Tileset3D {
|
|
|
674
634
|
*/
|
|
675
635
|
private calculateViewPropsTiles3D() {
|
|
676
636
|
const root = this.root as Tile3D;
|
|
677
|
-
assert(root);
|
|
678
637
|
const {center} = root.boundingVolume;
|
|
679
638
|
// TODO - handle all cases
|
|
680
639
|
if (!center) {
|
|
@@ -710,7 +669,7 @@ export class Tileset3D {
|
|
|
710
669
|
|
|
711
670
|
// Installs the main tileset JSON file or a tileset JSON file referenced from a tile.
|
|
712
671
|
// eslint-disable-next-line max-statements
|
|
713
|
-
_initializeTileHeaders(tilesetJson, parentTileHeader) {
|
|
672
|
+
_initializeTileHeaders(tilesetJson: TilesetJSON, parentTileHeader?: any) {
|
|
714
673
|
// A tileset JSON file referenced from a tile may exist in a different directory than the root tileset.
|
|
715
674
|
// Get the basePath relative to the external tileset.
|
|
716
675
|
const rootTile = new Tile3D(this, tilesetJson.root, parentTileHeader); // resource
|
|
@@ -733,6 +692,17 @@ export class Tileset3D {
|
|
|
733
692
|
const children = tile.header.children || [];
|
|
734
693
|
for (const childHeader of children) {
|
|
735
694
|
const childTile = new Tile3D(this, childHeader, tile);
|
|
695
|
+
|
|
696
|
+
// Special handling for Google
|
|
697
|
+
// A session key must be used for all tile requests
|
|
698
|
+
if (childTile.contentUrl?.includes('?session=')) {
|
|
699
|
+
const url = new URL(childTile.contentUrl);
|
|
700
|
+
const session = url.searchParams.get('session');
|
|
701
|
+
if (session) {
|
|
702
|
+
this._queryParams.session = session;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
736
706
|
tile.children.push(childTile);
|
|
737
707
|
childTile.depth = tile.depth + 1;
|
|
738
708
|
stack.push(childTile);
|
|
@@ -743,7 +713,7 @@ export class Tileset3D {
|
|
|
743
713
|
return rootTile;
|
|
744
714
|
}
|
|
745
715
|
|
|
746
|
-
_initializeTraverser() {
|
|
716
|
+
_initializeTraverser(): TilesetTraverser {
|
|
747
717
|
let TraverserClass;
|
|
748
718
|
const type = this.type;
|
|
749
719
|
switch (type) {
|
|
@@ -763,24 +733,24 @@ export class Tileset3D {
|
|
|
763
733
|
});
|
|
764
734
|
}
|
|
765
735
|
|
|
766
|
-
_destroyTileHeaders(parentTile) {
|
|
736
|
+
_destroyTileHeaders(parentTile: Tile3D): void {
|
|
767
737
|
this._destroySubtree(parentTile);
|
|
768
738
|
}
|
|
769
739
|
|
|
770
|
-
async _loadTile(tile) {
|
|
740
|
+
async _loadTile(tile: Tile3D): Promise<void> {
|
|
771
741
|
let loaded;
|
|
772
742
|
try {
|
|
773
743
|
this._onStartTileLoading();
|
|
774
744
|
loaded = await tile.loadContent();
|
|
775
|
-
} catch (error) {
|
|
776
|
-
this._onTileLoadError(tile, error);
|
|
745
|
+
} catch (error: unknown) {
|
|
746
|
+
this._onTileLoadError(tile, error instanceof Error ? error : new Error('load failed'));
|
|
777
747
|
} finally {
|
|
778
748
|
this._onEndTileLoading();
|
|
779
749
|
this._onTileLoad(tile, loaded);
|
|
780
750
|
}
|
|
781
751
|
}
|
|
782
752
|
|
|
783
|
-
_onTileLoadError(tile, error) {
|
|
753
|
+
_onTileLoadError(tile: Tile3D, error: Error): void {
|
|
784
754
|
this.stats.get(TILES_LOAD_FAILED).incrementCount();
|
|
785
755
|
|
|
786
756
|
const message = error.message || error.toString();
|
|
@@ -790,7 +760,7 @@ export class Tileset3D {
|
|
|
790
760
|
this.options.onTileError(tile, message, url);
|
|
791
761
|
}
|
|
792
762
|
|
|
793
|
-
_onTileLoad(tile, loaded) {
|
|
763
|
+
_onTileLoad(tile: Tile3D, loaded: boolean): void {
|
|
794
764
|
if (!loaded) {
|
|
795
765
|
return;
|
|
796
766
|
}
|
|
@@ -854,7 +824,7 @@ export class Tileset3D {
|
|
|
854
824
|
this.stats.get(TILES_LOADING).decrementCount();
|
|
855
825
|
}
|
|
856
826
|
|
|
857
|
-
_addTileToCache(tile) {
|
|
827
|
+
_addTileToCache(tile: Tile3D) {
|
|
858
828
|
this._cache.add(this, tile, (tileset) => tileset._updateCacheStats(tile));
|
|
859
829
|
}
|
|
860
830
|
|
|
@@ -863,12 +833,12 @@ export class Tileset3D {
|
|
|
863
833
|
this.stats.get(TILES_IN_MEMORY).incrementCount();
|
|
864
834
|
|
|
865
835
|
// Good enough? Just use the raw binary ArrayBuffer's byte length.
|
|
866
|
-
this.gpuMemoryUsageInBytes += tile.
|
|
836
|
+
this.gpuMemoryUsageInBytes += tile.gpuMemoryUsageInBytes || 0;
|
|
867
837
|
this.stats.get(TILES_GPU_MEMORY).count = this.gpuMemoryUsageInBytes;
|
|
868
838
|
}
|
|
869
839
|
|
|
870
840
|
_unloadTile(tile) {
|
|
871
|
-
this.gpuMemoryUsageInBytes -=
|
|
841
|
+
this.gpuMemoryUsageInBytes -= tile.gpuMemoryUsageInBytes || 0;
|
|
872
842
|
|
|
873
843
|
this.stats.get(TILES_IN_MEMORY).decrementCount();
|
|
874
844
|
this.stats.get(TILES_UNLOADED).incrementCount();
|
|
@@ -922,6 +892,12 @@ export class Tileset3D {
|
|
|
922
892
|
}
|
|
923
893
|
|
|
924
894
|
_initializeTiles3DTileset(tilesetJson) {
|
|
895
|
+
if (tilesetJson.queryString) {
|
|
896
|
+
const searchParams = new URLSearchParams(tilesetJson.queryString);
|
|
897
|
+
const queryParams = Object.fromEntries(searchParams.entries());
|
|
898
|
+
this._queryParams = {...this._queryParams, ...queryParams};
|
|
899
|
+
}
|
|
900
|
+
|
|
925
901
|
this.asset = tilesetJson.asset;
|
|
926
902
|
if (!this.asset) {
|
|
927
903
|
throw new Error('Tileset must have an asset property.');
|
|
@@ -945,29 +921,15 @@ export class Tileset3D {
|
|
|
945
921
|
// Gets the tileset's properties dictionary object, which contains metadata about per-feature properties.
|
|
946
922
|
this.properties = tilesetJson.properties;
|
|
947
923
|
this.geometricError = tilesetJson.geometricError;
|
|
948
|
-
this._extensionsUsed = tilesetJson.extensionsUsed;
|
|
924
|
+
this._extensionsUsed = tilesetJson.extensionsUsed || [];
|
|
949
925
|
// Returns the extras property at the top of the tileset JSON (application specific metadata).
|
|
950
926
|
this.extras = tilesetJson.extras;
|
|
951
927
|
}
|
|
952
928
|
|
|
953
929
|
_initializeI3STileset() {
|
|
930
|
+
// @ts-expect-error
|
|
954
931
|
if (this.loadOptions.i3s && 'token' in this.loadOptions.i3s) {
|
|
955
|
-
this._queryParams.token = this.loadOptions.i3s.token;
|
|
932
|
+
this._queryParams.token = this.loadOptions.i3s.token as string;
|
|
956
933
|
}
|
|
957
934
|
}
|
|
958
935
|
}
|
|
959
|
-
|
|
960
|
-
function getQueryParamString(queryParams): string {
|
|
961
|
-
const queryParamStrings: string[] = [];
|
|
962
|
-
for (const key of Object.keys(queryParams)) {
|
|
963
|
-
queryParamStrings.push(`${key}=${queryParams[key]}`);
|
|
964
|
-
}
|
|
965
|
-
switch (queryParamStrings.length) {
|
|
966
|
-
case 0:
|
|
967
|
-
return '';
|
|
968
|
-
case 1:
|
|
969
|
-
return `?${queryParamStrings[0]}`;
|
|
970
|
-
default:
|
|
971
|
-
return `?${queryParamStrings.join('&')}`;
|
|
972
|
-
}
|
|
973
|
-
}
|