@loaders.gl/tiles 5.0.0-alpha.6 → 5.0.0-alpha.7
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.dev.js +5160 -2896
- package/dist/dist.min.js +4 -2
- package/dist/index.cjs +1509 -454
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/spatial/format-spatial-reference.d.ts +1 -0
- package/dist/spatial/format-spatial-reference.d.ts.map +1 -1
- package/dist/spatial/format-spatial-reference.js +104 -46
- package/dist/spatial/format-spatial-reference.js.map +1 -1
- package/dist/spatial/get-spatial-coordinate-frame.d.ts +12 -1
- package/dist/spatial/get-spatial-coordinate-frame.d.ts.map +1 -1
- package/dist/spatial/get-spatial-coordinate-frame.js +105 -24
- package/dist/spatial/get-spatial-coordinate-frame.js.map +1 -1
- 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 +4 -0
- package/dist/spatial/spatial-coordinate-transformer.d.ts.map +1 -1
- package/dist/spatial/spatial-coordinate-transformer.js +89 -12
- package/dist/spatial/spatial-coordinate-transformer.js.map +1 -1
- 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-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 +29 -5
- package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tile-3d.js +147 -18
- package/dist/tileset-3d/common/tile-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.d.ts +14 -0
- package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.js +27 -1
- package/dist/tileset-3d/common/tileset-3d.js.map +1 -1
- 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 +3 -0
- package/dist/tileset-3d/common/tileset-source.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-source.js.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.js +4 -3
- package/dist/tileset-3d/common/tileset-traverser.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts +47 -1
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js +327 -30
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts +32 -0
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js +265 -14
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts +5 -3
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js +7 -4
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.d.ts +7 -3
- package/dist/tileset-3d/helpers/bounding-volume.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.js +19 -61
- package/dist/tileset-3d/helpers/bounding-volume.js.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.d.ts +4 -0
- package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.js +6 -1
- package/dist/tileset-3d/helpers/frame-state.js.map +1 -1
- 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/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/index.ts +13 -1
- package/src/spatial/format-spatial-reference.ts +127 -53
- package/src/spatial/get-spatial-coordinate-frame.ts +126 -31
- package/src/spatial/normalize-crs-identifier.ts +26 -0
- package/src/spatial/spatial-coordinate-transformer.ts +106 -15
- package/src/spatial/tiles-3d-spatial-transformer.ts +206 -0
- package/src/tileset-3d/common/tile-3d-contracts.ts +115 -0
- package/src/tileset-3d/common/tile-3d.ts +172 -18
- package/src/tileset-3d/common/tileset-3d.ts +29 -1
- package/src/tileset-3d/common/tileset-observability.ts +100 -0
- package/src/tileset-3d/common/tileset-source.ts +3 -0
- package/src/tileset-3d/common/tileset-traverser.ts +4 -3
- package/src/tileset-3d/format-3d-tiles/implicit-tiling.ts +481 -34
- package/src/tileset-3d/format-3d-tiles/tiles-3d-source.ts +387 -14
- package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +7 -4
- package/src/tileset-3d/helpers/bounding-volume.ts +29 -62
- package/src/tileset-3d/helpers/frame-state.ts +6 -1
- package/src/tileset-3d/helpers/s2-bounding-volume.ts +35 -0
- package/src/types.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -39,12 +39,14 @@ __export(index_exports, {
|
|
|
39
39
|
TILE_TYPE: () => TILE_TYPE,
|
|
40
40
|
Tile3D: () => Tile3D,
|
|
41
41
|
Tiles3DSource: () => Tiles3DSource,
|
|
42
|
+
Tiles3DSpatialTransformer: () => Tiles3DSpatialTransformer,
|
|
42
43
|
Tileset2D: () => Tileset2D,
|
|
43
44
|
Tileset3D: () => Tileset3D,
|
|
44
45
|
TilesetCache: () => TilesetCache,
|
|
45
46
|
TilesetTraverser: () => TilesetTraverser,
|
|
46
47
|
applyTilesetSpatialOptions: () => applyTilesetSpatialOptions,
|
|
47
48
|
calculateTransformProps: () => calculateTransformProps,
|
|
49
|
+
convertS2BoundingVolumeToOBB: () => convertS2BoundingVolumeToOBB,
|
|
48
50
|
createBoundingVolume: () => createBoundingVolume,
|
|
49
51
|
createImplicitSubtreeReference: () => createImplicitSubtreeReference,
|
|
50
52
|
createTilesetSpatialReference: () => createTilesetSpatialReference,
|
|
@@ -54,6 +56,7 @@ __export(index_exports, {
|
|
|
54
56
|
getI3SSpatialReference: () => getI3SSpatialReference,
|
|
55
57
|
getLodStatus: () => getLodStatus,
|
|
56
58
|
getSpatialCoordinateFrame: () => getSpatialCoordinateFrame,
|
|
59
|
+
getTileset3DTraversalSnapshot: () => getTileset3DTraversalSnapshot,
|
|
57
60
|
isTileset3DSource: () => isTileset3DSource,
|
|
58
61
|
markTilesetSpatialReferenceTransformed: () => markTilesetSpatialReferenceTransformed,
|
|
59
62
|
materializeImplicitSubtree: () => materializeImplicitSubtree,
|
|
@@ -77,6 +80,13 @@ function assert(condition, message) {
|
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
|
|
83
|
+
// ../loader-utils/src/lib/binary-utils/array-buffer-utils.ts
|
|
84
|
+
function sliceArrayBuffer(arrayBuffer, byteOffset, byteLength) {
|
|
85
|
+
const subArray = byteLength !== void 0 ? new Uint8Array(arrayBuffer).subarray(byteOffset, byteOffset + byteLength) : new Uint8Array(arrayBuffer).subarray(byteOffset);
|
|
86
|
+
const arrayCopy = new Uint8Array(subArray);
|
|
87
|
+
return arrayCopy.buffer;
|
|
88
|
+
}
|
|
89
|
+
|
|
80
90
|
// ../loader-utils/src/lib/request-utils/request-scheduler.ts
|
|
81
91
|
var import_stats = require("@probe.gl/stats");
|
|
82
92
|
var STAT_QUEUED_REQUESTS = "Queued Requests";
|
|
@@ -1900,7 +1910,7 @@ function getFrameState(viewport, frameNumber, options = {}) {
|
|
|
1900
1910
|
).normalize();
|
|
1901
1911
|
commonSpacePlanesToWGS84(viewport);
|
|
1902
1912
|
const ViewportClass = viewport.constructor;
|
|
1903
|
-
const { longitude, latitude, width, bearing, zoom } = viewport;
|
|
1913
|
+
const { longitude, latitude, width, bearing, zoom, position } = viewport;
|
|
1904
1914
|
const topDownViewport = new ViewportClass({
|
|
1905
1915
|
longitude,
|
|
1906
1916
|
latitude,
|
|
@@ -1908,6 +1918,7 @@ function getFrameState(viewport, frameNumber, options = {}) {
|
|
|
1908
1918
|
width,
|
|
1909
1919
|
bearing,
|
|
1910
1920
|
zoom,
|
|
1921
|
+
position,
|
|
1911
1922
|
pitch: 0
|
|
1912
1923
|
});
|
|
1913
1924
|
return {
|
|
@@ -2265,30 +2276,32 @@ function calculateTileRequestPriority(parameters) {
|
|
|
2265
2276
|
}
|
|
2266
2277
|
|
|
2267
2278
|
// dist/spatial/spatial-types.js
|
|
2268
|
-
var
|
|
2279
|
+
var import_crs2 = require("@math.gl/crs");
|
|
2269
2280
|
|
|
2270
2281
|
// dist/spatial/get-spatial-coordinate-frame.js
|
|
2271
|
-
var
|
|
2272
|
-
|
|
2282
|
+
var import_crs = require("@math.gl/crs");
|
|
2283
|
+
|
|
2284
|
+
// dist/spatial/normalize-crs-identifier.js
|
|
2285
|
+
var WGS84_GEOGRAPHIC_CRS = "EPSG:4326";
|
|
2286
|
+
var WGS84_GEOCENTRIC_CRS = "EPSG:4978";
|
|
2273
2287
|
function normalizeCrsIdentifier(identifier) {
|
|
2274
2288
|
const normalizedIdentifier = identifier.trim().toUpperCase();
|
|
2275
2289
|
const ogcMatch = normalizedIdentifier.match(/(?:\/DEF\/CRS\/|URN:OGC:DEF:CRS:)([A-Z0-9_-]+)(?:\/|::)(?:[^/:]*[/:])?([A-Z0-9_.-]+)$/);
|
|
2276
2290
|
return ogcMatch ? `${ogcMatch[1]}:${ogcMatch[2]}` : normalizedIdentifier;
|
|
2277
2291
|
}
|
|
2292
|
+
|
|
2293
|
+
// dist/spatial/get-spatial-coordinate-frame.js
|
|
2278
2294
|
function getSpatialCoordinateFrame(definition) {
|
|
2279
2295
|
var _a, _b;
|
|
2280
2296
|
if (typeof definition === "string") {
|
|
2281
|
-
const
|
|
2282
|
-
if (
|
|
2283
|
-
return
|
|
2297
|
+
const representation = (0, import_crs.inferCRSRepresentation)(definition);
|
|
2298
|
+
if (representation === "wkt") {
|
|
2299
|
+
return getWktCoordinateFrame(definition);
|
|
2284
2300
|
}
|
|
2285
|
-
if (
|
|
2286
|
-
return
|
|
2287
|
-
}
|
|
2288
|
-
if (/^(?:GEODCRS|GEODETICCRS)\s*[\[(]/.test(normalized)) {
|
|
2289
|
-
return /CS\s*[\[(]\s*CARTESIAN/.test(normalized) ? "geocentric" : "geographic";
|
|
2301
|
+
if (representation === "proj-string") {
|
|
2302
|
+
return getProjStringCoordinateFrame(definition);
|
|
2290
2303
|
}
|
|
2291
|
-
return "projected";
|
|
2304
|
+
return getKnownCrsIdentifierCoordinateFrame(definition) || "projected";
|
|
2292
2305
|
}
|
|
2293
2306
|
const projJsonDefinition = definition;
|
|
2294
2307
|
if (projJsonDefinition.type === "BoundCRS" && projJsonDefinition.source_crs) {
|
|
@@ -2306,7 +2319,84 @@ function getSpatialCoordinateFrame(definition) {
|
|
|
2306
2319
|
if (String(projJsonDefinition.type).includes("Geodetic")) {
|
|
2307
2320
|
return ((_b = projJsonDefinition.coordinate_system) == null ? void 0 : _b.subtype) === "Cartesian" ? "geocentric" : "geographic";
|
|
2308
2321
|
}
|
|
2309
|
-
return "
|
|
2322
|
+
return "unknown";
|
|
2323
|
+
}
|
|
2324
|
+
function getKnownCrsIdentifierCoordinateFrame(definition) {
|
|
2325
|
+
if (typeof definition !== "string") {
|
|
2326
|
+
return void 0;
|
|
2327
|
+
}
|
|
2328
|
+
const normalized = normalizeCrsIdentifier(definition);
|
|
2329
|
+
if (normalized === WGS84_GEOCENTRIC_CRS) {
|
|
2330
|
+
return "geocentric";
|
|
2331
|
+
}
|
|
2332
|
+
if (normalized === WGS84_GEOGRAPHIC_CRS || normalized === "OGC:CRS84") {
|
|
2333
|
+
return "geographic";
|
|
2334
|
+
}
|
|
2335
|
+
const epsgMatch = /^EPSG:(\d+)$/.exec(normalized);
|
|
2336
|
+
if (!epsgMatch) {
|
|
2337
|
+
return void 0;
|
|
2338
|
+
}
|
|
2339
|
+
const identifier = Number(epsgMatch[1]);
|
|
2340
|
+
if (identifier === 7789) {
|
|
2341
|
+
return "geocentric";
|
|
2342
|
+
}
|
|
2343
|
+
if (identifier === 4490 || identifier === 4979) {
|
|
2344
|
+
return "geographic";
|
|
2345
|
+
}
|
|
2346
|
+
if (identifier === 3857 || identifier >= 32601 && identifier <= 32660 || identifier >= 32701 && identifier <= 32760) {
|
|
2347
|
+
return "projected";
|
|
2348
|
+
}
|
|
2349
|
+
return void 0;
|
|
2350
|
+
}
|
|
2351
|
+
function getWktCoordinateFrame(definition) {
|
|
2352
|
+
let root;
|
|
2353
|
+
try {
|
|
2354
|
+
root = (0, import_crs.parseWKTCRS)(definition).root;
|
|
2355
|
+
} catch {
|
|
2356
|
+
return "unknown";
|
|
2357
|
+
}
|
|
2358
|
+
switch (root.keyword.toUpperCase()) {
|
|
2359
|
+
case "GEOCCS":
|
|
2360
|
+
return "geocentric";
|
|
2361
|
+
case "GEOGCS":
|
|
2362
|
+
case "GEOGCRS":
|
|
2363
|
+
case "GEOGRAPHICCRS":
|
|
2364
|
+
case "GEOGRAPHIC2DCRS":
|
|
2365
|
+
case "GEOGRAPHIC3DCRS":
|
|
2366
|
+
return "geographic";
|
|
2367
|
+
case "PROJCS":
|
|
2368
|
+
case "PROJCRS":
|
|
2369
|
+
case "PROJECTEDCRS":
|
|
2370
|
+
return "projected";
|
|
2371
|
+
case "GEODCRS":
|
|
2372
|
+
case "GEODETICCRS": {
|
|
2373
|
+
const coordinateSystem = root.values.find((value) => value.type === "node" && value.keyword.toUpperCase() === "CS");
|
|
2374
|
+
const subtype = coordinateSystem == null ? void 0 : coordinateSystem.values[0];
|
|
2375
|
+
if ((subtype == null ? void 0 : subtype.type) !== "enumeration" && (subtype == null ? void 0 : subtype.type) !== "string") {
|
|
2376
|
+
return "unknown";
|
|
2377
|
+
}
|
|
2378
|
+
return subtype.value.toUpperCase() === "CARTESIAN" ? "geocentric" : subtype.value.toUpperCase() === "ELLIPSOIDAL" ? "geographic" : "unknown";
|
|
2379
|
+
}
|
|
2380
|
+
default:
|
|
2381
|
+
return "unknown";
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
function getProjStringCoordinateFrame(definition) {
|
|
2385
|
+
var _a;
|
|
2386
|
+
try {
|
|
2387
|
+
const projection = (_a = (0, import_crs.parsePROJString)(definition).parameters.find((parameter) => parameter.name.toLowerCase() === "proj")) == null ? void 0 : _a.value;
|
|
2388
|
+
switch (projection == null ? void 0 : projection.toLowerCase()) {
|
|
2389
|
+
case "longlat":
|
|
2390
|
+
case "latlong":
|
|
2391
|
+
return "geographic";
|
|
2392
|
+
case "geocent":
|
|
2393
|
+
return "geocentric";
|
|
2394
|
+
default:
|
|
2395
|
+
return projection ? "projected" : "unknown";
|
|
2396
|
+
}
|
|
2397
|
+
} catch {
|
|
2398
|
+
return "unknown";
|
|
2399
|
+
}
|
|
2310
2400
|
}
|
|
2311
2401
|
|
|
2312
2402
|
// dist/spatial/spatial-types.js
|
|
@@ -2331,11 +2421,11 @@ function createTilesetSpatialReference(discovered, options = {}) {
|
|
|
2331
2421
|
const provenance = hasSourceCrsOverride ? "caller-override" : discovered.provenance || "unknown";
|
|
2332
2422
|
const coordinateFrame = hasSourceCrsOverride && sourceCrs ? getSpatialCoordinateFrame(sourceCrs) : discovered.coordinateFrame;
|
|
2333
2423
|
const sourceCrsState = hasSourceCrsOverride ? "explicit" : discovered.sourceCrsState || (sourceCrs ? provenance === "format-default" ? "default" : "explicit" : "absent");
|
|
2334
|
-
const spatialReference = (0,
|
|
2424
|
+
const spatialReference = (0, import_crs2.createSpatialReference)({
|
|
2335
2425
|
crs: sourceCrs ? {
|
|
2336
2426
|
state: sourceCrsState === "default" ? "default" : "explicit",
|
|
2337
2427
|
definition: sourceCrs,
|
|
2338
|
-
representation: !hasSourceCrsOverride && discovered.sourceCrsRepresentation || (0,
|
|
2428
|
+
representation: !hasSourceCrsOverride && discovered.sourceCrsRepresentation || (0, import_crs2.inferCRSRepresentation)(sourceCrs),
|
|
2339
2429
|
provenance,
|
|
2340
2430
|
alternatives: hasSourceCrsOverride ? void 0 : discovered.sourceCrsAlternatives
|
|
2341
2431
|
} : {
|
|
@@ -2345,7 +2435,7 @@ function createTilesetSpatialReference(discovered, options = {}) {
|
|
|
2345
2435
|
vertical: discovered.verticalCrs ? {
|
|
2346
2436
|
state: "explicit",
|
|
2347
2437
|
definition: discovered.verticalCrs,
|
|
2348
|
-
representation: (0,
|
|
2438
|
+
representation: (0, import_crs2.inferCRSRepresentation)(discovered.verticalCrs),
|
|
2349
2439
|
provenance: discovered.provenance || "metadata"
|
|
2350
2440
|
} : void 0,
|
|
2351
2441
|
coordinateEpoch: options.coordinateEpoch ?? discovered.coordinateEpoch,
|
|
@@ -2402,11 +2492,11 @@ function getKnownCRSDefinition(reference) {
|
|
|
2402
2492
|
return reference.state === "explicit" || reference.state === "default" ? reference.definition : void 0;
|
|
2403
2493
|
}
|
|
2404
2494
|
function cloneReadonlyCRSDefinition(definition) {
|
|
2405
|
-
const spatialReference = (0,
|
|
2495
|
+
const spatialReference = (0, import_crs2.createSpatialReference)({
|
|
2406
2496
|
crs: {
|
|
2407
2497
|
state: "explicit",
|
|
2408
2498
|
definition,
|
|
2409
|
-
representation: (0,
|
|
2499
|
+
representation: (0, import_crs2.inferCRSRepresentation)(definition),
|
|
2410
2500
|
provenance: "caller-override"
|
|
2411
2501
|
}
|
|
2412
2502
|
});
|
|
@@ -2661,6 +2751,24 @@ var Tileset3D = class {
|
|
|
2661
2751
|
get frameNumber() {
|
|
2662
2752
|
return this._frameNumber;
|
|
2663
2753
|
}
|
|
2754
|
+
/**
|
|
2755
|
+
* Returns the tiles requested during the most recent completed traversal.
|
|
2756
|
+
*
|
|
2757
|
+
* A defensive copy makes request ordering deterministic for diagnostics and prevents callers
|
|
2758
|
+
* from mutating the scheduler's working set.
|
|
2759
|
+
*/
|
|
2760
|
+
get requestedTiles() {
|
|
2761
|
+
return this._requestedTiles.slice();
|
|
2762
|
+
}
|
|
2763
|
+
/**
|
|
2764
|
+
* Returns empty tiles considered during the most recent completed traversal.
|
|
2765
|
+
*
|
|
2766
|
+
* Empty tiles can still be useful hierarchy placeholders, but their IDs are included in
|
|
2767
|
+
* observability snapshots so applications can distinguish traversal work from render content.
|
|
2768
|
+
*/
|
|
2769
|
+
get emptyTiles() {
|
|
2770
|
+
return this._emptyTiles.slice();
|
|
2771
|
+
}
|
|
2664
2772
|
/**
|
|
2665
2773
|
* Gets or sets the soft target, in bytes, for cached tile content not needed this frame.
|
|
2666
2774
|
*
|
|
@@ -2788,6 +2896,12 @@ var Tileset3D = class {
|
|
|
2788
2896
|
return;
|
|
2789
2897
|
}
|
|
2790
2898
|
const preparedViewports = viewports instanceof Array ? viewports : [viewports];
|
|
2899
|
+
const activeViewportIds = new Set(preparedViewports.map((viewport) => viewport.id));
|
|
2900
|
+
for (const frameStateId of Object.keys(this.frameStateData)) {
|
|
2901
|
+
if (!activeViewportIds.has(frameStateId)) {
|
|
2902
|
+
delete this.frameStateData[frameStateId];
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2791
2905
|
this._cache.reset();
|
|
2792
2906
|
this._frameNumber++;
|
|
2793
2907
|
this.traverseCounter = preparedViewports.length;
|
|
@@ -2976,21 +3090,21 @@ var Tileset3D = class {
|
|
|
2976
3090
|
this.stats.get(MAXIMUM_SSE).count = this.memoryAdjustedScreenSpaceError;
|
|
2977
3091
|
}
|
|
2978
3092
|
async _initializeTileSet() {
|
|
2979
|
-
var _a, _b, _c;
|
|
3093
|
+
var _a, _b, _c, _d;
|
|
2980
3094
|
try {
|
|
2981
3095
|
const initializePromise = this.source.initialize();
|
|
2982
3096
|
const initialMetadata = this._getSourceMetadata();
|
|
2983
3097
|
if (initialMetadata) {
|
|
2984
3098
|
this._syncSourceState(initialMetadata);
|
|
2985
3099
|
}
|
|
2986
|
-
if (((_a = initialMetadata == null ? void 0 : initialMetadata.tileset) == null ? void 0 : _a.root) && typeof initialMetadata.tileset.root.then !== "function" && !this.source.prepareTileset) {
|
|
3100
|
+
if (((_a = initialMetadata == null ? void 0 : initialMetadata.tileset) == null ? void 0 : _a.root) && typeof initialMetadata.tileset.root.then !== "function" && (!this.source.prepareTileset || ((_b = this.spatialReference) == null ? void 0 : _b.status) === "native")) {
|
|
2987
3101
|
this.root = this._initializeTileHeaders(initialMetadata.tileset, null);
|
|
2988
3102
|
this._applyViewState();
|
|
2989
3103
|
}
|
|
2990
3104
|
await initializePromise;
|
|
2991
3105
|
const metadata = this.source.getMetadata();
|
|
2992
3106
|
this._syncSourceState(metadata);
|
|
2993
|
-
await ((
|
|
3107
|
+
await ((_d = (_c = this.source).prepareTileset) == null ? void 0 : _d.call(_c, this));
|
|
2994
3108
|
if (!this.root) {
|
|
2995
3109
|
this.root = this._initializeTileHeaders(metadata.tileset, null);
|
|
2996
3110
|
}
|
|
@@ -3211,6 +3325,36 @@ function preserveTransformedSpatialReference(current, next) {
|
|
|
3211
3325
|
return (current == null ? void 0 : current.status) === "transformed" && current.sourceCrs === next.sourceCrs && current.targetCrs === next.targetCrs && current.targetHeightReference === next.targetHeightReference && current.outputCoordinates === next.outputCoordinates ? current : next;
|
|
3212
3326
|
}
|
|
3213
3327
|
|
|
3328
|
+
// dist/tileset-3d/common/tileset-observability.js
|
|
3329
|
+
function getTileset3DTraversalSnapshot(tileset) {
|
|
3330
|
+
var _a;
|
|
3331
|
+
const selectedTiles = tileset.selectedTiles.slice();
|
|
3332
|
+
const requestedTiles = tileset.requestedTiles.slice();
|
|
3333
|
+
const emptyTiles = tileset.emptyTiles.slice();
|
|
3334
|
+
const getTileIds = (tiles) => tiles.map((tile) => String(tile.id)).sort();
|
|
3335
|
+
const getStatCount = (name) => {
|
|
3336
|
+
const count = tileset.stats.get(name).count;
|
|
3337
|
+
return typeof count === "number" && Number.isFinite(count) ? count : 0;
|
|
3338
|
+
};
|
|
3339
|
+
const implicitTilingSource = tileset.source;
|
|
3340
|
+
const implicitTiling = (_a = implicitTilingSource.getImplicitTilingStats) == null ? void 0 : _a.call(implicitTilingSource);
|
|
3341
|
+
return {
|
|
3342
|
+
frameNumber: tileset.frameNumber,
|
|
3343
|
+
selectedTileIds: getTileIds(selectedTiles),
|
|
3344
|
+
requestedTileIds: getTileIds(requestedTiles),
|
|
3345
|
+
emptyTileIds: getTileIds(emptyTiles),
|
|
3346
|
+
visibleTileCount: selectedTiles.length,
|
|
3347
|
+
renderableTileCount: selectedTiles.filter((tile) => tile.contentAvailable && Boolean(tile.content)).length,
|
|
3348
|
+
loadingTileCount: getStatCount("Tiles Loading"),
|
|
3349
|
+
loadedTileCount: getStatCount("Tiles Loaded"),
|
|
3350
|
+
failedTileCount: getStatCount("Failed Tile Loads"),
|
|
3351
|
+
cachedTileCount: getStatCount("Tiles In Memory"),
|
|
3352
|
+
cacheBytes: tileset.gpuMemoryUsageInBytes,
|
|
3353
|
+
maximumScreenSpaceError: tileset.memoryAdjustedScreenSpaceError,
|
|
3354
|
+
...implicitTiling ? { implicitTiling } : {}
|
|
3355
|
+
};
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3214
3358
|
// dist/tileset-3d/common/indexed-archive-tileset-source.js
|
|
3215
3359
|
var IndexedArchiveTilesetSource = class {
|
|
3216
3360
|
/** URL exposed to the tileset source that owns this archive source. */
|
|
@@ -3327,6 +3471,47 @@ function stripQueryString(url) {
|
|
|
3327
3471
|
var import_core8 = require("@math.gl/core");
|
|
3328
3472
|
var import_culling4 = require("@math.gl/culling");
|
|
3329
3473
|
|
|
3474
|
+
// dist/tileset-3d/common/tile-3d-contracts.js
|
|
3475
|
+
function getTile3DFeatureIdSets(payload) {
|
|
3476
|
+
const featureIdSets = [];
|
|
3477
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3478
|
+
const visit = (value) => {
|
|
3479
|
+
var _a, _b;
|
|
3480
|
+
if (!value || typeof value !== "object") {
|
|
3481
|
+
return;
|
|
3482
|
+
}
|
|
3483
|
+
if (visited.has(value)) {
|
|
3484
|
+
return;
|
|
3485
|
+
}
|
|
3486
|
+
visited.add(value);
|
|
3487
|
+
const record = value;
|
|
3488
|
+
const declarations = (_b = (_a = record.extensions) == null ? void 0 : _a.EXT_mesh_features) == null ? void 0 : _b.featureIds;
|
|
3489
|
+
if (Array.isArray(declarations)) {
|
|
3490
|
+
for (const declaration of declarations) {
|
|
3491
|
+
if (!declaration || typeof declaration !== "object") {
|
|
3492
|
+
continue;
|
|
3493
|
+
}
|
|
3494
|
+
const source = declaration.texture ? "texture" : declaration.implicit ? "implicit" : declaration.attribute !== void 0 ? "attribute" : declaration.propertyTable !== void 0 ? "property-table" : "constant";
|
|
3495
|
+
featureIdSets.push({
|
|
3496
|
+
source,
|
|
3497
|
+
attribute: declaration.attribute,
|
|
3498
|
+
propertyTable: declaration.propertyTable,
|
|
3499
|
+
constant: declaration.constant,
|
|
3500
|
+
texture: declaration.texture,
|
|
3501
|
+
implicit: declaration.implicit,
|
|
3502
|
+
values: declaration.values,
|
|
3503
|
+
details: declaration
|
|
3504
|
+
});
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
for (const child of Object.values(record)) {
|
|
3508
|
+
visit(child);
|
|
3509
|
+
}
|
|
3510
|
+
};
|
|
3511
|
+
visit(payload);
|
|
3512
|
+
return featureIdSets;
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3330
3515
|
// dist/tileset-3d/helpers/bounding-volume.js
|
|
3331
3516
|
var import_core6 = require("@math.gl/core");
|
|
3332
3517
|
var import_culling3 = require("@math.gl/culling");
|
|
@@ -3336,21 +3521,25 @@ function defined(x) {
|
|
|
3336
3521
|
}
|
|
3337
3522
|
var scratchPoint = new import_core6.Vector3();
|
|
3338
3523
|
var scratchScale = new import_core6.Vector3();
|
|
3339
|
-
|
|
3524
|
+
var identityTransform = new import_core6.Matrix4();
|
|
3525
|
+
function createBoundingVolume(boundingVolumeHeader, transform, result, initialTransform = transform) {
|
|
3340
3526
|
assert(boundingVolumeHeader, "3D Tile: boundingVolume must be defined");
|
|
3341
3527
|
if (boundingVolumeHeader.box) {
|
|
3342
|
-
|
|
3528
|
+
const boxTransform = boundingVolumeHeader.s2VolumeInfo ? identityTransform : transform;
|
|
3529
|
+
return createBox(boundingVolumeHeader.box, boxTransform, result);
|
|
3343
3530
|
}
|
|
3344
3531
|
if (boundingVolumeHeader.region) {
|
|
3345
|
-
|
|
3532
|
+
const boundingVolume = (0, import_geospatial4.makeOBBFromRegion)(boundingVolumeHeader.region);
|
|
3533
|
+
const regionTransform = transform.equals(initialTransform) ? identityTransform : transform.clone().multiplyRight(initialTransform.clone().invert());
|
|
3534
|
+
return createBox([...boundingVolume.center, ...boundingVolume.halfAxes], regionTransform, result);
|
|
3346
3535
|
}
|
|
3347
3536
|
if (boundingVolumeHeader.sphere) {
|
|
3348
3537
|
return createSphere(boundingVolumeHeader.sphere, transform, result);
|
|
3349
3538
|
}
|
|
3350
3539
|
throw new Error("3D Tile: boundingVolume must contain a sphere, region, or box");
|
|
3351
3540
|
}
|
|
3352
|
-
function getCartographicBounds(boundingVolumeHeader, boundingVolume) {
|
|
3353
|
-
if (boundingVolumeHeader.box) {
|
|
3541
|
+
function getCartographicBounds(boundingVolumeHeader, boundingVolume, isRegionTransformed = false) {
|
|
3542
|
+
if (boundingVolumeHeader.box || boundingVolumeHeader.region && isRegionTransformed) {
|
|
3354
3543
|
return orientedBoundingBoxToCartographicBounds(boundingVolume);
|
|
3355
3544
|
}
|
|
3356
3545
|
if (boundingVolumeHeader.region) {
|
|
@@ -3830,7 +4019,7 @@ var TilesetTraverser = class {
|
|
|
3830
4019
|
}
|
|
3831
4020
|
stack.push(child);
|
|
3832
4021
|
hasVisibleChild = true;
|
|
3833
|
-
} else if (checkRefines || loadSiblings) {
|
|
4022
|
+
} else if ((checkRefines || loadSiblings) && child._inRequestVolume) {
|
|
3834
4023
|
this.loadTile(child, frameState);
|
|
3835
4024
|
this.touchTile(child, frameState);
|
|
3836
4025
|
}
|
|
@@ -4017,6 +4206,13 @@ function getContentVisibility(contentVolumes, fallbackVolume, cullingVolume2, vi
|
|
|
4017
4206
|
}
|
|
4018
4207
|
return intersectingVolume ? "intersecting" : "inside";
|
|
4019
4208
|
}
|
|
4209
|
+
function isNestedTilesetPayload(payload) {
|
|
4210
|
+
if (!payload || typeof payload !== "object") {
|
|
4211
|
+
return false;
|
|
4212
|
+
}
|
|
4213
|
+
const record = payload;
|
|
4214
|
+
return record.shape === "tileset3d" || record.type === "tileset3d" || Boolean(record.tileset);
|
|
4215
|
+
}
|
|
4020
4216
|
function defined2(x) {
|
|
4021
4217
|
return x !== void 0 && x !== null;
|
|
4022
4218
|
}
|
|
@@ -4044,6 +4240,8 @@ var Tile3D = class {
|
|
|
4044
4240
|
* separate ensures transform updates never compound an already-scaled geometric error.
|
|
4045
4241
|
*/
|
|
4046
4242
|
_unscaledLodMetricValue = 0;
|
|
4243
|
+
/** Whether the source format defines geometric error in transform-local units. */
|
|
4244
|
+
_scaleGeometricError = true;
|
|
4047
4245
|
/** @todo math.gl is not exporting BoundingVolume base type? */
|
|
4048
4246
|
boundingVolume = null;
|
|
4049
4247
|
/**
|
|
@@ -4053,6 +4251,14 @@ var Tile3D = class {
|
|
|
4053
4251
|
content = null;
|
|
4054
4252
|
/** Loaded payloads in the same order as {@link contentUrls}; `content` remains the primary payload. */
|
|
4055
4253
|
contents = [];
|
|
4254
|
+
/** Ordered renderer-neutral descriptors for each source content entry. */
|
|
4255
|
+
contentEntries = [];
|
|
4256
|
+
/** Raw metadata references inherited by this tile and its content. */
|
|
4257
|
+
metadataContext = {};
|
|
4258
|
+
/** Feature-id declarations normalized from supported content extensions. */
|
|
4259
|
+
featureIdSets = [];
|
|
4260
|
+
/** Decoded 3D Tiles vector topology for the primary loaded content, when present. */
|
|
4261
|
+
vectorContent = null;
|
|
4056
4262
|
/**
|
|
4057
4263
|
* Metadata entity attached to this tile in the source tileset, if present.
|
|
4058
4264
|
*
|
|
@@ -4119,6 +4325,7 @@ var Tile3D = class {
|
|
|
4119
4325
|
get viewerRequestVolume() {
|
|
4120
4326
|
return this._viewerRequestVolume;
|
|
4121
4327
|
}
|
|
4328
|
+
/** Accumulated tile transforms from the source JSON, excluding the tileset model matrix. */
|
|
4122
4329
|
_initialTransform = new import_core8.Matrix4();
|
|
4123
4330
|
// Used by traverser, cannot be marked private
|
|
4124
4331
|
_priority = 0;
|
|
@@ -4160,15 +4367,14 @@ var Tile3D = class {
|
|
|
4160
4367
|
this.type = header.type;
|
|
4161
4368
|
this.contentUrl = header.contentUrl;
|
|
4162
4369
|
this.contentUrls = header.contentUrls || (header.contentUrl ? [header.contentUrl] : []);
|
|
4163
|
-
this.
|
|
4164
|
-
const contentHeaders = Array.isArray(header.content) ? header.content : [header.content];
|
|
4165
|
-
this.contentMetadata = contentHeaders.filter(Boolean).map((contentHeader) => contentHeader.metadata || null);
|
|
4370
|
+
this._initializeMetadata(header);
|
|
4166
4371
|
this.childrenState = header.implicitSubtree ? "unloaded" : "ready";
|
|
4167
4372
|
this._initializeLodMetric(header);
|
|
4168
4373
|
this._initializeTransforms(header);
|
|
4169
4374
|
this._updateLodMetricScale();
|
|
4170
4375
|
this._initializeBoundingVolumes(header);
|
|
4171
4376
|
this._initializeContent(header);
|
|
4377
|
+
this._initializeContentEntries(header);
|
|
4172
4378
|
this._initializeRenderingState(header);
|
|
4173
4379
|
Object.seal(this);
|
|
4174
4380
|
}
|
|
@@ -4253,12 +4459,12 @@ var Tile3D = class {
|
|
|
4253
4459
|
return this._screenSpaceError;
|
|
4254
4460
|
}
|
|
4255
4461
|
/**
|
|
4256
|
-
* Get bounding
|
|
4462
|
+
* Get the current world-space bounding volume in cartographic coordinates.
|
|
4257
4463
|
* @returns [min, max] each in [longitude, latitude, altitude]
|
|
4258
4464
|
*/
|
|
4259
4465
|
get boundingBox() {
|
|
4260
4466
|
if (!this._boundingBox) {
|
|
4261
|
-
this._boundingBox = getCartographicBounds(this.header.boundingVolume, this.boundingVolume);
|
|
4467
|
+
this._boundingBox = getCartographicBounds(this.header.boundingVolume, this.boundingVolume, !this.computedTransform.equals(this._initialTransform));
|
|
4262
4468
|
}
|
|
4263
4469
|
return this._boundingBox;
|
|
4264
4470
|
}
|
|
@@ -4358,6 +4564,7 @@ var Tile3D = class {
|
|
|
4358
4564
|
*/
|
|
4359
4565
|
// eslint-disable-next-line max-statements, complexity
|
|
4360
4566
|
async loadContent() {
|
|
4567
|
+
var _a;
|
|
4361
4568
|
if (this.hasEmptyContent) {
|
|
4362
4569
|
return { loaded: false };
|
|
4363
4570
|
}
|
|
@@ -4380,11 +4587,13 @@ var Tile3D = class {
|
|
|
4380
4587
|
this.contents = loadResult.contents;
|
|
4381
4588
|
this.content = this.contents[0] || null;
|
|
4382
4589
|
}
|
|
4590
|
+
this.vectorContent = ((_a = this.contents.find((content) => Boolean(content == null ? void 0 : content.vectorContent))) == null ? void 0 : _a.vectorContent) || null;
|
|
4383
4591
|
if (this.tileset.options.contentLoader) {
|
|
4384
4592
|
await this.tileset.options.contentLoader(this);
|
|
4385
4593
|
}
|
|
4386
4594
|
this.contentState = TILE_CONTENT_STATE.READY;
|
|
4387
4595
|
this._onContentLoaded();
|
|
4596
|
+
this._updateContentEntriesAfterLoad(loadResult);
|
|
4388
4597
|
return loadResult;
|
|
4389
4598
|
} catch (error) {
|
|
4390
4599
|
this.contentState = TILE_CONTENT_STATE.FAILED;
|
|
@@ -4447,30 +4656,114 @@ var Tile3D = class {
|
|
|
4447
4656
|
/**
|
|
4448
4657
|
* Replaces a contentless implicit placeholder with its materialized subtree-root header.
|
|
4449
4658
|
*
|
|
4450
|
-
*
|
|
4451
|
-
* transform
|
|
4452
|
-
*
|
|
4659
|
+
* The placeholder transform is preserved when the subtree omits a root transform. An explicit
|
|
4660
|
+
* subtree-root transform replaces it and is recomposed against the runtime parent. Content,
|
|
4661
|
+
* metadata, bounds, and raw geometric error are reinitialized from the available header.
|
|
4453
4662
|
*
|
|
4454
4663
|
* @param materializedHeader - Available root header produced from one subtree resource.
|
|
4455
4664
|
*/
|
|
4456
4665
|
applyImplicitSubtreeHeader(materializedHeader) {
|
|
4457
4666
|
const existingTransform = this.header.transform;
|
|
4458
4667
|
const existingTransformMatrix = this.header.transformMatrix;
|
|
4668
|
+
const hasMaterializedTransform = materializedHeader.transform !== void 0;
|
|
4459
4669
|
this.header = {
|
|
4460
4670
|
...this.header,
|
|
4461
4671
|
...materializedHeader,
|
|
4462
|
-
transform: existingTransform,
|
|
4463
|
-
transformMatrix: existingTransformMatrix,
|
|
4672
|
+
transform: hasMaterializedTransform ? materializedHeader.transform : existingTransform,
|
|
4673
|
+
transformMatrix: hasMaterializedTransform ? materializedHeader.transformMatrix : existingTransformMatrix,
|
|
4464
4674
|
implicitSubtree: void 0
|
|
4465
4675
|
};
|
|
4676
|
+
if (hasMaterializedTransform) {
|
|
4677
|
+
this._initializeTransforms(this.header);
|
|
4678
|
+
}
|
|
4466
4679
|
this.refine = this._getRefine(materializedHeader.refine);
|
|
4467
4680
|
this.type = materializedHeader.type;
|
|
4468
4681
|
this.contentUrl = materializedHeader.contentUrl;
|
|
4469
4682
|
this.contentUrls = materializedHeader.contentUrls || (materializedHeader.contentUrl ? [materializedHeader.contentUrl] : []);
|
|
4683
|
+
this._initializeMetadata(this.header);
|
|
4470
4684
|
this._initializeLodMetric(materializedHeader);
|
|
4471
4685
|
this._updateLodMetricScale();
|
|
4472
4686
|
this._initializeBoundingVolumes(this.header);
|
|
4687
|
+
this._boundingBox = void 0;
|
|
4473
4688
|
this._initializeContent(this.header);
|
|
4689
|
+
this._initializeContentEntries(this.header);
|
|
4690
|
+
}
|
|
4691
|
+
/** Refreshes tile and content metadata from a source or materialized tile header. */
|
|
4692
|
+
_initializeMetadata(header) {
|
|
4693
|
+
var _a;
|
|
4694
|
+
this.metadata = header.metadata || null;
|
|
4695
|
+
const contentHeaders = Array.isArray(header.content) ? header.content : [header.content];
|
|
4696
|
+
this.contentMetadata = contentHeaders.filter(Boolean).map((contentHeader) => contentHeader.metadata || null);
|
|
4697
|
+
const firstContentHeader = contentHeaders.find(Boolean) || {};
|
|
4698
|
+
const groupReference = firstContentHeader.group;
|
|
4699
|
+
const group = typeof groupReference === "number" ? ((_a = this.tileset.groups) == null ? void 0 : _a[groupReference]) || null : groupReference || null;
|
|
4700
|
+
const metadataContext = {
|
|
4701
|
+
tileset: this.tileset.metadata || null,
|
|
4702
|
+
group,
|
|
4703
|
+
tile: this.metadata,
|
|
4704
|
+
content: this.contentMetadata[0] || null,
|
|
4705
|
+
subtree: header.implicitMetadata || null
|
|
4706
|
+
};
|
|
4707
|
+
if (this.tileset.groups) {
|
|
4708
|
+
metadataContext.groups = this.tileset.groups;
|
|
4709
|
+
}
|
|
4710
|
+
this.metadataContext = metadataContext;
|
|
4711
|
+
}
|
|
4712
|
+
/** Updates payload and renderability while retaining immutable metadata descriptors. */
|
|
4713
|
+
_updateContentEntriesAfterLoad(loadResult) {
|
|
4714
|
+
if (loadResult.contentEntries) {
|
|
4715
|
+
this.contentEntries = loadResult.contentEntries.map((entry, index) => {
|
|
4716
|
+
var _a;
|
|
4717
|
+
return {
|
|
4718
|
+
...entry,
|
|
4719
|
+
index,
|
|
4720
|
+
boundingVolume: entry.boundingVolume || this._contentBoundingVolumes[index] || this.boundingVolume,
|
|
4721
|
+
payload: entry.payload ?? this.contents[index] ?? null,
|
|
4722
|
+
featureIds: ((_a = entry.featureIds) == null ? void 0 : _a.length) ? entry.featureIds : getTile3DFeatureIdSets(entry.payload ?? this.contents[index]),
|
|
4723
|
+
renderable: Boolean(entry.renderable !== false && (entry.payload ?? this.contents[index]) && !isNestedTilesetPayload(entry.payload ?? this.contents[index]))
|
|
4724
|
+
};
|
|
4725
|
+
});
|
|
4726
|
+
this.featureIdSets = this.contentEntries.flatMap((entry) => entry.featureIds);
|
|
4727
|
+
return;
|
|
4728
|
+
}
|
|
4729
|
+
this.contentEntries = this.contentEntries.map((entry, index) => ({
|
|
4730
|
+
...entry,
|
|
4731
|
+
payload: this.contents[index] ?? null,
|
|
4732
|
+
featureIds: getTile3DFeatureIdSets(this.contents[index]),
|
|
4733
|
+
renderable: Boolean(this.contents[index]) && !isNestedTilesetPayload(this.contents[index])
|
|
4734
|
+
}));
|
|
4735
|
+
this.featureIdSets = this.contentEntries.flatMap((entry) => entry.featureIds);
|
|
4736
|
+
}
|
|
4737
|
+
/** Returns one ordered content descriptor, or null when the index is out of range. */
|
|
4738
|
+
getContentEntry(index) {
|
|
4739
|
+
return this.contentEntries[index] || null;
|
|
4740
|
+
}
|
|
4741
|
+
/** Returns whether an ordered content entry currently has renderable payload. */
|
|
4742
|
+
isContentRenderable(index) {
|
|
4743
|
+
var _a;
|
|
4744
|
+
return Boolean((_a = this.contentEntries[index]) == null ? void 0 : _a.renderable);
|
|
4745
|
+
}
|
|
4746
|
+
/** Initializes additive renderer-neutral descriptors from a normalized tile header. */
|
|
4747
|
+
_initializeContentEntries(tileHeader) {
|
|
4748
|
+
const headers = Array.isArray(tileHeader.content) ? tileHeader.content : tileHeader.content ? [tileHeader.content] : [];
|
|
4749
|
+
this.contentEntries = headers.map((contentHeader, index) => {
|
|
4750
|
+
const normalizedContentHeader = contentHeader || {};
|
|
4751
|
+
return {
|
|
4752
|
+
index,
|
|
4753
|
+
uri: this.contentUrls[index] || normalizedContentHeader.uri || normalizedContentHeader.url,
|
|
4754
|
+
group: normalizedContentHeader.group,
|
|
4755
|
+
type: normalizedContentHeader.type,
|
|
4756
|
+
payload: null,
|
|
4757
|
+
metadata: normalizedContentHeader.metadata || null,
|
|
4758
|
+
boundingVolume: this._contentBoundingVolumes[index] || this.boundingVolume,
|
|
4759
|
+
featureIds: this._getFeatureIdSets(normalizedContentHeader),
|
|
4760
|
+
renderable: false
|
|
4761
|
+
};
|
|
4762
|
+
});
|
|
4763
|
+
}
|
|
4764
|
+
/** Extracts renderer-neutral feature-id declarations without decoding property values. */
|
|
4765
|
+
_getFeatureIdSets(contentHeader) {
|
|
4766
|
+
return getTile3DFeatureIdSets(contentHeader);
|
|
4474
4767
|
}
|
|
4475
4768
|
// Unloads the tile's content.
|
|
4476
4769
|
unloadContent() {
|
|
@@ -4481,6 +4774,13 @@ var Tile3D = class {
|
|
|
4481
4774
|
}
|
|
4482
4775
|
this.contents = [];
|
|
4483
4776
|
this.content = null;
|
|
4777
|
+
this.vectorContent = null;
|
|
4778
|
+
this.contentEntries = this.contentEntries.map((entry) => ({
|
|
4779
|
+
...entry,
|
|
4780
|
+
payload: null,
|
|
4781
|
+
renderable: false
|
|
4782
|
+
}));
|
|
4783
|
+
this.featureIdSets = this.contentEntries.flatMap((entry) => entry.featureIds);
|
|
4484
4784
|
if (this.header.content && this.header.content.destroy) {
|
|
4485
4785
|
this.header.content.destroy();
|
|
4486
4786
|
}
|
|
@@ -4577,8 +4877,9 @@ var Tile3D = class {
|
|
|
4577
4877
|
* @param frameState Current camera, culling, and optional clipping-plane state.
|
|
4578
4878
|
* @returns The content visibility classification.
|
|
4579
4879
|
*/
|
|
4580
|
-
contentVisibility(frameState) {
|
|
4581
|
-
|
|
4880
|
+
contentVisibility(frameState, contentIndex) {
|
|
4881
|
+
const contentVolumes = contentIndex === void 0 ? this._contentBoundingVolumes : this._contentBoundingVolumes[contentIndex] ? [this._contentBoundingVolumes[contentIndex]] : [];
|
|
4882
|
+
return getContentVisibility(contentVolumes, this.boundingVolume, frameState.cullingVolume, this._visibilityPlaneMask, frameState.clippingPlanes);
|
|
4582
4883
|
}
|
|
4583
4884
|
/**
|
|
4584
4885
|
* Computes the (potentially approximate) distance from the closest point of the tile's bounding volume to the camera.
|
|
@@ -4625,6 +4926,8 @@ var Tile3D = class {
|
|
|
4625
4926
|
// INTERNAL METHODS
|
|
4626
4927
|
/** Initializes the tile's LOD metric from its header or its nearest available ancestor. */
|
|
4627
4928
|
_initializeLodMetric(header) {
|
|
4929
|
+
var _a;
|
|
4930
|
+
this._scaleGeometricError = typeof header._scaleGeometricError === "boolean" ? header._scaleGeometricError : ((_a = this.parent) == null ? void 0 : _a._scaleGeometricError) ?? true;
|
|
4628
4931
|
if ("lodMetricType" in header) {
|
|
4629
4932
|
this.lodMetricType = header.lodMetricType;
|
|
4630
4933
|
} else {
|
|
@@ -4660,7 +4963,7 @@ var Tile3D = class {
|
|
|
4660
4963
|
* I3S `maxScreenThreshold` is already a screen-space metric and must not be transform-scaled.
|
|
4661
4964
|
*/
|
|
4662
4965
|
_updateLodMetricScale() {
|
|
4663
|
-
if (this.lodMetricType !== LOD_METRIC_TYPE.GEOMETRIC_ERROR) {
|
|
4966
|
+
if (this.lodMetricType !== LOD_METRIC_TYPE.GEOMETRIC_ERROR || !this._scaleGeometricError) {
|
|
4664
4967
|
this.lodMetricValue = this._unscaledLodMetricValue;
|
|
4665
4968
|
return;
|
|
4666
4969
|
}
|
|
@@ -4740,16 +5043,17 @@ var Tile3D = class {
|
|
|
4740
5043
|
}
|
|
4741
5044
|
}
|
|
4742
5045
|
_updateBoundingVolume(header) {
|
|
4743
|
-
this.
|
|
5046
|
+
this._boundingBox = void 0;
|
|
5047
|
+
this.boundingVolume = createBoundingVolume(header.boundingVolume, this.computedTransform, this.boundingVolume, this._initialTransform);
|
|
4744
5048
|
if (header.viewerRequestVolume) {
|
|
4745
|
-
this._viewerRequestVolume = createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume);
|
|
5049
|
+
this._viewerRequestVolume = createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume, this._initialTransform);
|
|
4746
5050
|
}
|
|
4747
5051
|
const content = header.content;
|
|
4748
5052
|
if (content) {
|
|
4749
5053
|
this._contentBoundingVolumeHeaders = Array.isArray(content) ? content : [content];
|
|
4750
5054
|
}
|
|
4751
5055
|
const contentHeaders = content ? Array.isArray(content) ? content : [content] : this._contentBoundingVolumeHeaders;
|
|
4752
|
-
this._contentBoundingVolumes = contentHeaders.length ? contentHeaders.map((headerEntry) => (headerEntry == null ? void 0 : headerEntry.boundingVolume) ? createBoundingVolume(headerEntry.boundingVolume, this.computedTransform) : this.boundingVolume) : [this.boundingVolume];
|
|
5056
|
+
this._contentBoundingVolumes = contentHeaders.length ? contentHeaders.map((headerEntry) => (headerEntry == null ? void 0 : headerEntry.boundingVolume) ? createBoundingVolume(headerEntry.boundingVolume, this.computedTransform, void 0, this._initialTransform) : this.boundingVolume) : [this.boundingVolume];
|
|
4753
5057
|
this._contentBoundingVolume = this._contentBoundingVolumes[0] || null;
|
|
4754
5058
|
}
|
|
4755
5059
|
/**
|
|
@@ -4769,8 +5073,8 @@ var Tile3D = class {
|
|
|
4769
5073
|
};
|
|
4770
5074
|
|
|
4771
5075
|
// dist/tileset-3d/format-3d-tiles/tiles-3d-source.js
|
|
4772
|
-
var
|
|
4773
|
-
var
|
|
5076
|
+
var import_geospatial10 = require("@math.gl/geospatial");
|
|
5077
|
+
var import_core12 = require("@math.gl/core");
|
|
4774
5078
|
|
|
4775
5079
|
// dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js
|
|
4776
5080
|
var Tileset3DTraverser = class extends TilesetTraverser {
|
|
@@ -4980,10 +5284,12 @@ var Tileset3DTraverser = class extends TilesetTraverser {
|
|
|
4980
5284
|
return b._distanceToCamera === 0 && a._distanceToCamera === 0 ? b._centerZDepth - a._centerZDepth : b._distanceToCamera - a._distanceToCamera;
|
|
4981
5285
|
}
|
|
4982
5286
|
/**
|
|
4983
|
-
* Starts an implicit subtree request
|
|
5287
|
+
* Starts an implicit subtree request after culling and request-volume eligibility.
|
|
4984
5288
|
*
|
|
4985
|
-
* The
|
|
4986
|
-
*
|
|
5289
|
+
* The first subtree of an implicit hierarchy materializes independently of SSE because its
|
|
5290
|
+
* placeholder has no render content. Deeper subtree boundaries remain SSE-gated. The current
|
|
5291
|
+
* parent remains the traversal boundary while metadata is loading, which preserves REPLACE
|
|
5292
|
+
* coverage and ADD accumulation. Request scheduling reads the tile's existing
|
|
4987
5293
|
* progressive-resolution and foveated metrics, so subtree metadata follows the same priority
|
|
4988
5294
|
* policy as render content. A completion notification lets the owning tileset publish the newly
|
|
4989
5295
|
* materialized traversal result on the next update.
|
|
@@ -4992,7 +5298,9 @@ var Tileset3DTraverser = class extends TilesetTraverser {
|
|
|
4992
5298
|
* @param frameState - Current culling and LOD state.
|
|
4993
5299
|
*/
|
|
4994
5300
|
updateChildTiles(tile, frameState) {
|
|
4995
|
-
|
|
5301
|
+
var _a;
|
|
5302
|
+
const isImplicitHierarchyRoot = ((_a = tile.header.implicitSubtree) == null ? void 0 : _a.coordinates.level) === 0;
|
|
5303
|
+
if (tile.hasUnloadedChildren && tile.isVisibleAndInRequestVolume && (isImplicitHierarchyRoot || this.shouldRefine(tile, frameState))) {
|
|
4996
5304
|
const requestKey = `${frameState.viewport.id}:${tile.id}`;
|
|
4997
5305
|
if (!this.pendingImplicitSubtrees.has(requestKey)) {
|
|
4998
5306
|
this.pendingImplicitSubtrees.set(requestKey, frameState.frameNumber);
|
|
@@ -5183,7 +5491,7 @@ function getI3SSpatialReference(layer) {
|
|
|
5183
5491
|
const verticalUnitScale = getI3SVerticalUnitScale(verticalUnit, layer.ZFactor);
|
|
5184
5492
|
const heightReference = heightModel === "ellipsoidal" ? "ellipsoidal" : heightModel === "gravity_related_height" ? "orthometric" : "unknown";
|
|
5185
5493
|
const sourceIdentifier = getCrsIdentifier(spatialReference);
|
|
5186
|
-
const coordinateFrame = sourceIdentifier === void 0 ?
|
|
5494
|
+
const coordinateFrame = sourceIdentifier === void 0 ? sourceCrs ? getSpatialCoordinateFrame(sourceCrs) : "unknown" : getSpatialCoordinateFrame(`EPSG:${sourceIdentifier}`);
|
|
5187
5495
|
const units = getI3SCoordinateUnits(coordinateFrame, verticalUnit, layer.ZFactor);
|
|
5188
5496
|
const warnings = [];
|
|
5189
5497
|
const elevationMode = getI3SElevationMode((_e = layer.elevationInfo) == null ? void 0 : _e.mode);
|
|
@@ -5241,6 +5549,10 @@ function getI3SElevationMode(mode) {
|
|
|
5241
5549
|
}
|
|
5242
5550
|
function get3DTilesSpatialReference(tileset) {
|
|
5243
5551
|
var _a, _b;
|
|
5552
|
+
const draftSpatialReference = getDraft3DTilesSpatialReference(tileset);
|
|
5553
|
+
if (draftSpatialReference) {
|
|
5554
|
+
return draftSpatialReference;
|
|
5555
|
+
}
|
|
5244
5556
|
const geocentricCrs = getTilesetSemanticValue(tileset, "TILESET_CRS_GEOCENTRIC");
|
|
5245
5557
|
const coordinateEpoch = getTilesetSemanticValue(tileset, "TILESET_CRS_COORDINATE_EPOCH");
|
|
5246
5558
|
const warnings = [];
|
|
@@ -5278,6 +5590,87 @@ function get3DTilesSpatialReference(tileset) {
|
|
|
5278
5590
|
warnings
|
|
5279
5591
|
});
|
|
5280
5592
|
}
|
|
5593
|
+
function getDraft3DTilesSpatialReference(tileset) {
|
|
5594
|
+
var _a, _b, _c;
|
|
5595
|
+
const extension = (_a = tileset.extensions) == null ? void 0 : _a.EXT_geospatial_crs;
|
|
5596
|
+
if (!extension) {
|
|
5597
|
+
return void 0;
|
|
5598
|
+
}
|
|
5599
|
+
const warnings = [];
|
|
5600
|
+
let sourceCrs;
|
|
5601
|
+
let verticalCrs;
|
|
5602
|
+
let epoch;
|
|
5603
|
+
let representation;
|
|
5604
|
+
if (extension.format === "wkid") {
|
|
5605
|
+
const wkidExtension = (_b = extension.extensions) == null ? void 0 : _b.EXT_geospatial_crs_wkid;
|
|
5606
|
+
if (typeof (wkidExtension == null ? void 0 : wkidExtension.authority) === "string" && Number.isInteger(wkidExtension.wkid)) {
|
|
5607
|
+
sourceCrs = `${wkidExtension.authority}:${wkidExtension.wkid}`;
|
|
5608
|
+
representation = "identifier";
|
|
5609
|
+
if (Number.isInteger(wkidExtension.vcsWkid)) {
|
|
5610
|
+
verticalCrs = `${wkidExtension.authority}:${wkidExtension.vcsWkid}`;
|
|
5611
|
+
}
|
|
5612
|
+
epoch = parseCoordinateEpoch(wkidExtension.epoch);
|
|
5613
|
+
if (wkidExtension.epoch !== void 0 && epoch === void 0) {
|
|
5614
|
+
warnings.push("EXT_geospatial_crs_wkid epoch is not a finite decimal year");
|
|
5615
|
+
}
|
|
5616
|
+
} else {
|
|
5617
|
+
warnings.push("EXT_geospatial_crs_wkid requires string authority and integer wkid");
|
|
5618
|
+
}
|
|
5619
|
+
} else if (extension.format === "wkt2") {
|
|
5620
|
+
const wktExtension = (_c = extension.extensions) == null ? void 0 : _c.EXT_geospatial_crs_wkt2;
|
|
5621
|
+
if (typeof (wktExtension == null ? void 0 : wktExtension.wkt2) === "string" && wktExtension.wkt2.trim()) {
|
|
5622
|
+
sourceCrs = wktExtension.wkt2;
|
|
5623
|
+
representation = "wkt";
|
|
5624
|
+
} else {
|
|
5625
|
+
warnings.push("EXT_geospatial_crs_wkt2 requires a nonempty wkt2 string");
|
|
5626
|
+
}
|
|
5627
|
+
} else {
|
|
5628
|
+
warnings.push(`Unsupported EXT_geospatial_crs format ${String(extension.format)}`);
|
|
5629
|
+
}
|
|
5630
|
+
const coordinateFrame = representation === "wkt" ? getSpatialCoordinateFrame(sourceCrs) : getKnownCrsIdentifierCoordinateFrame(sourceCrs) || "unknown";
|
|
5631
|
+
const verticalSemantics = getDraftVerticalCrsSemantics(verticalCrs);
|
|
5632
|
+
if (verticalCrs && !verticalSemantics) {
|
|
5633
|
+
warnings.push(`Unsupported vertical CRS ${String(verticalCrs)}; vertical unit and height reference are unknown`);
|
|
5634
|
+
}
|
|
5635
|
+
const verticalUnit = verticalCrs ? verticalSemantics == null ? void 0 : verticalSemantics.unit : "meter";
|
|
5636
|
+
return createTilesetSpatialReference({
|
|
5637
|
+
sourceCrs,
|
|
5638
|
+
sourceCrsState: sourceCrs ? "explicit" : "unknown",
|
|
5639
|
+
sourceCrsRepresentation: representation,
|
|
5640
|
+
verticalCrs,
|
|
5641
|
+
coordinateEpoch: epoch,
|
|
5642
|
+
units: coordinateFrame === "geocentric" ? ["meter", "meter", "meter"] : coordinateFrame === "geographic" && verticalUnit ? ["degree", "degree", verticalUnit] : void 0,
|
|
5643
|
+
verticalUnitScale: verticalCrs ? (verticalSemantics == null ? void 0 : verticalSemantics.verticalUnitScale) ?? Number.NaN : 1,
|
|
5644
|
+
heightReference: verticalCrs ? (verticalSemantics == null ? void 0 : verticalSemantics.heightReference) ?? "unknown" : sourceCrs ? "ellipsoidal" : "unknown",
|
|
5645
|
+
coordinateFrame,
|
|
5646
|
+
axisOrder: sourceCrs ? "xyz" : "unknown",
|
|
5647
|
+
provenance: "metadata",
|
|
5648
|
+
warnings
|
|
5649
|
+
});
|
|
5650
|
+
}
|
|
5651
|
+
function getDraftVerticalCrsSemantics(verticalCrs) {
|
|
5652
|
+
if (typeof verticalCrs !== "string") {
|
|
5653
|
+
return void 0;
|
|
5654
|
+
}
|
|
5655
|
+
const epsgMatch = /^EPSG:(\d+)$/i.exec(verticalCrs);
|
|
5656
|
+
if (!epsgMatch) {
|
|
5657
|
+
return void 0;
|
|
5658
|
+
}
|
|
5659
|
+
switch (Number(epsgMatch[1])) {
|
|
5660
|
+
case 5702:
|
|
5661
|
+
// NGVD29 height (ftUS)
|
|
5662
|
+
case 6360:
|
|
5663
|
+
return {
|
|
5664
|
+
unit: "us-foot",
|
|
5665
|
+
verticalUnitScale: 1200 / 3937,
|
|
5666
|
+
heightReference: "orthometric"
|
|
5667
|
+
};
|
|
5668
|
+
case 5703:
|
|
5669
|
+
return { unit: "meter", verticalUnitScale: 1, heightReference: "orthometric" };
|
|
5670
|
+
default:
|
|
5671
|
+
return void 0;
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5281
5674
|
function parseCoordinateEpoch(value) {
|
|
5282
5675
|
if (typeof value !== "string" && typeof value !== "number") {
|
|
5283
5676
|
return void 0;
|
|
@@ -5302,41 +5695,6 @@ function getI3SVerticalCrsDefinition(spatialReference) {
|
|
|
5302
5695
|
function getCrsIdentifier(spatialReference) {
|
|
5303
5696
|
return (spatialReference == null ? void 0 : spatialReference.latestWkid) ?? (spatialReference == null ? void 0 : spatialReference.wkid);
|
|
5304
5697
|
}
|
|
5305
|
-
function getIdentifierCoordinateFrame(identifier) {
|
|
5306
|
-
if (identifier === 4978) {
|
|
5307
|
-
return "geocentric";
|
|
5308
|
-
}
|
|
5309
|
-
if (identifier === 4326 || identifier === 4490 || identifier === 4979) {
|
|
5310
|
-
return "geographic";
|
|
5311
|
-
}
|
|
5312
|
-
return "projected";
|
|
5313
|
-
}
|
|
5314
|
-
function getWktCoordinateFrame(wkt) {
|
|
5315
|
-
var _a;
|
|
5316
|
-
if (!wkt) {
|
|
5317
|
-
return "unknown";
|
|
5318
|
-
}
|
|
5319
|
-
const normalizedWkt = wkt.trim().toUpperCase();
|
|
5320
|
-
const rootKeyword = (_a = normalizedWkt.match(/^([A-Z][A-Z0-9_]*)\s*[\[(]/)) == null ? void 0 : _a[1];
|
|
5321
|
-
if (rootKeyword === "GEOCCS") {
|
|
5322
|
-
return "geocentric";
|
|
5323
|
-
}
|
|
5324
|
-
if (rootKeyword === "GEOGCS" || rootKeyword === "GEOGRAPHICCRS" || rootKeyword === "GEOGRAPHIC2DCRS" || rootKeyword === "GEOGRAPHIC3DCRS") {
|
|
5325
|
-
return "geographic";
|
|
5326
|
-
}
|
|
5327
|
-
if (rootKeyword === "PROJCS" || rootKeyword === "PROJCRS" || rootKeyword === "PROJECTEDCRS") {
|
|
5328
|
-
return "projected";
|
|
5329
|
-
}
|
|
5330
|
-
if (rootKeyword === "GEODCRS" || rootKeyword === "GEODETICCRS") {
|
|
5331
|
-
if (/\bCS\s*[\[(]\s*CARTESIAN\s*,\s*3\b/.test(normalizedWkt)) {
|
|
5332
|
-
return "geocentric";
|
|
5333
|
-
}
|
|
5334
|
-
if (/\bCS\s*[\[(]\s*ELLIPSOIDAL\s*,\s*[23]\b/.test(normalizedWkt)) {
|
|
5335
|
-
return "geographic";
|
|
5336
|
-
}
|
|
5337
|
-
}
|
|
5338
|
-
return "unknown";
|
|
5339
|
-
}
|
|
5340
5698
|
function getTilesetSemanticValue(tileset, semantic) {
|
|
5341
5699
|
var _a, _b, _c, _d;
|
|
5342
5700
|
const classIdentifier = (_a = tileset.metadata) == null ? void 0 : _a.class;
|
|
@@ -5354,131 +5712,787 @@ function getTilesetSemanticValue(tileset, semantic) {
|
|
|
5354
5712
|
return void 0;
|
|
5355
5713
|
}
|
|
5356
5714
|
|
|
5357
|
-
// dist/
|
|
5358
|
-
var
|
|
5359
|
-
var
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5715
|
+
// dist/spatial/spatial-coordinate-transformer.js
|
|
5716
|
+
var import_core10 = require("@math.gl/core");
|
|
5717
|
+
var import_geospatial7 = require("@math.gl/geospatial");
|
|
5718
|
+
var import_proj42 = require("@math.gl/proj4");
|
|
5719
|
+
|
|
5720
|
+
// dist/spatial/spatial-resource-registry.js
|
|
5721
|
+
var import_geoid = require("@math.gl/geoid");
|
|
5722
|
+
var import_proj4 = require("@math.gl/proj4");
|
|
5723
|
+
var geoidModels = /* @__PURE__ */ new Map();
|
|
5724
|
+
function registerSpatialCrs(name, definition) {
|
|
5725
|
+
validateResourceName(name, "CRS");
|
|
5726
|
+
import_proj4.Proj4Projection.defineProjectionAliases({ [name]: definition });
|
|
5366
5727
|
}
|
|
5367
|
-
function
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
const counters = { tileCount: 0, childSubtreeCount: 0 };
|
|
5371
|
-
const root = materializeAvailableTile(subtree, reference, { localLevel: 0, mortonIndex: 0 }, reference.coordinates, counters);
|
|
5372
|
-
if (!root) {
|
|
5373
|
-
throw new Error(`Invalid 3D Tiles subtree: root tile is unavailable at ${reference.subtreeUrl}`);
|
|
5374
|
-
}
|
|
5375
|
-
return { root, ...counters };
|
|
5728
|
+
function registerSpatialDatumGrid(name, data) {
|
|
5729
|
+
validateResourceName(name, "datum grid");
|
|
5730
|
+
import_proj4.Proj4Projection.registerDatumGrid(name, data);
|
|
5376
5731
|
}
|
|
5377
|
-
function
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
x: coordinates.x,
|
|
5381
|
-
y: coordinates.y,
|
|
5382
|
-
z: coordinates.z
|
|
5383
|
-
};
|
|
5384
|
-
return templateUrl.replace(/{(level|x|y|z)}/gi, (_match, coordinateName) => String(values[coordinateName.toLowerCase()]));
|
|
5732
|
+
function registerGeoidModel(name, geoid) {
|
|
5733
|
+
validateResourceName(name, "geoid model");
|
|
5734
|
+
geoidModels.set(name, geoid);
|
|
5385
5735
|
}
|
|
5386
|
-
function
|
|
5387
|
-
const
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
if (localCoordinates.localLevel + 1 < descriptor.subtreeLevels) {
|
|
5398
|
-
for (let childIndex = 0; childIndex < childCount; childIndex++) {
|
|
5399
|
-
const childCoordinates = getChildCoordinates(globalCoordinates, childIndex, descriptor.subdivisionScheme);
|
|
5400
|
-
const childHeader = materializeAvailableTile(subtree, reference, {
|
|
5401
|
-
localLevel: localCoordinates.localLevel + 1,
|
|
5402
|
-
mortonIndex: localCoordinates.mortonIndex * childCount + childIndex
|
|
5403
|
-
}, childCoordinates, counters);
|
|
5404
|
-
if (childHeader) {
|
|
5405
|
-
children.push(childHeader);
|
|
5406
|
-
}
|
|
5407
|
-
}
|
|
5408
|
-
} else {
|
|
5409
|
-
for (let childIndex = 0; childIndex < childCount; childIndex++) {
|
|
5410
|
-
const childSubtreeIndex = localCoordinates.mortonIndex * childCount + childIndex;
|
|
5411
|
-
if (getAvailabilityValue(subtree.childSubtreeAvailability, childSubtreeIndex)) {
|
|
5412
|
-
const childCoordinates = getChildCoordinates(globalCoordinates, childIndex, descriptor.subdivisionScheme);
|
|
5413
|
-
children.push(createLazyImplicitTileHeader(subtree, descriptor, childCoordinates));
|
|
5414
|
-
counters.childSubtreeCount++;
|
|
5415
|
-
}
|
|
5416
|
-
}
|
|
5417
|
-
}
|
|
5736
|
+
function registerGeoidModelFromPgm(name, data, options = {}) {
|
|
5737
|
+
const geoid = (0, import_geoid.parsePGM)(data, options);
|
|
5738
|
+
registerGeoidModel(name, geoid);
|
|
5739
|
+
return geoid;
|
|
5740
|
+
}
|
|
5741
|
+
function getGeoidModel(name) {
|
|
5742
|
+
return geoidModels.get(name);
|
|
5743
|
+
}
|
|
5744
|
+
function validateResourceName(name, resourceType) {
|
|
5745
|
+
if (!name.trim()) {
|
|
5746
|
+
throw new Error(`${resourceType} name must not be empty`);
|
|
5418
5747
|
}
|
|
5419
|
-
return formatImplicitTileHeader(subtree, descriptor, reference, globalCoordinates, contentAvailability, children);
|
|
5420
5748
|
}
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5749
|
+
|
|
5750
|
+
// dist/spatial/spatial-coordinate-transformer.js
|
|
5751
|
+
var SpatialCoordinateTransformer = class {
|
|
5752
|
+
/** Normalized spatial metadata describing this transformation. */
|
|
5753
|
+
spatialReference;
|
|
5754
|
+
/** Projection from the source CRS directly to the requested horizontal target CRS. */
|
|
5755
|
+
horizontalProjection;
|
|
5756
|
+
/** Projection from the source CRS to geographic longitude, latitude, and ellipsoidal height. */
|
|
5757
|
+
geographicProjection;
|
|
5758
|
+
/** Projection from adjusted geographic coordinates to the requested output CRS. */
|
|
5759
|
+
heightOutputProjection;
|
|
5760
|
+
/** Whether source coordinates use the WGS84 geocentric frame handled by math.gl. */
|
|
5761
|
+
sourceIsGeocentric;
|
|
5762
|
+
/** Whether output coordinates use the WGS84 geocentric frame handled by math.gl. */
|
|
5763
|
+
outputIsGeocentric;
|
|
5764
|
+
/** Whether source coordinates already use conventional WGS84 longitude/latitude order. */
|
|
5765
|
+
sourceIsGeographic;
|
|
5766
|
+
/** Whether output coordinates use conventional WGS84 longitude/latitude order. */
|
|
5767
|
+
outputIsGeographic;
|
|
5768
|
+
/** Geoid model used to convert between ellipsoidal and orthometric heights. */
|
|
5769
|
+
geoid;
|
|
5770
|
+
/**
|
|
5771
|
+
* Creates a coordinate transformer.
|
|
5772
|
+
*
|
|
5773
|
+
* @param spatialReference - Format-discovered and option-normalized spatial metadata.
|
|
5774
|
+
* @param options - Application options containing an optional geoid model.
|
|
5775
|
+
*/
|
|
5776
|
+
constructor(spatialReference, options = {}) {
|
|
5777
|
+
this.spatialReference = spatialReference;
|
|
5778
|
+
validateTransformRequest(spatialReference);
|
|
5779
|
+
const outputCrs = spatialReference.targetCrs || spatialReference.sourceCrs;
|
|
5780
|
+
this.sourceIsGeocentric = isWgs84Geocentric(spatialReference.sourceCrs);
|
|
5781
|
+
this.outputIsGeocentric = isWgs84Geocentric(outputCrs);
|
|
5782
|
+
this.sourceIsGeographic = isWgs84Geographic(spatialReference.sourceCrs);
|
|
5783
|
+
this.outputIsGeographic = isWgs84Geographic(outputCrs);
|
|
5784
|
+
if (spatialReference.sourceCrs && spatialReference.targetCrs && !this.sourceIsGeocentric && !this.outputIsGeocentric) {
|
|
5785
|
+
this.horizontalProjection = new import_proj42.Proj4Projection({
|
|
5786
|
+
from: getHorizontalProj4Definition(spatialReference.sourceCrs),
|
|
5787
|
+
to: getHorizontalProj4Definition(spatialReference.targetCrs),
|
|
5788
|
+
enforceAxis: false
|
|
5789
|
+
});
|
|
5790
|
+
}
|
|
5791
|
+
if (requiresHeightTransformation(spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
|
|
5792
|
+
if (!this.sourceIsGeographic && !this.sourceIsGeocentric) {
|
|
5793
|
+
this.geographicProjection = new import_proj42.Proj4Projection({
|
|
5794
|
+
from: getHorizontalProj4Definition(spatialReference.sourceCrs),
|
|
5795
|
+
to: WGS84_GEOGRAPHIC_CRS,
|
|
5796
|
+
enforceAxis: false
|
|
5797
|
+
});
|
|
5798
|
+
}
|
|
5799
|
+
if (!this.outputIsGeographic && !this.outputIsGeocentric) {
|
|
5800
|
+
this.heightOutputProjection = new import_proj42.Proj4Projection({
|
|
5801
|
+
from: WGS84_GEOGRAPHIC_CRS,
|
|
5802
|
+
to: getHorizontalProj4Definition(outputCrs),
|
|
5803
|
+
enforceAxis: false
|
|
5804
|
+
});
|
|
5805
|
+
}
|
|
5806
|
+
}
|
|
5807
|
+
if (requiresHeightTransformation(spatialReference)) {
|
|
5808
|
+
this.geoid = resolveGeoid(options.geoidModel);
|
|
5809
|
+
if (!this.geoid) {
|
|
5810
|
+
const modelName = typeof options.geoidModel === "string" ? ` "${options.geoidModel}"` : "";
|
|
5811
|
+
throw new Error(`Height conversion requires a registered geoid model${modelName}; call registerGeoidModel() or pass a parsed Geoid instance`);
|
|
5812
|
+
}
|
|
5813
|
+
}
|
|
5814
|
+
}
|
|
5815
|
+
/**
|
|
5816
|
+
* Transforms one `[x, y, z?]` coordinate while retaining additional components.
|
|
5817
|
+
*
|
|
5818
|
+
* @param coordinate - Source coordinate in the format adapter's normalized `x/y/z` order.
|
|
5819
|
+
* @returns A new transformed coordinate array.
|
|
5820
|
+
*/
|
|
5821
|
+
transformPosition(coordinate) {
|
|
5822
|
+
if (coordinate.length < 2) {
|
|
5823
|
+
throw new Error("A spatial coordinate must contain at least x and y components");
|
|
5824
|
+
}
|
|
5825
|
+
const result = [...coordinate];
|
|
5826
|
+
if (requiresHeightTransformation(this.spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
|
|
5827
|
+
if (result.length < 3 || !Number.isFinite(result[2])) {
|
|
5828
|
+
throw new Error("Three-dimensional CRS conversion requires a finite z coordinate");
|
|
5829
|
+
}
|
|
5830
|
+
const geographic = this.toGeographic(result);
|
|
5831
|
+
if (requiresHeightTransformation(this.spatialReference)) {
|
|
5832
|
+
const geoidUndulation = this.geoid.getHeight(geographic[1], geographic[0]);
|
|
5833
|
+
geographic[2] = transformHeight(geographic[2], geoidUndulation, this.spatialReference.heightReference, this.spatialReference.targetHeightReference);
|
|
5834
|
+
}
|
|
5835
|
+
const projected = this.fromGeographic(geographic);
|
|
5836
|
+
result.splice(0, projected.length, ...projected);
|
|
5837
|
+
return result;
|
|
5838
|
+
}
|
|
5839
|
+
if (this.horizontalProjection) {
|
|
5840
|
+
const projected = this.horizontalProjection.project(result.slice(0, 3));
|
|
5841
|
+
result.splice(0, projected.length, ...projected);
|
|
5842
|
+
}
|
|
5843
|
+
return result;
|
|
5844
|
+
}
|
|
5845
|
+
/** Transform a packed sequence of xyz positions, preserving the input array type only when safe. */
|
|
5846
|
+
transformPositions(positions) {
|
|
5847
|
+
if (positions.length % 3 !== 0) {
|
|
5848
|
+
throw new Error("Packed spatial positions must contain a multiple of three components");
|
|
5849
|
+
}
|
|
5850
|
+
const transformedPositions = new Float64Array(positions.length);
|
|
5851
|
+
for (let index = 0; index < positions.length; index += 3) {
|
|
5852
|
+
const transformed = this.transformPosition([
|
|
5853
|
+
Number(positions[index]),
|
|
5854
|
+
Number(positions[index + 1]),
|
|
5855
|
+
Number(positions[index + 2])
|
|
5856
|
+
]);
|
|
5857
|
+
transformedPositions[index] = transformed[0];
|
|
5858
|
+
transformedPositions[index + 1] = transformed[1];
|
|
5859
|
+
transformedPositions[index + 2] = transformed[2];
|
|
5860
|
+
}
|
|
5861
|
+
return transformedPositions;
|
|
5862
|
+
}
|
|
5863
|
+
/** Transform packed xyz normals using a local finite-difference tangent approximation. */
|
|
5864
|
+
transformNormals(normals, positions) {
|
|
5865
|
+
if (normals.length !== positions.length || normals.length % 3 !== 0) {
|
|
5866
|
+
throw new Error("Spatial normals and positions must have matching xyz component counts");
|
|
5867
|
+
}
|
|
5868
|
+
const transformedNormals = new Float32Array(normals.length);
|
|
5869
|
+
const epsilon = 1e-5;
|
|
5870
|
+
for (let index = 0; index < normals.length; index += 3) {
|
|
5871
|
+
const position = [
|
|
5872
|
+
Number(positions[index]),
|
|
5873
|
+
Number(positions[index + 1]),
|
|
5874
|
+
Number(positions[index + 2])
|
|
5875
|
+
];
|
|
5876
|
+
const normal = [
|
|
5877
|
+
Number(normals[index]),
|
|
5878
|
+
Number(normals[index + 1]),
|
|
5879
|
+
Number(normals[index + 2])
|
|
5880
|
+
];
|
|
5881
|
+
const jacobian = getFiniteDifferenceJacobian(this, position, epsilon);
|
|
5882
|
+
const transformedNormal = inverseTransposeMultiply(jacobian, normal);
|
|
5883
|
+
const length = Math.hypot(...transformedNormal);
|
|
5884
|
+
if (length > 0 && Number.isFinite(length)) {
|
|
5885
|
+
transformedNormals[index] = transformedNormal[0] / length;
|
|
5886
|
+
transformedNormals[index + 1] = transformedNormal[1] / length;
|
|
5887
|
+
transformedNormals[index + 2] = transformedNormal[2] / length;
|
|
5888
|
+
} else {
|
|
5889
|
+
transformedNormals[index] = normal[0];
|
|
5890
|
+
transformedNormals[index + 1] = normal[1];
|
|
5891
|
+
transformedNormals[index + 2] = normal[2];
|
|
5892
|
+
}
|
|
5893
|
+
}
|
|
5894
|
+
return transformedNormals;
|
|
5895
|
+
}
|
|
5896
|
+
/** Convert one source coordinate to conventional WGS84 longitude, latitude, and height. */
|
|
5897
|
+
toGeographic(coordinate) {
|
|
5898
|
+
if (this.sourceIsGeocentric) {
|
|
5899
|
+
return Array.from(import_geospatial7.Ellipsoid.WGS84.cartesianToCartographic(new import_core10.Vector3(coordinate)));
|
|
5900
|
+
}
|
|
5901
|
+
if (this.sourceIsGeographic) {
|
|
5902
|
+
return coordinate.slice(0, 3);
|
|
5903
|
+
}
|
|
5904
|
+
return this.geographicProjection.project(coordinate.slice(0, 3));
|
|
5905
|
+
}
|
|
5906
|
+
/** Convert one conventional WGS84 geographic coordinate to the selected output CRS. */
|
|
5907
|
+
fromGeographic(coordinate) {
|
|
5908
|
+
if (this.outputIsGeocentric) {
|
|
5909
|
+
return Array.from(import_geospatial7.Ellipsoid.WGS84.cartographicToCartesian(new import_core10.Vector3(coordinate)));
|
|
5910
|
+
}
|
|
5911
|
+
if (this.outputIsGeographic) {
|
|
5912
|
+
return coordinate.slice(0, 3);
|
|
5913
|
+
}
|
|
5914
|
+
return this.heightOutputProjection.project(coordinate.slice(0, 3));
|
|
5915
|
+
}
|
|
5916
|
+
};
|
|
5917
|
+
function getFiniteDifferenceJacobian(transformer, position, epsilon) {
|
|
5918
|
+
const columns = [];
|
|
5919
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
5920
|
+
const plus = position.slice();
|
|
5921
|
+
const minus = position.slice();
|
|
5922
|
+
plus[axis] += epsilon;
|
|
5923
|
+
minus[axis] -= epsilon;
|
|
5924
|
+
const plusPosition = transformer.transformPosition(plus);
|
|
5925
|
+
const minusPosition = transformer.transformPosition(minus);
|
|
5926
|
+
columns.push([
|
|
5927
|
+
(plusPosition[0] - minusPosition[0]) / (2 * epsilon),
|
|
5928
|
+
(plusPosition[1] - minusPosition[1]) / (2 * epsilon),
|
|
5929
|
+
(plusPosition[2] - minusPosition[2]) / (2 * epsilon)
|
|
5930
|
+
]);
|
|
5931
|
+
}
|
|
5932
|
+
return columns;
|
|
5933
|
+
}
|
|
5934
|
+
function inverseTransposeMultiply(jacobianColumns, vector) {
|
|
5935
|
+
const [a, b, c] = jacobianColumns;
|
|
5936
|
+
const determinant = a[0] * (b[1] * c[2] - b[2] * c[1]) - b[0] * (a[1] * c[2] - a[2] * c[1]) + c[0] * (a[1] * b[2] - a[2] * b[1]);
|
|
5937
|
+
if (!Number.isFinite(determinant) || Math.abs(determinant) < 1e-15) {
|
|
5938
|
+
return vector;
|
|
5939
|
+
}
|
|
5940
|
+
const inverseTranspose = [
|
|
5941
|
+
[b[1] * c[2] - b[2] * c[1], a[2] * c[1] - a[1] * c[2], a[1] * b[2] - a[2] * b[1]],
|
|
5942
|
+
[b[2] * c[0] - b[0] * c[2], a[0] * c[2] - a[2] * c[0], a[2] * b[0] - a[0] * b[2]],
|
|
5943
|
+
[b[0] * c[1] - b[1] * c[0], a[1] * c[0] - a[0] * c[1], a[0] * b[1] - a[1] * b[0]]
|
|
5944
|
+
];
|
|
5945
|
+
return inverseTranspose.map((row) => (row[0] * vector[0] + row[1] * vector[1] + row[2] * vector[2]) / determinant);
|
|
5946
|
+
}
|
|
5947
|
+
function getHorizontalProj4Definition(definition) {
|
|
5948
|
+
if (!definition) {
|
|
5949
|
+
throw new Error("Cannot construct a projection because the CRS is unknown");
|
|
5950
|
+
}
|
|
5951
|
+
return (0, import_proj42.toProj4CRSDefinition)(definition, { mode: "horizontal" });
|
|
5952
|
+
}
|
|
5953
|
+
function validateTransformRequest(spatialReference) {
|
|
5954
|
+
if (spatialReference.outputCoordinates === "local-enu") {
|
|
5955
|
+
throw new Error("local-enu output requires a dataset-derived local origin and must be created by a tileset source");
|
|
5956
|
+
}
|
|
5957
|
+
if (spatialReference.outputCoordinates === "target-crs" && !spatialReference.targetCrs) {
|
|
5958
|
+
throw new Error("target-crs output requires targetCrs");
|
|
5959
|
+
}
|
|
5960
|
+
if (!spatialReference.sourceCrs && spatialReference.status === "unresolved") {
|
|
5961
|
+
throw new Error("Cannot transform coordinates because the source CRS is unknown");
|
|
5962
|
+
}
|
|
5963
|
+
if (requiresHeightTransformation(spatialReference) && spatialReference.heightReference === "unknown") {
|
|
5964
|
+
throw new Error("Cannot convert heights because the source height reference is unknown");
|
|
5965
|
+
}
|
|
5966
|
+
if (spatialReference.coordinateFrame === "geocentric" && !isWgs84Geocentric(spatialReference.sourceCrs)) {
|
|
5967
|
+
throw new Error("Only EPSG:4978 geocentric coordinates are supported by the current spatial transformer");
|
|
5968
|
+
}
|
|
5969
|
+
if (spatialReference.status === "unresolved") {
|
|
5970
|
+
throw new Error("The requested spatial output cannot be resolved from the available metadata");
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
function isWgs84Geocentric(definition) {
|
|
5974
|
+
return typeof definition === "string" && normalizeCrsIdentifier(definition) === WGS84_GEOCENTRIC_CRS;
|
|
5975
|
+
}
|
|
5976
|
+
function isWgs84Geographic(definition) {
|
|
5977
|
+
if (typeof definition !== "string") {
|
|
5978
|
+
return false;
|
|
5979
|
+
}
|
|
5980
|
+
const identifier = normalizeCrsIdentifier(definition);
|
|
5981
|
+
return identifier === WGS84_GEOGRAPHIC_CRS || identifier === "EPSG:4979" || identifier === "OGC:CRS84";
|
|
5982
|
+
}
|
|
5983
|
+
function requiresHeightTransformation(spatialReference) {
|
|
5984
|
+
const target = spatialReference.targetHeightReference;
|
|
5985
|
+
return target !== "native" && target !== spatialReference.heightReference;
|
|
5986
|
+
}
|
|
5987
|
+
function resolveGeoid(model) {
|
|
5988
|
+
return typeof model === "string" ? getGeoidModel(model) : model;
|
|
5989
|
+
}
|
|
5990
|
+
function transformHeight(height, geoidUndulation, source, target) {
|
|
5991
|
+
if (source === target || target === "native") {
|
|
5992
|
+
return height;
|
|
5993
|
+
}
|
|
5994
|
+
if (source === "orthometric" && target === "ellipsoidal") {
|
|
5995
|
+
return height + geoidUndulation;
|
|
5996
|
+
}
|
|
5997
|
+
if (source === "ellipsoidal" && target === "orthometric") {
|
|
5998
|
+
return height - geoidUndulation;
|
|
5999
|
+
}
|
|
6000
|
+
throw new Error(`Unsupported height conversion from ${source} to ${target}`);
|
|
6001
|
+
}
|
|
6002
|
+
|
|
6003
|
+
// dist/spatial/tiles-3d-spatial-transformer.js
|
|
6004
|
+
var import_core11 = require("@math.gl/core");
|
|
6005
|
+
var import_geospatial8 = require("@math.gl/geospatial");
|
|
6006
|
+
var Tiles3DSpatialTransformer = class {
|
|
6007
|
+
/** Normalized reference describing the completed operation. */
|
|
6008
|
+
spatialReference;
|
|
6009
|
+
coordinateTransformer;
|
|
6010
|
+
geographicCoordinateTransformer;
|
|
6011
|
+
/** Creates a 3D Tiles transformer for a requested target CRS. */
|
|
6012
|
+
constructor(spatialReference, options = {}) {
|
|
6013
|
+
this.coordinateTransformer = new SpatialCoordinateTransformer(spatialReference, options);
|
|
6014
|
+
const geographicSpatialReference = {
|
|
6015
|
+
...spatialReference,
|
|
6016
|
+
sourceCrs: "EPSG:4326",
|
|
6017
|
+
targetCrs: spatialReference.targetCrs || spatialReference.sourceCrs,
|
|
6018
|
+
coordinateFrame: "geographic",
|
|
6019
|
+
axisOrder: "xy"
|
|
6020
|
+
};
|
|
6021
|
+
this.geographicCoordinateTransformer = new SpatialCoordinateTransformer(geographicSpatialReference, options);
|
|
6022
|
+
this.spatialReference = spatialReference;
|
|
6023
|
+
}
|
|
6024
|
+
/** Transform packed POSITION values into the target CRS. */
|
|
6025
|
+
transformPositions(positions) {
|
|
6026
|
+
return this.coordinateTransformer.transformPositions(positions);
|
|
6027
|
+
}
|
|
6028
|
+
/** Transform packed NORMAL values using the corresponding source positions. */
|
|
6029
|
+
transformNormals(normals, positions) {
|
|
6030
|
+
return this.coordinateTransformer.transformNormals(normals, positions);
|
|
6031
|
+
}
|
|
6032
|
+
/** Rebuild a conservative target-frame volume from a source volume. */
|
|
6033
|
+
transformBoundingVolume(volume, sourceTransform) {
|
|
6034
|
+
const transform = sourceTransform ? new import_core11.Matrix4(Array.from(sourceTransform)) : void 0;
|
|
6035
|
+
const samples = volume.region ? getRegionSamples(volume.region) : getVolumeSamples(volume).map((sample) => transform ? Array.from(transform.transformAsPoint(sample)) : sample);
|
|
6036
|
+
if (!samples.length) {
|
|
6037
|
+
return volume;
|
|
6038
|
+
}
|
|
6039
|
+
const transformed = volume.region ? samples.map((sample) => this.transformRegionSample(sample)) : samples.map((sample) => this.coordinateTransformer.transformPosition(sample));
|
|
6040
|
+
return { box: createAxisAlignedBox(transformed) };
|
|
6041
|
+
}
|
|
6042
|
+
/** Transforms one WGS84 region sample into the selected output frame. */
|
|
6043
|
+
transformRegionSample(sample) {
|
|
6044
|
+
const [longitudeDegrees, latitudeDegrees, height] = sample;
|
|
6045
|
+
const targetCrs = this.spatialReference.targetCrs || this.spatialReference.sourceCrs;
|
|
6046
|
+
if (targetCrs && getSpatialCoordinateFrame(targetCrs) === "geocentric") {
|
|
6047
|
+
const cartesian = import_geospatial8.Ellipsoid.WGS84.cartographicToCartesian([
|
|
6048
|
+
longitudeDegrees,
|
|
6049
|
+
latitudeDegrees,
|
|
6050
|
+
height
|
|
6051
|
+
]);
|
|
6052
|
+
return Array.from(cartesian);
|
|
6053
|
+
}
|
|
6054
|
+
return this.geographicCoordinateTransformer.transformPosition(sample);
|
|
6055
|
+
}
|
|
6056
|
+
};
|
|
6057
|
+
function getRegionSamples(region) {
|
|
6058
|
+
if (region.length < 6 || region.some((value) => !Number.isFinite(value))) {
|
|
6059
|
+
return [];
|
|
6060
|
+
}
|
|
6061
|
+
const [west, south, east, north, minimumHeight, maximumHeight] = region;
|
|
6062
|
+
const longitudeEnd = east < west ? east + Math.PI * 2 : east;
|
|
6063
|
+
const longitudes = getIntervalSamples(west, longitudeEnd);
|
|
6064
|
+
const latitudes = getIntervalSamples(south, north);
|
|
6065
|
+
const samples = [];
|
|
6066
|
+
for (const longitude of longitudes) {
|
|
6067
|
+
for (const latitude of latitudes) {
|
|
6068
|
+
for (const height of [minimumHeight, maximumHeight]) {
|
|
6069
|
+
samples.push([longitude * 180 / Math.PI, latitude * 180 / Math.PI, height]);
|
|
6070
|
+
}
|
|
6071
|
+
}
|
|
6072
|
+
}
|
|
6073
|
+
return samples;
|
|
6074
|
+
}
|
|
6075
|
+
function getIntervalSamples(start, end) {
|
|
6076
|
+
const samples = [start, (start + end) / 2, end];
|
|
6077
|
+
const angularStep = Math.PI / 2;
|
|
6078
|
+
const firstCriticalIndex = Math.ceil(start / angularStep);
|
|
6079
|
+
const lastCriticalIndex = Math.floor(end / angularStep);
|
|
6080
|
+
for (let criticalIndex = firstCriticalIndex; criticalIndex <= lastCriticalIndex; criticalIndex++) {
|
|
6081
|
+
samples.push(criticalIndex * angularStep);
|
|
6082
|
+
}
|
|
6083
|
+
return samples;
|
|
6084
|
+
}
|
|
6085
|
+
function getVolumeSamples(volume) {
|
|
6086
|
+
if (volume.box && volume.box.length >= 12) {
|
|
6087
|
+
const center = volume.box.slice(0, 3);
|
|
6088
|
+
const axes = [volume.box.slice(3, 6), volume.box.slice(6, 9), volume.box.slice(9, 12)];
|
|
6089
|
+
const samples = [];
|
|
6090
|
+
for (let firstIndex = 0; firstIndex <= 4; firstIndex++) {
|
|
6091
|
+
for (let secondIndex = 0; secondIndex <= 4; secondIndex++) {
|
|
6092
|
+
for (let thirdIndex = 0; thirdIndex <= 4; thirdIndex++) {
|
|
6093
|
+
const first = firstIndex / 2 - 1;
|
|
6094
|
+
const second = secondIndex / 2 - 1;
|
|
6095
|
+
const third = thirdIndex / 2 - 1;
|
|
6096
|
+
samples.push([
|
|
6097
|
+
center[0] + first * axes[0][0] + second * axes[1][0] + third * axes[2][0],
|
|
6098
|
+
center[1] + first * axes[0][1] + second * axes[1][1] + third * axes[2][1],
|
|
6099
|
+
center[2] + first * axes[0][2] + second * axes[1][2] + third * axes[2][2]
|
|
6100
|
+
]);
|
|
6101
|
+
}
|
|
6102
|
+
}
|
|
6103
|
+
}
|
|
6104
|
+
return samples;
|
|
6105
|
+
}
|
|
6106
|
+
if (volume.sphere && volume.sphere.length >= 4) {
|
|
6107
|
+
const [x, y, z, radius] = volume.sphere;
|
|
6108
|
+
const samples = [
|
|
6109
|
+
[x - radius, y, z],
|
|
6110
|
+
[x + radius, y, z],
|
|
6111
|
+
[x, y - radius, z],
|
|
6112
|
+
[x, y + radius, z],
|
|
6113
|
+
[x, y, z - radius],
|
|
6114
|
+
[x, y, z + radius]
|
|
6115
|
+
];
|
|
6116
|
+
for (let longitudeIndex = 0; longitudeIndex < 16; longitudeIndex++) {
|
|
6117
|
+
const longitude = longitudeIndex * Math.PI * 2 / 16;
|
|
6118
|
+
samples.push([x + radius * Math.cos(longitude), y + radius * Math.sin(longitude), z]);
|
|
6119
|
+
}
|
|
6120
|
+
return samples;
|
|
6121
|
+
}
|
|
6122
|
+
return [];
|
|
6123
|
+
}
|
|
6124
|
+
function createAxisAlignedBox(samples) {
|
|
6125
|
+
const minimum = [Infinity, Infinity, Infinity];
|
|
6126
|
+
const maximum = [-Infinity, -Infinity, -Infinity];
|
|
6127
|
+
for (const sample of samples) {
|
|
6128
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
6129
|
+
minimum[axis] = Math.min(minimum[axis], sample[axis]);
|
|
6130
|
+
maximum[axis] = Math.max(maximum[axis], sample[axis]);
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6133
|
+
const padding = [
|
|
6134
|
+
Math.max((maximum[0] - minimum[0]) * 0.01, 1e-9),
|
|
6135
|
+
Math.max((maximum[1] - minimum[1]) * 0.01, 1e-9),
|
|
6136
|
+
Math.max((maximum[2] - minimum[2]) * 0.01, 1e-9)
|
|
6137
|
+
];
|
|
6138
|
+
const center = [
|
|
6139
|
+
(minimum[0] + maximum[0]) / 2,
|
|
6140
|
+
(minimum[1] + maximum[1]) / 2,
|
|
6141
|
+
(minimum[2] + maximum[2]) / 2
|
|
6142
|
+
];
|
|
6143
|
+
return [
|
|
6144
|
+
...center,
|
|
6145
|
+
(maximum[0] - minimum[0]) / 2 + padding[0],
|
|
6146
|
+
0,
|
|
6147
|
+
0,
|
|
6148
|
+
0,
|
|
6149
|
+
(maximum[1] - minimum[1]) / 2 + padding[1],
|
|
6150
|
+
0,
|
|
6151
|
+
0,
|
|
6152
|
+
0,
|
|
6153
|
+
(maximum[2] - minimum[2]) / 2 + padding[2]
|
|
6154
|
+
];
|
|
6155
|
+
}
|
|
6156
|
+
|
|
6157
|
+
// dist/tileset-3d/format-3d-tiles/implicit-tiling.js
|
|
6158
|
+
var import_s22 = require("@math.gl/dggs/s2");
|
|
6159
|
+
|
|
6160
|
+
// dist/tileset-3d/helpers/s2-bounding-volume.js
|
|
6161
|
+
var import_s2 = require("@math.gl/dggs/s2");
|
|
6162
|
+
var import_geospatial9 = require("@math.gl/geospatial");
|
|
6163
|
+
function convertS2BoundingVolumeToOBB(s2VolumeInfo) {
|
|
6164
|
+
const [[west, south], [east, north]] = (0, import_s2.getS2Bounds)(s2VolumeInfo.token);
|
|
6165
|
+
const orientedBoundingBox = (0, import_geospatial9.makeOBBFromRegion)([west, south, east, north, s2VolumeInfo.minimumHeight, s2VolumeInfo.maximumHeight], import_geospatial9.Ellipsoid.WGS84, { units: "degrees" });
|
|
6166
|
+
return [...orientedBoundingBox.center, ...orientedBoundingBox.halfAxes];
|
|
6167
|
+
}
|
|
6168
|
+
|
|
6169
|
+
// dist/tileset-3d/format-3d-tiles/implicit-tiling.js
|
|
6170
|
+
var QUADTREE_CHILD_COUNT = 4;
|
|
6171
|
+
var OCTREE_CHILD_COUNT = 8;
|
|
6172
|
+
var AVAILABILITY_RANK_CACHE = /* @__PURE__ */ new WeakMap();
|
|
6173
|
+
function createImplicitSubtreeReference(descriptor, coordinates) {
|
|
6174
|
+
return {
|
|
6175
|
+
coordinates,
|
|
6176
|
+
subtreeUrl: replaceImplicitUrlTemplate(descriptor.subtreesUrlTemplate, coordinates),
|
|
6177
|
+
descriptor,
|
|
6178
|
+
resource: findImplicitPackageResource(descriptor.resourceFiles, replaceImplicitUrlTemplate(descriptor.subtreesUrlTemplate, coordinates))
|
|
6179
|
+
};
|
|
6180
|
+
}
|
|
6181
|
+
function materializeImplicitSubtree(subtree, reference) {
|
|
6182
|
+
const { descriptor } = reference;
|
|
6183
|
+
validateImplicitDescriptor(descriptor);
|
|
6184
|
+
validateImplicitSubtree(subtree, descriptor);
|
|
6185
|
+
const counters = { tileCount: 0, childSubtreeCount: 0 };
|
|
6186
|
+
const root = materializeAvailableTile(subtree, reference, { localLevel: 0, mortonIndex: 0 }, reference.coordinates, counters);
|
|
6187
|
+
if (!root) {
|
|
6188
|
+
throw new Error(`Invalid 3D Tiles subtree: root tile is unavailable at ${reference.subtreeUrl}`);
|
|
6189
|
+
}
|
|
6190
|
+
return { root, ...counters };
|
|
6191
|
+
}
|
|
6192
|
+
function validateImplicitSubtree(subtree, descriptor) {
|
|
6193
|
+
const childCount = getImplicitChildCount(descriptor.subdivisionScheme);
|
|
6194
|
+
const tileElementCount = (childCount ** descriptor.subtreeLevels - 1) / (childCount - 1);
|
|
6195
|
+
const childSubtreeElementCount = childCount ** descriptor.subtreeLevels;
|
|
6196
|
+
validateAvailabilityLength(subtree.tileAvailability, tileElementCount, "tile");
|
|
6197
|
+
const contentAvailabilityStreams = Array.isArray(subtree.contentAvailability) ? subtree.contentAvailability : subtree.contentAvailability ? [subtree.contentAvailability] : [];
|
|
6198
|
+
for (const contentAvailability of contentAvailabilityStreams) {
|
|
6199
|
+
validateAvailabilityLength(contentAvailability, tileElementCount, "content");
|
|
6200
|
+
}
|
|
6201
|
+
validateAvailabilityLength(subtree.childSubtreeAvailability, childSubtreeElementCount, "child subtree");
|
|
6202
|
+
const availableTileCount = countAvailableElements(subtree.tileAvailability, tileElementCount);
|
|
6203
|
+
const availableContentCount = contentAvailabilityStreams[0] ? countAvailableElements(contentAvailabilityStreams[0], tileElementCount) : 0;
|
|
6204
|
+
validateAttributeLengths(subtree.tileAttributes, availableTileCount, "tile");
|
|
6205
|
+
validateAttributeLengths(subtree.contentAttributes, availableContentCount, "content");
|
|
6206
|
+
if (subtree.tilePropertyRows && subtree.tilePropertyRows.length !== availableTileCount) {
|
|
6207
|
+
throw new Error("3DTILES_subtree: tile property-table count does not match availability");
|
|
6208
|
+
}
|
|
6209
|
+
if (subtree.contentPropertyRows && subtree.contentPropertyRows.length !== availableContentCount) {
|
|
6210
|
+
throw new Error("3DTILES_subtree: content property-table count does not match availability");
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
function validateAvailabilityLength(availability, elementCount, label) {
|
|
6214
|
+
if (availability.constant === 0 || availability.constant === 1) {
|
|
6215
|
+
return;
|
|
6216
|
+
}
|
|
6217
|
+
if (!availability.explicitBitstream || availability.explicitBitstream.byteLength * 8 < elementCount) {
|
|
6218
|
+
throw new Error(`3DTILES_subtree: ${label} availability bitstream is too short`);
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
function countAvailableElements(availability, elementCount) {
|
|
6222
|
+
if (availability.constant === 1) {
|
|
6223
|
+
return elementCount;
|
|
6224
|
+
}
|
|
6225
|
+
if (availability.constant === 0) {
|
|
6226
|
+
return 0;
|
|
6227
|
+
}
|
|
6228
|
+
let availableCount = 0;
|
|
6229
|
+
for (let index = 0; index < elementCount; index++) {
|
|
6230
|
+
if (getAvailabilityValue(availability, index)) {
|
|
6231
|
+
availableCount++;
|
|
6232
|
+
}
|
|
6233
|
+
}
|
|
6234
|
+
return availableCount;
|
|
6235
|
+
}
|
|
6236
|
+
function validateAttributeLengths(attributes, availableCount, label) {
|
|
6237
|
+
const componentCounts = {
|
|
6238
|
+
TILE_BOUNDING_BOX: 16,
|
|
6239
|
+
TILE_BOUNDING_SPHERE: 4,
|
|
6240
|
+
TILE_GEOMETRIC_ERROR: 1,
|
|
6241
|
+
TILE_REFINE: 1,
|
|
6242
|
+
TILE_TRANSFORM: 16,
|
|
6243
|
+
CONTENT_BOUNDING_BOX: 16,
|
|
6244
|
+
CONTENT_BOUNDING_SPHERE: 4
|
|
6245
|
+
};
|
|
6246
|
+
for (const [semantic, values] of Object.entries(attributes || {})) {
|
|
6247
|
+
const componentCount = componentCounts[semantic];
|
|
6248
|
+
if (componentCount && values.length !== availableCount * componentCount) {
|
|
6249
|
+
throw new Error(`3DTILES_subtree: ${label} attribute ${semantic} count does not match availability`);
|
|
6250
|
+
}
|
|
6251
|
+
}
|
|
6252
|
+
}
|
|
6253
|
+
function replaceImplicitUrlTemplate(templateUrl, coordinates, properties = {}) {
|
|
6254
|
+
const values = {
|
|
6255
|
+
level: coordinates.level,
|
|
6256
|
+
x: coordinates.x,
|
|
6257
|
+
y: coordinates.y,
|
|
6258
|
+
z: coordinates.z,
|
|
6259
|
+
...properties
|
|
6260
|
+
};
|
|
6261
|
+
return templateUrl.replace(/{([^{}]+)}/g, (match, propertyName) => {
|
|
6262
|
+
const value = Object.hasOwn(values, propertyName) ? values[propertyName] : values[propertyName.toLowerCase()];
|
|
6263
|
+
return value === void 0 ? match : String(value);
|
|
6264
|
+
});
|
|
6265
|
+
}
|
|
6266
|
+
function materializeAvailableTile(subtree, reference, localCoordinates, globalCoordinates, counters) {
|
|
6267
|
+
const { descriptor } = reference;
|
|
6268
|
+
const childCount = getImplicitChildCount(descriptor.subdivisionScheme);
|
|
6269
|
+
const availabilityIndex = getLevelOffset(childCount, localCoordinates.localLevel) + localCoordinates.mortonIndex;
|
|
6270
|
+
if (!getAvailabilityValue(subtree.tileAvailability, availabilityIndex)) {
|
|
6271
|
+
return null;
|
|
6272
|
+
}
|
|
6273
|
+
counters.tileCount++;
|
|
6274
|
+
const contentAvailability = getContentAvailability(subtree.contentAvailability, availabilityIndex);
|
|
6275
|
+
const children = [];
|
|
6276
|
+
if (globalCoordinates.level < descriptor.maximumLevel) {
|
|
6277
|
+
if (localCoordinates.localLevel + 1 < descriptor.subtreeLevels) {
|
|
6278
|
+
for (let childIndex = 0; childIndex < childCount; childIndex++) {
|
|
6279
|
+
const childCoordinates = getChildCoordinates(globalCoordinates, childIndex, descriptor.subdivisionScheme);
|
|
6280
|
+
const childHeader = materializeAvailableTile(subtree, reference, {
|
|
6281
|
+
localLevel: localCoordinates.localLevel + 1,
|
|
6282
|
+
mortonIndex: localCoordinates.mortonIndex * childCount + childIndex
|
|
6283
|
+
}, childCoordinates, counters);
|
|
6284
|
+
if (childHeader) {
|
|
6285
|
+
children.push(childHeader);
|
|
6286
|
+
}
|
|
6287
|
+
}
|
|
6288
|
+
} else {
|
|
6289
|
+
for (let childIndex = 0; childIndex < childCount; childIndex++) {
|
|
6290
|
+
const childSubtreeIndex = localCoordinates.mortonIndex * childCount + childIndex;
|
|
6291
|
+
if (getAvailabilityValue(subtree.childSubtreeAvailability, childSubtreeIndex)) {
|
|
6292
|
+
const childCoordinates = getChildCoordinates(globalCoordinates, childIndex, descriptor.subdivisionScheme);
|
|
6293
|
+
children.push(createLazyImplicitTileHeader(subtree, descriptor, childCoordinates));
|
|
6294
|
+
counters.childSubtreeCount++;
|
|
6295
|
+
}
|
|
6296
|
+
}
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
return formatImplicitTileHeader(subtree, descriptor, reference, globalCoordinates, availabilityIndex, contentAvailability, children);
|
|
6300
|
+
}
|
|
6301
|
+
function createLazyImplicitTileHeader(subtree, descriptor, coordinates) {
|
|
6302
|
+
const resourceFiles = mergeImplicitPackageFiles(descriptor.resourceFiles, subtree.resourceFiles);
|
|
6303
|
+
const childDescriptor = resourceFiles ? { ...descriptor, resourceFiles } : descriptor;
|
|
6304
|
+
const reference = createImplicitSubtreeReference(childDescriptor, coordinates);
|
|
6305
|
+
return {
|
|
6306
|
+
id: getImplicitTileId(reference, coordinates),
|
|
6307
|
+
children: [],
|
|
6308
|
+
implicitSubtree: reference,
|
|
6309
|
+
boundingVolume: calculateImplicitBoundingVolume(descriptor.rootBoundingVolume, coordinates, descriptor.subdivisionScheme),
|
|
6310
|
+
geometricError: descriptor.rootLodMetricValue / 2 ** coordinates.level,
|
|
5429
6311
|
lodMetricType: descriptor.lodMetricType,
|
|
5430
6312
|
lodMetricValue: descriptor.rootLodMetricValue / 2 ** coordinates.level,
|
|
5431
6313
|
refine: descriptor.refine,
|
|
5432
6314
|
type: TILE_TYPE.EMPTY,
|
|
5433
|
-
implicitMetadata: getImplicitSubtreeMetadata(subtree)
|
|
6315
|
+
implicitMetadata: getImplicitSubtreeMetadata(subtree),
|
|
6316
|
+
_scaleGeometricError: descriptor.scaleGeometricError !== false
|
|
6317
|
+
};
|
|
6318
|
+
}
|
|
6319
|
+
function getSubtreeAttributeOverrides(attributes, rowIndex, scope) {
|
|
6320
|
+
var _a, _b;
|
|
6321
|
+
if (!attributes || rowIndex < 0) {
|
|
6322
|
+
return {};
|
|
6323
|
+
}
|
|
6324
|
+
const box = getAttributeComponents(attributes[scope === "tile" ? "TILE_BOUNDING_BOX" : "CONTENT_BOUNDING_BOX"], rowIndex, 16);
|
|
6325
|
+
const sphere = getAttributeComponents(attributes[scope === "tile" ? "TILE_BOUNDING_SPHERE" : "CONTENT_BOUNDING_SPHERE"], rowIndex, 4);
|
|
6326
|
+
const boundingVolume = box ? {
|
|
6327
|
+
box: [
|
|
6328
|
+
box[12],
|
|
6329
|
+
box[13],
|
|
6330
|
+
box[14],
|
|
6331
|
+
box[0] / 2,
|
|
6332
|
+
box[1] / 2,
|
|
6333
|
+
box[2] / 2,
|
|
6334
|
+
box[4] / 2,
|
|
6335
|
+
box[5] / 2,
|
|
6336
|
+
box[6] / 2,
|
|
6337
|
+
box[8] / 2,
|
|
6338
|
+
box[9] / 2,
|
|
6339
|
+
box[10] / 2
|
|
6340
|
+
]
|
|
6341
|
+
} : sphere ? { sphere } : void 0;
|
|
6342
|
+
if (scope === "content") {
|
|
6343
|
+
return { boundingVolume };
|
|
6344
|
+
}
|
|
6345
|
+
const geometricError = (_a = getAttributeComponents(attributes.TILE_GEOMETRIC_ERROR, rowIndex, 1)) == null ? void 0 : _a[0];
|
|
6346
|
+
if (geometricError !== void 0 && (!Number.isFinite(geometricError) || geometricError < 0)) {
|
|
6347
|
+
throw new Error("3DTILES_subtree: TILE_GEOMETRIC_ERROR must be nonnegative");
|
|
6348
|
+
}
|
|
6349
|
+
const refineValue = (_b = getAttributeComponents(attributes.TILE_REFINE, rowIndex, 1)) == null ? void 0 : _b[0];
|
|
6350
|
+
if (refineValue !== void 0 && refineValue !== 0 && refineValue !== 1) {
|
|
6351
|
+
throw new Error("3DTILES_subtree: TILE_REFINE must be 0 or 1");
|
|
6352
|
+
}
|
|
6353
|
+
return {
|
|
6354
|
+
boundingVolume,
|
|
6355
|
+
geometricError,
|
|
6356
|
+
refine: refineValue === void 0 ? void 0 : refineValue === 0 ? TILE_REFINEMENT.ADD : TILE_REFINEMENT.REPLACE,
|
|
6357
|
+
transform: getAttributeComponents(attributes.TILE_TRANSFORM, rowIndex, 16)
|
|
5434
6358
|
};
|
|
5435
6359
|
}
|
|
5436
|
-
function
|
|
6360
|
+
function getAttributeComponents(values, rowIndex, componentCount) {
|
|
6361
|
+
if (!values) {
|
|
6362
|
+
return void 0;
|
|
6363
|
+
}
|
|
6364
|
+
const offset = rowIndex * componentCount;
|
|
6365
|
+
if (offset + componentCount > values.length) {
|
|
6366
|
+
throw new Error("3DTILES_subtree: attribute accessor is shorter than availability");
|
|
6367
|
+
}
|
|
6368
|
+
return Array.from({ length: componentCount }, (_unused, componentIndex) => Number(values[offset + componentIndex]));
|
|
6369
|
+
}
|
|
6370
|
+
function getAvailabilityRank(availability, index) {
|
|
6371
|
+
var _a;
|
|
6372
|
+
if (availability.constant === 1) {
|
|
6373
|
+
return index;
|
|
6374
|
+
}
|
|
6375
|
+
if (availability.constant === 0) {
|
|
6376
|
+
return 0;
|
|
6377
|
+
}
|
|
6378
|
+
let ranks = AVAILABILITY_RANK_CACHE.get(availability);
|
|
6379
|
+
if (!ranks) {
|
|
6380
|
+
const bitCount = (((_a = availability.explicitBitstream) == null ? void 0 : _a.byteLength) || 0) * 8;
|
|
6381
|
+
ranks = new Uint32Array(bitCount + 1);
|
|
6382
|
+
for (let candidateIndex = 0; candidateIndex < bitCount; candidateIndex++) {
|
|
6383
|
+
ranks[candidateIndex + 1] = ranks[candidateIndex] + Number(getAvailabilityValue(availability, candidateIndex));
|
|
6384
|
+
}
|
|
6385
|
+
AVAILABILITY_RANK_CACHE.set(availability, ranks);
|
|
6386
|
+
}
|
|
6387
|
+
return ranks[index];
|
|
6388
|
+
}
|
|
6389
|
+
function findImplicitPackageResource(files, resourceUrl) {
|
|
5437
6390
|
var _a;
|
|
5438
|
-
|
|
6391
|
+
if (!(files == null ? void 0 : files.length)) {
|
|
6392
|
+
return void 0;
|
|
6393
|
+
}
|
|
6394
|
+
const urlWithoutQuery = resourceUrl.split("?")[0];
|
|
6395
|
+
const packageRelativePath = (_a = /^gltf-package:\/\/[^/]+\/(.*)$/.exec(urlWithoutQuery)) == null ? void 0 : _a[1];
|
|
6396
|
+
const exactFileIndex = files.findIndex((file) => {
|
|
6397
|
+
const reference = file.originalUri || file.name;
|
|
6398
|
+
return file.uri === urlWithoutQuery || Boolean(reference && (urlWithoutQuery === reference || packageRelativePath === reference));
|
|
6399
|
+
});
|
|
6400
|
+
if (exactFileIndex >= 0) {
|
|
6401
|
+
return { fileIndex: exactFileIndex, files };
|
|
6402
|
+
}
|
|
6403
|
+
const fileIndex = files.findIndex((file) => {
|
|
6404
|
+
const reference = file.originalUri || file.name;
|
|
6405
|
+
return Boolean(reference && (urlWithoutQuery.endsWith(`/${reference}`) || urlWithoutQuery.endsWith(`:${reference}`)));
|
|
6406
|
+
});
|
|
6407
|
+
return fileIndex < 0 ? void 0 : { fileIndex, files };
|
|
6408
|
+
}
|
|
6409
|
+
function mergeImplicitPackageFiles(parentFiles, childFiles) {
|
|
6410
|
+
if (!(childFiles == null ? void 0 : childFiles.length)) {
|
|
6411
|
+
return parentFiles;
|
|
6412
|
+
}
|
|
6413
|
+
if (!(parentFiles == null ? void 0 : parentFiles.length)) {
|
|
6414
|
+
return childFiles;
|
|
6415
|
+
}
|
|
6416
|
+
const childReferences = new Set(childFiles.flatMap((file) => [file.uri, file.originalUri, file.name].filter(Boolean)));
|
|
6417
|
+
return [
|
|
6418
|
+
...childFiles,
|
|
6419
|
+
...parentFiles.filter((file) => ![file.uri, file.originalUri, file.name].some((reference) => reference && childReferences.has(reference)))
|
|
6420
|
+
];
|
|
6421
|
+
}
|
|
6422
|
+
function formatImplicitTileHeader(subtree, descriptor, reference, coordinates, availabilityIndex, contentAvailability, children) {
|
|
6423
|
+
var _a, _b, _c, _d, _e;
|
|
6424
|
+
const tilePropertyIndex = getAvailabilityRank(subtree.tileAvailability, availabilityIndex);
|
|
6425
|
+
const tileProperties = (_a = subtree.tilePropertyRows) == null ? void 0 : _a[tilePropertyIndex];
|
|
6426
|
+
const primaryContentAvailability = Array.isArray(subtree.contentAvailability) ? subtree.contentAvailability[0] : subtree.contentAvailability;
|
|
6427
|
+
const contentPropertyIndex = primaryContentAvailability && getAvailabilityValue(primaryContentAvailability, availabilityIndex) ? getAvailabilityRank(primaryContentAvailability, availabilityIndex) : -1;
|
|
6428
|
+
const contentProperties = (_b = subtree.contentPropertyRows) == null ? void 0 : _b[contentPropertyIndex];
|
|
6429
|
+
const tileTemplateProperties = ((_c = subtree.tileTemplatePropertyRows) == null ? void 0 : _c[tilePropertyIndex]) || tileProperties;
|
|
6430
|
+
const contentTemplateProperties = ((_d = subtree.contentTemplatePropertyRows) == null ? void 0 : _d[contentPropertyIndex]) || contentProperties;
|
|
6431
|
+
const templateProperties = { ...tileTemplateProperties, ...contentTemplateProperties };
|
|
6432
|
+
const tileAttributes = getSubtreeAttributeOverrides(subtree.tileAttributes, tilePropertyIndex, "tile");
|
|
6433
|
+
const contentAttributes = getSubtreeAttributeOverrides(subtree.contentAttributes, contentPropertyIndex, "content");
|
|
6434
|
+
const contentUrlTemplates = ((_e = descriptor.contentUrlTemplates) == null ? void 0 : _e.length) ? descriptor.contentUrlTemplates : [descriptor.contentUrlTemplate];
|
|
5439
6435
|
const contentEntries = contentUrlTemplates.map((templateUrl, contentIndex) => {
|
|
5440
6436
|
if (!contentAvailability[contentIndex] || !templateUrl) {
|
|
5441
6437
|
return null;
|
|
5442
6438
|
}
|
|
6439
|
+
const contentUrl2 = replaceImplicitUrlTemplate(templateUrl, coordinates, templateProperties);
|
|
6440
|
+
if (/{[^{}]+}/.test(contentUrl2)) {
|
|
6441
|
+
throw new Error(`Implicit content URI has unresolved template values: ${contentUrl2}`);
|
|
6442
|
+
}
|
|
5443
6443
|
return {
|
|
5444
6444
|
contentIndex,
|
|
5445
|
-
contentUrl:
|
|
6445
|
+
contentUrl: contentUrl2
|
|
5446
6446
|
};
|
|
5447
6447
|
}).filter((entry) => Boolean(entry));
|
|
5448
6448
|
const availableContentUrls = contentEntries.map((entry) => entry.contentUrl);
|
|
6449
|
+
const resourceFiles = mergeImplicitPackageFiles(descriptor.resourceFiles, subtree.resourceFiles);
|
|
5449
6450
|
const content = contentEntries.map(({ contentIndex, contentUrl: contentUrl2 }) => {
|
|
5450
6451
|
var _a2;
|
|
6452
|
+
const packageResource = findImplicitPackageResource(resourceFiles, contentUrl2);
|
|
5451
6453
|
return {
|
|
5452
6454
|
...((_a2 = descriptor.contentHeaders) == null ? void 0 : _a2[contentIndex]) || (contentIndex === 0 ? descriptor.contentHeader : {}) || {},
|
|
5453
|
-
|
|
6455
|
+
...contentAttributes,
|
|
6456
|
+
uri: contentUrl2,
|
|
6457
|
+
...contentProperties ? { metadata: { properties: contentProperties } } : {},
|
|
6458
|
+
...packageResource ? { _resource: packageResource } : {}
|
|
5454
6459
|
};
|
|
5455
6460
|
});
|
|
5456
6461
|
const contentUrl = availableContentUrls[0];
|
|
5457
|
-
const
|
|
6462
|
+
const computedLodMetricValue = descriptor.rootLodMetricValue / 2 ** coordinates.level;
|
|
6463
|
+
const lodMetricValue = tileAttributes.geometricError ?? computedLodMetricValue;
|
|
6464
|
+
const computedBoundingVolume = calculateImplicitBoundingVolume(descriptor.rootBoundingVolume, coordinates, descriptor.subdivisionScheme);
|
|
5458
6465
|
return {
|
|
5459
6466
|
id: getImplicitTileId(reference, coordinates),
|
|
5460
6467
|
children,
|
|
5461
6468
|
contentUrl,
|
|
5462
6469
|
content: content.length > 1 ? content : content[0],
|
|
6470
|
+
contents: descriptor.useCanonicalContents && content.length ? content : void 0,
|
|
5463
6471
|
contentUrls: availableContentUrls,
|
|
5464
|
-
refine: descriptor.refine,
|
|
6472
|
+
refine: tileAttributes.refine || descriptor.refine,
|
|
5465
6473
|
type: getImplicitTileType(contentUrl),
|
|
5466
6474
|
lodMetricType: descriptor.lodMetricType,
|
|
5467
6475
|
lodMetricValue,
|
|
5468
6476
|
geometricError: lodMetricValue,
|
|
5469
|
-
boundingVolume:
|
|
5470
|
-
|
|
6477
|
+
boundingVolume: tileAttributes.boundingVolume || computedBoundingVolume,
|
|
6478
|
+
transform: tileAttributes.transform,
|
|
6479
|
+
transformMatrix: tileAttributes.transform,
|
|
6480
|
+
metadata: tileProperties ? { properties: tileProperties } : void 0,
|
|
6481
|
+
implicitMetadata: getImplicitSubtreeMetadata(subtree, tileProperties, contentProperties),
|
|
6482
|
+
_scaleGeometricError: descriptor.scaleGeometricError !== false
|
|
5471
6483
|
};
|
|
5472
6484
|
}
|
|
5473
|
-
function getImplicitSubtreeMetadata(subtree) {
|
|
5474
|
-
if (!subtree.propertyTables && subtree.tileMetadata === void 0 && !subtree.contentMetadata && subtree.subtreeMetadata === void 0) {
|
|
6485
|
+
function getImplicitSubtreeMetadata(subtree, tileProperties, contentProperties) {
|
|
6486
|
+
if (!subtree.propertyTables && subtree.tileMetadata === void 0 && !subtree.contentMetadata && subtree.subtreeMetadata === void 0 && !tileProperties && !contentProperties) {
|
|
5475
6487
|
return void 0;
|
|
5476
6488
|
}
|
|
5477
6489
|
return {
|
|
5478
6490
|
propertyTables: subtree.propertyTables,
|
|
5479
6491
|
tileMetadata: subtree.tileMetadata,
|
|
5480
6492
|
contentMetadata: subtree.contentMetadata,
|
|
5481
|
-
subtreeMetadata: subtree.subtreeMetadata
|
|
6493
|
+
subtreeMetadata: subtree.subtreeMetadata,
|
|
6494
|
+
tileProperties,
|
|
6495
|
+
contentProperties
|
|
5482
6496
|
};
|
|
5483
6497
|
}
|
|
5484
6498
|
function getImplicitTileId(reference, coordinates) {
|
|
@@ -5515,12 +6529,15 @@ function getImplicitChildCount(subdivisionScheme) {
|
|
|
5515
6529
|
return subdivisionScheme === "OCTREE" ? OCTREE_CHILD_COUNT : QUADTREE_CHILD_COUNT;
|
|
5516
6530
|
}
|
|
5517
6531
|
function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdivisionScheme) {
|
|
6532
|
+
var _a;
|
|
5518
6533
|
if (rootBoundingVolume.region) {
|
|
5519
6534
|
const [west, south, east, north, minimumHeight, maximumHeight] = rootBoundingVolume.region;
|
|
5520
6535
|
const divisionCount = 2 ** coordinates.level;
|
|
5521
|
-
const
|
|
6536
|
+
const longitudeSpan = east >= west ? east - west : east + 2 * Math.PI - west;
|
|
6537
|
+
const longitudeSize = longitudeSpan / divisionCount;
|
|
5522
6538
|
const latitudeSize = (north - south) / divisionCount;
|
|
5523
|
-
const childWest = west + longitudeSize * coordinates.x;
|
|
6539
|
+
const childWest = normalizeRegionLongitude(west + longitudeSize * coordinates.x);
|
|
6540
|
+
const childEast = normalizeRegionLongitude(west + longitudeSize * (coordinates.x + 1));
|
|
5524
6541
|
const childSouth = south + latitudeSize * coordinates.y;
|
|
5525
6542
|
let childMinimumHeight = minimumHeight;
|
|
5526
6543
|
let childMaximumHeight = maximumHeight;
|
|
@@ -5533,7 +6550,7 @@ function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdiv
|
|
|
5533
6550
|
region: [
|
|
5534
6551
|
childWest,
|
|
5535
6552
|
childSouth,
|
|
5536
|
-
|
|
6553
|
+
childEast,
|
|
5537
6554
|
childSouth + latitudeSize,
|
|
5538
6555
|
childMinimumHeight,
|
|
5539
6556
|
childMaximumHeight
|
|
@@ -5542,7 +6559,13 @@ function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdiv
|
|
|
5542
6559
|
}
|
|
5543
6560
|
if (rootBoundingVolume.box) {
|
|
5544
6561
|
if (rootBoundingVolume.s2VolumeInfo) {
|
|
5545
|
-
return
|
|
6562
|
+
return calculateS2ImplicitBoundingVolume(rootBoundingVolume, coordinates, subdivisionScheme);
|
|
6563
|
+
}
|
|
6564
|
+
if ((_a = rootBoundingVolume.extensions) == null ? void 0 : _a["3DTILES_shape_cylinder_region"]) {
|
|
6565
|
+
return {
|
|
6566
|
+
...rootBoundingVolume,
|
|
6567
|
+
box: [...rootBoundingVolume.box]
|
|
6568
|
+
};
|
|
5546
6569
|
}
|
|
5547
6570
|
const box = rootBoundingVolume.box;
|
|
5548
6571
|
const divisionCount = 2 ** coordinates.level;
|
|
@@ -5572,6 +6595,41 @@ function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdiv
|
|
|
5572
6595
|
}
|
|
5573
6596
|
throw new Error(`Unsupported implicit 3D Tiles bounding volume: ${JSON.stringify(rootBoundingVolume)}`);
|
|
5574
6597
|
}
|
|
6598
|
+
function calculateS2ImplicitBoundingVolume(rootBoundingVolume, coordinates, subdivisionScheme) {
|
|
6599
|
+
const rootS2VolumeInfo = rootBoundingVolume.s2VolumeInfo;
|
|
6600
|
+
const rootIndex = (0, import_s22.getS2IndexFromToken)(rootS2VolumeInfo.token);
|
|
6601
|
+
const descendantIndex = (0, import_s22.getS2DescendantIndex)(rootIndex, coordinates.level, coordinates.x, coordinates.y);
|
|
6602
|
+
const divisionCount = 2 ** coordinates.level;
|
|
6603
|
+
const heightSize = (rootS2VolumeInfo.maximumHeight - rootS2VolumeInfo.minimumHeight) / divisionCount;
|
|
6604
|
+
const childS2VolumeInfo = {
|
|
6605
|
+
token: (0, import_s22.getS2TokenFromIndex)(descendantIndex),
|
|
6606
|
+
minimumHeight: rootS2VolumeInfo.minimumHeight + (subdivisionScheme === "OCTREE" ? heightSize * coordinates.z : 0),
|
|
6607
|
+
maximumHeight: rootS2VolumeInfo.minimumHeight + (subdivisionScheme === "OCTREE" ? heightSize * (coordinates.z + 1) : heightSize * divisionCount)
|
|
6608
|
+
};
|
|
6609
|
+
const extensions = rootBoundingVolume.extensions ? { ...rootBoundingVolume.extensions } : void 0;
|
|
6610
|
+
if (extensions == null ? void 0 : extensions["3DTILES_bounding_volume_S2"]) {
|
|
6611
|
+
extensions["3DTILES_bounding_volume_S2"] = childS2VolumeInfo;
|
|
6612
|
+
}
|
|
6613
|
+
if (extensions == null ? void 0 : extensions["3DTILES_shape_s2"]) {
|
|
6614
|
+
extensions["3DTILES_shape_s2"] = childS2VolumeInfo;
|
|
6615
|
+
}
|
|
6616
|
+
return {
|
|
6617
|
+
...rootBoundingVolume,
|
|
6618
|
+
...extensions ? { extensions } : {},
|
|
6619
|
+
s2VolumeInfo: childS2VolumeInfo,
|
|
6620
|
+
box: convertS2BoundingVolumeToOBB(childS2VolumeInfo)
|
|
6621
|
+
};
|
|
6622
|
+
}
|
|
6623
|
+
function normalizeRegionLongitude(longitude) {
|
|
6624
|
+
let normalizedLongitude = longitude;
|
|
6625
|
+
while (normalizedLongitude > Math.PI) {
|
|
6626
|
+
normalizedLongitude -= 2 * Math.PI;
|
|
6627
|
+
}
|
|
6628
|
+
while (normalizedLongitude < -Math.PI) {
|
|
6629
|
+
normalizedLongitude += 2 * Math.PI;
|
|
6630
|
+
}
|
|
6631
|
+
return normalizedLongitude;
|
|
6632
|
+
}
|
|
5575
6633
|
function getImplicitTileType(contentUrl) {
|
|
5576
6634
|
var _a;
|
|
5577
6635
|
if (!contentUrl) {
|
|
@@ -5640,6 +6698,12 @@ var Tiles3DSource = class {
|
|
|
5640
6698
|
queryParams = {};
|
|
5641
6699
|
/** Final request URLs cached by unmodified tile content URL. */
|
|
5642
6700
|
tileUrlCache = /* @__PURE__ */ new Map();
|
|
6701
|
+
/** Original content descriptors retained across {@link Tile3D.unloadContent} calls. */
|
|
6702
|
+
tileContentHeaders = /* @__PURE__ */ new WeakMap();
|
|
6703
|
+
/** Source-local namespaces assigned to distinct embedded glTF package file collections. */
|
|
6704
|
+
packageNamespaces = /* @__PURE__ */ new WeakMap();
|
|
6705
|
+
/** Next source-local package namespace. */
|
|
6706
|
+
nextPackageNamespace = 0;
|
|
5643
6707
|
/** Parsed subtree requests keyed by final source URL for deduplication and LRU reuse. */
|
|
5644
6708
|
implicitSubtreeCache;
|
|
5645
6709
|
/** Mutable counters exposed as a defensive snapshot through {@link getImplicitTilingStats}. */
|
|
@@ -5654,6 +6718,10 @@ var Tiles3DSource = class {
|
|
|
5654
6718
|
extensionsUsed = [];
|
|
5655
6719
|
resolver;
|
|
5656
6720
|
rootTileset;
|
|
6721
|
+
/** CRS transformer shared by this source's headers and decoded glTF content. */
|
|
6722
|
+
spatialTransformer;
|
|
6723
|
+
/** Root header after composing source-frame transforms and rebuilding target bounds. */
|
|
6724
|
+
preparedRootHeader;
|
|
5657
6725
|
/**
|
|
5658
6726
|
* Creates a 3D Tiles source.
|
|
5659
6727
|
* @param input Root metadata request, or preloaded root metadata for tests and internal callers.
|
|
@@ -5711,8 +6779,8 @@ var Tiles3DSource = class {
|
|
|
5711
6779
|
if (!this.asset) {
|
|
5712
6780
|
throw new Error("Tileset must have an asset property.");
|
|
5713
6781
|
}
|
|
5714
|
-
if (this.asset.version !== "0.0" && this.asset.version !== "1.0" && this.asset.version !== "1.1") {
|
|
5715
|
-
throw new Error("The tileset must be 3D Tiles version
|
|
6782
|
+
if (this.rootTileset.formatVersion !== "2.0-draft" && this.asset.version !== "0.0" && this.asset.version !== "1.0" && this.asset.version !== "1.1") {
|
|
6783
|
+
throw new Error("The tileset must be 3D Tiles version 0.0, 1.0, 1.1, or 2.0-draft.");
|
|
5716
6784
|
}
|
|
5717
6785
|
if ("tilesetVersion" in this.asset) {
|
|
5718
6786
|
this.setQueryParameter("v", this.asset.tilesetVersion);
|
|
@@ -5748,12 +6816,26 @@ var Tiles3DSource = class {
|
|
|
5748
6816
|
async getRootTileset() {
|
|
5749
6817
|
return this.getMetadata().tileset;
|
|
5750
6818
|
}
|
|
6819
|
+
/** Prepare nonlinear CRS state before runtime headers are materialized. */
|
|
6820
|
+
async prepareTileset(tileset) {
|
|
6821
|
+
const spatialReference = tileset.spatialReference;
|
|
6822
|
+
if (spatialReference.status === "unresolved") {
|
|
6823
|
+
throw new Error(spatialReference.warnings[0] || "3D Tiles spatial operations cannot be resolved from the supplied metadata and options");
|
|
6824
|
+
}
|
|
6825
|
+
if (spatialReference.status !== "transformable" && spatialReference.status !== "transformed") {
|
|
6826
|
+
return;
|
|
6827
|
+
}
|
|
6828
|
+
this.spatialTransformer ||= new Tiles3DSpatialTransformer(spatialReference, tileset.options.spatial);
|
|
6829
|
+
tileset.spatialReference = markTilesetSpatialReferenceTransformed(spatialReference);
|
|
6830
|
+
this.preparedRootHeader = this.transformTileHeader(this.getMetadata().tileset.root, new import_core12.Matrix4());
|
|
6831
|
+
}
|
|
5751
6832
|
/**
|
|
5752
6833
|
* Builds explicit runtime headers while leaving implicit subtree references lazy.
|
|
5753
6834
|
*/
|
|
5754
6835
|
initializeTileHeaders(tileset, tilesetJson, parentTile) {
|
|
5755
6836
|
var _a;
|
|
5756
|
-
const
|
|
6837
|
+
const rootHeader = parentTile ? tilesetJson.root : this.preparedRootHeader || tilesetJson.root;
|
|
6838
|
+
const rootTile = new Tile3D(tileset, rootHeader, parentTile || void 0);
|
|
5757
6839
|
if (parentTile) {
|
|
5758
6840
|
parentTile.children.push(rootTile);
|
|
5759
6841
|
rootTile.depth = parentTile.depth + 1;
|
|
@@ -5789,7 +6871,13 @@ var Tiles3DSource = class {
|
|
|
5789
6871
|
* Loads binary content or nested tileset JSON for a runtime tile.
|
|
5790
6872
|
*/
|
|
5791
6873
|
async loadTileContent(tile) {
|
|
6874
|
+
var _a, _b, _c, _d, _e, _f;
|
|
5792
6875
|
const contentUrls = (tile.contentUrls || [tile.contentUrl]).filter(Boolean);
|
|
6876
|
+
const cachedContentHeaders = this.tileContentHeaders.get(tile);
|
|
6877
|
+
const contentHeaders = cachedContentHeaders || (Array.isArray((_a = tile.header) == null ? void 0 : _a.content) ? tile.header.content : ((_b = tile.header) == null ? void 0 : _b.content) ? [tile.header.content] : []);
|
|
6878
|
+
if (!cachedContentHeaders) {
|
|
6879
|
+
this.tileContentHeaders.set(tile, contentHeaders);
|
|
6880
|
+
}
|
|
5793
6881
|
const tilesetLoaderOptions = this.loadOptions[this.loader.id] || {};
|
|
5794
6882
|
const options = {
|
|
5795
6883
|
...this.loadOptions,
|
|
@@ -5798,18 +6886,64 @@ var Tiles3DSource = class {
|
|
|
5798
6886
|
// Content bytes, rather than URL suffixes, distinguish external tilesets from renderable
|
|
5799
6887
|
// payloads. This is required for signed and extensionless resources.
|
|
5800
6888
|
isTileset: "auto",
|
|
5801
|
-
assetGltfUpAxis: this.asset && this.asset.gltfUpAxis || "Y"
|
|
6889
|
+
assetGltfUpAxis: this.asset && this.asset.gltfUpAxis || "Y",
|
|
6890
|
+
_tilesetOptions: {
|
|
6891
|
+
spatialReference: ((_c = tile.header) == null ? void 0 : _c._spatialReference) || ((_d = tile.tileset) == null ? void 0 : _d.spatialReference),
|
|
6892
|
+
spatialOptions: (_e = tile.tileset) == null ? void 0 : _e.options.spatial,
|
|
6893
|
+
spatialTransform: (_f = tile.header) == null ? void 0 : _f._spatialTransform
|
|
6894
|
+
}
|
|
5802
6895
|
}
|
|
5803
6896
|
};
|
|
5804
|
-
const contents = await Promise.all(contentUrls.map((contentUrl) =>
|
|
6897
|
+
const contents = await Promise.all(contentUrls.map((contentUrl, contentIndex) => {
|
|
6898
|
+
var _a2;
|
|
6899
|
+
const contentHeader = contentHeaders[contentIndex] || {};
|
|
6900
|
+
const vectorExtension = (_a2 = contentHeader.extensions) == null ? void 0 : _a2["3DTILES_content_gltf_vector"];
|
|
6901
|
+
const vectorContent = contentHeader._vectorContent || ((vectorExtension == null ? void 0 : vectorExtension.vector) === true ? { clip: vectorExtension.clip === true } : void 0);
|
|
6902
|
+
const contentOptions = vectorContent ? {
|
|
6903
|
+
...options,
|
|
6904
|
+
[this.loader.id]: {
|
|
6905
|
+
...options[this.loader.id],
|
|
6906
|
+
vectorContent
|
|
6907
|
+
}
|
|
6908
|
+
} : options;
|
|
6909
|
+
return this.loadContentResource(this.getTileUrl(contentUrl), contentHeader._resource, contentOptions);
|
|
6910
|
+
}));
|
|
5805
6911
|
tile.contents = contents;
|
|
5806
6912
|
tile.content = contents[0] || null;
|
|
5807
6913
|
const nestedTilesets = contents.filter((content) => (content == null ? void 0 : content.shape) === "tileset3d");
|
|
5808
6914
|
return {
|
|
5809
|
-
loaded: true,
|
|
5810
|
-
contents,
|
|
5811
|
-
nestedTileset: nestedTilesets[0],
|
|
5812
|
-
nestedTilesets
|
|
6915
|
+
loaded: true,
|
|
6916
|
+
contents,
|
|
6917
|
+
nestedTileset: nestedTilesets[0],
|
|
6918
|
+
nestedTilesets
|
|
6919
|
+
};
|
|
6920
|
+
}
|
|
6921
|
+
/** Transform a tile header and its eagerly declared descendants. */
|
|
6922
|
+
transformTileHeader(header, parentTransform = new import_core12.Matrix4()) {
|
|
6923
|
+
if (!this.spatialTransformer) {
|
|
6924
|
+
return header;
|
|
6925
|
+
}
|
|
6926
|
+
return this.transformTileHeaderWithTransformer(header, this.spatialTransformer, parentTransform);
|
|
6927
|
+
}
|
|
6928
|
+
/** Rebuilds one header subtree using an explicitly selected CRS transformer. */
|
|
6929
|
+
transformTileHeaderWithTransformer(header, transformer, parentTransform, spatialReference) {
|
|
6930
|
+
const localTransform = header.transform ? new import_core12.Matrix4(header.transform) : new import_core12.Matrix4();
|
|
6931
|
+
const composedTransform = new import_core12.Matrix4(parentTransform).multiplyRight(localTransform);
|
|
6932
|
+
const content = Array.isArray(header.content) ? header.content.map((entry) => this.transformContentHeader(entry, composedTransform, transformer)) : header.content ? this.transformContentHeader(header.content, composedTransform, transformer) : header.content;
|
|
6933
|
+
return {
|
|
6934
|
+
...header,
|
|
6935
|
+
transform: void 0,
|
|
6936
|
+
boundingVolume: header.boundingVolume ? transformer.transformBoundingVolume(header.boundingVolume, composedTransform) : header.boundingVolume,
|
|
6937
|
+
_spatialReference: spatialReference,
|
|
6938
|
+
_spatialTransform: composedTransform.toArray(),
|
|
6939
|
+
content,
|
|
6940
|
+
children: Array.isArray(header.children) ? header.children.map((child) => this.transformTileHeaderWithTransformer(child, transformer, composedTransform, spatialReference)) : header.children
|
|
6941
|
+
};
|
|
6942
|
+
}
|
|
6943
|
+
transformContentHeader(content, composedTransform, transformer) {
|
|
6944
|
+
return {
|
|
6945
|
+
...content,
|
|
6946
|
+
boundingVolume: content.boundingVolume ? transformer.transformBoundingVolume(content.boundingVolume, composedTransform) : content.boundingVolume
|
|
5813
6947
|
};
|
|
5814
6948
|
}
|
|
5815
6949
|
/**
|
|
@@ -5830,7 +6964,7 @@ var Tiles3DSource = class {
|
|
|
5830
6964
|
return { loaded: false, tileCount: 0, childSubtreeCount: 0 };
|
|
5831
6965
|
}
|
|
5832
6966
|
const subtreeUrl = this.getTileUrl(reference.subtreeUrl);
|
|
5833
|
-
const subtree = await this.loadImplicitSubtreeResource(subtreeUrl);
|
|
6967
|
+
const subtree = await this.loadImplicitSubtreeResource(subtreeUrl, reference.resource);
|
|
5834
6968
|
if (this.destroyed || tile.isDestroyed()) {
|
|
5835
6969
|
return { loaded: false, tileCount: 0, childSubtreeCount: 0 };
|
|
5836
6970
|
}
|
|
@@ -5838,8 +6972,11 @@ var Tiles3DSource = class {
|
|
|
5838
6972
|
...reference,
|
|
5839
6973
|
subtreeUrl
|
|
5840
6974
|
});
|
|
5841
|
-
tile.
|
|
5842
|
-
const
|
|
6975
|
+
const nestedSpatialReference = tile.header._spatialReference;
|
|
6976
|
+
const subtreeTransformer = nestedSpatialReference ? new Tiles3DSpatialTransformer(nestedSpatialReference, tile.tileset.options.spatial) : this.spatialTransformer;
|
|
6977
|
+
const materializedRoot = subtreeTransformer ? this.transformTileHeaderWithTransformer(materializedSubtree.root, subtreeTransformer, new import_core12.Matrix4(), nestedSpatialReference) : materializedSubtree.root;
|
|
6978
|
+
tile.applyImplicitSubtreeHeader(materializedRoot);
|
|
6979
|
+
const materializedTileCount = this.initializeMaterializedChildren(tile.tileset, tile, materializedRoot.children);
|
|
5843
6980
|
this.implicitTilingStats.loadedSubtrees++;
|
|
5844
6981
|
this.implicitTilingStats.materializedTiles += materializedTileCount;
|
|
5845
6982
|
return {
|
|
@@ -5926,10 +7063,10 @@ var Tiles3DSource = class {
|
|
|
5926
7063
|
const { center } = rootTile.boundingVolume;
|
|
5927
7064
|
let cartographicCenter;
|
|
5928
7065
|
if (center && (center[0] !== 0 || center[1] !== 0 || center[2] !== 0)) {
|
|
5929
|
-
cartographicCenter = new
|
|
5930
|
-
|
|
7066
|
+
cartographicCenter = new import_core12.Vector3();
|
|
7067
|
+
import_geospatial10.Ellipsoid.WGS84.cartesianToCartographic(center, cartographicCenter);
|
|
5931
7068
|
} else {
|
|
5932
|
-
cartographicCenter = new
|
|
7069
|
+
cartographicCenter = new import_core12.Vector3(0, 0, -import_geospatial10.Ellipsoid.WGS84.radii[0]);
|
|
5933
7070
|
}
|
|
5934
7071
|
return {
|
|
5935
7072
|
asset: this.asset,
|
|
@@ -5968,8 +7105,58 @@ var Tiles3DSource = class {
|
|
|
5968
7105
|
}
|
|
5969
7106
|
const nestedTilesets = loadResult.nestedTilesets || (loadResult.nestedTileset ? [loadResult.nestedTileset] : []);
|
|
5970
7107
|
for (const nestedTileset of nestedTilesets) {
|
|
5971
|
-
tileset._initializeTileHeaders(nestedTileset, tile);
|
|
7108
|
+
tileset._initializeTileHeaders(this.prepareNestedTileset(tileset, nestedTileset), tile);
|
|
7109
|
+
}
|
|
7110
|
+
}
|
|
7111
|
+
/**
|
|
7112
|
+
* Resolves a nested tileset's CRS independently and adapts it to the owning tileset output frame.
|
|
7113
|
+
*
|
|
7114
|
+
* Nested resources may use a different source CRS from their parent. Their headers and glTF
|
|
7115
|
+
* payloads must therefore use a transformer built from the nested descriptor, while the parent
|
|
7116
|
+
* runtime continues to expose one requested output frame to traversal and rendering.
|
|
7117
|
+
*/
|
|
7118
|
+
prepareNestedTileset(tileset, nestedTileset) {
|
|
7119
|
+
const nestedSpatialReference = nestedTileset.spatialMetadata;
|
|
7120
|
+
const parentSpatialReference = tileset.spatialReference;
|
|
7121
|
+
if ((nestedSpatialReference == null ? void 0 : nestedSpatialReference.status) === "unresolved" || (nestedSpatialReference == null ? void 0 : nestedSpatialReference.crs.state) === "unknown") {
|
|
7122
|
+
throw new Error(nestedSpatialReference.warnings[0] || "Nested 3D Tiles CRS is explicitly unresolved and cannot be placed in the parent frame");
|
|
7123
|
+
}
|
|
7124
|
+
if (!nestedSpatialReference || !nestedSpatialReference.sourceCrs) {
|
|
7125
|
+
if (this.spatialTransformer && (parentSpatialReference.status === "transformable" || parentSpatialReference.status === "transformed")) {
|
|
7126
|
+
return {
|
|
7127
|
+
...nestedTileset,
|
|
7128
|
+
spatialMetadata: parentSpatialReference,
|
|
7129
|
+
root: this.transformTileHeaderWithTransformer(nestedTileset.root, this.spatialTransformer, new import_core12.Matrix4(), parentSpatialReference)
|
|
7130
|
+
};
|
|
7131
|
+
}
|
|
7132
|
+
return addNestedSpatialReference(nestedTileset, parentSpatialReference);
|
|
7133
|
+
}
|
|
7134
|
+
const parentCoordinateEpoch = parentSpatialReference.coordinateEpoch;
|
|
7135
|
+
const nestedCoordinateEpoch = nestedSpatialReference.coordinateEpoch;
|
|
7136
|
+
if (parentCoordinateEpoch !== void 0 && nestedCoordinateEpoch !== void 0 && parentCoordinateEpoch !== nestedCoordinateEpoch) {
|
|
7137
|
+
throw new Error(`Nested 3D Tiles coordinate epoch ${nestedCoordinateEpoch} differs from parent epoch ${parentCoordinateEpoch}; epoch-aware transformation is unavailable`);
|
|
7138
|
+
}
|
|
7139
|
+
const outputCrs = parentSpatialReference.targetCrs || parentSpatialReference.sourceCrs;
|
|
7140
|
+
if (!outputCrs) {
|
|
7141
|
+
return addNestedSpatialReference(nestedTileset, nestedSpatialReference);
|
|
5972
7142
|
}
|
|
7143
|
+
const nestedOutputReference = applyTilesetSpatialOptions(nestedSpatialReference, {
|
|
7144
|
+
...tileset.options.spatial,
|
|
7145
|
+
outputCoordinates: "target-crs",
|
|
7146
|
+
targetCrs: outputCrs
|
|
7147
|
+
});
|
|
7148
|
+
if (nestedOutputReference.status === "unresolved") {
|
|
7149
|
+
throw new Error(nestedOutputReference.warnings[0] || "Nested 3D Tiles CRS cannot be resolved in the parent output frame");
|
|
7150
|
+
}
|
|
7151
|
+
if (nestedOutputReference.status === "native") {
|
|
7152
|
+
return addNestedSpatialReference(nestedTileset, nestedOutputReference);
|
|
7153
|
+
}
|
|
7154
|
+
const nestedTransformer = new Tiles3DSpatialTransformer(nestedOutputReference, tileset.options.spatial);
|
|
7155
|
+
return {
|
|
7156
|
+
...nestedTileset,
|
|
7157
|
+
spatialMetadata: nestedOutputReference,
|
|
7158
|
+
root: this.transformTileHeaderWithTransformer(nestedTileset.root, nestedTransformer, new import_core12.Matrix4(), nestedOutputReference)
|
|
7159
|
+
};
|
|
5973
7160
|
}
|
|
5974
7161
|
/**
|
|
5975
7162
|
* Loads data through injected core APIs so this module stays independent from `@loaders.gl/core`.
|
|
@@ -5998,13 +7185,84 @@ var Tiles3DSource = class {
|
|
|
5998
7185
|
}
|
|
5999
7186
|
return await this.loadWithCoreApi(url, options, loader);
|
|
6000
7187
|
}
|
|
7188
|
+
/** Loads a URL content reference or parses a buffer-view file retained from a glTF package. */
|
|
7189
|
+
async loadContentResource(url, packageResource, options) {
|
|
7190
|
+
if (!packageResource) {
|
|
7191
|
+
return await this.loadResourceData(url, options);
|
|
7192
|
+
}
|
|
7193
|
+
const file = packageResource.files[packageResource.fileIndex];
|
|
7194
|
+
if (!file) {
|
|
7195
|
+
throw new Error(`3D Tiles package references missing file ${packageResource.fileIndex}`);
|
|
7196
|
+
}
|
|
7197
|
+
if (file.uri) {
|
|
7198
|
+
return await this.loadResourceData(this.getTileUrl(file.uri), options);
|
|
7199
|
+
}
|
|
7200
|
+
if (!this.coreApi) {
|
|
7201
|
+
throw new Error("Tiles3DSource requires an injected coreApi to parse embedded package data");
|
|
7202
|
+
}
|
|
7203
|
+
const data = await this.getPackageFileData(file);
|
|
7204
|
+
const packageNamespace = this.getPackageNamespace(packageResource.files);
|
|
7205
|
+
const packageRootUrl = `gltf-package://${packageNamespace}/${packageResource.fileIndex}`;
|
|
7206
|
+
const fileName = file.name || "content";
|
|
7207
|
+
const directorySeparatorIndex = fileName.lastIndexOf("/");
|
|
7208
|
+
const packageBaseUrl = directorySeparatorIndex >= 0 ? `${packageRootUrl}/${fileName.slice(0, directorySeparatorIndex)}` : packageRootUrl;
|
|
7209
|
+
return await this.coreApi.parse(data, this.loader, options, {
|
|
7210
|
+
url: `${packageRootUrl}/${fileName}`,
|
|
7211
|
+
filename: fileName,
|
|
7212
|
+
baseUrl: packageBaseUrl,
|
|
7213
|
+
loaders: [this.loader],
|
|
7214
|
+
coreApi: this.coreApi,
|
|
7215
|
+
_parse: this.coreApi.parse,
|
|
7216
|
+
_tiles3dPackageFiles: packageResource.files,
|
|
7217
|
+
fetch: async (resource, init) => {
|
|
7218
|
+
const reference = resource.startsWith(`${packageRootUrl}/`) ? resource.slice(packageRootUrl.length + 1) : resource;
|
|
7219
|
+
const referencedFile = packageResource.files.find((packageFile) => packageFile.name === reference || packageFile.originalUri === reference);
|
|
7220
|
+
if (!referencedFile) {
|
|
7221
|
+
throw new Error(`3D Tiles glTF package does not contain file ${reference}`);
|
|
7222
|
+
}
|
|
7223
|
+
if (referencedFile.uri) {
|
|
7224
|
+
return await this.coreApi.fetchFile(this.getTileUrl(referencedFile.uri), init);
|
|
7225
|
+
}
|
|
7226
|
+
const referencedData = await this.getPackageFileData(referencedFile);
|
|
7227
|
+
return new Response(referencedData, {
|
|
7228
|
+
headers: { "content-type": referencedFile.mimeType }
|
|
7229
|
+
});
|
|
7230
|
+
}
|
|
7231
|
+
});
|
|
7232
|
+
}
|
|
7233
|
+
/** Returns a stable source-local namespace for one embedded glTF package file collection. */
|
|
7234
|
+
getPackageNamespace(files) {
|
|
7235
|
+
const existingNamespace = this.packageNamespaces.get(files);
|
|
7236
|
+
if (existingNamespace !== void 0) {
|
|
7237
|
+
return existingNamespace;
|
|
7238
|
+
}
|
|
7239
|
+
const packageNamespace = this.nextPackageNamespace++;
|
|
7240
|
+
this.packageNamespaces.set(files, packageNamespace);
|
|
7241
|
+
return packageNamespace;
|
|
7242
|
+
}
|
|
7243
|
+
/** Resolves a retained package-file byte range without eagerly copying other package files. */
|
|
7244
|
+
async getPackageFileData(file) {
|
|
7245
|
+
if (file.data) {
|
|
7246
|
+
return sliceArrayBuffer(file.data, file.byteOffset, file.byteLength);
|
|
7247
|
+
}
|
|
7248
|
+
if (file.bufferUri && this.coreApi) {
|
|
7249
|
+
const response = await this.coreApi.fetchFile(this.getTileUrl(file.bufferUri));
|
|
7250
|
+
if (!response.ok) {
|
|
7251
|
+
throw new Error(`Failed to fetch 3D Tiles package buffer: HTTP ${response.status}`);
|
|
7252
|
+
}
|
|
7253
|
+
const buffer = await response.arrayBuffer();
|
|
7254
|
+
return sliceArrayBuffer(buffer, file.byteOffset, file.byteLength);
|
|
7255
|
+
}
|
|
7256
|
+
throw new Error("3D Tiles package file has no available byte source");
|
|
7257
|
+
}
|
|
6001
7258
|
/**
|
|
6002
7259
|
* Returns a parsed subtree from the LRU cache or starts one source-managed request.
|
|
6003
7260
|
*
|
|
6004
7261
|
* @param subtreeUrl - Final subtree URL after query inheritance.
|
|
7262
|
+
* @param packageResource - Optional glTF package file satisfying the subtree reference.
|
|
6005
7263
|
* @returns Parsed subtree availability data.
|
|
6006
7264
|
*/
|
|
6007
|
-
async loadImplicitSubtreeResource(subtreeUrl) {
|
|
7265
|
+
async loadImplicitSubtreeResource(subtreeUrl, packageResource) {
|
|
6008
7266
|
const cachedSubtree = this.implicitSubtreeCache.get(subtreeUrl);
|
|
6009
7267
|
if (cachedSubtree) {
|
|
6010
7268
|
this.implicitTilingStats.cacheHits++;
|
|
@@ -6013,14 +7271,15 @@ var Tiles3DSource = class {
|
|
|
6013
7271
|
this.implicitTilingStats.requestedSubtrees++;
|
|
6014
7272
|
const loaderOptions = this.loadOptions[this.loader.id] || {};
|
|
6015
7273
|
return await this.implicitSubtreeCache.getOrLoad(subtreeUrl, async () => {
|
|
6016
|
-
|
|
7274
|
+
const options = {
|
|
6017
7275
|
...this.loadOptions,
|
|
6018
7276
|
[this.loader.id]: {
|
|
6019
7277
|
...loaderOptions,
|
|
6020
7278
|
isTileset: false,
|
|
6021
7279
|
isSubtree: true
|
|
6022
7280
|
}
|
|
6023
|
-
}
|
|
7281
|
+
};
|
|
7282
|
+
return await (packageResource ? this.loadContentResource(subtreeUrl, packageResource, options) : this.loadResourceData(subtreeUrl, options));
|
|
6024
7283
|
});
|
|
6025
7284
|
}
|
|
6026
7285
|
/**
|
|
@@ -6071,10 +7330,22 @@ function normalizeTiles3DRequest(input) {
|
|
|
6071
7330
|
coreApi: input.coreApi
|
|
6072
7331
|
};
|
|
6073
7332
|
}
|
|
7333
|
+
function addNestedSpatialReference(nestedTileset, spatialReference) {
|
|
7334
|
+
const addToHeader = (header) => ({
|
|
7335
|
+
...header,
|
|
7336
|
+
_spatialReference: spatialReference,
|
|
7337
|
+
children: Array.isArray(header.children) ? header.children.map(addToHeader) : header.children
|
|
7338
|
+
});
|
|
7339
|
+
return {
|
|
7340
|
+
...nestedTileset,
|
|
7341
|
+
spatialMetadata: spatialReference,
|
|
7342
|
+
root: addToHeader(nestedTileset.root)
|
|
7343
|
+
};
|
|
7344
|
+
}
|
|
6074
7345
|
|
|
6075
7346
|
// dist/tileset-3d/format-i3s/i3s-source.js
|
|
6076
|
-
var
|
|
6077
|
-
var
|
|
7347
|
+
var import_geospatial12 = require("@math.gl/geospatial");
|
|
7348
|
+
var import_core14 = require("@math.gl/core");
|
|
6078
7349
|
|
|
6079
7350
|
// dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js
|
|
6080
7351
|
var I3SPendingTilesRegister = class {
|
|
@@ -6255,224 +7526,8 @@ var I3STilesetTraverser = class extends TilesetTraverser {
|
|
|
6255
7526
|
};
|
|
6256
7527
|
|
|
6257
7528
|
// dist/spatial/i3s-spatial-transformer.js
|
|
6258
|
-
var
|
|
6259
|
-
var
|
|
6260
|
-
|
|
6261
|
-
// dist/spatial/spatial-coordinate-transformer.js
|
|
6262
|
-
var import_core11 = require("@math.gl/core");
|
|
6263
|
-
var import_geospatial8 = require("@math.gl/geospatial");
|
|
6264
|
-
var import_proj42 = require("@math.gl/proj4");
|
|
6265
|
-
|
|
6266
|
-
// dist/spatial/spatial-resource-registry.js
|
|
6267
|
-
var import_geoid = require("@math.gl/geoid");
|
|
6268
|
-
var import_proj4 = require("@math.gl/proj4");
|
|
6269
|
-
var geoidModels = /* @__PURE__ */ new Map();
|
|
6270
|
-
function registerSpatialCrs(name, definition) {
|
|
6271
|
-
validateResourceName(name, "CRS");
|
|
6272
|
-
import_proj4.Proj4Projection.defineProjectionAliases({ [name]: definition });
|
|
6273
|
-
}
|
|
6274
|
-
function registerSpatialDatumGrid(name, data) {
|
|
6275
|
-
validateResourceName(name, "datum grid");
|
|
6276
|
-
import_proj4.Proj4Projection.registerDatumGrid(name, data);
|
|
6277
|
-
}
|
|
6278
|
-
function registerGeoidModel(name, geoid) {
|
|
6279
|
-
validateResourceName(name, "geoid model");
|
|
6280
|
-
geoidModels.set(name, geoid);
|
|
6281
|
-
}
|
|
6282
|
-
function registerGeoidModelFromPgm(name, data, options = {}) {
|
|
6283
|
-
const geoid = (0, import_geoid.parsePGM)(data, options);
|
|
6284
|
-
registerGeoidModel(name, geoid);
|
|
6285
|
-
return geoid;
|
|
6286
|
-
}
|
|
6287
|
-
function getGeoidModel(name) {
|
|
6288
|
-
return geoidModels.get(name);
|
|
6289
|
-
}
|
|
6290
|
-
function validateResourceName(name, resourceType) {
|
|
6291
|
-
if (!name.trim()) {
|
|
6292
|
-
throw new Error(`${resourceType} name must not be empty`);
|
|
6293
|
-
}
|
|
6294
|
-
}
|
|
6295
|
-
|
|
6296
|
-
// dist/spatial/spatial-coordinate-transformer.js
|
|
6297
|
-
var GEOGRAPHIC_CRS2 = "EPSG:4326";
|
|
6298
|
-
var GEOCENTRIC_CRS2 = "EPSG:4978";
|
|
6299
|
-
var SpatialCoordinateTransformer = class {
|
|
6300
|
-
/** Normalized spatial metadata describing this transformation. */
|
|
6301
|
-
spatialReference;
|
|
6302
|
-
/** Projection from the source CRS directly to the requested horizontal target CRS. */
|
|
6303
|
-
horizontalProjection;
|
|
6304
|
-
/** Projection from the source CRS to geographic longitude, latitude, and ellipsoidal height. */
|
|
6305
|
-
geographicProjection;
|
|
6306
|
-
/** Projection from adjusted geographic coordinates to the requested output CRS. */
|
|
6307
|
-
heightOutputProjection;
|
|
6308
|
-
/** Whether source coordinates use the WGS84 geocentric frame handled by math.gl. */
|
|
6309
|
-
sourceIsGeocentric;
|
|
6310
|
-
/** Whether output coordinates use the WGS84 geocentric frame handled by math.gl. */
|
|
6311
|
-
outputIsGeocentric;
|
|
6312
|
-
/** Whether source coordinates already use conventional WGS84 longitude/latitude order. */
|
|
6313
|
-
sourceIsGeographic;
|
|
6314
|
-
/** Whether output coordinates use conventional WGS84 longitude/latitude order. */
|
|
6315
|
-
outputIsGeographic;
|
|
6316
|
-
/** Geoid model used to convert between ellipsoidal and orthometric heights. */
|
|
6317
|
-
geoid;
|
|
6318
|
-
/**
|
|
6319
|
-
* Creates a coordinate transformer.
|
|
6320
|
-
*
|
|
6321
|
-
* @param spatialReference - Format-discovered and option-normalized spatial metadata.
|
|
6322
|
-
* @param options - Application options containing an optional geoid model.
|
|
6323
|
-
*/
|
|
6324
|
-
constructor(spatialReference, options = {}) {
|
|
6325
|
-
this.spatialReference = spatialReference;
|
|
6326
|
-
validateTransformRequest(spatialReference);
|
|
6327
|
-
const outputCrs = spatialReference.targetCrs || spatialReference.sourceCrs;
|
|
6328
|
-
this.sourceIsGeocentric = isWgs84Geocentric(spatialReference.sourceCrs);
|
|
6329
|
-
this.outputIsGeocentric = isWgs84Geocentric(outputCrs);
|
|
6330
|
-
this.sourceIsGeographic = isWgs84Geographic(spatialReference.sourceCrs);
|
|
6331
|
-
this.outputIsGeographic = isWgs84Geographic(outputCrs);
|
|
6332
|
-
if (spatialReference.sourceCrs && spatialReference.targetCrs && !this.sourceIsGeocentric && !this.outputIsGeocentric) {
|
|
6333
|
-
this.horizontalProjection = new import_proj42.Proj4Projection({
|
|
6334
|
-
from: getHorizontalProj4Definition(spatialReference.sourceCrs),
|
|
6335
|
-
to: getHorizontalProj4Definition(spatialReference.targetCrs),
|
|
6336
|
-
enforceAxis: false
|
|
6337
|
-
});
|
|
6338
|
-
}
|
|
6339
|
-
if (requiresHeightTransformation(spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
|
|
6340
|
-
if (!this.sourceIsGeographic && !this.sourceIsGeocentric) {
|
|
6341
|
-
this.geographicProjection = new import_proj42.Proj4Projection({
|
|
6342
|
-
from: getHorizontalProj4Definition(spatialReference.sourceCrs),
|
|
6343
|
-
to: GEOGRAPHIC_CRS2,
|
|
6344
|
-
enforceAxis: false
|
|
6345
|
-
});
|
|
6346
|
-
}
|
|
6347
|
-
if (!this.outputIsGeographic && !this.outputIsGeocentric) {
|
|
6348
|
-
this.heightOutputProjection = new import_proj42.Proj4Projection({
|
|
6349
|
-
from: GEOGRAPHIC_CRS2,
|
|
6350
|
-
to: getHorizontalProj4Definition(outputCrs),
|
|
6351
|
-
enforceAxis: false
|
|
6352
|
-
});
|
|
6353
|
-
}
|
|
6354
|
-
}
|
|
6355
|
-
if (requiresHeightTransformation(spatialReference)) {
|
|
6356
|
-
this.geoid = resolveGeoid(options.geoidModel);
|
|
6357
|
-
if (!this.geoid) {
|
|
6358
|
-
const modelName = typeof options.geoidModel === "string" ? ` "${options.geoidModel}"` : "";
|
|
6359
|
-
throw new Error(`Height conversion requires a registered geoid model${modelName}; call registerGeoidModel() or pass a parsed Geoid instance`);
|
|
6360
|
-
}
|
|
6361
|
-
}
|
|
6362
|
-
}
|
|
6363
|
-
/**
|
|
6364
|
-
* Transforms one `[x, y, z?]` coordinate while retaining additional components.
|
|
6365
|
-
*
|
|
6366
|
-
* @param coordinate - Source coordinate in the format adapter's normalized `x/y/z` order.
|
|
6367
|
-
* @returns A new transformed coordinate array.
|
|
6368
|
-
*/
|
|
6369
|
-
transformPosition(coordinate) {
|
|
6370
|
-
if (coordinate.length < 2) {
|
|
6371
|
-
throw new Error("A spatial coordinate must contain at least x and y components");
|
|
6372
|
-
}
|
|
6373
|
-
const result = [...coordinate];
|
|
6374
|
-
if (requiresHeightTransformation(this.spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
|
|
6375
|
-
if (result.length < 3 || !Number.isFinite(result[2])) {
|
|
6376
|
-
throw new Error("Three-dimensional CRS conversion requires a finite z coordinate");
|
|
6377
|
-
}
|
|
6378
|
-
const geographic = this.toGeographic(result);
|
|
6379
|
-
if (requiresHeightTransformation(this.spatialReference)) {
|
|
6380
|
-
const geoidUndulation = this.geoid.getHeight(geographic[1], geographic[0]);
|
|
6381
|
-
geographic[2] = transformHeight(geographic[2], geoidUndulation, this.spatialReference.heightReference, this.spatialReference.targetHeightReference);
|
|
6382
|
-
}
|
|
6383
|
-
const projected = this.fromGeographic(geographic);
|
|
6384
|
-
result.splice(0, projected.length, ...projected);
|
|
6385
|
-
return result;
|
|
6386
|
-
}
|
|
6387
|
-
if (this.horizontalProjection) {
|
|
6388
|
-
const projected = this.horizontalProjection.project(result.slice(0, 3));
|
|
6389
|
-
result.splice(0, projected.length, ...projected);
|
|
6390
|
-
}
|
|
6391
|
-
return result;
|
|
6392
|
-
}
|
|
6393
|
-
/** Convert one source coordinate to conventional WGS84 longitude, latitude, and height. */
|
|
6394
|
-
toGeographic(coordinate) {
|
|
6395
|
-
if (this.sourceIsGeocentric) {
|
|
6396
|
-
return Array.from(import_geospatial8.Ellipsoid.WGS84.cartesianToCartographic(new import_core11.Vector3(coordinate)));
|
|
6397
|
-
}
|
|
6398
|
-
if (this.sourceIsGeographic) {
|
|
6399
|
-
return coordinate.slice(0, 3);
|
|
6400
|
-
}
|
|
6401
|
-
return this.geographicProjection.project(coordinate.slice(0, 3));
|
|
6402
|
-
}
|
|
6403
|
-
/** Convert one conventional WGS84 geographic coordinate to the selected output CRS. */
|
|
6404
|
-
fromGeographic(coordinate) {
|
|
6405
|
-
if (this.outputIsGeocentric) {
|
|
6406
|
-
return Array.from(import_geospatial8.Ellipsoid.WGS84.cartographicToCartesian(new import_core11.Vector3(coordinate)));
|
|
6407
|
-
}
|
|
6408
|
-
if (this.outputIsGeographic) {
|
|
6409
|
-
return coordinate.slice(0, 3);
|
|
6410
|
-
}
|
|
6411
|
-
return this.heightOutputProjection.project(coordinate.slice(0, 3));
|
|
6412
|
-
}
|
|
6413
|
-
};
|
|
6414
|
-
function getHorizontalProj4Definition(definition) {
|
|
6415
|
-
if (!definition) {
|
|
6416
|
-
throw new Error("Cannot construct a projection because the CRS is unknown");
|
|
6417
|
-
}
|
|
6418
|
-
return (0, import_proj42.toProj4CRSDefinition)(definition, { mode: "horizontal" });
|
|
6419
|
-
}
|
|
6420
|
-
function validateTransformRequest(spatialReference) {
|
|
6421
|
-
if (spatialReference.outputCoordinates === "local-enu") {
|
|
6422
|
-
throw new Error("local-enu output requires a dataset-derived local origin and must be created by a tileset source");
|
|
6423
|
-
}
|
|
6424
|
-
if (spatialReference.outputCoordinates === "target-crs" && !spatialReference.targetCrs) {
|
|
6425
|
-
throw new Error("target-crs output requires targetCrs");
|
|
6426
|
-
}
|
|
6427
|
-
if (!spatialReference.sourceCrs && spatialReference.status === "unresolved") {
|
|
6428
|
-
throw new Error("Cannot transform coordinates because the source CRS is unknown");
|
|
6429
|
-
}
|
|
6430
|
-
if (requiresHeightTransformation(spatialReference) && spatialReference.heightReference === "unknown") {
|
|
6431
|
-
throw new Error("Cannot convert heights because the source height reference is unknown");
|
|
6432
|
-
}
|
|
6433
|
-
if (spatialReference.coordinateFrame === "geocentric" && !isWgs84Geocentric(spatialReference.sourceCrs)) {
|
|
6434
|
-
throw new Error("Only EPSG:4978 geocentric coordinates are supported by the current spatial transformer");
|
|
6435
|
-
}
|
|
6436
|
-
if (spatialReference.status === "unresolved") {
|
|
6437
|
-
throw new Error("The requested spatial output cannot be resolved from the available metadata");
|
|
6438
|
-
}
|
|
6439
|
-
}
|
|
6440
|
-
function isWgs84Geocentric(definition) {
|
|
6441
|
-
return typeof definition === "string" && normalizeCrsIdentifier2(definition) === GEOCENTRIC_CRS2;
|
|
6442
|
-
}
|
|
6443
|
-
function isWgs84Geographic(definition) {
|
|
6444
|
-
if (typeof definition !== "string") {
|
|
6445
|
-
return false;
|
|
6446
|
-
}
|
|
6447
|
-
const identifier = normalizeCrsIdentifier2(definition);
|
|
6448
|
-
return identifier === GEOGRAPHIC_CRS2 || identifier === "EPSG:4979" || identifier === "OGC:CRS84";
|
|
6449
|
-
}
|
|
6450
|
-
function normalizeCrsIdentifier2(identifier) {
|
|
6451
|
-
const normalizedIdentifier = identifier.trim().toUpperCase();
|
|
6452
|
-
const ogcMatch = normalizedIdentifier.match(/(?:\/DEF\/CRS\/|URN:OGC:DEF:CRS:)([A-Z0-9_-]+)(?:\/|::)(?:[^/:]*[/:])?([A-Z0-9_.-]+)$/);
|
|
6453
|
-
return ogcMatch ? `${ogcMatch[1]}:${ogcMatch[2]}` : normalizedIdentifier;
|
|
6454
|
-
}
|
|
6455
|
-
function requiresHeightTransformation(spatialReference) {
|
|
6456
|
-
const target = spatialReference.targetHeightReference;
|
|
6457
|
-
return target !== "native" && target !== spatialReference.heightReference;
|
|
6458
|
-
}
|
|
6459
|
-
function resolveGeoid(model) {
|
|
6460
|
-
return typeof model === "string" ? getGeoidModel(model) : model;
|
|
6461
|
-
}
|
|
6462
|
-
function transformHeight(height, geoidUndulation, source, target) {
|
|
6463
|
-
if (source === target || target === "native") {
|
|
6464
|
-
return height;
|
|
6465
|
-
}
|
|
6466
|
-
if (source === "orthometric" && target === "ellipsoidal") {
|
|
6467
|
-
return height + geoidUndulation;
|
|
6468
|
-
}
|
|
6469
|
-
if (source === "ellipsoidal" && target === "orthometric") {
|
|
6470
|
-
return height - geoidUndulation;
|
|
6471
|
-
}
|
|
6472
|
-
throw new Error(`Unsupported height conversion from ${source} to ${target}`);
|
|
6473
|
-
}
|
|
6474
|
-
|
|
6475
|
-
// dist/spatial/i3s-spatial-transformer.js
|
|
7529
|
+
var import_core13 = require("@math.gl/core");
|
|
7530
|
+
var import_geospatial11 = require("@math.gl/geospatial");
|
|
6476
7531
|
var I3SSpatialTransformer = class {
|
|
6477
7532
|
/** Descriptor attached to output after all adapter-owned spatial values have been transformed. */
|
|
6478
7533
|
spatialReference;
|
|
@@ -6667,7 +7722,7 @@ var I3SSpatialTransformer = class {
|
|
|
6667
7722
|
positions[index + 2] = transformed[2] - origin[2];
|
|
6668
7723
|
}
|
|
6669
7724
|
const isGeographic = this.targetCoordinateFrame === "geographic";
|
|
6670
|
-
const modelMatrix = isGeographic ? new
|
|
7725
|
+
const modelMatrix = isGeographic ? new import_core13.Matrix4() : new import_core13.Matrix4().translate(origin);
|
|
6671
7726
|
return {
|
|
6672
7727
|
positions,
|
|
6673
7728
|
sourcePositions: absoluteSourcePositions,
|
|
@@ -6695,7 +7750,7 @@ var I3SSpatialTransformer = class {
|
|
|
6695
7750
|
sourcePositions[index + 1],
|
|
6696
7751
|
sourcePositions[index + 2]
|
|
6697
7752
|
]);
|
|
6698
|
-
const inputNormal = new
|
|
7753
|
+
const inputNormal = new import_core13.Vector3([
|
|
6699
7754
|
normals[index],
|
|
6700
7755
|
normals[index + 1],
|
|
6701
7756
|
normals[index + 2]
|
|
@@ -6733,12 +7788,12 @@ var I3SSpatialTransformer = class {
|
|
|
6733
7788
|
}
|
|
6734
7789
|
/** Rebuild an I3S bound as a WGS84 ECEF box for generic `Tileset3D` traversal. */
|
|
6735
7790
|
transformBoundingVolumeToGeocentric(bounds) {
|
|
6736
|
-
const cartesianSamples = this.getGeographicBoundSamples(bounds).map((position) => Array.from(
|
|
7791
|
+
const cartesianSamples = this.getGeographicBoundSamples(bounds).map((position) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position))));
|
|
6737
7792
|
return { box: getAxisAlignedBox(cartesianSamples) };
|
|
6738
7793
|
}
|
|
6739
7794
|
/** Rebuild an I3S bound as WGS84 ECEF after asynchronous elevation placement. */
|
|
6740
7795
|
async transformBoundingVolumeToGeocentricAsync(bounds) {
|
|
6741
|
-
const cartesianSamples = (await this.getGeographicBoundSamplesAsync(bounds)).map((position) => Array.from(
|
|
7796
|
+
const cartesianSamples = (await this.getGeographicBoundSamplesAsync(bounds)).map((position) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position))));
|
|
6742
7797
|
return { box: getAxisAlignedBox(cartesianSamples) };
|
|
6743
7798
|
}
|
|
6744
7799
|
/** Return a WGS84 geographic MBS used by the I3S screen-threshold calculation. */
|
|
@@ -6765,7 +7820,7 @@ var I3SSpatialTransformer = class {
|
|
|
6765
7820
|
*/
|
|
6766
7821
|
async transformBoundsAsync(bounds) {
|
|
6767
7822
|
const geographicSamples = await this.getGeographicBoundSamplesAsync(bounds);
|
|
6768
|
-
const cartesianSamples = geographicSamples.map((position) => Array.from(
|
|
7823
|
+
const cartesianSamples = geographicSamples.map((position) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position))));
|
|
6769
7824
|
const targetSamples = geographicSamples.map((position) => this.geographicToTargetTransformer.transformPosition(position));
|
|
6770
7825
|
return {
|
|
6771
7826
|
boundingVolume: { box: getAxisAlignedBox(cartesianSamples) },
|
|
@@ -6888,21 +7943,21 @@ var I3SSpatialTransformer = class {
|
|
|
6888
7943
|
if (this.targetCoordinateFrame === "geographic") {
|
|
6889
7944
|
return ecefVectorToLocalEnu(ecefNormal, geographic).normalize();
|
|
6890
7945
|
}
|
|
6891
|
-
const cartesian =
|
|
7946
|
+
const cartesian = import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(geographic));
|
|
6892
7947
|
const jacobianColumns = [];
|
|
6893
7948
|
for (const direction of getPositiveAxisDirections()) {
|
|
6894
|
-
const positiveGeographic =
|
|
6895
|
-
const negativeGeographic =
|
|
7949
|
+
const positiveGeographic = import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(new import_core13.Vector3(cartesian).add(direction));
|
|
7950
|
+
const negativeGeographic = import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(new import_core13.Vector3(cartesian).subtract(direction));
|
|
6896
7951
|
const positiveTarget = this.geographicToTargetTransformer.transformPosition(positiveGeographic);
|
|
6897
7952
|
const negativeTarget = this.geographicToTargetTransformer.transformPosition(negativeGeographic);
|
|
6898
7953
|
jacobianColumns.push((positiveTarget[0] - negativeTarget[0]) / 2, (positiveTarget[1] - negativeTarget[1]) / 2, (positiveTarget[2] - negativeTarget[2]) / 2);
|
|
6899
7954
|
}
|
|
6900
|
-
const normalMatrix = new
|
|
7955
|
+
const normalMatrix = new import_core13.Matrix3(jacobianColumns);
|
|
6901
7956
|
if (Math.abs(normalMatrix.determinant()) < 1e-12) {
|
|
6902
7957
|
throw new Error("Cannot transform an I3S normal through a singular local projection");
|
|
6903
7958
|
}
|
|
6904
7959
|
normalMatrix.invert().transpose();
|
|
6905
|
-
return new
|
|
7960
|
+
return new import_core13.Vector3(ecefNormal).transformByMatrix3(normalMatrix).normalize();
|
|
6906
7961
|
}
|
|
6907
7962
|
};
|
|
6908
7963
|
function getElevationProvider(mode, options) {
|
|
@@ -6934,17 +7989,17 @@ function getGeographicBoundingSphere(geographicSamples) {
|
|
|
6934
7989
|
if (!geographicSamples.length) {
|
|
6935
7990
|
throw new Error("I3S spatial transformation requires at least one bound sample");
|
|
6936
7991
|
}
|
|
6937
|
-
const cartesianSamples = geographicSamples.map((position) =>
|
|
6938
|
-
const cartesianCenter = new
|
|
7992
|
+
const cartesianSamples = geographicSamples.map((position) => import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position)));
|
|
7993
|
+
const cartesianCenter = new import_core13.Vector3();
|
|
6939
7994
|
for (const sample of cartesianSamples) {
|
|
6940
7995
|
cartesianCenter.add(sample);
|
|
6941
7996
|
}
|
|
6942
7997
|
cartesianCenter.scale(1 / cartesianSamples.length);
|
|
6943
7998
|
let radius = 0;
|
|
6944
7999
|
for (const sample of cartesianSamples) {
|
|
6945
|
-
radius = Math.max(radius, new
|
|
8000
|
+
radius = Math.max(radius, new import_core13.Vector3(sample).subtract(cartesianCenter).magnitude());
|
|
6946
8001
|
}
|
|
6947
|
-
const geographicCenter =
|
|
8002
|
+
const geographicCenter = import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(cartesianCenter);
|
|
6948
8003
|
return [geographicCenter[0], geographicCenter[1], geographicCenter[2], radius];
|
|
6949
8004
|
}
|
|
6950
8005
|
function getSourceBoundSamples(bounds, sourceFrame, sourceToGeographicTransformer, sourceVerticalUnitScale) {
|
|
@@ -6953,28 +8008,28 @@ function getSourceBoundSamples(bounds, sourceFrame, sourceToGeographicTransforme
|
|
|
6953
8008
|
const center2 = Array.from(obb.center).slice(0, 3);
|
|
6954
8009
|
center2[2] *= sourceVerticalUnitScale;
|
|
6955
8010
|
const halfSize = Array.from(obb.halfSize).slice(0, 3);
|
|
6956
|
-
const quaternion = new
|
|
8011
|
+
const quaternion = new import_core13.Quaternion().fromArray(Array.from(obb.quaternion));
|
|
6957
8012
|
const axes = [
|
|
6958
|
-
new
|
|
6959
|
-
new
|
|
6960
|
-
new
|
|
8013
|
+
new import_core13.Vector3([halfSize[0], 0, 0]).transformByQuaternion(quaternion),
|
|
8014
|
+
new import_core13.Vector3([0, halfSize[1], 0]).transformByQuaternion(quaternion),
|
|
8015
|
+
new import_core13.Vector3([0, 0, halfSize[2]]).transformByQuaternion(quaternion)
|
|
6961
8016
|
];
|
|
6962
8017
|
if (sourceFrame === "geographic") {
|
|
6963
8018
|
const geographicCenter = sourceToGeographicTransformer.transformPosition(center2);
|
|
6964
|
-
const cartesianCenter =
|
|
8019
|
+
const cartesianCenter = import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(geographicCenter));
|
|
6965
8020
|
const cartesianAxes = bounds.normalReferenceFrame === "vertex-reference-frame" ? axes.map((axis) => localEnuVectorToEcef(axis, geographicCenter)) : axes;
|
|
6966
8021
|
return getBoxSigns().map((signs) => {
|
|
6967
|
-
const corner = new
|
|
8022
|
+
const corner = new import_core13.Vector3(cartesianCenter);
|
|
6968
8023
|
for (let axisIndex = 0; axisIndex < 3; axisIndex++) {
|
|
6969
|
-
corner.add(new
|
|
8024
|
+
corner.add(new import_core13.Vector3(cartesianAxes[axisIndex]).scale(signs[axisIndex]));
|
|
6970
8025
|
}
|
|
6971
|
-
return Array.from(
|
|
8026
|
+
return Array.from(import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(corner));
|
|
6972
8027
|
});
|
|
6973
8028
|
}
|
|
6974
8029
|
return getBoxSigns().map((signs) => {
|
|
6975
|
-
const corner = new
|
|
8030
|
+
const corner = new import_core13.Vector3(center2);
|
|
6976
8031
|
for (let axisIndex = 0; axisIndex < 3; axisIndex++) {
|
|
6977
|
-
corner.add(new
|
|
8032
|
+
corner.add(new import_core13.Vector3(axes[axisIndex]).scale(signs[axisIndex]));
|
|
6978
8033
|
}
|
|
6979
8034
|
return Array.from(corner);
|
|
6980
8035
|
});
|
|
@@ -6988,10 +8043,10 @@ function getSourceBoundSamples(bounds, sourceFrame, sourceToGeographicTransforme
|
|
|
6988
8043
|
const radius = mbs[3];
|
|
6989
8044
|
if (sourceFrame === "geographic") {
|
|
6990
8045
|
const geographicCenter = sourceToGeographicTransformer.transformPosition(center);
|
|
6991
|
-
const cartesianCenter =
|
|
6992
|
-
return getAxisDirections().map((direction) => Array.from(
|
|
8046
|
+
const cartesianCenter = import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(geographicCenter));
|
|
8047
|
+
return getAxisDirections().map((direction) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(new import_core13.Vector3(cartesianCenter).add(new import_core13.Vector3(direction).scale(radius)))));
|
|
6993
8048
|
}
|
|
6994
|
-
return getAxisDirections().map((direction) => Array.from(new
|
|
8049
|
+
return getAxisDirections().map((direction) => Array.from(new import_core13.Vector3(center).add(new import_core13.Vector3(direction).scale(radius))));
|
|
6995
8050
|
}
|
|
6996
8051
|
function getBoxSigns() {
|
|
6997
8052
|
return [-1, 1].flatMap((x) => [-1, 1].flatMap((y) => [-1, 1].map((z) => [x, y, z])));
|
|
@@ -7007,18 +8062,18 @@ function getAxisDirections() {
|
|
|
7007
8062
|
];
|
|
7008
8063
|
}
|
|
7009
8064
|
function getPositiveAxisDirections() {
|
|
7010
|
-
return [new
|
|
8065
|
+
return [new import_core13.Vector3([1, 0, 0]), new import_core13.Vector3([0, 1, 0]), new import_core13.Vector3([0, 0, 1])];
|
|
7011
8066
|
}
|
|
7012
8067
|
function localEnuVectorToEcef(vector, geographic) {
|
|
7013
8068
|
const longitude = geographic[0] * Math.PI / 180;
|
|
7014
8069
|
const latitude = geographic[1] * Math.PI / 180;
|
|
7015
|
-
const east = new
|
|
7016
|
-
const north = new
|
|
8070
|
+
const east = new import_core13.Vector3([-Math.sin(longitude), Math.cos(longitude), 0]);
|
|
8071
|
+
const north = new import_core13.Vector3([
|
|
7017
8072
|
-Math.sin(latitude) * Math.cos(longitude),
|
|
7018
8073
|
-Math.sin(latitude) * Math.sin(longitude),
|
|
7019
8074
|
Math.cos(latitude)
|
|
7020
8075
|
]);
|
|
7021
|
-
const up = new
|
|
8076
|
+
const up = new import_core13.Vector3([
|
|
7022
8077
|
Math.cos(latitude) * Math.cos(longitude),
|
|
7023
8078
|
Math.cos(latitude) * Math.sin(longitude),
|
|
7024
8079
|
Math.sin(latitude)
|
|
@@ -7028,18 +8083,18 @@ function localEnuVectorToEcef(vector, geographic) {
|
|
|
7028
8083
|
function ecefVectorToLocalEnu(vector, geographic) {
|
|
7029
8084
|
const longitude = geographic[0] * Math.PI / 180;
|
|
7030
8085
|
const latitude = geographic[1] * Math.PI / 180;
|
|
7031
|
-
const east = new
|
|
7032
|
-
const north = new
|
|
8086
|
+
const east = new import_core13.Vector3([-Math.sin(longitude), Math.cos(longitude), 0]);
|
|
8087
|
+
const north = new import_core13.Vector3([
|
|
7033
8088
|
-Math.sin(latitude) * Math.cos(longitude),
|
|
7034
8089
|
-Math.sin(latitude) * Math.sin(longitude),
|
|
7035
8090
|
Math.cos(latitude)
|
|
7036
8091
|
]);
|
|
7037
|
-
const up = new
|
|
8092
|
+
const up = new import_core13.Vector3([
|
|
7038
8093
|
Math.cos(latitude) * Math.cos(longitude),
|
|
7039
8094
|
Math.cos(latitude) * Math.sin(longitude),
|
|
7040
8095
|
Math.sin(latitude)
|
|
7041
8096
|
]);
|
|
7042
|
-
return new
|
|
8097
|
+
return new import_core13.Vector3([east.dot(vector), north.dot(vector), up.dot(vector)]);
|
|
7043
8098
|
}
|
|
7044
8099
|
function getAxisAlignedBox(positions) {
|
|
7045
8100
|
const minimum = [Infinity, Infinity, Infinity];
|
|
@@ -7304,8 +8359,8 @@ var I3SSource = class {
|
|
|
7304
8359
|
getViewState(rootTile) {
|
|
7305
8360
|
var _a;
|
|
7306
8361
|
if (this.spatialTransformer && rootTile) {
|
|
7307
|
-
const center = new
|
|
7308
|
-
const cartographicCenter = new
|
|
8362
|
+
const center = new import_core14.Vector3(rootTile.boundingVolume.center);
|
|
8363
|
+
const cartographicCenter = new import_core14.Vector3(rootTile.header.i3sLodMbs.slice(0, 3));
|
|
7309
8364
|
if (this.spatialTransformer.targetCoordinateFrame === "geographic") {
|
|
7310
8365
|
return {
|
|
7311
8366
|
boundingVolume: rootTile.boundingVolume,
|
|
@@ -7325,9 +8380,9 @@ var I3SSource = class {
|
|
|
7325
8380
|
const fullExtent = metadata.tileset.fullExtent;
|
|
7326
8381
|
if (fullExtent) {
|
|
7327
8382
|
const { xmin, xmax, ymin, ymax, zmin, zmax } = fullExtent;
|
|
7328
|
-
const cartographicCenter = new
|
|
7329
|
-
const cartesianCenter = new
|
|
7330
|
-
|
|
8383
|
+
const cartographicCenter = new import_core14.Vector3(xmin + (xmax - xmin) / 2, ymin + (ymax - ymin) / 2, zmin + (zmax - zmin) / 2);
|
|
8384
|
+
const cartesianCenter = new import_core14.Vector3();
|
|
8385
|
+
import_geospatial12.Ellipsoid.WGS84.cartographicToCartesian(cartographicCenter, cartesianCenter);
|
|
7331
8386
|
return {
|
|
7332
8387
|
cartographicCenter,
|
|
7333
8388
|
cartesianCenter,
|
|
@@ -7337,9 +8392,9 @@ var I3SSource = class {
|
|
|
7337
8392
|
const extent = (_a = metadata.tileset.store) == null ? void 0 : _a.extent;
|
|
7338
8393
|
if (extent) {
|
|
7339
8394
|
const [xmin, ymin, xmax, ymax] = extent;
|
|
7340
|
-
const cartographicCenter = new
|
|
7341
|
-
const cartesianCenter = new
|
|
7342
|
-
|
|
8395
|
+
const cartographicCenter = new import_core14.Vector3(xmin + (xmax - xmin) / 2, ymin + (ymax - ymin) / 2, 0);
|
|
8396
|
+
const cartesianCenter = new import_core14.Vector3();
|
|
8397
|
+
import_geospatial12.Ellipsoid.WGS84.cartographicToCartesian(cartographicCenter, cartesianCenter);
|
|
7343
8398
|
return {
|
|
7344
8399
|
cartographicCenter,
|
|
7345
8400
|
cartesianCenter,
|
|
@@ -7348,7 +8403,7 @@ var I3SSource = class {
|
|
|
7348
8403
|
}
|
|
7349
8404
|
console.warn("Extent is not defined in the tileset header");
|
|
7350
8405
|
return {
|
|
7351
|
-
cartographicCenter: new
|
|
8406
|
+
cartographicCenter: new import_core14.Vector3(),
|
|
7352
8407
|
zoom: 1
|
|
7353
8408
|
};
|
|
7354
8409
|
}
|
|
@@ -8668,7 +9723,7 @@ function isAbortError3(error) {
|
|
|
8668
9723
|
}
|
|
8669
9724
|
|
|
8670
9725
|
// dist/point-cloud/point-cloud-tileset.js
|
|
8671
|
-
var
|
|
9726
|
+
var import_core15 = require("@math.gl/core");
|
|
8672
9727
|
var import_culling6 = require("@math.gl/culling");
|
|
8673
9728
|
|
|
8674
9729
|
// dist/point-cloud/point-cloud-tile.js
|
|
@@ -8832,7 +9887,7 @@ var PointCloudTileset = class {
|
|
|
8832
9887
|
const viewState = await ((_b = (_a = this.dataSource).getViewState) == null ? void 0 : _b.call(_a));
|
|
8833
9888
|
this.boundingVolume = (viewState == null ? void 0 : viewState.boundingVolume) || this.root.boundingVolume;
|
|
8834
9889
|
const center = (viewState == null ? void 0 : viewState.cartographicCenter) || this.root.boundingVolume.center;
|
|
8835
|
-
this.cartographicCenter = new
|
|
9890
|
+
this.cartographicCenter = new import_core15.Vector3(center);
|
|
8836
9891
|
this.zoom = (viewState == null ? void 0 : viewState.zoom) || this.estimateZoom(this.boundingVolume);
|
|
8837
9892
|
}
|
|
8838
9893
|
/**
|