@loaders.gl/tiles 3.3.1 → 3.3.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.
@@ -1,6 +1,7 @@
1
1
  import { Matrix4 } from '@math.gl/core';
2
2
  import type { Tileset3D } from './tileset-3d';
3
3
  import { FrameState } from './helpers/frame-state';
4
+ import { CartographicBounds } from './helpers/bounding-volume';
4
5
  /**
5
6
  * @param tileset - Tileset3D instance
6
7
  * @param header - tile header - JSON loaded from a dataset
@@ -53,6 +54,7 @@ export declare class Tile3D {
53
54
  private _expireDate;
54
55
  private _expiredContent;
55
56
  private _shouldRefine;
57
+ private _boundingBox?;
56
58
  _distanceToCamera: number;
57
59
  private _centerZDepth;
58
60
  private _screenSpaceError;
@@ -121,6 +123,11 @@ export declare class Tile3D {
121
123
  * Screen space error for LOD selection
122
124
  */
123
125
  get screenSpaceError(): number;
126
+ /**
127
+ * Get bounding box in cartographic coordinates
128
+ * @returns [min, max] each in [longitude, latitude, altitude]
129
+ */
130
+ get boundingBox(): CartographicBounds;
124
131
  /** Get the tile's screen space error. */
125
132
  getScreenSpaceError(frameState: any, useParentLodMetric: any): number;
