@loaders.gl/tiles 3.2.0-alpha.1 → 3.2.0-alpha.2
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/dist.min.js +102 -16
- package/dist/es5/tileset/helpers/zoom.js +32 -0
- package/dist/es5/tileset/helpers/zoom.js.map +1 -1
- package/dist/es5/tileset/tileset-3d.js +119 -41
- package/dist/es5/tileset/tileset-3d.js.map +1 -1
- package/dist/es5/tileset/traversers/i3s-frame-counter.js +45 -0
- package/dist/es5/tileset/traversers/i3s-frame-counter.js.map +1 -0
- package/dist/es5/tileset/traversers/i3s-tile-manager.js +17 -0
- package/dist/es5/tileset/traversers/i3s-tile-manager.js.map +1 -1
- package/dist/es5/tileset/traversers/i3s-tileset-traverser.js +6 -1
- package/dist/es5/tileset/traversers/i3s-tileset-traverser.js.map +1 -1
- package/dist/es5/tileset/traversers/tileset-traverser.js +13 -1
- package/dist/es5/tileset/traversers/tileset-traverser.js.map +1 -1
- package/dist/esm/tileset/helpers/zoom.js +17 -0
- package/dist/esm/tileset/helpers/zoom.js.map +1 -1
- package/dist/esm/tileset/tileset-3d.js +60 -14
- package/dist/esm/tileset/tileset-3d.js.map +1 -1
- package/dist/esm/tileset/traversers/i3s-frame-counter.js +23 -0
- package/dist/esm/tileset/traversers/i3s-frame-counter.js.map +1 -0
- package/dist/esm/tileset/traversers/i3s-tile-manager.js +15 -0
- package/dist/esm/tileset/traversers/i3s-tile-manager.js.map +1 -1
- package/dist/esm/tileset/traversers/i3s-tileset-traverser.js +5 -1
- package/dist/esm/tileset/traversers/i3s-tileset-traverser.js.map +1 -1
- package/dist/esm/tileset/traversers/tileset-traverser.js +14 -1
- package/dist/esm/tileset/traversers/tileset-traverser.js.map +1 -1
- package/dist/tileset/helpers/zoom.d.ts +35 -0
- package/dist/tileset/helpers/zoom.d.ts.map +1 -1
- package/dist/tileset/helpers/zoom.js +41 -1
- package/dist/tileset/tileset-3d.d.ts +17 -3
- package/dist/tileset/tileset-3d.d.ts.map +1 -1
- package/dist/tileset/tileset-3d.js +60 -19
- package/dist/tileset/traversers/i3s-frame-counter.d.ts +24 -0
- package/dist/tileset/traversers/i3s-frame-counter.d.ts.map +1 -0
- package/dist/tileset/traversers/i3s-frame-counter.js +37 -0
- package/dist/tileset/traversers/i3s-tile-manager.d.ts +10 -2
- package/dist/tileset/traversers/i3s-tile-manager.d.ts.map +1 -1
- package/dist/tileset/traversers/i3s-tile-manager.js +24 -0
- package/dist/tileset/traversers/i3s-tileset-traverser.d.ts +9 -2
- package/dist/tileset/traversers/i3s-tileset-traverser.d.ts.map +1 -1
- package/dist/tileset/traversers/i3s-tileset-traverser.js +10 -1
- package/dist/tileset/traversers/tileset-traverser.d.ts +5 -1
- package/dist/tileset/traversers/tileset-traverser.d.ts.map +1 -1
- package/dist/tileset/traversers/tileset-traverser.js +10 -1
- package/package.json +5 -5
- package/src/tileset/helpers/zoom.ts +64 -0
- package/src/tileset/tileset-3d.ts +72 -19
- package/src/tileset/traversers/i3s-frame-counter.ts +35 -0
- package/src/tileset/traversers/i3s-tile-manager.ts +26 -2
- package/src/tileset/traversers/i3s-tileset-traverser.ts +16 -3
- package/src/tileset/traversers/tileset-traverser.ts +13 -2
|
@@ -13,6 +13,14 @@ class I3STilesetTraverser extends tileset_traverser_1.default {
|
|
|
13
13
|
super(options);
|
|
14
14
|
this._tileManager = new i3s_tile_manager_1.default();
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Check if there are no penging tile header requests,
|
|
18
|
+
* that means the traversal is finished and we can call
|
|
19
|
+
* following-up callbacks.
|
|
20
|
+
*/
|
|
21
|
+
get traversalFinished() {
|
|
22
|
+
return !this._tileManager.hasPendingTiles(this._frameNumber || 0);
|
|
23
|
+
}
|
|
16
24
|
shouldRefine(tile, frameState) {
|
|
17
25
|
tile._lodJudge = (0, i3s_lod_1.getLodStatus)(tile, frameState);
|
|
18
26
|
return tile._lodJudge === 'DIG';
|
|
@@ -77,7 +85,8 @@ class I3STilesetTraverser extends tileset_traverser_1.default {
|
|
|
77
85
|
const frameState = this._tileManager.find(childTile.id).frameState;
|
|
78
86
|
this.updateTile(childTile, frameState);
|
|
79
87
|
// after tile fetched, resume traversal if still in current update/traversal frame
|
|
80
|
-
if (this._frameNumber === frameState.frameNumber
|
|
88
|
+
if (this._frameNumber === frameState.frameNumber &&
|
|
89
|
+
(this.traversalFinished || new Date().getTime() - this.lastUpdate > this.updateDebounceTime)) {
|
|
81
90
|
this.executeTraversal(childTile, frameState);
|
|
82
91
|
}
|
|
83
92
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ManagedArray from '../../utils/managed-array';
|
|
2
|
+
import { FrameState } from '../helpers/frame-state';
|
|
2
3
|
export declare type TilesetTraverserProps = {
|
|
3
4
|
loadSiblings?: boolean;
|
|
4
5
|
skipLevelOfDetail?: boolean;
|
|
@@ -27,13 +28,16 @@ export default class TilesetTraverser {
|
|
|
27
28
|
requestedTiles: object;
|
|
28
29
|
selectedTiles: object;
|
|
29
30
|
emptyTiles: object;
|
|
31
|
+
protected lastUpdate: number;
|
|
32
|
+
protected readonly updateDebounceTime = 1000;
|
|
30
33
|
protected _traversalStack: ManagedArray;
|
|
31
34
|
protected _emptyTraversalStack: ManagedArray;
|
|
32
35
|
protected _frameNumber: number | null;
|
|
36
|
+
protected get traversalFinished(): boolean;
|
|
33
37
|
constructor(options: TilesetTraverserProps);
|
|
34
38
|
traverse(root: any, frameState: any, options: any): void;
|
|
35
39
|
reset(): void;
|
|
36
|
-
executeTraversal(root: any, frameState:
|
|
40
|
+
executeTraversal(root: any, frameState: FrameState): void;
|
|
37
41
|
updateChildTiles(tile: any, frameState: any): boolean;
|
|
38
42
|
updateAndPushChildren(tile: any, frameState: any, stack: any, depth: any): boolean;
|
|
39
43
|
updateTile(tile: any, frameState: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tileset-traverser.d.ts","sourceRoot":"","sources":["../../../src/tileset/traversers/tileset-traverser.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"tileset-traverser.d.ts","sourceRoot":"","sources":["../../../src/tileset/traversers/tileset-traverser.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,2BAA2B,CAAC;AAErD,OAAO,EAAC,UAAU,EAAC,MAAM,wBAAwB,CAAC;AAElD,oBAAY,qBAAqB,GAAG;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,UAAU,KAAA,KAAK,GAAG,CAAC;IACrC,qBAAqB,CAAC,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,oBAAY,KAAK,GAAG;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,CAAC,UAAU,KAAA,KAAK,GAAG,CAAC;IACpC,qBAAqB,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,gBAAgB;IACnC,OAAO,EAAE,KAAK,CAAC;IAEf,IAAI,EAAE,GAAG,CAAC;IACV,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAEnB,SAAS,CAAC,UAAU,EAAE,MAAM,CAAwB;IACpD,SAAS,CAAC,QAAQ,CAAC,kBAAkB,QAAQ;IAC7C,SAAS,CAAC,eAAe,EAAE,YAAY,CAAC;IACxC,SAAS,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC7C,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtC,SAAS,KAAK,iBAAiB,IAAI,OAAO,CAEzC;gBAGW,OAAO,EAAE,qBAAqB;IAuB1C,QAAQ,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA,EAAE,OAAO,KAAA;IAclC,KAAK;IAgBL,gBAAgB,CAAC,IAAI,KAAA,EAAE,UAAU,EAAE,UAAU;IAmE7C,gBAAgB,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IASjC,qBAAqB,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA,EAAE,KAAK,KAAA,EAAE,KAAK,KAAA;IAuDpD,UAAU,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IAK3B,UAAU,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IAS3B,QAAQ,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IASzB,SAAS,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IAQ1B,WAAW,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA,EAAE,eAAe,UAAQ,EAAE,gBAAgB,UAAQ;IAmB/E,cAAc,CAAC,IAAI,KAAA;IAMnB,gBAAgB,CAAC,IAAI,KAAA;IAOrB,YAAY,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA,EAAE,eAAe,KAAA;IAS9C,oBAAoB,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IAiBrC,uBAAuB,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA;IAI5B,kBAAkB,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;IAWnC,qBAAqB,CAAC,IAAI,KAAA,EAAE,UAAU,KAAA;CAqCvC"}
|
|
@@ -18,6 +18,8 @@ exports.DEFAULT_PROPS = {
|
|
|
18
18
|
class TilesetTraverser {
|
|
19
19
|
// TODO nested props
|
|
20
20
|
constructor(options) {
|
|
21
|
+
this.lastUpdate = new Date().getTime();
|
|
22
|
+
this.updateDebounceTime = 1000;
|
|
21
23
|
this.options = { ...exports.DEFAULT_PROPS, ...options };
|
|
22
24
|
// TRAVERSAL
|
|
23
25
|
// temporary storage to hold the traversed tiles during a traversal
|
|
@@ -35,6 +37,9 @@ class TilesetTraverser {
|
|
|
35
37
|
// tiles does not have render content
|
|
36
38
|
this.emptyTiles = {};
|
|
37
39
|
}
|
|
40
|
+
get traversalFinished() {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
38
43
|
// tiles should be visible
|
|
39
44
|
traverse(root, frameState, options) {
|
|
40
45
|
this.root = root; // for root screen space error
|
|
@@ -110,7 +115,11 @@ class TilesetTraverser {
|
|
|
110
115
|
// 4. update tile refine prop and parent refinement status to trickle down to the descendants
|
|
111
116
|
tile._shouldRefine = shouldRefine && parentRefines;
|
|
112
117
|
}
|
|
113
|
-
|
|
118
|
+
const newTime = new Date().getTime();
|
|
119
|
+
if (this.traversalFinished || newTime - this.lastUpdate > this.updateDebounceTime) {
|
|
120
|
+
this.lastUpdate = newTime;
|
|
121
|
+
this.options.onTraversalEnd(frameState);
|
|
122
|
+
}
|
|
114
123
|
}
|
|
115
124
|
updateChildTiles(tile, frameState) {
|
|
116
125
|
const children = tile.children;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/tiles",
|
|
3
|
-
"version": "3.2.0-alpha.
|
|
3
|
+
"version": "3.2.0-alpha.2",
|
|
4
4
|
"description": "Common components for different tiles loaders.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"build-bundle": "esbuild src/bundle.ts --bundle --outfile=dist/dist.min.js"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@loaders.gl/loader-utils": "3.2.0-alpha.
|
|
37
|
-
"@loaders.gl/math": "3.2.0-alpha.
|
|
36
|
+
"@loaders.gl/loader-utils": "3.2.0-alpha.2",
|
|
37
|
+
"@loaders.gl/math": "3.2.0-alpha.2",
|
|
38
38
|
"@math.gl/core": "^3.5.1",
|
|
39
39
|
"@math.gl/culling": "^3.5.1",
|
|
40
40
|
"@math.gl/geospatial": "^3.5.1",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@probe.gl/stats": "^3.5.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@loaders.gl/core": "
|
|
45
|
+
"@loaders.gl/core": "3.2.0-alpha.1"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "52a602739cbfce60fc314f474efc984d199dff78"
|
|
48
48
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {Vector3} from '@math.gl/core';
|
|
2
2
|
import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
|
|
3
|
+
import {Ellipsoid} from '@math.gl/geospatial';
|
|
3
4
|
import {BoundingRectangle} from '../../types';
|
|
4
5
|
|
|
5
6
|
const WGS84_RADIUS_X = 6378137.0;
|
|
@@ -42,6 +43,69 @@ export function getZoomFromBoundingVolume(
|
|
|
42
43
|
return 1;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Calculate initial zoom for the tileset from 3D `fullExtent` defined in
|
|
48
|
+
* the tileset metadata
|
|
49
|
+
* @param fullExtent - 3D extent of the tileset
|
|
50
|
+
* @param fullExtent.xmin - minimal longitude in decimal degrees
|
|
51
|
+
* @param fullExtent.xmax - maximal longitude in decimal degrees
|
|
52
|
+
* @param fullExtent.ymin - minimal latitude in decimal degrees
|
|
53
|
+
* @param fullExtent.ymax - maximal latitude in decimal degrees
|
|
54
|
+
* @param fullExtent.zmin - minimal elevation in meters
|
|
55
|
+
* @param fullExtent.zmax - maximal elevation in meters
|
|
56
|
+
* @param cartorgraphicCenter - tileset center in cartographic coordinate system
|
|
57
|
+
* @param cartesianCenter - tileset center in cartesian coordinate system
|
|
58
|
+
* @returns - initial zoom for the tileset
|
|
59
|
+
*/
|
|
60
|
+
export function getZoomFromFullExtent(
|
|
61
|
+
fullExtent: {
|
|
62
|
+
xmin: number;
|
|
63
|
+
xmax: number;
|
|
64
|
+
ymin: number;
|
|
65
|
+
ymax: number;
|
|
66
|
+
zmin: number;
|
|
67
|
+
zmax: number;
|
|
68
|
+
},
|
|
69
|
+
cartorgraphicCenter: Vector3,
|
|
70
|
+
cartesianCenter: Vector3
|
|
71
|
+
) {
|
|
72
|
+
const extentVertex = Ellipsoid.WGS84.cartographicToCartesian(
|
|
73
|
+
[fullExtent.xmax, fullExtent.ymax, fullExtent.zmax],
|
|
74
|
+
new Vector3()
|
|
75
|
+
);
|
|
76
|
+
const extentSize = Math.sqrt(
|
|
77
|
+
Math.pow(extentVertex[0] - cartesianCenter[0], 2) +
|
|
78
|
+
Math.pow(extentVertex[1] - cartesianCenter[1], 2) +
|
|
79
|
+
Math.pow(extentVertex[2] - cartesianCenter[2], 2)
|
|
80
|
+
);
|
|
81
|
+
return Math.log2(WGS84_RADIUS_Z / (extentSize + cartorgraphicCenter[2]));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Calculate initial zoom for the tileset from 2D `extent` defined in
|
|
86
|
+
* the tileset metadata
|
|
87
|
+
* @param extent - 2D extent of the tileset. It is array of 4 elements [xmin, ymin, xmax, ymax]
|
|
88
|
+
* @param extent[0] - minimal longitude in decimal degrees
|
|
89
|
+
* @param extent[1] - minimal latitude in decimal degrees
|
|
90
|
+
* @param extent[2] - maximal longitude in decimal degrees
|
|
91
|
+
* @param extent[3] - maximal latitude in decimal degrees
|
|
92
|
+
* @param cartorgraphicCenter - tileset center in cartographic coordinate system
|
|
93
|
+
* @param cartesianCenter - tileset center in cartesian coordinate system
|
|
94
|
+
* @returns - initial zoom for the tileset
|
|
95
|
+
*/
|
|
96
|
+
export function getZoomFromExtent(
|
|
97
|
+
extent: [number, number, number, number],
|
|
98
|
+
cartorgraphicCenter: Vector3,
|
|
99
|
+
cartesianCenter: Vector3
|
|
100
|
+
) {
|
|
101
|
+
const [xmin, ymin, xmax, ymax] = extent;
|
|
102
|
+
return getZoomFromFullExtent(
|
|
103
|
+
{xmin, xmax, ymin, ymax, zmin: 0, zmax: 0},
|
|
104
|
+
cartorgraphicCenter,
|
|
105
|
+
cartesianCenter
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
45
109
|
function getObbSize(halfAxes) {
|
|
46
110
|
halfAxes.getColumn(0, scratchVector);
|
|
47
111
|
const axeY = halfAxes.getColumn(1);
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
import TilesetCache from './tileset-cache';
|
|
50
50
|
import {calculateTransformProps} from './helpers/transform-utils';
|
|
51
51
|
import {FrameState, getFrameState, limitSelectedTiles} from './helpers/frame-state';
|
|
52
|
-
import {getZoomFromBoundingVolume} from './helpers/zoom';
|
|
52
|
+
import {getZoomFromBoundingVolume, getZoomFromExtent, getZoomFromFullExtent} from './helpers/zoom';
|
|
53
53
|
import Tile3D from './tile-3d';
|
|
54
54
|
import Tileset3DTraverser from './traversers/tileset-3d-traverser';
|
|
55
55
|
import TilesetTraverser from './traversers/tileset-traverser';
|
|
@@ -157,7 +157,6 @@ const DEFAULT_PROPS: Props = {
|
|
|
157
157
|
// View distance scale modifier
|
|
158
158
|
viewDistanceScale: 1.0,
|
|
159
159
|
|
|
160
|
-
// TODO CESIUM
|
|
161
160
|
// The maximum screen space error used to drive level of detail refinement.
|
|
162
161
|
maximumScreenSpaceError: 8,
|
|
163
162
|
|
|
@@ -216,6 +215,7 @@ export default class Tileset3D {
|
|
|
216
215
|
geometricError: number;
|
|
217
216
|
selectedTiles: Tile3D[];
|
|
218
217
|
private updatePromise: Promise<number> | null = null;
|
|
218
|
+
tilesetInitializationPromise: Promise<void>;
|
|
219
219
|
|
|
220
220
|
cartographicCenter: Vector3 | null;
|
|
221
221
|
cartesianCenter: Vector3 | null;
|
|
@@ -333,7 +333,7 @@ export default class Tileset3D {
|
|
|
333
333
|
this.credits = {};
|
|
334
334
|
this.description = this.options.description || '';
|
|
335
335
|
|
|
336
|
-
this._initializeTileSet(json);
|
|
336
|
+
this.tilesetInitializationPromise = this._initializeTileSet(json);
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
/** Release resources */
|
|
@@ -394,12 +394,15 @@ export default class Tileset3D {
|
|
|
394
394
|
* @deprecated
|
|
395
395
|
*/
|
|
396
396
|
update(viewports: any[] | null = null) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
398
|
+
this.tilesetInitializationPromise.then(() => {
|
|
399
|
+
if (!viewports && this.lastUpdatedVieports) {
|
|
400
|
+
viewports = this.lastUpdatedVieports;
|
|
401
|
+
} else {
|
|
402
|
+
this.lastUpdatedVieports = viewports;
|
|
403
|
+
}
|
|
404
|
+
this.doUpdate(viewports);
|
|
405
|
+
});
|
|
403
406
|
}
|
|
404
407
|
|
|
405
408
|
/**
|
|
@@ -409,6 +412,7 @@ export default class Tileset3D {
|
|
|
409
412
|
* @returns Promise of new frameNumber
|
|
410
413
|
*/
|
|
411
414
|
async selectTiles(viewports: any[] | null = null): Promise<number> {
|
|
415
|
+
await this.tilesetInitializationPromise;
|
|
412
416
|
if (viewports) {
|
|
413
417
|
this.lastUpdatedVieports = viewports;
|
|
414
418
|
}
|
|
@@ -589,29 +593,78 @@ export default class Tileset3D {
|
|
|
589
593
|
this.stats.get(POINTS_COUNT).count = pointsRenderable;
|
|
590
594
|
}
|
|
591
595
|
|
|
592
|
-
_initializeTileSet(tilesetJson) {
|
|
596
|
+
async _initializeTileSet(tilesetJson) {
|
|
597
|
+
if (this.type === TILESET_TYPE.I3S) {
|
|
598
|
+
this.calculateViewPropsI3S();
|
|
599
|
+
tilesetJson.root = await tilesetJson.root;
|
|
600
|
+
}
|
|
593
601
|
this.root = this._initializeTileHeaders(tilesetJson, null);
|
|
594
602
|
|
|
595
|
-
// TODO CESIUM Specific
|
|
596
603
|
if (this.type === TILESET_TYPE.TILES3D) {
|
|
597
|
-
this.
|
|
604
|
+
this._initializeTiles3DTileset(tilesetJson);
|
|
605
|
+
this.calculateViewPropsTiles3D();
|
|
598
606
|
}
|
|
599
607
|
|
|
600
608
|
if (this.type === TILESET_TYPE.I3S) {
|
|
601
609
|
this._initializeI3STileset();
|
|
602
610
|
}
|
|
603
|
-
// Calculate cartographicCenter & zoom props to help apps center view on tileset
|
|
604
|
-
this._calculateViewProps();
|
|
605
611
|
}
|
|
606
612
|
|
|
607
|
-
|
|
608
|
-
|
|
613
|
+
/**
|
|
614
|
+
* Called during initialize Tileset to initialize the tileset's cartographic center (longitude, latitude) and zoom.
|
|
615
|
+
* These metrics help apps center view on tileset
|
|
616
|
+
* For I3S there is extent (<1.8 version) or fullExtent (>=1.8 version) to calculate view props
|
|
617
|
+
* @returns
|
|
618
|
+
*/
|
|
619
|
+
private calculateViewPropsI3S() {
|
|
620
|
+
// for I3S 1.8 try to calculate with fullExtent
|
|
621
|
+
const fullExtent = this.tileset.fullExtent;
|
|
622
|
+
if (fullExtent) {
|
|
623
|
+
const {xmin, xmax, ymin, ymax, zmin, zmax} = fullExtent;
|
|
624
|
+
this.cartographicCenter = new Vector3(
|
|
625
|
+
xmin + (xmax - xmin) / 2,
|
|
626
|
+
ymin + (ymax - ymin) / 2,
|
|
627
|
+
zmin + (zmax - zmin) / 2
|
|
628
|
+
);
|
|
629
|
+
this.cartesianCenter = Ellipsoid.WGS84.cartographicToCartesian(
|
|
630
|
+
this.cartographicCenter,
|
|
631
|
+
new Vector3()
|
|
632
|
+
);
|
|
633
|
+
this.zoom = getZoomFromFullExtent(fullExtent, this.cartographicCenter, this.cartesianCenter);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
// for I3S 1.6-1.7 try to calculate with extent
|
|
637
|
+
const extent = this.tileset.store?.extent;
|
|
638
|
+
if (extent) {
|
|
639
|
+
const [xmin, ymin, xmax, ymax] = extent;
|
|
640
|
+
this.cartographicCenter = new Vector3(xmin + (xmax - xmin) / 2, ymin + (ymax - ymin) / 2, 0);
|
|
641
|
+
this.cartesianCenter = Ellipsoid.WGS84.cartographicToCartesian(
|
|
642
|
+
this.cartographicCenter,
|
|
643
|
+
new Vector3()
|
|
644
|
+
);
|
|
645
|
+
this.zoom = getZoomFromExtent(extent, this.cartographicCenter, this.cartesianCenter);
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
// eslint-disable-next-line no-console
|
|
649
|
+
console.warn('Extent is not defined in the tileset header');
|
|
650
|
+
this.cartographicCenter = new Vector3();
|
|
651
|
+
this.zoom = 1;
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Called during initialize Tileset to initialize the tileset's cartographic center (longitude, latitude) and zoom.
|
|
657
|
+
* These metrics help apps center view on tileset.
|
|
658
|
+
* For 3DTiles the root tile data is used to calculate view props.
|
|
659
|
+
* @returns
|
|
660
|
+
*/
|
|
661
|
+
private calculateViewPropsTiles3D() {
|
|
609
662
|
const root = this.root as Tile3D;
|
|
610
663
|
assert(root);
|
|
611
664
|
const {center} = root.boundingVolume;
|
|
612
665
|
// TODO - handle all cases
|
|
613
666
|
if (!center) {
|
|
614
|
-
// eslint-disable-next-line
|
|
667
|
+
// eslint-disable-next-line no-console
|
|
615
668
|
console.warn('center was not pre-calculated for the root tile');
|
|
616
669
|
this.cartographicCenter = new Vector3();
|
|
617
670
|
this.zoom = 1;
|
|
@@ -649,7 +702,7 @@ export default class Tileset3D {
|
|
|
649
702
|
rootTile.depth = parentTileHeader.depth + 1;
|
|
650
703
|
}
|
|
651
704
|
|
|
652
|
-
//
|
|
705
|
+
// 3DTiles knows the hierarchy beforehand
|
|
653
706
|
if (this.type === TILESET_TYPE.TILES3D) {
|
|
654
707
|
const stack: Tile3D[] = [];
|
|
655
708
|
stack.push(rootTile);
|
|
@@ -808,7 +861,7 @@ export default class Tileset3D {
|
|
|
808
861
|
tile.destroy();
|
|
809
862
|
}
|
|
810
863
|
|
|
811
|
-
|
|
864
|
+
_initializeTiles3DTileset(tilesetJson) {
|
|
812
865
|
this.asset = tilesetJson.asset;
|
|
813
866
|
if (!this.asset) {
|
|
814
867
|
throw new Error('Tileset must have an asset property.');
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counter to register pending tile headers for the particular frameNumber
|
|
3
|
+
* Until all tiles are loaded we won't call `onTraversalEnd` callback
|
|
4
|
+
*/
|
|
5
|
+
export default class I3SPendingTilesRegister {
|
|
6
|
+
private frameNumberMap: Map<number, number> = new Map();
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Register a new pending tile header for the particular frameNumber
|
|
10
|
+
* @param frameNumber
|
|
11
|
+
*/
|
|
12
|
+
register(frameNumber: number) {
|
|
13
|
+
const oldCount = this.frameNumberMap.get(frameNumber) || 0;
|
|
14
|
+
this.frameNumberMap.set(frameNumber, (oldCount || 0) + 1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Deregister a pending tile header for the particular frameNumber
|
|
19
|
+
* @param frameNumber
|
|
20
|
+
*/
|
|
21
|
+
deregister(frameNumber: number) {
|
|
22
|
+
const oldCount = this.frameNumberMap.get(frameNumber) || 1;
|
|
23
|
+
this.frameNumberMap.set(frameNumber, (oldCount || 0) - 1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Check is there are no pending tile headers registered for the particular frameNumber
|
|
28
|
+
* @param frameNumber
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
isZero(frameNumber: number) {
|
|
32
|
+
const count = this.frameNumberMap.get(frameNumber) || 0;
|
|
33
|
+
return count === 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {FrameState} from '../helpers/frame-state';
|
|
2
|
+
import I3SPendingTilesRegister from './i3s-frame-counter';
|
|
3
|
+
|
|
1
4
|
const STATUS = {
|
|
2
5
|
REQUESTED: 'REQUESTED',
|
|
3
6
|
COMPLETED: 'COMPLETED',
|
|
@@ -7,28 +10,40 @@ const STATUS = {
|
|
|
7
10
|
// A helper class to manage tile metadata fetching
|
|
8
11
|
export default class I3STileManager {
|
|
9
12
|
private _statusMap: object;
|
|
13
|
+
private pendingTilesRegister = new I3SPendingTilesRegister();
|
|
10
14
|
|
|
11
15
|
constructor() {
|
|
12
16
|
this._statusMap = {};
|
|
13
17
|
}
|
|
14
18
|
|
|
15
|
-
add(request, key, callback, frameState) {
|
|
19
|
+
add(request, key, callback, frameState: FrameState) {
|
|
16
20
|
if (!this._statusMap[key]) {
|
|
21
|
+
const {frameNumber} = frameState;
|
|
17
22
|
this._statusMap[key] = {request, callback, key, frameState, status: STATUS.REQUESTED};
|
|
23
|
+
// Register pending request for the frameNumber
|
|
24
|
+
this.pendingTilesRegister.register(frameNumber);
|
|
18
25
|
request()
|
|
19
26
|
.then((data) => {
|
|
20
27
|
this._statusMap[key].status = STATUS.COMPLETED;
|
|
28
|
+
// Deregister pending request for the frameNumber
|
|
29
|
+
this.pendingTilesRegister.deregister(frameNumber);
|
|
21
30
|
this._statusMap[key].callback(data, frameState);
|
|
22
31
|
})
|
|
23
32
|
.catch((error) => {
|
|
24
33
|
this._statusMap[key].status = STATUS.ERROR;
|
|
34
|
+
// Deregister pending request for the frameNumber
|
|
35
|
+
this.pendingTilesRegister.deregister(frameNumber);
|
|
25
36
|
callback(error);
|
|
26
37
|
});
|
|
27
38
|
}
|
|
28
39
|
}
|
|
29
40
|
|
|
30
|
-
update(key, frameState) {
|
|
41
|
+
update(key, frameState: FrameState) {
|
|
31
42
|
if (this._statusMap[key]) {
|
|
43
|
+
// Deregister pending request for the old frameNumber
|
|
44
|
+
this.pendingTilesRegister.deregister(this._statusMap[key].frameState.frameNumber);
|
|
45
|
+
// Register pending request for the new frameNumber
|
|
46
|
+
this.pendingTilesRegister.register(frameState.frameNumber);
|
|
32
47
|
this._statusMap[key].frameState = frameState;
|
|
33
48
|
}
|
|
34
49
|
}
|
|
@@ -36,4 +51,13 @@ export default class I3STileManager {
|
|
|
36
51
|
find(key) {
|
|
37
52
|
return this._statusMap[key];
|
|
38
53
|
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check it there are pending tile headers for the particular frameNumber
|
|
57
|
+
* @param frameNumber
|
|
58
|
+
* @returns
|
|
59
|
+
*/
|
|
60
|
+
hasPendingTiles(frameNumber: number): boolean {
|
|
61
|
+
return !this.pendingTilesRegister.isZero(frameNumber);
|
|
62
|
+
}
|
|
39
63
|
}
|
|
@@ -4,21 +4,31 @@ import TilesetTraverser from './tileset-traverser';
|
|
|
4
4
|
import {getLodStatus} from '../helpers/i3s-lod';
|
|
5
5
|
import TileHeader from '../tile-3d';
|
|
6
6
|
import I3STileManager from './i3s-tile-manager';
|
|
7
|
+
import {FrameState} from '../helpers/frame-state';
|
|
7
8
|
|
|
8
9
|
export default class I3STilesetTraverser extends TilesetTraverser {
|
|
9
10
|
private _tileManager: I3STileManager;
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Check if there are no penging tile header requests,
|
|
14
|
+
* that means the traversal is finished and we can call
|
|
15
|
+
* following-up callbacks.
|
|
16
|
+
*/
|
|
17
|
+
protected get traversalFinished(): boolean {
|
|
18
|
+
return !this._tileManager.hasPendingTiles(this._frameNumber || 0);
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
constructor(options) {
|
|
12
22
|
super(options);
|
|
13
23
|
this._tileManager = new I3STileManager();
|
|
14
24
|
}
|
|
15
25
|
|
|
16
|
-
shouldRefine(tile, frameState) {
|
|
26
|
+
shouldRefine(tile, frameState: FrameState) {
|
|
17
27
|
tile._lodJudge = getLodStatus(tile, frameState);
|
|
18
28
|
return tile._lodJudge === 'DIG';
|
|
19
29
|
}
|
|
20
30
|
|
|
21
|
-
updateChildTiles(tile, frameState): boolean {
|
|
31
|
+
updateChildTiles(tile, frameState: FrameState): boolean {
|
|
22
32
|
const children = tile.header.children || [];
|
|
23
33
|
// children which are already fetched and constructed as Tile3D instances
|
|
24
34
|
const childTiles = tile.children;
|
|
@@ -86,7 +96,10 @@ export default class I3STilesetTraverser extends TilesetTraverser {
|
|
|
86
96
|
this.updateTile(childTile, frameState);
|
|
87
97
|
|
|
88
98
|
// after tile fetched, resume traversal if still in current update/traversal frame
|
|
89
|
-
if (
|
|
99
|
+
if (
|
|
100
|
+
this._frameNumber === frameState.frameNumber &&
|
|
101
|
+
(this.traversalFinished || new Date().getTime() - this.lastUpdate > this.updateDebounceTime)
|
|
102
|
+
) {
|
|
90
103
|
this.executeTraversal(childTile, frameState);
|
|
91
104
|
}
|
|
92
105
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ManagedArray from '../../utils/managed-array';
|
|
2
2
|
import {TILE_REFINEMENT} from '../../constants';
|
|
3
|
+
import {FrameState} from '../helpers/frame-state';
|
|
3
4
|
|
|
4
5
|
export type TilesetTraverserProps = {
|
|
5
6
|
loadSiblings?: boolean;
|
|
@@ -38,10 +39,16 @@ export default class TilesetTraverser {
|
|
|
38
39
|
selectedTiles: object;
|
|
39
40
|
emptyTiles: object;
|
|
40
41
|
|
|
42
|
+
protected lastUpdate: number = new Date().getTime();
|
|
43
|
+
protected readonly updateDebounceTime = 1000;
|
|
41
44
|
protected _traversalStack: ManagedArray;
|
|
42
45
|
protected _emptyTraversalStack: ManagedArray;
|
|
43
46
|
protected _frameNumber: number | null;
|
|
44
47
|
|
|
48
|
+
protected get traversalFinished(): boolean {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
45
52
|
// TODO nested props
|
|
46
53
|
constructor(options: TilesetTraverserProps) {
|
|
47
54
|
this.options = {...DEFAULT_PROPS, ...options};
|
|
@@ -96,7 +103,7 @@ export default class TilesetTraverser {
|
|
|
96
103
|
// all other tiles are part of the skip traversal. The skip traversal allows for skipping levels of the tree
|
|
97
104
|
// and rendering children and parent tiles simultaneously.
|
|
98
105
|
/* eslint-disable-next-line complexity, max-statements */
|
|
99
|
-
executeTraversal(root, frameState) {
|
|
106
|
+
executeTraversal(root, frameState: FrameState) {
|
|
100
107
|
// stack to store traversed tiles, only visible tiles should be added to stack
|
|
101
108
|
// visible: visible in the current view frustum
|
|
102
109
|
const stack = this._traversalStack;
|
|
@@ -156,7 +163,11 @@ export default class TilesetTraverser {
|
|
|
156
163
|
tile._shouldRefine = shouldRefine && parentRefines;
|
|
157
164
|
}
|
|
158
165
|
|
|
159
|
-
|
|
166
|
+
const newTime = new Date().getTime();
|
|
167
|
+
if (this.traversalFinished || newTime - this.lastUpdate > this.updateDebounceTime) {
|
|
168
|
+
this.lastUpdate = newTime;
|
|
169
|
+
this.options.onTraversalEnd(frameState);
|
|
170
|
+
}
|
|
160
171
|
}
|
|
161
172
|
|
|
162
173
|
updateChildTiles(tile, frameState) {
|