126
133
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tile-3d.d.ts","sourceRoot":"","sources":["../../src/tileset/tile-3d.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tile-3d.d.ts","sourceRoot":"","sources":["../../src/tileset/tile-3d.ts"],"names":[],"mappings":"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"}
@@ -171,6 +171,16 @@ class Tile3D {
171
171
  get screenSpaceError() {
172
172
  return this._screenSpaceError;
173
173
  }
174
+ /**
175
+ * Get bounding box in cartographic coordinates
176
+ * @returns [min, max] each in [longitude, latitude, altitude]
177
+ */
178
+ get boundingBox() {
179
+ if (!this._boundingBox) {
180
+ this._boundingBox = (0, bounding_volume_1.getCartographicBounds)(this.header.boundingVolume, this.boundingVolume);
181
+ }
182
+ return this._boundingBox;
183
+ }
174
184
  /** Get the tile's screen space error. */
175
185
  getScreenSpaceError(frameState, useParentLodMetric) {
176
186
  switch (this.tileset.type) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/tiles",
3
- "version": "3.3.1",
3
+ "version": "3.3.3",
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.3.1",
37
- "@loaders.gl/math": "3.3.1",
36
+ "@loaders.gl/loader-utils": "3.3.3",
37
+ "@loaders.gl/math": "3.3.3",
38
38
  "@math.gl/core": "^3.5.1",
39
39
  "@math.gl/culling": "^3.5.1",
40
40
  "@math.gl/geospatial": "^3.5.1",
@@ -44,5 +44,5 @@
44
44
  "peerDependencies": {
45
45
  "@loaders.gl/core": "^3.2.0"
46
46
  },
47
- "gitHead": "51632b5948e496a4b75e970030ad7579650c129d"
47
+ "gitHead": "44f4e272d8216f226a332eaae81e832e44c7e474"
48
48
  }
@@ -14,6 +14,7 @@ function defined(x) {
14
14
  }
15
15
 
16
16
  // const scratchMatrix = new Matrix3();
17
+ const scratchPoint = new Vector3();
17
18
  const scratchScale = new Vector3();
18
19
  const scratchNorthWest = new Vector3();
19
20
  const scratchSouthEast = new Vector3();
@@ -68,6 +69,43 @@ export function createBoundingVolume(boundingVolumeHeader, transform, result) {
68
69
  throw new Error('3D Tile: boundingVolume must contain a sphere, region, or box');
69
70
  }
70
71
 
72
+ /** [min, max] each in [longitude, latitude, altitude] */
73
+ export type CartographicBounds = [min: number[], max: number[]];
74
+
75
+ /**
76
+ * Calculate the cartographic bounding box the tile's bounding volume.
77
+ * @param {Object} boundingVolumeHeader The tile's bounding volume header.
78
+ * @param {BoundingVolume} boundingVolume The bounding volume.
79
+ * @returns {CartographicBounds}
80
+ */
81
+ export function getCartographicBounds(
82
+ boundingVolumeHeader,
83
+ boundingVolume: OrientedBoundingBox | BoundingSphere
84
+ ): CartographicBounds {
85
+ // boundingVolume schema:
86
+ // https://github.com/AnalyticalGraphicsInc/3d-tiles/blob/master/specification/schema/boundingVolume.schema.json
87
+ if (boundingVolumeHeader.box) {
88
+ return orientedBoundingBoxToCartographicBounds(boundingVolume as OrientedBoundingBox);
89
+ }
90
+ if (boundingVolumeHeader.region) {
91
+ // [west, south, east, north, minimum height, maximum height]
92
+ // Latitudes and longitudes are in the WGS 84 datum as defined in EPSG 4979 and are in radians.
93
+ // Heights are in meters above (or below) the WGS 84 ellipsoid.
94
+ const [west, south, east, north, minHeight, maxHeight] = boundingVolumeHeader.region;
95
+
96
+ return [
97
+ [degrees(west), degrees(south), minHeight],
98
+ [degrees(east), degrees(north), maxHeight]
99
+ ];
100
+ }
101
+
102
+ if (boundingVolumeHeader.sphere) {
103
+ return boundingSphereToCartographicBounds(boundingVolume as BoundingSphere);
104
+ }
105
+
106
+ throw new Error('Unkown boundingVolume type');
107
+ }
108
+
71
109
  function createBox(box, transform, result) {
72
110
  // https://math.gl/modules/culling/docs/api-reference/oriented-bounding-box
73
111
  // 1. A half-axes based representation.
@@ -197,3 +235,101 @@ function createSphere(sphere, transform, result?) {
197
235
 
198
236
  return new BoundingSphere(center, radius);
199
237
  }
238
+
239
+ /**
240
+ * Convert a bounding volume defined by OrientedBoundingBox to cartographic bounds
241
+ * @returns {CartographicBounds}
242
+ */
243
+ function orientedBoundingBoxToCartographicBounds(
244
+ boundingVolume: OrientedBoundingBox
245
+ ): CartographicBounds {
246
+ const result = emptyCartographicBounds();
247
+
248
+ const {halfAxes} = boundingVolume as OrientedBoundingBox;
249
+ const xAxis = new Vector3(halfAxes.getColumn(0));
250
+ const yAxis = new Vector3(halfAxes.getColumn(1));
251
+ const zAxis = new Vector3(halfAxes.getColumn(2));
252
+
253
+ // Test all 8 corners of the box
254
+ for (let x = 0; x < 2; x++) {
255
+ for (let y = 0; y < 2; y++) {
256
+ for (let z = 0; z < 2; z++) {
257
+ scratchPoint.copy(boundingVolume.center);
258
+ scratchPoint.add(xAxis);
259
+ scratchPoint.add(yAxis);
260
+ scratchPoint.add(zAxis);
261
+
262
+ addToCartographicBounds(result, scratchPoint);
263
+ zAxis.negate();
264
+ }
265
+ yAxis.negate();
266
+ }
267
+ xAxis.negate();
268
+ }
269
+ return result;
270
+ }
271
+
272
+ /**
273
+ * Convert a bounding volume defined by BoundingSphere to cartographic bounds
274
+ * @returns {CartographicBounds}
275
+ */
276
+ function boundingSphereToCartographicBounds(boundingVolume: BoundingSphere): CartographicBounds {
277
+ const result = emptyCartographicBounds();
278
+
279
+ const {center, radius} = boundingVolume as BoundingSphere;
280
+ const point = Ellipsoid.WGS84.scaleToGeodeticSurface(center, scratchPoint);
281
+
282
+ let zAxis: Vector3;
283
+ if (point) {
284
+ zAxis = Ellipsoid.WGS84.geodeticSurfaceNormal(point) as Vector3;
285
+ } else {
286
+ zAxis = new Vector3(0, 0, 1);
287
+ }
288
+ let xAxis = new Vector3(zAxis[2], -zAxis[1], 0);
289
+ if (xAxis.len() > 0) {
290
+ xAxis.normalize();
291
+ } else {
292
+ xAxis = new Vector3(0, 1, 0);
293
+ }
294
+ const yAxis = xAxis.clone().cross(zAxis);
295
+
296
+ // Test 6 end points of the 3 axes
297
+ for (const axis of [xAxis, yAxis, zAxis]) {
298
+ scratchScale.copy(axis).scale(radius);
299
+ for (let dir = 0; dir < 2; dir++) {
300
+ scratchPoint.copy(center);
301
+ scratchPoint.add(scratchScale);
302
+ addToCartographicBounds(result, scratchPoint);
303
+ // Flip the axis
304
+ scratchScale.negate();
305
+ }
306
+ }
307
+ return result;
308
+ }
309
+
310
+ /**
311
+ * Create a new cartographic bounds that contains no points
312
+ * @returns {CartographicBounds}
313
+ */
314
+ function emptyCartographicBounds(): CartographicBounds {
315
+ return [
316
+ [Infinity, Infinity, Infinity],
317
+ [-Infinity, -Infinity, -Infinity]
318
+ ];
319
+ }
320
+
321
+ /**
322
+ * Add a point to the target cartographic bounds
323
+ * @param {CartographicBounds} target
324
+ * @param {Vector3} cartesian coordinates of the point to add
325
+ */
326
+ function addToCartographicBounds(target: CartographicBounds, cartesian: Readonly<Vector3>) {
327
+ Ellipsoid.WGS84.cartesianToCartographic(cartesian, scratchPoint);
328
+ target[0][0] = Math.min(target[0][0], scratchPoint[0]);
329
+ target[0][1] = Math.min(target[0][1], scratchPoint[1]);
330
+ target[0][2] = Math.min(target[0][2], scratchPoint[2]);
331
+
332
+ target[1][0] = Math.max(target[1][0], scratchPoint[0]);
333
+ target[1][1] = Math.max(target[1][1], scratchPoint[1]);
334
+ target[1][2] = Math.max(target[1][2], scratchPoint[2]);
335
+ }
@@ -13,7 +13,11 @@ import type {Tileset3D} from './tileset-3d';
13
13
  import {TILE_REFINEMENT, TILE_CONTENT_STATE, TILESET_TYPE} from '../constants';
14
14
 
15
15
  import {FrameState} from './helpers/frame-state';
16
- import {createBoundingVolume} from './helpers/bounding-volume';
16
+ import {
17
+ createBoundingVolume,
18
+ getCartographicBounds,
19
+ CartographicBounds
20
+ } from './helpers/bounding-volume';
17
21
  import {getTiles3DScreenSpaceError} from './helpers/tiles-3d-lod';
18
22
  import {getProjectedRadius} from './helpers/i3s-lod';
19
23
  import {get3dTilesOptions} from './helpers/3d-tiles-options';
@@ -86,6 +90,8 @@ export class Tile3D {
86
90
  // @ts-ignore
87
91
  private _shouldRefine: boolean;
88
92
 
93
+ private _boundingBox?: CartographicBounds;
94
+
89
95
  // Members this are updated every frame for tree traversal and rendering optimizations:
90
96
  public _distanceToCamera: number;
91
97
  // @ts-ignore
@@ -303,6 +309,17 @@ export class Tile3D {
303
309
  return this._screenSpaceError;
304
310
  }
305
311
 
312
+ /**
313
+ * Get bounding box in cartographic coordinates
314
+ * @returns [min, max] each in [longitude, latitude, altitude]
315
+ */
316
+ get boundingBox(): CartographicBounds {
317
+ if (!this._boundingBox) {
318
+ this._boundingBox = getCartographicBounds(this.header.boundingVolume, this.boundingVolume);
319
+ }
320
+ return this._boundingBox;
321
+ }
322
+
306
323
  /** Get the tile's screen space error. */
307
324
  getScreenSpaceError(frameState, useParentLodMetric) {
308
325
  switch (this.tileset.type) {