@loaders.gl/tiles 5.0.0-alpha.6 → 5.0.0-alpha.8
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/README.md +26 -0
- package/dist/dist.dev.js +10015 -8172
- package/dist/dist.min.js +3 -4
- package/dist/index.cjs +1676 -477
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -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 +102 -18
- package/dist/spatial/spatial-coordinate-transformer.js.map +1 -1
- package/dist/spatial/spatial-resource-registry.js +3 -3
- package/dist/spatial/spatial-resource-registry.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 +33 -5
- package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tile-3d.js +179 -29
- package/dist/tileset-3d/common/tile-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.d.ts +15 -25
- package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.js +35 -42
- package/dist/tileset-3d/common/tileset-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-content-traversal.d.ts +37 -0
- package/dist/tileset-3d/common/tileset-content-traversal.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-content-traversal.js +80 -0
- package/dist/tileset-3d/common/tileset-content-traversal.js.map +1 -0
- 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 +11 -1
- 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 +34 -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 +278 -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/format-i3s/i3s-source.d.ts +4 -2
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-source.js +60 -9
- package/dist/tileset-3d/format-i3s/i3s-source.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-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 +5 -0
- package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.js +11 -5
- 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 +11 -12
- package/src/index.ts +18 -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 +124 -24
- package/src/spatial/spatial-resource-registry.ts +3 -3
- 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 +208 -32
- package/src/tileset-3d/common/tileset-3d.ts +37 -61
- package/src/tileset-3d/common/tileset-content-traversal.ts +114 -0
- package/src/tileset-3d/common/tileset-observability.ts +100 -0
- package/src/tileset-3d/common/tileset-source.ts +19 -1
- 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 +405 -14
- package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +7 -4
- package/src/tileset-3d/format-i3s/i3s-source.ts +84 -13
- package/src/tileset-3d/format-i3s/i3s-tileset-traverser.ts +2 -1
- package/src/tileset-3d/helpers/bounding-volume.ts +29 -62
- package/src/tileset-3d/helpers/frame-state.ts +15 -7
- 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,
|
|
@@ -61,7 +64,8 @@ __export(index_exports, {
|
|
|
61
64
|
registerGeoidModelFromPgm: () => registerGeoidModelFromPgm,
|
|
62
65
|
registerSpatialCrs: () => registerSpatialCrs,
|
|
63
66
|
registerSpatialDatumGrid: () => registerSpatialDatumGrid,
|
|
64
|
-
replaceImplicitUrlTemplate: () => replaceImplicitUrlTemplate
|
|
67
|
+
replaceImplicitUrlTemplate: () => replaceImplicitUrlTemplate,
|
|
68
|
+
traverseTilesetContents: () => traverseTilesetContents
|
|
65
69
|
});
|
|
66
70
|
module.exports = __toCommonJS(index_exports);
|
|
67
71
|
|
|
@@ -77,6 +81,13 @@ function assert(condition, message) {
|
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
83
|
|
|
84
|
+
// ../loader-utils/src/lib/binary-utils/array-buffer-utils.ts
|
|
85
|
+
function sliceArrayBuffer(arrayBuffer, byteOffset, byteLength) {
|
|
86
|
+
const subArray = byteLength !== void 0 ? new Uint8Array(arrayBuffer).subarray(byteOffset, byteOffset + byteLength) : new Uint8Array(arrayBuffer).subarray(byteOffset);
|
|
87
|
+
const arrayCopy = new Uint8Array(subArray);
|
|
88
|
+
return arrayCopy.buffer;
|
|
89
|
+
}
|
|
90
|
+
|
|
80
91
|
// ../loader-utils/src/lib/request-utils/request-scheduler.ts
|
|
81
92
|
var import_stats = require("@probe.gl/stats");
|
|
82
93
|
var STAT_QUEUED_REQUESTS = "Queued Requests";
|
|
@@ -103,6 +114,7 @@ var RequestScheduler = class {
|
|
|
103
114
|
/** Tracks the number of active requests and prioritizes/cancels queued requests. */
|
|
104
115
|
requestQueue = [];
|
|
105
116
|
requestMap = /* @__PURE__ */ new Map();
|
|
117
|
+
/** Pending arrival debounce or next-tick refill; only new arrivals replace this timer. */
|
|
106
118
|
updateTimer = null;
|
|
107
119
|
constructor(props = {}) {
|
|
108
120
|
this.props = { ...DEFAULT_PROPS, ...props };
|
|
@@ -170,20 +182,27 @@ var RequestScheduler = class {
|
|
|
170
182
|
isDone = true;
|
|
171
183
|
this.requestMap.delete(handle);
|
|
172
184
|
this.activeRequestCount--;
|
|
173
|
-
this.
|
|
185
|
+
this.scheduleRefill();
|
|
174
186
|
}
|
|
175
187
|
};
|
|
176
188
|
this.activeRequestCount++;
|
|
177
189
|
return resolve2 ? resolve2({ done }) : Promise.resolve({ done });
|
|
178
190
|
}
|
|
179
|
-
/**
|
|
191
|
+
/** Refills freed slots on the next tick while preserving any pending arrival debounce. */
|
|
192
|
+
scheduleRefill() {
|
|
193
|
+
if (this.updateTimer !== null) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
this.updateTimer = setTimeout(() => this._issueNewRequestsAsync(), 0);
|
|
197
|
+
}
|
|
198
|
+
/** Restarts the quiet period when a new request enters the queue. */
|
|
180
199
|
_issueNewRequests() {
|
|
181
200
|
if (this.updateTimer !== null) {
|
|
182
201
|
clearTimeout(this.updateTimer);
|
|
183
202
|
}
|
|
184
203
|
this.updateTimer = setTimeout(() => this._issueNewRequestsAsync(), this.props.debounceTime);
|
|
185
204
|
}
|
|
186
|
-
/**
|
|
205
|
+
/** Clears timer ownership before updating priorities and dispatching queued requests. */
|
|
187
206
|
_issueNewRequestsAsync() {
|
|
188
207
|
if (this.updateTimer !== null) {
|
|
189
208
|
clearTimeout(this.updateTimer);
|
|
@@ -485,6 +504,7 @@ var RangeRequestScheduler = class {
|
|
|
485
504
|
/** Optional event callback for range batching diagnostics. */
|
|
486
505
|
onEvent;
|
|
487
506
|
pendingRequests = [];
|
|
507
|
+
/** Pending batch window, independent of in-flight transport requests. */
|
|
488
508
|
flushTimer = null;
|
|
489
509
|
/** Creates a scheduler for one group of byte-range-addressable resources. */
|
|
490
510
|
constructor(props = {}) {
|
|
@@ -561,7 +581,7 @@ var RangeRequestScheduler = class {
|
|
|
561
581
|
}
|
|
562
582
|
/** Immediately starts loading the currently queued requests. */
|
|
563
583
|
flush() {
|
|
564
|
-
if (this.flushTimer) {
|
|
584
|
+
if (this.flushTimer !== null) {
|
|
565
585
|
clearTimeout(this.flushTimer);
|
|
566
586
|
this.flushTimer = null;
|
|
567
587
|
}
|
|
@@ -583,9 +603,9 @@ var RangeRequestScheduler = class {
|
|
|
583
603
|
this.fetchMergedRequest(mergedRequest);
|
|
584
604
|
}
|
|
585
605
|
}
|
|
586
|
-
/**
|
|
606
|
+
/** Starts a fixed batch window only when no flush is already scheduled. */
|
|
587
607
|
scheduleFlush() {
|
|
588
|
-
if (this.flushTimer) {
|
|
608
|
+
if (this.flushTimer !== null) {
|
|
589
609
|
return;
|
|
590
610
|
}
|
|
591
611
|
this.flushTimer = setTimeout(() => this.flush(), this.props.batchDelayMs);
|
|
@@ -1900,7 +1920,7 @@ function getFrameState(viewport, frameNumber, options = {}) {
|
|
|
1900
1920
|
).normalize();
|
|
1901
1921
|
commonSpacePlanesToWGS84(viewport);
|
|
1902
1922
|
const ViewportClass = viewport.constructor;
|
|
1903
|
-
const { longitude, latitude, width, bearing, zoom } = viewport;
|
|
1923
|
+
const { longitude, latitude, width, bearing, zoom, position } = viewport;
|
|
1904
1924
|
const topDownViewport = new ViewportClass({
|
|
1905
1925
|
longitude,
|
|
1906
1926
|
latitude,
|
|
@@ -1908,15 +1928,17 @@ function getFrameState(viewport, frameNumber, options = {}) {
|
|
|
1908
1928
|
width,
|
|
1909
1929
|
bearing,
|
|
1910
1930
|
zoom,
|
|
1931
|
+
position,
|
|
1911
1932
|
pitch: 0
|
|
1912
1933
|
});
|
|
1934
|
+
const verticalFieldOfView = Number.isFinite(viewport.fovy) && Number(viewport.fovy) > 0 && Number(viewport.fovy) < 180 ? Number(viewport.fovy) * Math.PI / 180 : Math.PI / 3;
|
|
1913
1935
|
return {
|
|
1914
1936
|
camera: {
|
|
1915
1937
|
position: cameraPositionCartesian2,
|
|
1916
1938
|
direction: cameraDirectionCartesian,
|
|
1917
1939
|
up: cameraUpCartesian,
|
|
1918
1940
|
cartographicPosition: cameraPositionCartographic,
|
|
1919
|
-
verticalFieldOfView
|
|
1941
|
+
verticalFieldOfView,
|
|
1920
1942
|
timeSinceMovement: options.timeSinceCameraMovement ?? Number.POSITIVE_INFINITY
|
|
1921
1943
|
},
|
|
1922
1944
|
viewport,
|
|
@@ -1926,8 +1948,7 @@ function getFrameState(viewport, frameNumber, options = {}) {
|
|
|
1926
1948
|
clippingPlanes: viewport.clippingPlanes,
|
|
1927
1949
|
frameNumber,
|
|
1928
1950
|
// TODO: This can be the same between updates, what number is unique for between updates?
|
|
1929
|
-
sseDenominator:
|
|
1930
|
-
// Assumes fovy = 60 degrees
|
|
1951
|
+
sseDenominator: 2 * Math.tan(verticalFieldOfView / 2),
|
|
1931
1952
|
// Tileset3D fills this immediately before traversal because it depends on the root volume.
|
|
1932
1953
|
dynamicScreenSpaceErrorDensity: 0
|
|
1933
1954
|
};
|
|
@@ -2265,30 +2286,32 @@ function calculateTileRequestPriority(parameters) {
|
|
|
2265
2286
|
}
|
|
2266
2287
|
|
|
2267
2288
|
// dist/spatial/spatial-types.js
|
|
2268
|
-
var
|
|
2289
|
+
var import_crs2 = require("@math.gl/crs");
|
|
2269
2290
|
|
|
2270
2291
|
// dist/spatial/get-spatial-coordinate-frame.js
|
|
2271
|
-
var
|
|
2272
|
-
|
|
2292
|
+
var import_crs = require("@math.gl/crs");
|
|
2293
|
+
|
|
2294
|
+
// dist/spatial/normalize-crs-identifier.js
|
|
2295
|
+
var WGS84_GEOGRAPHIC_CRS = "EPSG:4326";
|
|
2296
|
+
var WGS84_GEOCENTRIC_CRS = "EPSG:4978";
|
|
2273
2297
|
function normalizeCrsIdentifier(identifier) {
|
|
2274
2298
|
const normalizedIdentifier = identifier.trim().toUpperCase();
|
|
2275
2299
|
const ogcMatch = normalizedIdentifier.match(/(?:\/DEF\/CRS\/|URN:OGC:DEF:CRS:)([A-Z0-9_-]+)(?:\/|::)(?:[^/:]*[/:])?([A-Z0-9_.-]+)$/);
|
|
2276
2300
|
return ogcMatch ? `${ogcMatch[1]}:${ogcMatch[2]}` : normalizedIdentifier;
|
|
2277
2301
|
}
|
|
2302
|
+
|
|
2303
|
+
// dist/spatial/get-spatial-coordinate-frame.js
|
|
2278
2304
|
function getSpatialCoordinateFrame(definition) {
|
|
2279
2305
|
var _a, _b;
|
|
2280
2306
|
if (typeof definition === "string") {
|
|
2281
|
-
const
|
|
2282
|
-
if (
|
|
2283
|
-
return
|
|
2307
|
+
const representation = (0, import_crs.inferCRSRepresentation)(definition);
|
|
2308
|
+
if (representation === "wkt") {
|
|
2309
|
+
return getWktCoordinateFrame(definition);
|
|
2284
2310
|
}
|
|
2285
|
-
if (
|
|
2286
|
-
return
|
|
2287
|
-
}
|
|
2288
|
-
if (/^(?:GEODCRS|GEODETICCRS)\s*[\[(]/.test(normalized)) {
|
|
2289
|
-
return /CS\s*[\[(]\s*CARTESIAN/.test(normalized) ? "geocentric" : "geographic";
|
|
2311
|
+
if (representation === "proj-string") {
|
|
2312
|
+
return getProjStringCoordinateFrame(definition);
|
|
2290
2313
|
}
|
|
2291
|
-
return "projected";
|
|
2314
|
+
return getKnownCrsIdentifierCoordinateFrame(definition) || "projected";
|
|
2292
2315
|
}
|
|
2293
2316
|
const projJsonDefinition = definition;
|
|
2294
2317
|
if (projJsonDefinition.type === "BoundCRS" && projJsonDefinition.source_crs) {
|
|
@@ -2306,7 +2329,84 @@ function getSpatialCoordinateFrame(definition) {
|
|
|
2306
2329
|
if (String(projJsonDefinition.type).includes("Geodetic")) {
|
|
2307
2330
|
return ((_b = projJsonDefinition.coordinate_system) == null ? void 0 : _b.subtype) === "Cartesian" ? "geocentric" : "geographic";
|
|
2308
2331
|
}
|
|
2309
|
-
return "
|
|
2332
|
+
return "unknown";
|
|
2333
|
+
}
|
|
2334
|
+
function getKnownCrsIdentifierCoordinateFrame(definition) {
|
|
2335
|
+
if (typeof definition !== "string") {
|
|
2336
|
+
return void 0;
|
|
2337
|
+
}
|
|
2338
|
+
const normalized = normalizeCrsIdentifier(definition);
|
|
2339
|
+
if (normalized === WGS84_GEOCENTRIC_CRS) {
|
|
2340
|
+
return "geocentric";
|
|
2341
|
+
}
|
|
2342
|
+
if (normalized === WGS84_GEOGRAPHIC_CRS || normalized === "OGC:CRS84") {
|
|
2343
|
+
return "geographic";
|
|
2344
|
+
}
|
|
2345
|
+
const epsgMatch = /^EPSG:(\d+)$/.exec(normalized);
|
|
2346
|
+
if (!epsgMatch) {
|
|
2347
|
+
return void 0;
|
|
2348
|
+
}
|
|
2349
|
+
const identifier = Number(epsgMatch[1]);
|
|
2350
|
+
if (identifier === 7789) {
|
|
2351
|
+
return "geocentric";
|
|
2352
|
+
}
|
|
2353
|
+
if (identifier === 4490 || identifier === 4979) {
|
|
2354
|
+
return "geographic";
|
|
2355
|
+
}
|
|
2356
|
+
if (identifier === 3857 || identifier >= 32601 && identifier <= 32660 || identifier >= 32701 && identifier <= 32760) {
|
|
2357
|
+
return "projected";
|
|
2358
|
+
}
|
|
2359
|
+
return void 0;
|
|
2360
|
+
}
|
|
2361
|
+
function getWktCoordinateFrame(definition) {
|
|
2362
|
+
let root;
|
|
2363
|
+
try {
|
|
2364
|
+
root = (0, import_crs.parseWKTCRS)(definition).root;
|
|
2365
|
+
} catch {
|
|
2366
|
+
return "unknown";
|
|
2367
|
+
}
|
|
2368
|
+
switch (root.keyword.toUpperCase()) {
|
|
2369
|
+
case "GEOCCS":
|
|
2370
|
+
return "geocentric";
|
|
2371
|
+
case "GEOGCS":
|
|
2372
|
+
case "GEOGCRS":
|
|
2373
|
+
case "GEOGRAPHICCRS":
|
|
2374
|
+
case "GEOGRAPHIC2DCRS":
|
|
2375
|
+
case "GEOGRAPHIC3DCRS":
|
|
2376
|
+
return "geographic";
|
|
2377
|
+
case "PROJCS":
|
|
2378
|
+
case "PROJCRS":
|
|
2379
|
+
case "PROJECTEDCRS":
|
|
2380
|
+
return "projected";
|
|
2381
|
+
case "GEODCRS":
|
|
2382
|
+
case "GEODETICCRS": {
|
|
2383
|
+
const coordinateSystem = root.values.find((value) => value.type === "node" && value.keyword.toUpperCase() === "CS");
|
|
2384
|
+
const subtype = coordinateSystem == null ? void 0 : coordinateSystem.values[0];
|
|
2385
|
+
if ((subtype == null ? void 0 : subtype.type) !== "enumeration" && (subtype == null ? void 0 : subtype.type) !== "string") {
|
|
2386
|
+
return "unknown";
|
|
2387
|
+
}
|
|
2388
|
+
return subtype.value.toUpperCase() === "CARTESIAN" ? "geocentric" : subtype.value.toUpperCase() === "ELLIPSOIDAL" ? "geographic" : "unknown";
|
|
2389
|
+
}
|
|
2390
|
+
default:
|
|
2391
|
+
return "unknown";
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
function getProjStringCoordinateFrame(definition) {
|
|
2395
|
+
var _a;
|
|
2396
|
+
try {
|
|
2397
|
+
const projection = (_a = (0, import_crs.parsePROJString)(definition).parameters.find((parameter) => parameter.name.toLowerCase() === "proj")) == null ? void 0 : _a.value;
|
|
2398
|
+
switch (projection == null ? void 0 : projection.toLowerCase()) {
|
|
2399
|
+
case "longlat":
|
|
2400
|
+
case "latlong":
|
|
2401
|
+
return "geographic";
|
|
2402
|
+
case "geocent":
|
|
2403
|
+
return "geocentric";
|
|
2404
|
+
default:
|
|
2405
|
+
return projection ? "projected" : "unknown";
|
|
2406
|
+
}
|
|
2407
|
+
} catch {
|
|
2408
|
+
return "unknown";
|
|
2409
|
+
}
|
|
2310
2410
|
}
|
|
2311
2411
|
|
|
2312
2412
|
// dist/spatial/spatial-types.js
|
|
@@ -2331,11 +2431,11 @@ function createTilesetSpatialReference(discovered, options = {}) {
|
|
|
2331
2431
|
const provenance = hasSourceCrsOverride ? "caller-override" : discovered.provenance || "unknown";
|
|
2332
2432
|
const coordinateFrame = hasSourceCrsOverride && sourceCrs ? getSpatialCoordinateFrame(sourceCrs) : discovered.coordinateFrame;
|
|
2333
2433
|
const sourceCrsState = hasSourceCrsOverride ? "explicit" : discovered.sourceCrsState || (sourceCrs ? provenance === "format-default" ? "default" : "explicit" : "absent");
|
|
2334
|
-
const spatialReference = (0,
|
|
2434
|
+
const spatialReference = (0, import_crs2.createSpatialReference)({
|
|
2335
2435
|
crs: sourceCrs ? {
|
|
2336
2436
|
state: sourceCrsState === "default" ? "default" : "explicit",
|
|
2337
2437
|
definition: sourceCrs,
|
|
2338
|
-
representation: !hasSourceCrsOverride && discovered.sourceCrsRepresentation || (0,
|
|
2438
|
+
representation: !hasSourceCrsOverride && discovered.sourceCrsRepresentation || (0, import_crs2.inferCRSRepresentation)(sourceCrs),
|
|
2339
2439
|
provenance,
|
|
2340
2440
|
alternatives: hasSourceCrsOverride ? void 0 : discovered.sourceCrsAlternatives
|
|
2341
2441
|
} : {
|
|
@@ -2345,7 +2445,7 @@ function createTilesetSpatialReference(discovered, options = {}) {
|
|
|
2345
2445
|
vertical: discovered.verticalCrs ? {
|
|
2346
2446
|
state: "explicit",
|
|
2347
2447
|
definition: discovered.verticalCrs,
|
|
2348
|
-
representation: (0,
|
|
2448
|
+
representation: (0, import_crs2.inferCRSRepresentation)(discovered.verticalCrs),
|
|
2349
2449
|
provenance: discovered.provenance || "metadata"
|
|
2350
2450
|
} : void 0,
|
|
2351
2451
|
coordinateEpoch: options.coordinateEpoch ?? discovered.coordinateEpoch,
|
|
@@ -2402,11 +2502,11 @@ function getKnownCRSDefinition(reference) {
|
|
|
2402
2502
|
return reference.state === "explicit" || reference.state === "default" ? reference.definition : void 0;
|
|
2403
2503
|
}
|
|
2404
2504
|
function cloneReadonlyCRSDefinition(definition) {
|
|
2405
|
-
const spatialReference = (0,
|
|
2505
|
+
const spatialReference = (0, import_crs2.createSpatialReference)({
|
|
2406
2506
|
crs: {
|
|
2407
2507
|
state: "explicit",
|
|
2408
2508
|
definition,
|
|
2409
|
-
representation: (0,
|
|
2509
|
+
representation: (0, import_crs2.inferCRSRepresentation)(definition),
|
|
2410
2510
|
provenance: "caller-override"
|
|
2411
2511
|
}
|
|
2412
2512
|
});
|
|
@@ -2453,11 +2553,11 @@ function validateCacheByteLength(value, optionName) {
|
|
|
2453
2553
|
return value;
|
|
2454
2554
|
}
|
|
2455
2555
|
function resolveCacheBytes(options, fallbackCacheBytes) {
|
|
2456
|
-
const cacheBytes = options.cacheBytes ??
|
|
2556
|
+
const cacheBytes = options.cacheBytes ?? fallbackCacheBytes;
|
|
2457
2557
|
return validateCacheByteLength(cacheBytes, "cacheBytes");
|
|
2458
2558
|
}
|
|
2459
2559
|
function resolveMaximumCacheOverflowBytes(options, fallbackOverflowBytes) {
|
|
2460
|
-
const maximumCacheOverflowBytes = options.maximumCacheOverflowBytes ??
|
|
2560
|
+
const maximumCacheOverflowBytes = options.maximumCacheOverflowBytes ?? fallbackOverflowBytes;
|
|
2461
2561
|
return validateCacheByteLength(maximumCacheOverflowBytes, "maximumCacheOverflowBytes");
|
|
2462
2562
|
}
|
|
2463
2563
|
var DEFAULT_PROPS3 = {
|
|
@@ -2468,8 +2568,6 @@ var DEFAULT_PROPS3 = {
|
|
|
2468
2568
|
maxRequests: 64,
|
|
2469
2569
|
cacheBytes: DEFAULT_CACHE_BYTES,
|
|
2470
2570
|
maximumCacheOverflowBytes: DEFAULT_MAXIMUM_CACHE_OVERFLOW_BYTES,
|
|
2471
|
-
maximumMemoryUsage: DEFAULT_CACHE_BYTES / BYTES_PER_MEBIBYTE,
|
|
2472
|
-
memoryCacheOverflow: DEFAULT_MAXIMUM_CACHE_OVERFLOW_BYTES / BYTES_PER_MEBIBYTE,
|
|
2473
2571
|
maximumTilesSelected: 0,
|
|
2474
2572
|
debounceTime: 0,
|
|
2475
2573
|
onTileLoad: () => {
|
|
@@ -2613,8 +2711,6 @@ var Tileset3D = class {
|
|
|
2613
2711
|
...suppliedOptions,
|
|
2614
2712
|
cacheBytes,
|
|
2615
2713
|
maximumCacheOverflowBytes,
|
|
2616
|
-
maximumMemoryUsage: cacheBytes / BYTES_PER_MEBIBYTE,
|
|
2617
|
-
memoryCacheOverflow: maximumCacheOverflowBytes / BYTES_PER_MEBIBYTE,
|
|
2618
2714
|
memoryAdjustedScreenSpaceError: suppliedOptions.memoryAdjustedScreenSpaceError ?? usesTiles3DCacheDefaults
|
|
2619
2715
|
};
|
|
2620
2716
|
this.loadOptions = this.options.loadOptions || {};
|
|
@@ -2661,6 +2757,24 @@ var Tileset3D = class {
|
|
|
2661
2757
|
get frameNumber() {
|
|
2662
2758
|
return this._frameNumber;
|
|
2663
2759
|
}
|
|
2760
|
+
/**
|
|
2761
|
+
* Returns the tiles requested during the most recent completed traversal.
|
|
2762
|
+
*
|
|
2763
|
+
* A defensive copy makes request ordering deterministic for diagnostics and prevents callers
|
|
2764
|
+
* from mutating the scheduler's working set.
|
|
2765
|
+
*/
|
|
2766
|
+
get requestedTiles() {
|
|
2767
|
+
return this._requestedTiles.slice();
|
|
2768
|
+
}
|
|
2769
|
+
/**
|
|
2770
|
+
* Returns empty tiles considered during the most recent completed traversal.
|
|
2771
|
+
*
|
|
2772
|
+
* Empty tiles can still be useful hierarchy placeholders, but their IDs are included in
|
|
2773
|
+
* observability snapshots so applications can distinguish traversal work from render content.
|
|
2774
|
+
*/
|
|
2775
|
+
get emptyTiles() {
|
|
2776
|
+
return this._emptyTiles.slice();
|
|
2777
|
+
}
|
|
2664
2778
|
/**
|
|
2665
2779
|
* Gets or sets the soft target, in bytes, for cached tile content not needed this frame.
|
|
2666
2780
|
*
|
|
@@ -2675,7 +2789,6 @@ var Tileset3D = class {
|
|
|
2675
2789
|
set cacheBytes(value) {
|
|
2676
2790
|
this._cacheBytes = validateCacheByteLength(value, "cacheBytes");
|
|
2677
2791
|
this.options.cacheBytes = this._cacheBytes;
|
|
2678
|
-
this.options.maximumMemoryUsage = this._cacheBytes / BYTES_PER_MEBIBYTE;
|
|
2679
2792
|
}
|
|
2680
2793
|
/**
|
|
2681
2794
|
* Gets or sets the additional current-frame headroom, in bytes, before memory-adjusted SSE rises.
|
|
@@ -2690,17 +2803,6 @@ var Tileset3D = class {
|
|
|
2690
2803
|
set maximumCacheOverflowBytes(value) {
|
|
2691
2804
|
this._maximumCacheOverflowBytes = validateCacheByteLength(value, "maximumCacheOverflowBytes");
|
|
2692
2805
|
this.options.maximumCacheOverflowBytes = this._maximumCacheOverflowBytes;
|
|
2693
|
-
this.options.memoryCacheOverflow = this._maximumCacheOverflowBytes / BYTES_PER_MEBIBYTE;
|
|
2694
|
-
}
|
|
2695
|
-
/**
|
|
2696
|
-
* Gets or sets the soft cache target in mebibytes.
|
|
2697
|
-
* @deprecated Use {@link Tileset3D.cacheBytes}. Assignments remain synchronized for compatibility.
|
|
2698
|
-
*/
|
|
2699
|
-
get maximumMemoryUsage() {
|
|
2700
|
-
return this.cacheBytes / BYTES_PER_MEBIBYTE;
|
|
2701
|
-
}
|
|
2702
|
-
set maximumMemoryUsage(value) {
|
|
2703
|
-
this.cacheBytes = validateCacheByteLength(value * BYTES_PER_MEBIBYTE, "maximumMemoryUsage");
|
|
2704
2806
|
}
|
|
2705
2807
|
get queryParams() {
|
|
2706
2808
|
const rootUrl = this.source.getTileUrl(this.url);
|
|
@@ -2708,10 +2810,7 @@ var Tileset3D = class {
|
|
|
2708
2810
|
return queryIndex >= 0 ? rootUrl.slice(queryIndex + 1) : "";
|
|
2709
2811
|
}
|
|
2710
2812
|
/**
|
|
2711
|
-
* Updates traversal and runtime options
|
|
2712
|
-
*
|
|
2713
|
-
* For each budget, the byte-native option takes precedence when both unit forms are supplied.
|
|
2714
|
-
* Unspecified budgets retain their current byte values, avoiding repeated MiB conversion.
|
|
2813
|
+
* Updates traversal and runtime options while retaining unspecified byte budgets.
|
|
2715
2814
|
*
|
|
2716
2815
|
* @param props - Partial runtime options to apply.
|
|
2717
2816
|
*/
|
|
@@ -2722,9 +2821,7 @@ var Tileset3D = class {
|
|
|
2722
2821
|
...this.options,
|
|
2723
2822
|
...props,
|
|
2724
2823
|
cacheBytes,
|
|
2725
|
-
maximumCacheOverflowBytes
|
|
2726
|
-
maximumMemoryUsage: cacheBytes / BYTES_PER_MEBIBYTE,
|
|
2727
|
-
memoryCacheOverflow: maximumCacheOverflowBytes / BYTES_PER_MEBIBYTE
|
|
2824
|
+
maximumCacheOverflowBytes
|
|
2728
2825
|
};
|
|
2729
2826
|
this._cacheBytes = cacheBytes;
|
|
2730
2827
|
this._maximumCacheOverflowBytes = maximumCacheOverflowBytes;
|
|
@@ -2788,6 +2885,12 @@ var Tileset3D = class {
|
|
|
2788
2885
|
return;
|
|
2789
2886
|
}
|
|
2790
2887
|
const preparedViewports = viewports instanceof Array ? viewports : [viewports];
|
|
2888
|
+
const activeViewportIds = new Set(preparedViewports.map((viewport) => viewport.id));
|
|
2889
|
+
for (const frameStateId of Object.keys(this.frameStateData)) {
|
|
2890
|
+
if (!activeViewportIds.has(frameStateId)) {
|
|
2891
|
+
delete this.frameStateData[frameStateId];
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2791
2894
|
this._cache.reset();
|
|
2792
2895
|
this._frameNumber++;
|
|
2793
2896
|
this.traverseCounter = preparedViewports.length;
|
|
@@ -2976,21 +3079,21 @@ var Tileset3D = class {
|
|
|
2976
3079
|
this.stats.get(MAXIMUM_SSE).count = this.memoryAdjustedScreenSpaceError;
|
|
2977
3080
|
}
|
|
2978
3081
|
async _initializeTileSet() {
|
|
2979
|
-
var _a, _b, _c;
|
|
3082
|
+
var _a, _b, _c, _d;
|
|
2980
3083
|
try {
|
|
2981
3084
|
const initializePromise = this.source.initialize();
|
|
2982
3085
|
const initialMetadata = this._getSourceMetadata();
|
|
2983
3086
|
if (initialMetadata) {
|
|
2984
3087
|
this._syncSourceState(initialMetadata);
|
|
2985
3088
|
}
|
|
2986
|
-
if (((_a = initialMetadata == null ? void 0 : initialMetadata.tileset) == null ? void 0 : _a.root) && typeof initialMetadata.tileset.root.then !== "function" && !this.source.prepareTileset) {
|
|
3089
|
+
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
3090
|
this.root = this._initializeTileHeaders(initialMetadata.tileset, null);
|
|
2988
3091
|
this._applyViewState();
|
|
2989
3092
|
}
|
|
2990
3093
|
await initializePromise;
|
|
2991
3094
|
const metadata = this.source.getMetadata();
|
|
2992
3095
|
this._syncSourceState(metadata);
|
|
2993
|
-
await ((
|
|
3096
|
+
await ((_d = (_c = this.source).prepareTileset) == null ? void 0 : _d.call(_c, this));
|
|
2994
3097
|
if (!this.root) {
|
|
2995
3098
|
this.root = this._initializeTileHeaders(metadata.tileset, null);
|
|
2996
3099
|
}
|
|
@@ -3211,6 +3314,98 @@ function preserveTransformedSpatialReference(current, next) {
|
|
|
3211
3314
|
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
3315
|
}
|
|
3213
3316
|
|
|
3317
|
+
// dist/tileset-3d/common/tileset-observability.js
|
|
3318
|
+
function getTileset3DTraversalSnapshot(tileset) {
|
|
3319
|
+
var _a;
|
|
3320
|
+
const selectedTiles = tileset.selectedTiles.slice();
|
|
3321
|
+
const requestedTiles = tileset.requestedTiles.slice();
|
|
3322
|
+
const emptyTiles = tileset.emptyTiles.slice();
|
|
3323
|
+
const getTileIds = (tiles) => tiles.map((tile) => String(tile.id)).sort();
|
|
3324
|
+
const getStatCount = (name) => {
|
|
3325
|
+
const count = tileset.stats.get(name).count;
|
|
3326
|
+
return typeof count === "number" && Number.isFinite(count) ? count : 0;
|
|
3327
|
+
};
|
|
3328
|
+
const implicitTilingSource = tileset.source;
|
|
3329
|
+
const implicitTiling = (_a = implicitTilingSource.getImplicitTilingStats) == null ? void 0 : _a.call(implicitTilingSource);
|
|
3330
|
+
return {
|
|
3331
|
+
frameNumber: tileset.frameNumber,
|
|
3332
|
+
selectedTileIds: getTileIds(selectedTiles),
|
|
3333
|
+
requestedTileIds: getTileIds(requestedTiles),
|
|
3334
|
+
emptyTileIds: getTileIds(emptyTiles),
|
|
3335
|
+
visibleTileCount: selectedTiles.length,
|
|
3336
|
+
renderableTileCount: selectedTiles.filter((tile) => tile.contentAvailable && Boolean(tile.content)).length,
|
|
3337
|
+
loadingTileCount: getStatCount("Tiles Loading"),
|
|
3338
|
+
loadedTileCount: getStatCount("Tiles Loaded"),
|
|
3339
|
+
failedTileCount: getStatCount("Failed Tile Loads"),
|
|
3340
|
+
cachedTileCount: getStatCount("Tiles In Memory"),
|
|
3341
|
+
cacheBytes: tileset.gpuMemoryUsageInBytes,
|
|
3342
|
+
maximumScreenSpaceError: tileset.memoryAdjustedScreenSpaceError,
|
|
3343
|
+
...implicitTiling ? { implicitTiling } : {}
|
|
3344
|
+
};
|
|
3345
|
+
}
|
|
3346
|
+
|
|
3347
|
+
// dist/tileset-3d/common/tileset-content-traversal.js
|
|
3348
|
+
async function* traverseTilesetContents(tileset, options = {}) {
|
|
3349
|
+
var _a, _b;
|
|
3350
|
+
await tileset.tilesetInitializationPromise;
|
|
3351
|
+
throwIfAborted(options.signal);
|
|
3352
|
+
if (!tileset.root) {
|
|
3353
|
+
throw new Error("Tileset initialization completed without a root tile");
|
|
3354
|
+
}
|
|
3355
|
+
const stack = [tileset.root];
|
|
3356
|
+
const visitedTiles = /* @__PURE__ */ new Set();
|
|
3357
|
+
while (stack.length > 0) {
|
|
3358
|
+
throwIfAborted(options.signal);
|
|
3359
|
+
const tile = stack.pop();
|
|
3360
|
+
if (visitedTiles.has(tile)) {
|
|
3361
|
+
continue;
|
|
3362
|
+
}
|
|
3363
|
+
visitedTiles.add(tile);
|
|
3364
|
+
if (tile.header.implicitSubtree && tile.childrenState !== "ready") {
|
|
3365
|
+
const loadChildren = tileset.source.loadTileChildrenForTraversal;
|
|
3366
|
+
if (!loadChildren) {
|
|
3367
|
+
throw new Error("Tileset source does not support camera-independent subtree loading");
|
|
3368
|
+
}
|
|
3369
|
+
const result = await loadChildren.call(tileset.source, tile, options.signal);
|
|
3370
|
+
if (!result.loaded) {
|
|
3371
|
+
throw new Error(`Unable to load implicit subtree for tile ${tile.id}`);
|
|
3372
|
+
}
|
|
3373
|
+
tile.childrenState = "ready";
|
|
3374
|
+
}
|
|
3375
|
+
if (tileset.type === TILESET_TYPE.I3S && tileset.source.loadTileChildrenForTraversal) {
|
|
3376
|
+
const result = await tileset.source.loadTileChildrenForTraversal(tile, options.signal);
|
|
3377
|
+
if (!result.loaded) {
|
|
3378
|
+
throw new Error(`Unable to load I3S child nodes for tile ${tile.id}`);
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
throwIfAborted(options.signal);
|
|
3382
|
+
const loadsContent = tile.contentUrls.length > 0 && !tile.content;
|
|
3383
|
+
try {
|
|
3384
|
+
if (loadsContent) {
|
|
3385
|
+
const loadResult = await tile.loadContentForTraversal();
|
|
3386
|
+
throwIfAborted(options.signal);
|
|
3387
|
+
if (!loadResult.loaded) {
|
|
3388
|
+
throw new Error(`Unable to load tile content for tile ${tile.id}`);
|
|
3389
|
+
}
|
|
3390
|
+
(_b = (_a = tileset.source).onTileLoaded) == null ? void 0 : _b.call(_a, tileset, tile, loadResult);
|
|
3391
|
+
}
|
|
3392
|
+
yield { tile, contents: tile.contentEntries };
|
|
3393
|
+
} finally {
|
|
3394
|
+
if (options.unloadContent && loadsContent) {
|
|
3395
|
+
tile.unloadContent();
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
for (let childIndex = tile.children.length - 1; childIndex >= 0; childIndex--) {
|
|
3399
|
+
stack.push(tile.children[childIndex]);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
function throwIfAborted(signal) {
|
|
3404
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
3405
|
+
throw signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3214
3409
|
// dist/tileset-3d/common/indexed-archive-tileset-source.js
|
|
3215
3410
|
var IndexedArchiveTilesetSource = class {
|
|
3216
3411
|
/** URL exposed to the tileset source that owns this archive source. */
|
|
@@ -3327,6 +3522,47 @@ function stripQueryString(url) {
|
|
|
3327
3522
|
var import_core8 = require("@math.gl/core");
|
|
3328
3523
|
var import_culling4 = require("@math.gl/culling");
|
|
3329
3524
|
|
|
3525
|
+
// dist/tileset-3d/common/tile-3d-contracts.js
|
|
3526
|
+
function getTile3DFeatureIdSets(payload) {
|
|
3527
|
+
const featureIdSets = [];
|
|
3528
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3529
|
+
const visit = (value) => {
|
|
3530
|
+
var _a, _b;
|
|
3531
|
+
if (!value || typeof value !== "object") {
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3534
|
+
if (visited.has(value)) {
|
|
3535
|
+
return;
|
|
3536
|
+
}
|
|
3537
|
+
visited.add(value);
|
|
3538
|
+
const record = value;
|
|
3539
|
+
const declarations = (_b = (_a = record.extensions) == null ? void 0 : _a.EXT_mesh_features) == null ? void 0 : _b.featureIds;
|
|
3540
|
+
if (Array.isArray(declarations)) {
|
|
3541
|
+
for (const declaration of declarations) {
|
|
3542
|
+
if (!declaration || typeof declaration !== "object") {
|
|
3543
|
+
continue;
|
|
3544
|
+
}
|
|
3545
|
+
const source = declaration.texture ? "texture" : declaration.implicit ? "implicit" : declaration.attribute !== void 0 ? "attribute" : declaration.propertyTable !== void 0 ? "property-table" : "constant";
|
|
3546
|
+
featureIdSets.push({
|
|
3547
|
+
source,
|
|
3548
|
+
attribute: declaration.attribute,
|
|
3549
|
+
propertyTable: declaration.propertyTable,
|
|
3550
|
+
constant: declaration.constant,
|
|
3551
|
+
texture: declaration.texture,
|
|
3552
|
+
implicit: declaration.implicit,
|
|
3553
|
+
values: declaration.values,
|
|
3554
|
+
details: declaration
|
|
3555
|
+
});
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3558
|
+
for (const child of Object.values(record)) {
|
|
3559
|
+
visit(child);
|
|
3560
|
+
}
|
|
3561
|
+
};
|
|
3562
|
+
visit(payload);
|
|
3563
|
+
return featureIdSets;
|
|
3564
|
+
}
|
|
3565
|
+
|
|
3330
3566
|
// dist/tileset-3d/helpers/bounding-volume.js
|
|
3331
3567
|
var import_core6 = require("@math.gl/core");
|
|
3332
3568
|
var import_culling3 = require("@math.gl/culling");
|
|
@@ -3336,21 +3572,25 @@ function defined(x) {
|
|
|
3336
3572
|
}
|
|
3337
3573
|
var scratchPoint = new import_core6.Vector3();
|
|
3338
3574
|
var scratchScale = new import_core6.Vector3();
|
|
3339
|
-
|
|
3575
|
+
var identityTransform = new import_core6.Matrix4();
|
|
3576
|
+
function createBoundingVolume(boundingVolumeHeader, transform, result, initialTransform = transform) {
|
|
3340
3577
|
assert(boundingVolumeHeader, "3D Tile: boundingVolume must be defined");
|
|
3341
3578
|
if (boundingVolumeHeader.box) {
|
|
3342
|
-
|
|
3579
|
+
const boxTransform = boundingVolumeHeader.s2VolumeInfo ? identityTransform : transform;
|
|
3580
|
+
return createBox(boundingVolumeHeader.box, boxTransform, result);
|
|
3343
3581
|
}
|
|
3344
3582
|
if (boundingVolumeHeader.region) {
|
|
3345
|
-
|
|
3583
|
+
const boundingVolume = (0, import_geospatial4.makeOBBFromRegion)(boundingVolumeHeader.region);
|
|
3584
|
+
const regionTransform = transform.equals(initialTransform) ? identityTransform : transform.clone().multiplyRight(initialTransform.clone().invert());
|
|
3585
|
+
return createBox([...boundingVolume.center, ...boundingVolume.halfAxes], regionTransform, result);
|
|
3346
3586
|
}
|
|
3347
3587
|
if (boundingVolumeHeader.sphere) {
|
|
3348
3588
|
return createSphere(boundingVolumeHeader.sphere, transform, result);
|
|
3349
3589
|
}
|
|
3350
3590
|
throw new Error("3D Tile: boundingVolume must contain a sphere, region, or box");
|
|
3351
3591
|
}
|
|
3352
|
-
function getCartographicBounds(boundingVolumeHeader, boundingVolume) {
|
|
3353
|
-
if (boundingVolumeHeader.box) {
|
|
3592
|
+
function getCartographicBounds(boundingVolumeHeader, boundingVolume, isRegionTransformed = false) {
|
|
3593
|
+
if (boundingVolumeHeader.box || boundingVolumeHeader.region && isRegionTransformed) {
|
|
3354
3594
|
return orientedBoundingBoxToCartographicBounds(boundingVolume);
|
|
3355
3595
|
}
|
|
3356
3596
|
if (boundingVolumeHeader.region) {
|
|
@@ -3830,7 +4070,7 @@ var TilesetTraverser = class {
|
|
|
3830
4070
|
}
|
|
3831
4071
|
stack.push(child);
|
|
3832
4072
|
hasVisibleChild = true;
|
|
3833
|
-
} else if (checkRefines || loadSiblings) {
|
|
4073
|
+
} else if ((checkRefines || loadSiblings) && child._inRequestVolume) {
|
|
3834
4074
|
this.loadTile(child, frameState);
|
|
3835
4075
|
this.touchTile(child, frameState);
|
|
3836
4076
|
}
|
|
@@ -4017,6 +4257,13 @@ function getContentVisibility(contentVolumes, fallbackVolume, cullingVolume2, vi
|
|
|
4017
4257
|
}
|
|
4018
4258
|
return intersectingVolume ? "intersecting" : "inside";
|
|
4019
4259
|
}
|
|
4260
|
+
function isNestedTilesetPayload(payload) {
|
|
4261
|
+
if (!payload || typeof payload !== "object") {
|
|
4262
|
+
return false;
|
|
4263
|
+
}
|
|
4264
|
+
const record = payload;
|
|
4265
|
+
return record.shape === "tileset3d" || record.type === "tileset3d" || Boolean(record.tileset);
|
|
4266
|
+
}
|
|
4020
4267
|
function defined2(x) {
|
|
4021
4268
|
return x !== void 0 && x !== null;
|
|
4022
4269
|
}
|
|
@@ -4044,6 +4291,8 @@ var Tile3D = class {
|
|
|
4044
4291
|
* separate ensures transform updates never compound an already-scaled geometric error.
|
|
4045
4292
|
*/
|
|
4046
4293
|
_unscaledLodMetricValue = 0;
|
|
4294
|
+
/** Whether the source format defines geometric error in transform-local units. */
|
|
4295
|
+
_scaleGeometricError = true;
|
|
4047
4296
|
/** @todo math.gl is not exporting BoundingVolume base type? */
|
|
4048
4297
|
boundingVolume = null;
|
|
4049
4298
|
/**
|
|
@@ -4053,6 +4302,14 @@ var Tile3D = class {
|
|
|
4053
4302
|
content = null;
|
|
4054
4303
|
/** Loaded payloads in the same order as {@link contentUrls}; `content` remains the primary payload. */
|
|
4055
4304
|
contents = [];
|
|
4305
|
+
/** Ordered renderer-neutral descriptors for each source content entry. */
|
|
4306
|
+
contentEntries = [];
|
|
4307
|
+
/** Raw metadata references inherited by this tile and its content. */
|
|
4308
|
+
metadataContext = {};
|
|
4309
|
+
/** Feature-id declarations normalized from supported content extensions. */
|
|
4310
|
+
featureIdSets = [];
|
|
4311
|
+
/** Decoded 3D Tiles vector topology for the primary loaded content, when present. */
|
|
4312
|
+
vectorContent = null;
|
|
4056
4313
|
/**
|
|
4057
4314
|
* Metadata entity attached to this tile in the source tileset, if present.
|
|
4058
4315
|
*
|
|
@@ -4119,6 +4376,7 @@ var Tile3D = class {
|
|
|
4119
4376
|
get viewerRequestVolume() {
|
|
4120
4377
|
return this._viewerRequestVolume;
|
|
4121
4378
|
}
|
|
4379
|
+
/** Accumulated tile transforms from the source JSON, excluding the tileset model matrix. */
|
|
4122
4380
|
_initialTransform = new import_core8.Matrix4();
|
|
4123
4381
|
// Used by traverser, cannot be marked private
|
|
4124
4382
|
_priority = 0;
|
|
@@ -4160,15 +4418,14 @@ var Tile3D = class {
|
|
|
4160
4418
|
this.type = header.type;
|
|
4161
4419
|
this.contentUrl = header.contentUrl;
|
|
4162
4420
|
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);
|
|
4421
|
+
this._initializeMetadata(header);
|
|
4166
4422
|
this.childrenState = header.implicitSubtree ? "unloaded" : "ready";
|
|
4167
4423
|
this._initializeLodMetric(header);
|
|
4168
4424
|
this._initializeTransforms(header);
|
|
4169
4425
|
this._updateLodMetricScale();
|
|
4170
4426
|
this._initializeBoundingVolumes(header);
|
|
4171
4427
|
this._initializeContent(header);
|
|
4428
|
+
this._initializeContentEntries(header);
|
|
4172
4429
|
this._initializeRenderingState(header);
|
|
4173
4430
|
Object.seal(this);
|
|
4174
4431
|
}
|
|
@@ -4253,12 +4510,12 @@ var Tile3D = class {
|
|
|
4253
4510
|
return this._screenSpaceError;
|
|
4254
4511
|
}
|
|
4255
4512
|
/**
|
|
4256
|
-
* Get bounding
|
|
4513
|
+
* Get the current world-space bounding volume in cartographic coordinates.
|
|
4257
4514
|
* @returns [min, max] each in [longitude, latitude, altitude]
|
|
4258
4515
|
*/
|
|
4259
4516
|
get boundingBox() {
|
|
4260
4517
|
if (!this._boundingBox) {
|
|
4261
|
-
this._boundingBox = getCartographicBounds(this.header.boundingVolume, this.boundingVolume);
|
|
4518
|
+
this._boundingBox = getCartographicBounds(this.header.boundingVolume, this.boundingVolume, !this.computedTransform.equals(this._initialTransform));
|
|
4262
4519
|
}
|
|
4263
4520
|
return this._boundingBox;
|
|
4264
4521
|
}
|
|
@@ -4375,17 +4632,7 @@ var Tile3D = class {
|
|
|
4375
4632
|
return { loaded: false };
|
|
4376
4633
|
}
|
|
4377
4634
|
try {
|
|
4378
|
-
|
|
4379
|
-
if (loadResult.contents) {
|
|
4380
|
-
this.contents = loadResult.contents;
|
|
4381
|
-
this.content = this.contents[0] || null;
|
|
4382
|
-
}
|
|
4383
|
-
if (this.tileset.options.contentLoader) {
|
|
4384
|
-
await this.tileset.options.contentLoader(this);
|
|
4385
|
-
}
|
|
4386
|
-
this.contentState = TILE_CONTENT_STATE.READY;
|
|
4387
|
-
this._onContentLoaded();
|
|
4388
|
-
return loadResult;
|
|
4635
|
+
return await this._loadContentFromSource();
|
|
4389
4636
|
} catch (error) {
|
|
4390
4637
|
this.contentState = TILE_CONTENT_STATE.FAILED;
|
|
4391
4638
|
throw error;
|
|
@@ -4393,6 +4640,39 @@ var Tile3D = class {
|
|
|
4393
4640
|
requestToken.done();
|
|
4394
4641
|
}
|
|
4395
4642
|
}
|
|
4643
|
+
/** Loads content for complete dataset operations without viewport-based request priority. */
|
|
4644
|
+
async loadContentForTraversal() {
|
|
4645
|
+
if (this.hasEmptyContent) {
|
|
4646
|
+
return { loaded: false };
|
|
4647
|
+
}
|
|
4648
|
+
if (this.content) {
|
|
4649
|
+
return { loaded: true, contents: this.contents };
|
|
4650
|
+
}
|
|
4651
|
+
this.contentState = TILE_CONTENT_STATE.LOADING;
|
|
4652
|
+
try {
|
|
4653
|
+
return await this._loadContentFromSource();
|
|
4654
|
+
} catch (error) {
|
|
4655
|
+
this.contentState = TILE_CONTENT_STATE.FAILED;
|
|
4656
|
+
throw error;
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
/** Loads source content and updates the tile's renderer-neutral payload state. */
|
|
4660
|
+
async _loadContentFromSource() {
|
|
4661
|
+
var _a;
|
|
4662
|
+
const loadResult = await this.tileset.source.loadTileContent(this);
|
|
4663
|
+
if (loadResult.contents) {
|
|
4664
|
+
this.contents = loadResult.contents;
|
|
4665
|
+
this.content = this.contents[0] || null;
|
|
4666
|
+
}
|
|
4667
|
+
this.vectorContent = ((_a = this.contents.find((content) => Boolean(content == null ? void 0 : content.vectorContent))) == null ? void 0 : _a.vectorContent) || null;
|
|
4668
|
+
if (this.tileset.options.contentLoader) {
|
|
4669
|
+
await this.tileset.options.contentLoader(this);
|
|
4670
|
+
}
|
|
4671
|
+
this.contentState = TILE_CONTENT_STATE.READY;
|
|
4672
|
+
this._onContentLoaded();
|
|
4673
|
+
this._updateContentEntriesAfterLoad(loadResult);
|
|
4674
|
+
return loadResult;
|
|
4675
|
+
}
|
|
4396
4676
|
/**
|
|
4397
4677
|
* Requests and installs this tile's lazy child-header group through its source.
|
|
4398
4678
|
*
|
|
@@ -4447,30 +4727,114 @@ var Tile3D = class {
|
|
|
4447
4727
|
/**
|
|
4448
4728
|
* Replaces a contentless implicit placeholder with its materialized subtree-root header.
|
|
4449
4729
|
*
|
|
4450
|
-
*
|
|
4451
|
-
* transform
|
|
4452
|
-
*
|
|
4730
|
+
* The placeholder transform is preserved when the subtree omits a root transform. An explicit
|
|
4731
|
+
* subtree-root transform replaces it and is recomposed against the runtime parent. Content,
|
|
4732
|
+
* metadata, bounds, and raw geometric error are reinitialized from the available header.
|
|
4453
4733
|
*
|
|
4454
4734
|
* @param materializedHeader - Available root header produced from one subtree resource.
|
|
4455
4735
|
*/
|
|
4456
4736
|
applyImplicitSubtreeHeader(materializedHeader) {
|
|
4457
4737
|
const existingTransform = this.header.transform;
|
|
4458
4738
|
const existingTransformMatrix = this.header.transformMatrix;
|
|
4739
|
+
const hasMaterializedTransform = materializedHeader.transform !== void 0;
|
|
4459
4740
|
this.header = {
|
|
4460
4741
|
...this.header,
|
|
4461
4742
|
...materializedHeader,
|
|
4462
|
-
transform: existingTransform,
|
|
4463
|
-
transformMatrix: existingTransformMatrix,
|
|
4743
|
+
transform: hasMaterializedTransform ? materializedHeader.transform : existingTransform,
|
|
4744
|
+
transformMatrix: hasMaterializedTransform ? materializedHeader.transformMatrix : existingTransformMatrix,
|
|
4464
4745
|
implicitSubtree: void 0
|
|
4465
4746
|
};
|
|
4747
|
+
if (hasMaterializedTransform) {
|
|
4748
|
+
this._initializeTransforms(this.header);
|
|
4749
|
+
}
|
|
4466
4750
|
this.refine = this._getRefine(materializedHeader.refine);
|
|
4467
4751
|
this.type = materializedHeader.type;
|
|
4468
4752
|
this.contentUrl = materializedHeader.contentUrl;
|
|
4469
4753
|
this.contentUrls = materializedHeader.contentUrls || (materializedHeader.contentUrl ? [materializedHeader.contentUrl] : []);
|
|
4754
|
+
this._initializeMetadata(this.header);
|
|
4470
4755
|
this._initializeLodMetric(materializedHeader);
|
|
4471
4756
|
this._updateLodMetricScale();
|
|
4472
4757
|
this._initializeBoundingVolumes(this.header);
|
|
4758
|
+
this._boundingBox = void 0;
|
|
4473
4759
|
this._initializeContent(this.header);
|
|
4760
|
+
this._initializeContentEntries(this.header);
|
|
4761
|
+
}
|
|
4762
|
+
/** Refreshes tile and content metadata from a source or materialized tile header. */
|
|
4763
|
+
_initializeMetadata(header) {
|
|
4764
|
+
var _a;
|
|
4765
|
+
this.metadata = header.metadata || null;
|
|
4766
|
+
const contentHeaders = Array.isArray(header.content) ? header.content : [header.content];
|
|
4767
|
+
this.contentMetadata = contentHeaders.filter(Boolean).map((contentHeader) => contentHeader.metadata || null);
|
|
4768
|
+
const firstContentHeader = contentHeaders.find(Boolean) || {};
|
|
4769
|
+
const groupReference = firstContentHeader.group;
|
|
4770
|
+
const group = typeof groupReference === "number" ? ((_a = this.tileset.groups) == null ? void 0 : _a[groupReference]) || null : groupReference || null;
|
|
4771
|
+
const metadataContext = {
|
|
4772
|
+
tileset: this.tileset.metadata || null,
|
|
4773
|
+
group,
|
|
4774
|
+
tile: this.metadata,
|
|
4775
|
+
content: this.contentMetadata[0] || null,
|
|
4776
|
+
subtree: header.implicitMetadata || null
|
|
4777
|
+
};
|
|
4778
|
+
if (this.tileset.groups) {
|
|
4779
|
+
metadataContext.groups = this.tileset.groups;
|
|
4780
|
+
}
|
|
4781
|
+
this.metadataContext = metadataContext;
|
|
4782
|
+
}
|
|
4783
|
+
/** Updates payload and renderability while retaining immutable metadata descriptors. */
|
|
4784
|
+
_updateContentEntriesAfterLoad(loadResult) {
|
|
4785
|
+
if (loadResult.contentEntries) {
|
|
4786
|
+
this.contentEntries = loadResult.contentEntries.map((entry, index) => {
|
|
4787
|
+
var _a;
|
|
4788
|
+
return {
|
|
4789
|
+
...entry,
|
|
4790
|
+
index,
|
|
4791
|
+
boundingVolume: entry.boundingVolume || this._contentBoundingVolumes[index] || this.boundingVolume,
|
|
4792
|
+
payload: entry.payload ?? this.contents[index] ?? null,
|
|
4793
|
+
featureIds: ((_a = entry.featureIds) == null ? void 0 : _a.length) ? entry.featureIds : getTile3DFeatureIdSets(entry.payload ?? this.contents[index]),
|
|
4794
|
+
renderable: Boolean(entry.renderable !== false && (entry.payload ?? this.contents[index]) && !isNestedTilesetPayload(entry.payload ?? this.contents[index]))
|
|
4795
|
+
};
|
|
4796
|
+
});
|
|
4797
|
+
this.featureIdSets = this.contentEntries.flatMap((entry) => entry.featureIds);
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
this.contentEntries = this.contentEntries.map((entry, index) => ({
|
|
4801
|
+
...entry,
|
|
4802
|
+
payload: this.contents[index] ?? null,
|
|
4803
|
+
featureIds: getTile3DFeatureIdSets(this.contents[index]),
|
|
4804
|
+
renderable: Boolean(this.contents[index]) && !isNestedTilesetPayload(this.contents[index])
|
|
4805
|
+
}));
|
|
4806
|
+
this.featureIdSets = this.contentEntries.flatMap((entry) => entry.featureIds);
|
|
4807
|
+
}
|
|
4808
|
+
/** Returns one ordered content descriptor, or null when the index is out of range. */
|
|
4809
|
+
getContentEntry(index) {
|
|
4810
|
+
return this.contentEntries[index] || null;
|
|
4811
|
+
}
|
|
4812
|
+
/** Returns whether an ordered content entry currently has renderable payload. */
|
|
4813
|
+
isContentRenderable(index) {
|
|
4814
|
+
var _a;
|
|
4815
|
+
return Boolean((_a = this.contentEntries[index]) == null ? void 0 : _a.renderable);
|
|
4816
|
+
}
|
|
4817
|
+
/** Initializes additive renderer-neutral descriptors from a normalized tile header. */
|
|
4818
|
+
_initializeContentEntries(tileHeader) {
|
|
4819
|
+
const headers = Array.isArray(tileHeader.content) ? tileHeader.content : tileHeader.content ? [tileHeader.content] : [];
|
|
4820
|
+
this.contentEntries = headers.map((contentHeader, index) => {
|
|
4821
|
+
const normalizedContentHeader = contentHeader || {};
|
|
4822
|
+
return {
|
|
4823
|
+
index,
|
|
4824
|
+
uri: this.contentUrls[index] || normalizedContentHeader.uri || normalizedContentHeader.url,
|
|
4825
|
+
group: normalizedContentHeader.group,
|
|
4826
|
+
type: normalizedContentHeader.type,
|
|
4827
|
+
payload: null,
|
|
4828
|
+
metadata: normalizedContentHeader.metadata || null,
|
|
4829
|
+
boundingVolume: this._contentBoundingVolumes[index] || this.boundingVolume,
|
|
4830
|
+
featureIds: this._getFeatureIdSets(normalizedContentHeader),
|
|
4831
|
+
renderable: false
|
|
4832
|
+
};
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
/** Extracts renderer-neutral feature-id declarations without decoding property values. */
|
|
4836
|
+
_getFeatureIdSets(contentHeader) {
|
|
4837
|
+
return getTile3DFeatureIdSets(contentHeader);
|
|
4474
4838
|
}
|
|
4475
4839
|
// Unloads the tile's content.
|
|
4476
4840
|
unloadContent() {
|
|
@@ -4481,6 +4845,13 @@ var Tile3D = class {
|
|
|
4481
4845
|
}
|
|
4482
4846
|
this.contents = [];
|
|
4483
4847
|
this.content = null;
|
|
4848
|
+
this.vectorContent = null;
|
|
4849
|
+
this.contentEntries = this.contentEntries.map((entry) => ({
|
|
4850
|
+
...entry,
|
|
4851
|
+
payload: null,
|
|
4852
|
+
renderable: false
|
|
4853
|
+
}));
|
|
4854
|
+
this.featureIdSets = this.contentEntries.flatMap((entry) => entry.featureIds);
|
|
4484
4855
|
if (this.header.content && this.header.content.destroy) {
|
|
4485
4856
|
this.header.content.destroy();
|
|
4486
4857
|
}
|
|
@@ -4577,8 +4948,9 @@ var Tile3D = class {
|
|
|
4577
4948
|
* @param frameState Current camera, culling, and optional clipping-plane state.
|
|
4578
4949
|
* @returns The content visibility classification.
|
|
4579
4950
|
*/
|
|
4580
|
-
contentVisibility(frameState) {
|
|
4581
|
-
|
|
4951
|
+
contentVisibility(frameState, contentIndex) {
|
|
4952
|
+
const contentVolumes = contentIndex === void 0 ? this._contentBoundingVolumes : this._contentBoundingVolumes[contentIndex] ? [this._contentBoundingVolumes[contentIndex]] : [];
|
|
4953
|
+
return getContentVisibility(contentVolumes, this.boundingVolume, frameState.cullingVolume, this._visibilityPlaneMask, frameState.clippingPlanes);
|
|
4582
4954
|
}
|
|
4583
4955
|
/**
|
|
4584
4956
|
* Computes the (potentially approximate) distance from the closest point of the tile's bounding volume to the camera.
|
|
@@ -4625,6 +4997,8 @@ var Tile3D = class {
|
|
|
4625
4997
|
// INTERNAL METHODS
|
|
4626
4998
|
/** Initializes the tile's LOD metric from its header or its nearest available ancestor. */
|
|
4627
4999
|
_initializeLodMetric(header) {
|
|
5000
|
+
var _a;
|
|
5001
|
+
this._scaleGeometricError = typeof header._scaleGeometricError === "boolean" ? header._scaleGeometricError : ((_a = this.parent) == null ? void 0 : _a._scaleGeometricError) ?? true;
|
|
4628
5002
|
if ("lodMetricType" in header) {
|
|
4629
5003
|
this.lodMetricType = header.lodMetricType;
|
|
4630
5004
|
} else {
|
|
@@ -4660,7 +5034,7 @@ var Tile3D = class {
|
|
|
4660
5034
|
* I3S `maxScreenThreshold` is already a screen-space metric and must not be transform-scaled.
|
|
4661
5035
|
*/
|
|
4662
5036
|
_updateLodMetricScale() {
|
|
4663
|
-
if (this.lodMetricType !== LOD_METRIC_TYPE.GEOMETRIC_ERROR) {
|
|
5037
|
+
if (this.lodMetricType !== LOD_METRIC_TYPE.GEOMETRIC_ERROR || !this._scaleGeometricError) {
|
|
4664
5038
|
this.lodMetricValue = this._unscaledLodMetricValue;
|
|
4665
5039
|
return;
|
|
4666
5040
|
}
|
|
@@ -4740,16 +5114,17 @@ var Tile3D = class {
|
|
|
4740
5114
|
}
|
|
4741
5115
|
}
|
|
4742
5116
|
_updateBoundingVolume(header) {
|
|
4743
|
-
this.
|
|
5117
|
+
this._boundingBox = void 0;
|
|
5118
|
+
this.boundingVolume = createBoundingVolume(header.boundingVolume, this.computedTransform, this.boundingVolume, this._initialTransform);
|
|
4744
5119
|
if (header.viewerRequestVolume) {
|
|
4745
|
-
this._viewerRequestVolume = createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume);
|
|
5120
|
+
this._viewerRequestVolume = createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume, this._initialTransform);
|
|
4746
5121
|
}
|
|
4747
5122
|
const content = header.content;
|
|
4748
5123
|
if (content) {
|
|
4749
5124
|
this._contentBoundingVolumeHeaders = Array.isArray(content) ? content : [content];
|
|
4750
5125
|
}
|
|
4751
5126
|
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];
|
|
5127
|
+
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
5128
|
this._contentBoundingVolume = this._contentBoundingVolumes[0] || null;
|
|
4754
5129
|
}
|
|
4755
5130
|
/**
|
|
@@ -4769,8 +5144,8 @@ var Tile3D = class {
|
|
|
4769
5144
|
};
|
|
4770
5145
|
|
|
4771
5146
|
// dist/tileset-3d/format-3d-tiles/tiles-3d-source.js
|
|
4772
|
-
var
|
|
4773
|
-
var
|
|
5147
|
+
var import_geospatial10 = require("@math.gl/geospatial");
|
|
5148
|
+
var import_core12 = require("@math.gl/core");
|
|
4774
5149
|
|
|
4775
5150
|
// dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js
|
|
4776
5151
|
var Tileset3DTraverser = class extends TilesetTraverser {
|
|
@@ -4980,10 +5355,12 @@ var Tileset3DTraverser = class extends TilesetTraverser {
|
|
|
4980
5355
|
return b._distanceToCamera === 0 && a._distanceToCamera === 0 ? b._centerZDepth - a._centerZDepth : b._distanceToCamera - a._distanceToCamera;
|
|
4981
5356
|
}
|
|
4982
5357
|
/**
|
|
4983
|
-
* Starts an implicit subtree request
|
|
5358
|
+
* Starts an implicit subtree request after culling and request-volume eligibility.
|
|
4984
5359
|
*
|
|
4985
|
-
* The
|
|
4986
|
-
*
|
|
5360
|
+
* The first subtree of an implicit hierarchy materializes independently of SSE because its
|
|
5361
|
+
* placeholder has no render content. Deeper subtree boundaries remain SSE-gated. The current
|
|
5362
|
+
* parent remains the traversal boundary while metadata is loading, which preserves REPLACE
|
|
5363
|
+
* coverage and ADD accumulation. Request scheduling reads the tile's existing
|
|
4987
5364
|
* progressive-resolution and foveated metrics, so subtree metadata follows the same priority
|
|
4988
5365
|
* policy as render content. A completion notification lets the owning tileset publish the newly
|
|
4989
5366
|
* materialized traversal result on the next update.
|
|
@@ -4992,7 +5369,9 @@ var Tileset3DTraverser = class extends TilesetTraverser {
|
|
|
4992
5369
|
* @param frameState - Current culling and LOD state.
|
|
4993
5370
|
*/
|
|
4994
5371
|
updateChildTiles(tile, frameState) {
|
|
4995
|
-
|
|
5372
|
+
var _a;
|
|
5373
|
+
const isImplicitHierarchyRoot = ((_a = tile.header.implicitSubtree) == null ? void 0 : _a.coordinates.level) === 0;
|
|
5374
|
+
if (tile.hasUnloadedChildren && tile.isVisibleAndInRequestVolume && (isImplicitHierarchyRoot || this.shouldRefine(tile, frameState))) {
|
|
4996
5375
|
const requestKey = `${frameState.viewport.id}:${tile.id}`;
|
|
4997
5376
|
if (!this.pendingImplicitSubtrees.has(requestKey)) {
|
|
4998
5377
|
this.pendingImplicitSubtrees.set(requestKey, frameState.frameNumber);
|
|
@@ -5183,7 +5562,7 @@ function getI3SSpatialReference(layer) {
|
|
|
5183
5562
|
const verticalUnitScale = getI3SVerticalUnitScale(verticalUnit, layer.ZFactor);
|
|
5184
5563
|
const heightReference = heightModel === "ellipsoidal" ? "ellipsoidal" : heightModel === "gravity_related_height" ? "orthometric" : "unknown";
|
|
5185
5564
|
const sourceIdentifier = getCrsIdentifier(spatialReference);
|
|
5186
|
-
const coordinateFrame = sourceIdentifier === void 0 ?
|
|
5565
|
+
const coordinateFrame = sourceIdentifier === void 0 ? sourceCrs ? getSpatialCoordinateFrame(sourceCrs) : "unknown" : getSpatialCoordinateFrame(`EPSG:${sourceIdentifier}`);
|
|
5187
5566
|
const units = getI3SCoordinateUnits(coordinateFrame, verticalUnit, layer.ZFactor);
|
|
5188
5567
|
const warnings = [];
|
|
5189
5568
|
const elevationMode = getI3SElevationMode((_e = layer.elevationInfo) == null ? void 0 : _e.mode);
|
|
@@ -5241,6 +5620,10 @@ function getI3SElevationMode(mode) {
|
|
|
5241
5620
|
}
|
|
5242
5621
|
function get3DTilesSpatialReference(tileset) {
|
|
5243
5622
|
var _a, _b;
|
|
5623
|
+
const draftSpatialReference = getDraft3DTilesSpatialReference(tileset);
|
|
5624
|
+
if (draftSpatialReference) {
|
|
5625
|
+
return draftSpatialReference;
|
|
5626
|
+
}
|
|
5244
5627
|
const geocentricCrs = getTilesetSemanticValue(tileset, "TILESET_CRS_GEOCENTRIC");
|
|
5245
5628
|
const coordinateEpoch = getTilesetSemanticValue(tileset, "TILESET_CRS_COORDINATE_EPOCH");
|
|
5246
5629
|
const warnings = [];
|
|
@@ -5278,6 +5661,87 @@ function get3DTilesSpatialReference(tileset) {
|
|
|
5278
5661
|
warnings
|
|
5279
5662
|
});
|
|
5280
5663
|
}
|
|
5664
|
+
function getDraft3DTilesSpatialReference(tileset) {
|
|
5665
|
+
var _a, _b, _c;
|
|
5666
|
+
const extension = (_a = tileset.extensions) == null ? void 0 : _a.EXT_geospatial_crs;
|
|
5667
|
+
if (!extension) {
|
|
5668
|
+
return void 0;
|
|
5669
|
+
}
|
|
5670
|
+
const warnings = [];
|
|
5671
|
+
let sourceCrs;
|
|
5672
|
+
let verticalCrs;
|
|
5673
|
+
let epoch;
|
|
5674
|
+
let representation;
|
|
5675
|
+
if (extension.format === "wkid") {
|
|
5676
|
+
const wkidExtension = (_b = extension.extensions) == null ? void 0 : _b.EXT_geospatial_crs_wkid;
|
|
5677
|
+
if (typeof (wkidExtension == null ? void 0 : wkidExtension.authority) === "string" && Number.isInteger(wkidExtension.wkid)) {
|
|
5678
|
+
sourceCrs = `${wkidExtension.authority}:${wkidExtension.wkid}`;
|
|
5679
|
+
representation = "identifier";
|
|
5680
|
+
if (Number.isInteger(wkidExtension.vcsWkid)) {
|
|
5681
|
+
verticalCrs = `${wkidExtension.authority}:${wkidExtension.vcsWkid}`;
|
|
5682
|
+
}
|
|
5683
|
+
epoch = parseCoordinateEpoch(wkidExtension.epoch);
|
|
5684
|
+
if (wkidExtension.epoch !== void 0 && epoch === void 0) {
|
|
5685
|
+
warnings.push("EXT_geospatial_crs_wkid epoch is not a finite decimal year");
|
|
5686
|
+
}
|
|
5687
|
+
} else {
|
|
5688
|
+
warnings.push("EXT_geospatial_crs_wkid requires string authority and integer wkid");
|
|
5689
|
+
}
|
|
5690
|
+
} else if (extension.format === "wkt2") {
|
|
5691
|
+
const wktExtension = (_c = extension.extensions) == null ? void 0 : _c.EXT_geospatial_crs_wkt2;
|
|
5692
|
+
if (typeof (wktExtension == null ? void 0 : wktExtension.wkt2) === "string" && wktExtension.wkt2.trim()) {
|
|
5693
|
+
sourceCrs = wktExtension.wkt2;
|
|
5694
|
+
representation = "wkt";
|
|
5695
|
+
} else {
|
|
5696
|
+
warnings.push("EXT_geospatial_crs_wkt2 requires a nonempty wkt2 string");
|
|
5697
|
+
}
|
|
5698
|
+
} else {
|
|
5699
|
+
warnings.push(`Unsupported EXT_geospatial_crs format ${String(extension.format)}`);
|
|
5700
|
+
}
|
|
5701
|
+
const coordinateFrame = representation === "wkt" ? getSpatialCoordinateFrame(sourceCrs) : getKnownCrsIdentifierCoordinateFrame(sourceCrs) || "unknown";
|
|
5702
|
+
const verticalSemantics = getDraftVerticalCrsSemantics(verticalCrs);
|
|
5703
|
+
if (verticalCrs && !verticalSemantics) {
|
|
5704
|
+
warnings.push(`Unsupported vertical CRS ${String(verticalCrs)}; vertical unit and height reference are unknown`);
|
|
5705
|
+
}
|
|
5706
|
+
const verticalUnit = verticalCrs ? verticalSemantics == null ? void 0 : verticalSemantics.unit : "meter";
|
|
5707
|
+
return createTilesetSpatialReference({
|
|
5708
|
+
sourceCrs,
|
|
5709
|
+
sourceCrsState: sourceCrs ? "explicit" : "unknown",
|
|
5710
|
+
sourceCrsRepresentation: representation,
|
|
5711
|
+
verticalCrs,
|
|
5712
|
+
coordinateEpoch: epoch,
|
|
5713
|
+
units: coordinateFrame === "geocentric" ? ["meter", "meter", "meter"] : coordinateFrame === "geographic" && verticalUnit ? ["degree", "degree", verticalUnit] : void 0,
|
|
5714
|
+
verticalUnitScale: verticalCrs ? (verticalSemantics == null ? void 0 : verticalSemantics.verticalUnitScale) ?? Number.NaN : 1,
|
|
5715
|
+
heightReference: verticalCrs ? (verticalSemantics == null ? void 0 : verticalSemantics.heightReference) ?? "unknown" : sourceCrs ? "ellipsoidal" : "unknown",
|
|
5716
|
+
coordinateFrame,
|
|
5717
|
+
axisOrder: sourceCrs ? "xyz" : "unknown",
|
|
5718
|
+
provenance: "metadata",
|
|
5719
|
+
warnings
|
|
5720
|
+
});
|
|
5721
|
+
}
|
|
5722
|
+
function getDraftVerticalCrsSemantics(verticalCrs) {
|
|
5723
|
+
if (typeof verticalCrs !== "string") {
|
|
5724
|
+
return void 0;
|
|
5725
|
+
}
|
|
5726
|
+
const epsgMatch = /^EPSG:(\d+)$/i.exec(verticalCrs);
|
|
5727
|
+
if (!epsgMatch) {
|
|
5728
|
+
return void 0;
|
|
5729
|
+
}
|
|
5730
|
+
switch (Number(epsgMatch[1])) {
|
|
5731
|
+
case 5702:
|
|
5732
|
+
// NGVD29 height (ftUS)
|
|
5733
|
+
case 6360:
|
|
5734
|
+
return {
|
|
5735
|
+
unit: "us-foot",
|
|
5736
|
+
verticalUnitScale: 1200 / 3937,
|
|
5737
|
+
heightReference: "orthometric"
|
|
5738
|
+
};
|
|
5739
|
+
case 5703:
|
|
5740
|
+
return { unit: "meter", verticalUnitScale: 1, heightReference: "orthometric" };
|
|
5741
|
+
default:
|
|
5742
|
+
return void 0;
|
|
5743
|
+
}
|
|
5744
|
+
}
|
|
5281
5745
|
function parseCoordinateEpoch(value) {
|
|
5282
5746
|
if (typeof value !== "string" && typeof value !== "number") {
|
|
5283
5747
|
return void 0;
|
|
@@ -5302,41 +5766,6 @@ function getI3SVerticalCrsDefinition(spatialReference) {
|
|
|
5302
5766
|
function getCrsIdentifier(spatialReference) {
|
|
5303
5767
|
return (spatialReference == null ? void 0 : spatialReference.latestWkid) ?? (spatialReference == null ? void 0 : spatialReference.wkid);
|
|
5304
5768
|
}
|
|
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
5769
|
function getTilesetSemanticValue(tileset, semantic) {
|
|
5341
5770
|
var _a, _b, _c, _d;
|
|
5342
5771
|
const classIdentifier = (_a = tileset.metadata) == null ? void 0 : _a.class;
|
|
@@ -5354,39 +5783,568 @@ function getTilesetSemanticValue(tileset, semantic) {
|
|
|
5354
5783
|
return void 0;
|
|
5355
5784
|
}
|
|
5356
5785
|
|
|
5357
|
-
// dist/
|
|
5358
|
-
var
|
|
5359
|
-
var
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5786
|
+
// dist/spatial/spatial-coordinate-transformer.js
|
|
5787
|
+
var import_core10 = require("@math.gl/core");
|
|
5788
|
+
var import_geospatial7 = require("@math.gl/geospatial");
|
|
5789
|
+
var import_proj42 = require("@math.gl/proj4");
|
|
5790
|
+
|
|
5791
|
+
// dist/spatial/spatial-resource-registry.js
|
|
5792
|
+
var import_geoid = require("@math.gl/geoid");
|
|
5793
|
+
var import_proj4 = require("@math.gl/proj4");
|
|
5794
|
+
var geoidModels = /* @__PURE__ */ new Map();
|
|
5795
|
+
function registerSpatialCrs(name, definition) {
|
|
5796
|
+
validateResourceName(name, "CRS");
|
|
5797
|
+
import_proj4.Projection.defineProjectionAliases({ [name]: definition });
|
|
5366
5798
|
}
|
|
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 };
|
|
5799
|
+
function registerSpatialDatumGrid(name, data) {
|
|
5800
|
+
validateResourceName(name, "datum grid");
|
|
5801
|
+
import_proj4.Projection.registerDatumGrid(name, data);
|
|
5376
5802
|
}
|
|
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()]));
|
|
5803
|
+
function registerGeoidModel(name, geoid) {
|
|
5804
|
+
validateResourceName(name, "geoid model");
|
|
5805
|
+
geoidModels.set(name, geoid);
|
|
5385
5806
|
}
|
|
5386
|
-
function
|
|
5387
|
-
const
|
|
5388
|
-
|
|
5389
|
-
|
|
5807
|
+
function registerGeoidModelFromPgm(name, data, options = {}) {
|
|
5808
|
+
const geoid = (0, import_geoid.parsePGM)(data, options);
|
|
5809
|
+
registerGeoidModel(name, geoid);
|
|
5810
|
+
return geoid;
|
|
5811
|
+
}
|
|
5812
|
+
function getGeoidModel(name) {
|
|
5813
|
+
return geoidModels.get(name);
|
|
5814
|
+
}
|
|
5815
|
+
function validateResourceName(name, resourceType) {
|
|
5816
|
+
if (!name.trim()) {
|
|
5817
|
+
throw new Error(`${resourceType} name must not be empty`);
|
|
5818
|
+
}
|
|
5819
|
+
}
|
|
5820
|
+
|
|
5821
|
+
// dist/spatial/spatial-coordinate-transformer.js
|
|
5822
|
+
var SpatialCoordinateTransformer = class {
|
|
5823
|
+
/** Normalized spatial metadata describing this transformation. */
|
|
5824
|
+
spatialReference;
|
|
5825
|
+
/** Projection from the source CRS directly to the requested horizontal target CRS. */
|
|
5826
|
+
horizontalProjection;
|
|
5827
|
+
/** Projection from the source CRS to geographic longitude, latitude, and ellipsoidal height. */
|
|
5828
|
+
geographicProjection;
|
|
5829
|
+
/** Projection from adjusted geographic coordinates to the requested output CRS. */
|
|
5830
|
+
heightOutputProjection;
|
|
5831
|
+
/** Whether source coordinates use the WGS84 geocentric frame handled by math.gl. */
|
|
5832
|
+
sourceIsGeocentric;
|
|
5833
|
+
/** Whether output coordinates use the WGS84 geocentric frame handled by math.gl. */
|
|
5834
|
+
outputIsGeocentric;
|
|
5835
|
+
/** Whether source coordinates already use conventional WGS84 longitude/latitude order. */
|
|
5836
|
+
sourceIsGeographic;
|
|
5837
|
+
/** Whether output coordinates use conventional WGS84 longitude/latitude order. */
|
|
5838
|
+
outputIsGeographic;
|
|
5839
|
+
/** Geoid model used to convert between ellipsoidal and orthometric heights. */
|
|
5840
|
+
geoid;
|
|
5841
|
+
/**
|
|
5842
|
+
* Creates a coordinate transformer.
|
|
5843
|
+
*
|
|
5844
|
+
* @param spatialReference - Format-discovered and option-normalized spatial metadata.
|
|
5845
|
+
* @param options - Application options containing an optional geoid model.
|
|
5846
|
+
*/
|
|
5847
|
+
constructor(spatialReference, options = {}) {
|
|
5848
|
+
this.spatialReference = spatialReference;
|
|
5849
|
+
validateTransformRequest(spatialReference);
|
|
5850
|
+
const outputCrs = spatialReference.targetCrs || spatialReference.sourceCrs;
|
|
5851
|
+
this.sourceIsGeocentric = isWgs84Geocentric(spatialReference.sourceCrs);
|
|
5852
|
+
this.outputIsGeocentric = isWgs84Geocentric(outputCrs);
|
|
5853
|
+
this.sourceIsGeographic = isWgs84Geographic(spatialReference.sourceCrs);
|
|
5854
|
+
this.outputIsGeographic = isWgs84Geographic(outputCrs);
|
|
5855
|
+
if (spatialReference.sourceCrs && spatialReference.targetCrs && !this.sourceIsGeocentric && !this.outputIsGeocentric) {
|
|
5856
|
+
this.horizontalProjection = new import_proj42.Projection({
|
|
5857
|
+
from: getHorizontalProj4Definition(spatialReference.sourceCrs),
|
|
5858
|
+
to: getHorizontalProj4Definition(spatialReference.targetCrs),
|
|
5859
|
+
enforceAxis: false
|
|
5860
|
+
});
|
|
5861
|
+
}
|
|
5862
|
+
if (requiresHeightTransformation(spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
|
|
5863
|
+
if (!this.sourceIsGeographic && !this.sourceIsGeocentric) {
|
|
5864
|
+
this.geographicProjection = new import_proj42.Projection({
|
|
5865
|
+
from: getHorizontalProj4Definition(spatialReference.sourceCrs),
|
|
5866
|
+
to: WGS84_GEOGRAPHIC_CRS,
|
|
5867
|
+
enforceAxis: false
|
|
5868
|
+
});
|
|
5869
|
+
}
|
|
5870
|
+
if (!this.outputIsGeographic && !this.outputIsGeocentric) {
|
|
5871
|
+
this.heightOutputProjection = new import_proj42.Projection({
|
|
5872
|
+
from: WGS84_GEOGRAPHIC_CRS,
|
|
5873
|
+
to: getHorizontalProj4Definition(outputCrs),
|
|
5874
|
+
enforceAxis: false
|
|
5875
|
+
});
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
if (requiresHeightTransformation(spatialReference)) {
|
|
5879
|
+
this.geoid = resolveGeoid(options.geoidModel);
|
|
5880
|
+
if (!this.geoid) {
|
|
5881
|
+
const modelName = typeof options.geoidModel === "string" ? ` "${options.geoidModel}"` : "";
|
|
5882
|
+
throw new Error(`Height conversion requires a registered geoid model${modelName}; call registerGeoidModel() or pass a parsed Geoid instance`);
|
|
5883
|
+
}
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5886
|
+
/**
|
|
5887
|
+
* Transforms one `[x, y, z?]` coordinate while retaining additional components.
|
|
5888
|
+
*
|
|
5889
|
+
* @param coordinate - Source coordinate in the format adapter's normalized `x/y/z` order.
|
|
5890
|
+
* @returns A new transformed coordinate array.
|
|
5891
|
+
*/
|
|
5892
|
+
transformPosition(coordinate) {
|
|
5893
|
+
if (coordinate.length < 2) {
|
|
5894
|
+
throw new Error("A spatial coordinate must contain at least x and y components");
|
|
5895
|
+
}
|
|
5896
|
+
const result = [...coordinate];
|
|
5897
|
+
if (requiresHeightTransformation(this.spatialReference) || this.sourceIsGeocentric || this.outputIsGeocentric) {
|
|
5898
|
+
if (result.length < 3 || !Number.isFinite(result[2])) {
|
|
5899
|
+
throw new Error("Three-dimensional CRS conversion requires a finite z coordinate");
|
|
5900
|
+
}
|
|
5901
|
+
const geographic = this.toGeographic(result);
|
|
5902
|
+
if (requiresHeightTransformation(this.spatialReference)) {
|
|
5903
|
+
const geoidUndulation = this.geoid.getHeight(geographic[1], geographic[0]);
|
|
5904
|
+
geographic[2] = transformHeight(geographic[2], geoidUndulation, this.spatialReference.heightReference, this.spatialReference.targetHeightReference);
|
|
5905
|
+
}
|
|
5906
|
+
const projected = this.fromGeographic(geographic);
|
|
5907
|
+
result.splice(0, projected.length, ...projected);
|
|
5908
|
+
return result;
|
|
5909
|
+
}
|
|
5910
|
+
if (this.horizontalProjection) {
|
|
5911
|
+
const projected = this.horizontalProjection.project(result.slice(0, 3));
|
|
5912
|
+
result.splice(0, projected.length, ...projected);
|
|
5913
|
+
}
|
|
5914
|
+
return result;
|
|
5915
|
+
}
|
|
5916
|
+
/** Transform a packed sequence of xyz positions, preserving the input array type only when safe. */
|
|
5917
|
+
transformPositions(positions) {
|
|
5918
|
+
if (positions.length % 3 !== 0) {
|
|
5919
|
+
throw new Error("Packed spatial positions must contain a multiple of three components");
|
|
5920
|
+
}
|
|
5921
|
+
const transformedPositions = new Float64Array(positions.length);
|
|
5922
|
+
for (let index = 0; index < positions.length; index += 3) {
|
|
5923
|
+
const transformed = this.transformPosition([
|
|
5924
|
+
Number(positions[index]),
|
|
5925
|
+
Number(positions[index + 1]),
|
|
5926
|
+
Number(positions[index + 2])
|
|
5927
|
+
]);
|
|
5928
|
+
transformedPositions[index] = transformed[0];
|
|
5929
|
+
transformedPositions[index + 1] = transformed[1];
|
|
5930
|
+
transformedPositions[index + 2] = transformed[2];
|
|
5931
|
+
}
|
|
5932
|
+
return transformedPositions;
|
|
5933
|
+
}
|
|
5934
|
+
/** Transform packed xyz normals using a local finite-difference tangent approximation. */
|
|
5935
|
+
transformNormals(normals, positions) {
|
|
5936
|
+
if (normals.length !== positions.length || normals.length % 3 !== 0) {
|
|
5937
|
+
throw new Error("Spatial normals and positions must have matching xyz component counts");
|
|
5938
|
+
}
|
|
5939
|
+
const transformedNormals = new Float32Array(normals.length);
|
|
5940
|
+
const epsilon = 1e-5;
|
|
5941
|
+
for (let index = 0; index < normals.length; index += 3) {
|
|
5942
|
+
const position = [
|
|
5943
|
+
Number(positions[index]),
|
|
5944
|
+
Number(positions[index + 1]),
|
|
5945
|
+
Number(positions[index + 2])
|
|
5946
|
+
];
|
|
5947
|
+
const normal = [
|
|
5948
|
+
Number(normals[index]),
|
|
5949
|
+
Number(normals[index + 1]),
|
|
5950
|
+
Number(normals[index + 2])
|
|
5951
|
+
];
|
|
5952
|
+
const jacobian = getFiniteDifferenceJacobian(this, position, epsilon);
|
|
5953
|
+
const transformedNormal = inverseTransposeMultiply(jacobian, normal);
|
|
5954
|
+
const length = Math.hypot(...transformedNormal);
|
|
5955
|
+
if (length > 0 && Number.isFinite(length)) {
|
|
5956
|
+
transformedNormals[index] = transformedNormal[0] / length;
|
|
5957
|
+
transformedNormals[index + 1] = transformedNormal[1] / length;
|
|
5958
|
+
transformedNormals[index + 2] = transformedNormal[2] / length;
|
|
5959
|
+
} else {
|
|
5960
|
+
transformedNormals[index] = normal[0];
|
|
5961
|
+
transformedNormals[index + 1] = normal[1];
|
|
5962
|
+
transformedNormals[index + 2] = normal[2];
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
return transformedNormals;
|
|
5966
|
+
}
|
|
5967
|
+
/** Convert one source coordinate to conventional WGS84 longitude, latitude, and height. */
|
|
5968
|
+
toGeographic(coordinate) {
|
|
5969
|
+
if (this.sourceIsGeocentric) {
|
|
5970
|
+
return Array.from(import_geospatial7.Ellipsoid.WGS84.cartesianToCartographic(new import_core10.Vector3(coordinate)));
|
|
5971
|
+
}
|
|
5972
|
+
if (this.sourceIsGeographic) {
|
|
5973
|
+
return coordinate.slice(0, 3);
|
|
5974
|
+
}
|
|
5975
|
+
return this.geographicProjection.project(coordinate.slice(0, 3));
|
|
5976
|
+
}
|
|
5977
|
+
/** Convert one conventional WGS84 geographic coordinate to the selected output CRS. */
|
|
5978
|
+
fromGeographic(coordinate) {
|
|
5979
|
+
if (this.outputIsGeocentric) {
|
|
5980
|
+
return Array.from(import_geospatial7.Ellipsoid.WGS84.cartographicToCartesian(new import_core10.Vector3(coordinate)));
|
|
5981
|
+
}
|
|
5982
|
+
if (this.outputIsGeographic) {
|
|
5983
|
+
return coordinate.slice(0, 3);
|
|
5984
|
+
}
|
|
5985
|
+
return this.heightOutputProjection.project(coordinate.slice(0, 3));
|
|
5986
|
+
}
|
|
5987
|
+
};
|
|
5988
|
+
function getFiniteDifferenceJacobian(transformer, position, epsilon) {
|
|
5989
|
+
const columns = [];
|
|
5990
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
5991
|
+
const plus = position.slice();
|
|
5992
|
+
const minus = position.slice();
|
|
5993
|
+
plus[axis] += epsilon;
|
|
5994
|
+
minus[axis] -= epsilon;
|
|
5995
|
+
const plusPosition = transformer.transformPosition(plus);
|
|
5996
|
+
const minusPosition = transformer.transformPosition(minus);
|
|
5997
|
+
columns.push([
|
|
5998
|
+
(plusPosition[0] - minusPosition[0]) / (2 * epsilon),
|
|
5999
|
+
(plusPosition[1] - minusPosition[1]) / (2 * epsilon),
|
|
6000
|
+
(plusPosition[2] - minusPosition[2]) / (2 * epsilon)
|
|
6001
|
+
]);
|
|
6002
|
+
}
|
|
6003
|
+
return columns;
|
|
6004
|
+
}
|
|
6005
|
+
function inverseTransposeMultiply(jacobianColumns, vector) {
|
|
6006
|
+
const [a, b, c] = jacobianColumns;
|
|
6007
|
+
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]);
|
|
6008
|
+
if (!Number.isFinite(determinant) || Math.abs(determinant) < 1e-15) {
|
|
6009
|
+
return vector;
|
|
6010
|
+
}
|
|
6011
|
+
const inverseTranspose = [
|
|
6012
|
+
[b[1] * c[2] - b[2] * c[1], a[2] * c[1] - a[1] * c[2], a[1] * b[2] - a[2] * b[1]],
|
|
6013
|
+
[b[2] * c[0] - b[0] * c[2], a[0] * c[2] - a[2] * c[0], a[2] * b[0] - a[0] * b[2]],
|
|
6014
|
+
[b[0] * c[1] - b[1] * c[0], a[1] * c[0] - a[0] * c[1], a[0] * b[1] - a[1] * b[0]]
|
|
6015
|
+
];
|
|
6016
|
+
return inverseTranspose.map((row) => (row[0] * vector[0] + row[1] * vector[1] + row[2] * vector[2]) / determinant);
|
|
6017
|
+
}
|
|
6018
|
+
function getHorizontalProj4Definition(definition) {
|
|
6019
|
+
if (!definition) {
|
|
6020
|
+
throw new Error("Cannot construct a projection because the CRS is unknown");
|
|
6021
|
+
}
|
|
6022
|
+
if (typeof definition !== "string" && definition.type === "CompoundCRS") {
|
|
6023
|
+
const horizontalComponents = definition.components.filter((component) => component.type !== "VerticalCRS");
|
|
6024
|
+
if (horizontalComponents.length !== 1) {
|
|
6025
|
+
throw new Error("CompoundCRS requires exactly one horizontal component");
|
|
6026
|
+
}
|
|
6027
|
+
return getHorizontalProj4Definition(horizontalComponents[0]);
|
|
6028
|
+
}
|
|
6029
|
+
return definition;
|
|
6030
|
+
}
|
|
6031
|
+
function validateTransformRequest(spatialReference) {
|
|
6032
|
+
if (spatialReference.outputCoordinates === "local-enu") {
|
|
6033
|
+
throw new Error("local-enu output requires a dataset-derived local origin and must be created by a tileset source");
|
|
6034
|
+
}
|
|
6035
|
+
if (spatialReference.outputCoordinates === "target-crs" && !spatialReference.targetCrs) {
|
|
6036
|
+
throw new Error("target-crs output requires targetCrs");
|
|
6037
|
+
}
|
|
6038
|
+
if (!spatialReference.sourceCrs && spatialReference.status === "unresolved") {
|
|
6039
|
+
throw new Error("Cannot transform coordinates because the source CRS is unknown");
|
|
6040
|
+
}
|
|
6041
|
+
if (requiresHeightTransformation(spatialReference) && spatialReference.heightReference === "unknown") {
|
|
6042
|
+
throw new Error("Cannot convert heights because the source height reference is unknown");
|
|
6043
|
+
}
|
|
6044
|
+
if (spatialReference.coordinateFrame === "geocentric" && !isWgs84Geocentric(spatialReference.sourceCrs)) {
|
|
6045
|
+
throw new Error("Only EPSG:4978 geocentric coordinates are supported by the current spatial transformer");
|
|
6046
|
+
}
|
|
6047
|
+
if (spatialReference.status === "unresolved") {
|
|
6048
|
+
throw new Error("The requested spatial output cannot be resolved from the available metadata");
|
|
6049
|
+
}
|
|
6050
|
+
}
|
|
6051
|
+
function isWgs84Geocentric(definition) {
|
|
6052
|
+
return typeof definition === "string" && normalizeCrsIdentifier(definition) === WGS84_GEOCENTRIC_CRS;
|
|
6053
|
+
}
|
|
6054
|
+
function isWgs84Geographic(definition) {
|
|
6055
|
+
if (typeof definition !== "string") {
|
|
6056
|
+
return false;
|
|
6057
|
+
}
|
|
6058
|
+
const identifier = normalizeCrsIdentifier(definition);
|
|
6059
|
+
return identifier === WGS84_GEOGRAPHIC_CRS || identifier === "EPSG:4979" || identifier === "OGC:CRS84";
|
|
6060
|
+
}
|
|
6061
|
+
function requiresHeightTransformation(spatialReference) {
|
|
6062
|
+
const target = spatialReference.targetHeightReference;
|
|
6063
|
+
return target !== "native" && target !== spatialReference.heightReference;
|
|
6064
|
+
}
|
|
6065
|
+
function resolveGeoid(model) {
|
|
6066
|
+
return typeof model === "string" ? getGeoidModel(model) : model;
|
|
6067
|
+
}
|
|
6068
|
+
function transformHeight(height, geoidUndulation, source, target) {
|
|
6069
|
+
if (source === target || target === "native") {
|
|
6070
|
+
return height;
|
|
6071
|
+
}
|
|
6072
|
+
if (source === "orthometric" && target === "ellipsoidal") {
|
|
6073
|
+
return height + geoidUndulation;
|
|
6074
|
+
}
|
|
6075
|
+
if (source === "ellipsoidal" && target === "orthometric") {
|
|
6076
|
+
return height - geoidUndulation;
|
|
6077
|
+
}
|
|
6078
|
+
throw new Error(`Unsupported height conversion from ${source} to ${target}`);
|
|
6079
|
+
}
|
|
6080
|
+
|
|
6081
|
+
// dist/spatial/tiles-3d-spatial-transformer.js
|
|
6082
|
+
var import_core11 = require("@math.gl/core");
|
|
6083
|
+
var import_geospatial8 = require("@math.gl/geospatial");
|
|
6084
|
+
var Tiles3DSpatialTransformer = class {
|
|
6085
|
+
/** Normalized reference describing the completed operation. */
|
|
6086
|
+
spatialReference;
|
|
6087
|
+
coordinateTransformer;
|
|
6088
|
+
geographicCoordinateTransformer;
|
|
6089
|
+
/** Creates a 3D Tiles transformer for a requested target CRS. */
|
|
6090
|
+
constructor(spatialReference, options = {}) {
|
|
6091
|
+
this.coordinateTransformer = new SpatialCoordinateTransformer(spatialReference, options);
|
|
6092
|
+
const geographicSpatialReference = {
|
|
6093
|
+
...spatialReference,
|
|
6094
|
+
sourceCrs: "EPSG:4326",
|
|
6095
|
+
targetCrs: spatialReference.targetCrs || spatialReference.sourceCrs,
|
|
6096
|
+
coordinateFrame: "geographic",
|
|
6097
|
+
axisOrder: "xy"
|
|
6098
|
+
};
|
|
6099
|
+
this.geographicCoordinateTransformer = new SpatialCoordinateTransformer(geographicSpatialReference, options);
|
|
6100
|
+
this.spatialReference = spatialReference;
|
|
6101
|
+
}
|
|
6102
|
+
/** Transform packed POSITION values into the target CRS. */
|
|
6103
|
+
transformPositions(positions) {
|
|
6104
|
+
return this.coordinateTransformer.transformPositions(positions);
|
|
6105
|
+
}
|
|
6106
|
+
/** Transform packed NORMAL values using the corresponding source positions. */
|
|
6107
|
+
transformNormals(normals, positions) {
|
|
6108
|
+
return this.coordinateTransformer.transformNormals(normals, positions);
|
|
6109
|
+
}
|
|
6110
|
+
/** Rebuild a conservative target-frame volume from a source volume. */
|
|
6111
|
+
transformBoundingVolume(volume, sourceTransform) {
|
|
6112
|
+
const transform = sourceTransform ? new import_core11.Matrix4(Array.from(sourceTransform)) : void 0;
|
|
6113
|
+
const samples = volume.region ? getRegionSamples(volume.region) : getVolumeSamples(volume).map((sample) => transform ? Array.from(transform.transformAsPoint(sample)) : sample);
|
|
6114
|
+
if (!samples.length) {
|
|
6115
|
+
return volume;
|
|
6116
|
+
}
|
|
6117
|
+
const transformed = volume.region ? samples.map((sample) => this.transformRegionSample(sample)) : samples.map((sample) => this.coordinateTransformer.transformPosition(sample));
|
|
6118
|
+
return { box: createAxisAlignedBox(transformed) };
|
|
6119
|
+
}
|
|
6120
|
+
/** Transforms one WGS84 region sample into the selected output frame. */
|
|
6121
|
+
transformRegionSample(sample) {
|
|
6122
|
+
const [longitudeDegrees, latitudeDegrees, height] = sample;
|
|
6123
|
+
const targetCrs = this.spatialReference.targetCrs || this.spatialReference.sourceCrs;
|
|
6124
|
+
if (targetCrs && getSpatialCoordinateFrame(targetCrs) === "geocentric") {
|
|
6125
|
+
const cartesian = import_geospatial8.Ellipsoid.WGS84.cartographicToCartesian([
|
|
6126
|
+
longitudeDegrees,
|
|
6127
|
+
latitudeDegrees,
|
|
6128
|
+
height
|
|
6129
|
+
]);
|
|
6130
|
+
return Array.from(cartesian);
|
|
6131
|
+
}
|
|
6132
|
+
return this.geographicCoordinateTransformer.transformPosition(sample);
|
|
6133
|
+
}
|
|
6134
|
+
};
|
|
6135
|
+
function getRegionSamples(region) {
|
|
6136
|
+
if (region.length < 6 || region.some((value) => !Number.isFinite(value))) {
|
|
6137
|
+
return [];
|
|
6138
|
+
}
|
|
6139
|
+
const [west, south, east, north, minimumHeight, maximumHeight] = region;
|
|
6140
|
+
const longitudeEnd = east < west ? east + Math.PI * 2 : east;
|
|
6141
|
+
const longitudes = getIntervalSamples(west, longitudeEnd);
|
|
6142
|
+
const latitudes = getIntervalSamples(south, north);
|
|
6143
|
+
const samples = [];
|
|
6144
|
+
for (const longitude of longitudes) {
|
|
6145
|
+
for (const latitude of latitudes) {
|
|
6146
|
+
for (const height of [minimumHeight, maximumHeight]) {
|
|
6147
|
+
samples.push([longitude * 180 / Math.PI, latitude * 180 / Math.PI, height]);
|
|
6148
|
+
}
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
return samples;
|
|
6152
|
+
}
|
|
6153
|
+
function getIntervalSamples(start, end) {
|
|
6154
|
+
const samples = [start, (start + end) / 2, end];
|
|
6155
|
+
const angularStep = Math.PI / 2;
|
|
6156
|
+
const firstCriticalIndex = Math.ceil(start / angularStep);
|
|
6157
|
+
const lastCriticalIndex = Math.floor(end / angularStep);
|
|
6158
|
+
for (let criticalIndex = firstCriticalIndex; criticalIndex <= lastCriticalIndex; criticalIndex++) {
|
|
6159
|
+
samples.push(criticalIndex * angularStep);
|
|
6160
|
+
}
|
|
6161
|
+
return samples;
|
|
6162
|
+
}
|
|
6163
|
+
function getVolumeSamples(volume) {
|
|
6164
|
+
if (volume.box && volume.box.length >= 12) {
|
|
6165
|
+
const center = volume.box.slice(0, 3);
|
|
6166
|
+
const axes = [volume.box.slice(3, 6), volume.box.slice(6, 9), volume.box.slice(9, 12)];
|
|
6167
|
+
const samples = [];
|
|
6168
|
+
for (let firstIndex = 0; firstIndex <= 4; firstIndex++) {
|
|
6169
|
+
for (let secondIndex = 0; secondIndex <= 4; secondIndex++) {
|
|
6170
|
+
for (let thirdIndex = 0; thirdIndex <= 4; thirdIndex++) {
|
|
6171
|
+
const first = firstIndex / 2 - 1;
|
|
6172
|
+
const second = secondIndex / 2 - 1;
|
|
6173
|
+
const third = thirdIndex / 2 - 1;
|
|
6174
|
+
samples.push([
|
|
6175
|
+
center[0] + first * axes[0][0] + second * axes[1][0] + third * axes[2][0],
|
|
6176
|
+
center[1] + first * axes[0][1] + second * axes[1][1] + third * axes[2][1],
|
|
6177
|
+
center[2] + first * axes[0][2] + second * axes[1][2] + third * axes[2][2]
|
|
6178
|
+
]);
|
|
6179
|
+
}
|
|
6180
|
+
}
|
|
6181
|
+
}
|
|
6182
|
+
return samples;
|
|
6183
|
+
}
|
|
6184
|
+
if (volume.sphere && volume.sphere.length >= 4) {
|
|
6185
|
+
const [x, y, z, radius] = volume.sphere;
|
|
6186
|
+
const samples = [
|
|
6187
|
+
[x - radius, y, z],
|
|
6188
|
+
[x + radius, y, z],
|
|
6189
|
+
[x, y - radius, z],
|
|
6190
|
+
[x, y + radius, z],
|
|
6191
|
+
[x, y, z - radius],
|
|
6192
|
+
[x, y, z + radius]
|
|
6193
|
+
];
|
|
6194
|
+
for (let longitudeIndex = 0; longitudeIndex < 16; longitudeIndex++) {
|
|
6195
|
+
const longitude = longitudeIndex * Math.PI * 2 / 16;
|
|
6196
|
+
samples.push([x + radius * Math.cos(longitude), y + radius * Math.sin(longitude), z]);
|
|
6197
|
+
}
|
|
6198
|
+
return samples;
|
|
6199
|
+
}
|
|
6200
|
+
return [];
|
|
6201
|
+
}
|
|
6202
|
+
function createAxisAlignedBox(samples) {
|
|
6203
|
+
const minimum = [Infinity, Infinity, Infinity];
|
|
6204
|
+
const maximum = [-Infinity, -Infinity, -Infinity];
|
|
6205
|
+
for (const sample of samples) {
|
|
6206
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
6207
|
+
minimum[axis] = Math.min(minimum[axis], sample[axis]);
|
|
6208
|
+
maximum[axis] = Math.max(maximum[axis], sample[axis]);
|
|
6209
|
+
}
|
|
6210
|
+
}
|
|
6211
|
+
const padding = [
|
|
6212
|
+
Math.max((maximum[0] - minimum[0]) * 0.01, 1e-9),
|
|
6213
|
+
Math.max((maximum[1] - minimum[1]) * 0.01, 1e-9),
|
|
6214
|
+
Math.max((maximum[2] - minimum[2]) * 0.01, 1e-9)
|
|
6215
|
+
];
|
|
6216
|
+
const center = [
|
|
6217
|
+
(minimum[0] + maximum[0]) / 2,
|
|
6218
|
+
(minimum[1] + maximum[1]) / 2,
|
|
6219
|
+
(minimum[2] + maximum[2]) / 2
|
|
6220
|
+
];
|
|
6221
|
+
return [
|
|
6222
|
+
...center,
|
|
6223
|
+
(maximum[0] - minimum[0]) / 2 + padding[0],
|
|
6224
|
+
0,
|
|
6225
|
+
0,
|
|
6226
|
+
0,
|
|
6227
|
+
(maximum[1] - minimum[1]) / 2 + padding[1],
|
|
6228
|
+
0,
|
|
6229
|
+
0,
|
|
6230
|
+
0,
|
|
6231
|
+
(maximum[2] - minimum[2]) / 2 + padding[2]
|
|
6232
|
+
];
|
|
6233
|
+
}
|
|
6234
|
+
|
|
6235
|
+
// dist/tileset-3d/format-3d-tiles/implicit-tiling.js
|
|
6236
|
+
var import_s22 = require("@math.gl/dggs/s2");
|
|
6237
|
+
|
|
6238
|
+
// dist/tileset-3d/helpers/s2-bounding-volume.js
|
|
6239
|
+
var import_s2 = require("@math.gl/dggs/s2");
|
|
6240
|
+
var import_geospatial9 = require("@math.gl/geospatial");
|
|
6241
|
+
function convertS2BoundingVolumeToOBB(s2VolumeInfo) {
|
|
6242
|
+
const [[west, south], [east, north]] = (0, import_s2.getS2Bounds)(s2VolumeInfo.token);
|
|
6243
|
+
const orientedBoundingBox = (0, import_geospatial9.makeOBBFromRegion)([west, south, east, north, s2VolumeInfo.minimumHeight, s2VolumeInfo.maximumHeight], import_geospatial9.Ellipsoid.WGS84, { units: "degrees" });
|
|
6244
|
+
return [...orientedBoundingBox.center, ...orientedBoundingBox.halfAxes];
|
|
6245
|
+
}
|
|
6246
|
+
|
|
6247
|
+
// dist/tileset-3d/format-3d-tiles/implicit-tiling.js
|
|
6248
|
+
var QUADTREE_CHILD_COUNT = 4;
|
|
6249
|
+
var OCTREE_CHILD_COUNT = 8;
|
|
6250
|
+
var AVAILABILITY_RANK_CACHE = /* @__PURE__ */ new WeakMap();
|
|
6251
|
+
function createImplicitSubtreeReference(descriptor, coordinates) {
|
|
6252
|
+
return {
|
|
6253
|
+
coordinates,
|
|
6254
|
+
subtreeUrl: replaceImplicitUrlTemplate(descriptor.subtreesUrlTemplate, coordinates),
|
|
6255
|
+
descriptor,
|
|
6256
|
+
resource: findImplicitPackageResource(descriptor.resourceFiles, replaceImplicitUrlTemplate(descriptor.subtreesUrlTemplate, coordinates))
|
|
6257
|
+
};
|
|
6258
|
+
}
|
|
6259
|
+
function materializeImplicitSubtree(subtree, reference) {
|
|
6260
|
+
const { descriptor } = reference;
|
|
6261
|
+
validateImplicitDescriptor(descriptor);
|
|
6262
|
+
validateImplicitSubtree(subtree, descriptor);
|
|
6263
|
+
const counters = { tileCount: 0, childSubtreeCount: 0 };
|
|
6264
|
+
const root = materializeAvailableTile(subtree, reference, { localLevel: 0, mortonIndex: 0 }, reference.coordinates, counters);
|
|
6265
|
+
if (!root) {
|
|
6266
|
+
throw new Error(`Invalid 3D Tiles subtree: root tile is unavailable at ${reference.subtreeUrl}`);
|
|
6267
|
+
}
|
|
6268
|
+
return { root, ...counters };
|
|
6269
|
+
}
|
|
6270
|
+
function validateImplicitSubtree(subtree, descriptor) {
|
|
6271
|
+
const childCount = getImplicitChildCount(descriptor.subdivisionScheme);
|
|
6272
|
+
const tileElementCount = (childCount ** descriptor.subtreeLevels - 1) / (childCount - 1);
|
|
6273
|
+
const childSubtreeElementCount = childCount ** descriptor.subtreeLevels;
|
|
6274
|
+
validateAvailabilityLength(subtree.tileAvailability, tileElementCount, "tile");
|
|
6275
|
+
const contentAvailabilityStreams = Array.isArray(subtree.contentAvailability) ? subtree.contentAvailability : subtree.contentAvailability ? [subtree.contentAvailability] : [];
|
|
6276
|
+
for (const contentAvailability of contentAvailabilityStreams) {
|
|
6277
|
+
validateAvailabilityLength(contentAvailability, tileElementCount, "content");
|
|
6278
|
+
}
|
|
6279
|
+
validateAvailabilityLength(subtree.childSubtreeAvailability, childSubtreeElementCount, "child subtree");
|
|
6280
|
+
const availableTileCount = countAvailableElements(subtree.tileAvailability, tileElementCount);
|
|
6281
|
+
const availableContentCount = contentAvailabilityStreams[0] ? countAvailableElements(contentAvailabilityStreams[0], tileElementCount) : 0;
|
|
6282
|
+
validateAttributeLengths(subtree.tileAttributes, availableTileCount, "tile");
|
|
6283
|
+
validateAttributeLengths(subtree.contentAttributes, availableContentCount, "content");
|
|
6284
|
+
if (subtree.tilePropertyRows && subtree.tilePropertyRows.length !== availableTileCount) {
|
|
6285
|
+
throw new Error("3DTILES_subtree: tile property-table count does not match availability");
|
|
6286
|
+
}
|
|
6287
|
+
if (subtree.contentPropertyRows && subtree.contentPropertyRows.length !== availableContentCount) {
|
|
6288
|
+
throw new Error("3DTILES_subtree: content property-table count does not match availability");
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
function validateAvailabilityLength(availability, elementCount, label) {
|
|
6292
|
+
if (availability.constant === 0 || availability.constant === 1) {
|
|
6293
|
+
return;
|
|
6294
|
+
}
|
|
6295
|
+
if (!availability.explicitBitstream || availability.explicitBitstream.byteLength * 8 < elementCount) {
|
|
6296
|
+
throw new Error(`3DTILES_subtree: ${label} availability bitstream is too short`);
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
function countAvailableElements(availability, elementCount) {
|
|
6300
|
+
if (availability.constant === 1) {
|
|
6301
|
+
return elementCount;
|
|
6302
|
+
}
|
|
6303
|
+
if (availability.constant === 0) {
|
|
6304
|
+
return 0;
|
|
6305
|
+
}
|
|
6306
|
+
let availableCount = 0;
|
|
6307
|
+
for (let index = 0; index < elementCount; index++) {
|
|
6308
|
+
if (getAvailabilityValue(availability, index)) {
|
|
6309
|
+
availableCount++;
|
|
6310
|
+
}
|
|
6311
|
+
}
|
|
6312
|
+
return availableCount;
|
|
6313
|
+
}
|
|
6314
|
+
function validateAttributeLengths(attributes, availableCount, label) {
|
|
6315
|
+
const componentCounts = {
|
|
6316
|
+
TILE_BOUNDING_BOX: 16,
|
|
6317
|
+
TILE_BOUNDING_SPHERE: 4,
|
|
6318
|
+
TILE_GEOMETRIC_ERROR: 1,
|
|
6319
|
+
TILE_REFINE: 1,
|
|
6320
|
+
TILE_TRANSFORM: 16,
|
|
6321
|
+
CONTENT_BOUNDING_BOX: 16,
|
|
6322
|
+
CONTENT_BOUNDING_SPHERE: 4
|
|
6323
|
+
};
|
|
6324
|
+
for (const [semantic, values] of Object.entries(attributes || {})) {
|
|
6325
|
+
const componentCount = componentCounts[semantic];
|
|
6326
|
+
if (componentCount && values.length !== availableCount * componentCount) {
|
|
6327
|
+
throw new Error(`3DTILES_subtree: ${label} attribute ${semantic} count does not match availability`);
|
|
6328
|
+
}
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
function replaceImplicitUrlTemplate(templateUrl, coordinates, properties = {}) {
|
|
6332
|
+
const values = {
|
|
6333
|
+
level: coordinates.level,
|
|
6334
|
+
x: coordinates.x,
|
|
6335
|
+
y: coordinates.y,
|
|
6336
|
+
z: coordinates.z,
|
|
6337
|
+
...properties
|
|
6338
|
+
};
|
|
6339
|
+
return templateUrl.replace(/{([^{}]+)}/g, (match, propertyName) => {
|
|
6340
|
+
const value = Object.hasOwn(values, propertyName) ? values[propertyName] : values[propertyName.toLowerCase()];
|
|
6341
|
+
return value === void 0 ? match : String(value);
|
|
6342
|
+
});
|
|
6343
|
+
}
|
|
6344
|
+
function materializeAvailableTile(subtree, reference, localCoordinates, globalCoordinates, counters) {
|
|
6345
|
+
const { descriptor } = reference;
|
|
6346
|
+
const childCount = getImplicitChildCount(descriptor.subdivisionScheme);
|
|
6347
|
+
const availabilityIndex = getLevelOffset(childCount, localCoordinates.localLevel) + localCoordinates.mortonIndex;
|
|
5390
6348
|
if (!getAvailabilityValue(subtree.tileAvailability, availabilityIndex)) {
|
|
5391
6349
|
return null;
|
|
5392
6350
|
}
|
|
@@ -5416,10 +6374,12 @@ function materializeAvailableTile(subtree, reference, localCoordinates, globalCo
|
|
|
5416
6374
|
}
|
|
5417
6375
|
}
|
|
5418
6376
|
}
|
|
5419
|
-
return formatImplicitTileHeader(subtree, descriptor, reference, globalCoordinates, contentAvailability, children);
|
|
6377
|
+
return formatImplicitTileHeader(subtree, descriptor, reference, globalCoordinates, availabilityIndex, contentAvailability, children);
|
|
5420
6378
|
}
|
|
5421
6379
|
function createLazyImplicitTileHeader(subtree, descriptor, coordinates) {
|
|
5422
|
-
const
|
|
6380
|
+
const resourceFiles = mergeImplicitPackageFiles(descriptor.resourceFiles, subtree.resourceFiles);
|
|
6381
|
+
const childDescriptor = resourceFiles ? { ...descriptor, resourceFiles } : descriptor;
|
|
6382
|
+
const reference = createImplicitSubtreeReference(childDescriptor, coordinates);
|
|
5423
6383
|
return {
|
|
5424
6384
|
id: getImplicitTileId(reference, coordinates),
|
|
5425
6385
|
children: [],
|
|
@@ -5430,55 +6390,187 @@ function createLazyImplicitTileHeader(subtree, descriptor, coordinates) {
|
|
|
5430
6390
|
lodMetricValue: descriptor.rootLodMetricValue / 2 ** coordinates.level,
|
|
5431
6391
|
refine: descriptor.refine,
|
|
5432
6392
|
type: TILE_TYPE.EMPTY,
|
|
5433
|
-
implicitMetadata: getImplicitSubtreeMetadata(subtree)
|
|
6393
|
+
implicitMetadata: getImplicitSubtreeMetadata(subtree),
|
|
6394
|
+
_scaleGeometricError: descriptor.scaleGeometricError !== false
|
|
6395
|
+
};
|
|
6396
|
+
}
|
|
6397
|
+
function getSubtreeAttributeOverrides(attributes, rowIndex, scope) {
|
|
6398
|
+
var _a, _b;
|
|
6399
|
+
if (!attributes || rowIndex < 0) {
|
|
6400
|
+
return {};
|
|
6401
|
+
}
|
|
6402
|
+
const box = getAttributeComponents(attributes[scope === "tile" ? "TILE_BOUNDING_BOX" : "CONTENT_BOUNDING_BOX"], rowIndex, 16);
|
|
6403
|
+
const sphere = getAttributeComponents(attributes[scope === "tile" ? "TILE_BOUNDING_SPHERE" : "CONTENT_BOUNDING_SPHERE"], rowIndex, 4);
|
|
6404
|
+
const boundingVolume = box ? {
|
|
6405
|
+
box: [
|
|
6406
|
+
box[12],
|
|
6407
|
+
box[13],
|
|
6408
|
+
box[14],
|
|
6409
|
+
box[0] / 2,
|
|
6410
|
+
box[1] / 2,
|
|
6411
|
+
box[2] / 2,
|
|
6412
|
+
box[4] / 2,
|
|
6413
|
+
box[5] / 2,
|
|
6414
|
+
box[6] / 2,
|
|
6415
|
+
box[8] / 2,
|
|
6416
|
+
box[9] / 2,
|
|
6417
|
+
box[10] / 2
|
|
6418
|
+
]
|
|
6419
|
+
} : sphere ? { sphere } : void 0;
|
|
6420
|
+
if (scope === "content") {
|
|
6421
|
+
return { boundingVolume };
|
|
6422
|
+
}
|
|
6423
|
+
const geometricError = (_a = getAttributeComponents(attributes.TILE_GEOMETRIC_ERROR, rowIndex, 1)) == null ? void 0 : _a[0];
|
|
6424
|
+
if (geometricError !== void 0 && (!Number.isFinite(geometricError) || geometricError < 0)) {
|
|
6425
|
+
throw new Error("3DTILES_subtree: TILE_GEOMETRIC_ERROR must be nonnegative");
|
|
6426
|
+
}
|
|
6427
|
+
const refineValue = (_b = getAttributeComponents(attributes.TILE_REFINE, rowIndex, 1)) == null ? void 0 : _b[0];
|
|
6428
|
+
if (refineValue !== void 0 && refineValue !== 0 && refineValue !== 1) {
|
|
6429
|
+
throw new Error("3DTILES_subtree: TILE_REFINE must be 0 or 1");
|
|
6430
|
+
}
|
|
6431
|
+
return {
|
|
6432
|
+
boundingVolume,
|
|
6433
|
+
geometricError,
|
|
6434
|
+
refine: refineValue === void 0 ? void 0 : refineValue === 0 ? TILE_REFINEMENT.ADD : TILE_REFINEMENT.REPLACE,
|
|
6435
|
+
transform: getAttributeComponents(attributes.TILE_TRANSFORM, rowIndex, 16)
|
|
5434
6436
|
};
|
|
5435
6437
|
}
|
|
5436
|
-
function
|
|
6438
|
+
function getAttributeComponents(values, rowIndex, componentCount) {
|
|
6439
|
+
if (!values) {
|
|
6440
|
+
return void 0;
|
|
6441
|
+
}
|
|
6442
|
+
const offset = rowIndex * componentCount;
|
|
6443
|
+
if (offset + componentCount > values.length) {
|
|
6444
|
+
throw new Error("3DTILES_subtree: attribute accessor is shorter than availability");
|
|
6445
|
+
}
|
|
6446
|
+
return Array.from({ length: componentCount }, (_unused, componentIndex) => Number(values[offset + componentIndex]));
|
|
6447
|
+
}
|
|
6448
|
+
function getAvailabilityRank(availability, index) {
|
|
5437
6449
|
var _a;
|
|
5438
|
-
|
|
6450
|
+
if (availability.constant === 1) {
|
|
6451
|
+
return index;
|
|
6452
|
+
}
|
|
6453
|
+
if (availability.constant === 0) {
|
|
6454
|
+
return 0;
|
|
6455
|
+
}
|
|
6456
|
+
let ranks = AVAILABILITY_RANK_CACHE.get(availability);
|
|
6457
|
+
if (!ranks) {
|
|
6458
|
+
const bitCount = (((_a = availability.explicitBitstream) == null ? void 0 : _a.byteLength) || 0) * 8;
|
|
6459
|
+
ranks = new Uint32Array(bitCount + 1);
|
|
6460
|
+
for (let candidateIndex = 0; candidateIndex < bitCount; candidateIndex++) {
|
|
6461
|
+
ranks[candidateIndex + 1] = ranks[candidateIndex] + Number(getAvailabilityValue(availability, candidateIndex));
|
|
6462
|
+
}
|
|
6463
|
+
AVAILABILITY_RANK_CACHE.set(availability, ranks);
|
|
6464
|
+
}
|
|
6465
|
+
return ranks[index];
|
|
6466
|
+
}
|
|
6467
|
+
function findImplicitPackageResource(files, resourceUrl) {
|
|
6468
|
+
var _a;
|
|
6469
|
+
if (!(files == null ? void 0 : files.length)) {
|
|
6470
|
+
return void 0;
|
|
6471
|
+
}
|
|
6472
|
+
const urlWithoutQuery = resourceUrl.split("?")[0];
|
|
6473
|
+
const packageRelativePath = (_a = /^gltf-package:\/\/[^/]+\/(.*)$/.exec(urlWithoutQuery)) == null ? void 0 : _a[1];
|
|
6474
|
+
const exactFileIndex = files.findIndex((file) => {
|
|
6475
|
+
const reference = file.originalUri || file.name;
|
|
6476
|
+
return file.uri === urlWithoutQuery || Boolean(reference && (urlWithoutQuery === reference || packageRelativePath === reference));
|
|
6477
|
+
});
|
|
6478
|
+
if (exactFileIndex >= 0) {
|
|
6479
|
+
return { fileIndex: exactFileIndex, files };
|
|
6480
|
+
}
|
|
6481
|
+
const fileIndex = files.findIndex((file) => {
|
|
6482
|
+
const reference = file.originalUri || file.name;
|
|
6483
|
+
return Boolean(reference && (urlWithoutQuery.endsWith(`/${reference}`) || urlWithoutQuery.endsWith(`:${reference}`)));
|
|
6484
|
+
});
|
|
6485
|
+
return fileIndex < 0 ? void 0 : { fileIndex, files };
|
|
6486
|
+
}
|
|
6487
|
+
function mergeImplicitPackageFiles(parentFiles, childFiles) {
|
|
6488
|
+
if (!(childFiles == null ? void 0 : childFiles.length)) {
|
|
6489
|
+
return parentFiles;
|
|
6490
|
+
}
|
|
6491
|
+
if (!(parentFiles == null ? void 0 : parentFiles.length)) {
|
|
6492
|
+
return childFiles;
|
|
6493
|
+
}
|
|
6494
|
+
const childReferences = new Set(childFiles.flatMap((file) => [file.uri, file.originalUri, file.name].filter(Boolean)));
|
|
6495
|
+
return [
|
|
6496
|
+
...childFiles,
|
|
6497
|
+
...parentFiles.filter((file) => ![file.uri, file.originalUri, file.name].some((reference) => reference && childReferences.has(reference)))
|
|
6498
|
+
];
|
|
6499
|
+
}
|
|
6500
|
+
function formatImplicitTileHeader(subtree, descriptor, reference, coordinates, availabilityIndex, contentAvailability, children) {
|
|
6501
|
+
var _a, _b, _c, _d, _e;
|
|
6502
|
+
const tilePropertyIndex = getAvailabilityRank(subtree.tileAvailability, availabilityIndex);
|
|
6503
|
+
const tileProperties = (_a = subtree.tilePropertyRows) == null ? void 0 : _a[tilePropertyIndex];
|
|
6504
|
+
const primaryContentAvailability = Array.isArray(subtree.contentAvailability) ? subtree.contentAvailability[0] : subtree.contentAvailability;
|
|
6505
|
+
const contentPropertyIndex = primaryContentAvailability && getAvailabilityValue(primaryContentAvailability, availabilityIndex) ? getAvailabilityRank(primaryContentAvailability, availabilityIndex) : -1;
|
|
6506
|
+
const contentProperties = (_b = subtree.contentPropertyRows) == null ? void 0 : _b[contentPropertyIndex];
|
|
6507
|
+
const tileTemplateProperties = ((_c = subtree.tileTemplatePropertyRows) == null ? void 0 : _c[tilePropertyIndex]) || tileProperties;
|
|
6508
|
+
const contentTemplateProperties = ((_d = subtree.contentTemplatePropertyRows) == null ? void 0 : _d[contentPropertyIndex]) || contentProperties;
|
|
6509
|
+
const templateProperties = { ...tileTemplateProperties, ...contentTemplateProperties };
|
|
6510
|
+
const tileAttributes = getSubtreeAttributeOverrides(subtree.tileAttributes, tilePropertyIndex, "tile");
|
|
6511
|
+
const contentAttributes = getSubtreeAttributeOverrides(subtree.contentAttributes, contentPropertyIndex, "content");
|
|
6512
|
+
const contentUrlTemplates = ((_e = descriptor.contentUrlTemplates) == null ? void 0 : _e.length) ? descriptor.contentUrlTemplates : [descriptor.contentUrlTemplate];
|
|
5439
6513
|
const contentEntries = contentUrlTemplates.map((templateUrl, contentIndex) => {
|
|
5440
6514
|
if (!contentAvailability[contentIndex] || !templateUrl) {
|
|
5441
6515
|
return null;
|
|
5442
6516
|
}
|
|
6517
|
+
const contentUrl2 = replaceImplicitUrlTemplate(templateUrl, coordinates, templateProperties);
|
|
6518
|
+
if (/{[^{}]+}/.test(contentUrl2)) {
|
|
6519
|
+
throw new Error(`Implicit content URI has unresolved template values: ${contentUrl2}`);
|
|
6520
|
+
}
|
|
5443
6521
|
return {
|
|
5444
6522
|
contentIndex,
|
|
5445
|
-
contentUrl:
|
|
6523
|
+
contentUrl: contentUrl2
|
|
5446
6524
|
};
|
|
5447
6525
|
}).filter((entry) => Boolean(entry));
|
|
5448
6526
|
const availableContentUrls = contentEntries.map((entry) => entry.contentUrl);
|
|
6527
|
+
const resourceFiles = mergeImplicitPackageFiles(descriptor.resourceFiles, subtree.resourceFiles);
|
|
5449
6528
|
const content = contentEntries.map(({ contentIndex, contentUrl: contentUrl2 }) => {
|
|
5450
6529
|
var _a2;
|
|
6530
|
+
const packageResource = findImplicitPackageResource(resourceFiles, contentUrl2);
|
|
5451
6531
|
return {
|
|
5452
6532
|
...((_a2 = descriptor.contentHeaders) == null ? void 0 : _a2[contentIndex]) || (contentIndex === 0 ? descriptor.contentHeader : {}) || {},
|
|
5453
|
-
|
|
6533
|
+
...contentAttributes,
|
|
6534
|
+
uri: contentUrl2,
|
|
6535
|
+
...contentProperties ? { metadata: { properties: contentProperties } } : {},
|
|
6536
|
+
...packageResource ? { _resource: packageResource } : {}
|
|
5454
6537
|
};
|
|
5455
6538
|
});
|
|
5456
6539
|
const contentUrl = availableContentUrls[0];
|
|
5457
|
-
const
|
|
6540
|
+
const computedLodMetricValue = descriptor.rootLodMetricValue / 2 ** coordinates.level;
|
|
6541
|
+
const lodMetricValue = tileAttributes.geometricError ?? computedLodMetricValue;
|
|
6542
|
+
const computedBoundingVolume = calculateImplicitBoundingVolume(descriptor.rootBoundingVolume, coordinates, descriptor.subdivisionScheme);
|
|
5458
6543
|
return {
|
|
5459
6544
|
id: getImplicitTileId(reference, coordinates),
|
|
5460
6545
|
children,
|
|
5461
6546
|
contentUrl,
|
|
5462
6547
|
content: content.length > 1 ? content : content[0],
|
|
6548
|
+
contents: descriptor.useCanonicalContents && content.length ? content : void 0,
|
|
5463
6549
|
contentUrls: availableContentUrls,
|
|
5464
|
-
refine: descriptor.refine,
|
|
6550
|
+
refine: tileAttributes.refine || descriptor.refine,
|
|
5465
6551
|
type: getImplicitTileType(contentUrl),
|
|
5466
6552
|
lodMetricType: descriptor.lodMetricType,
|
|
5467
6553
|
lodMetricValue,
|
|
5468
6554
|
geometricError: lodMetricValue,
|
|
5469
|
-
boundingVolume:
|
|
5470
|
-
|
|
6555
|
+
boundingVolume: tileAttributes.boundingVolume || computedBoundingVolume,
|
|
6556
|
+
transform: tileAttributes.transform,
|
|
6557
|
+
transformMatrix: tileAttributes.transform,
|
|
6558
|
+
metadata: tileProperties ? { properties: tileProperties } : void 0,
|
|
6559
|
+
implicitMetadata: getImplicitSubtreeMetadata(subtree, tileProperties, contentProperties),
|
|
6560
|
+
_scaleGeometricError: descriptor.scaleGeometricError !== false
|
|
5471
6561
|
};
|
|
5472
6562
|
}
|
|
5473
|
-
function getImplicitSubtreeMetadata(subtree) {
|
|
5474
|
-
if (!subtree.propertyTables && subtree.tileMetadata === void 0 && !subtree.contentMetadata && subtree.subtreeMetadata === void 0) {
|
|
6563
|
+
function getImplicitSubtreeMetadata(subtree, tileProperties, contentProperties) {
|
|
6564
|
+
if (!subtree.propertyTables && subtree.tileMetadata === void 0 && !subtree.contentMetadata && subtree.subtreeMetadata === void 0 && !tileProperties && !contentProperties) {
|
|
5475
6565
|
return void 0;
|
|
5476
6566
|
}
|
|
5477
6567
|
return {
|
|
5478
6568
|
propertyTables: subtree.propertyTables,
|
|
5479
6569
|
tileMetadata: subtree.tileMetadata,
|
|
5480
6570
|
contentMetadata: subtree.contentMetadata,
|
|
5481
|
-
subtreeMetadata: subtree.subtreeMetadata
|
|
6571
|
+
subtreeMetadata: subtree.subtreeMetadata,
|
|
6572
|
+
tileProperties,
|
|
6573
|
+
contentProperties
|
|
5482
6574
|
};
|
|
5483
6575
|
}
|
|
5484
6576
|
function getImplicitTileId(reference, coordinates) {
|
|
@@ -5515,12 +6607,15 @@ function getImplicitChildCount(subdivisionScheme) {
|
|
|
5515
6607
|
return subdivisionScheme === "OCTREE" ? OCTREE_CHILD_COUNT : QUADTREE_CHILD_COUNT;
|
|
5516
6608
|
}
|
|
5517
6609
|
function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdivisionScheme) {
|
|
6610
|
+
var _a;
|
|
5518
6611
|
if (rootBoundingVolume.region) {
|
|
5519
6612
|
const [west, south, east, north, minimumHeight, maximumHeight] = rootBoundingVolume.region;
|
|
5520
6613
|
const divisionCount = 2 ** coordinates.level;
|
|
5521
|
-
const
|
|
6614
|
+
const longitudeSpan = east >= west ? east - west : east + 2 * Math.PI - west;
|
|
6615
|
+
const longitudeSize = longitudeSpan / divisionCount;
|
|
5522
6616
|
const latitudeSize = (north - south) / divisionCount;
|
|
5523
|
-
const childWest = west + longitudeSize * coordinates.x;
|
|
6617
|
+
const childWest = normalizeRegionLongitude(west + longitudeSize * coordinates.x);
|
|
6618
|
+
const childEast = normalizeRegionLongitude(west + longitudeSize * (coordinates.x + 1));
|
|
5524
6619
|
const childSouth = south + latitudeSize * coordinates.y;
|
|
5525
6620
|
let childMinimumHeight = minimumHeight;
|
|
5526
6621
|
let childMaximumHeight = maximumHeight;
|
|
@@ -5533,7 +6628,7 @@ function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdiv
|
|
|
5533
6628
|
region: [
|
|
5534
6629
|
childWest,
|
|
5535
6630
|
childSouth,
|
|
5536
|
-
|
|
6631
|
+
childEast,
|
|
5537
6632
|
childSouth + latitudeSize,
|
|
5538
6633
|
childMinimumHeight,
|
|
5539
6634
|
childMaximumHeight
|
|
@@ -5542,7 +6637,13 @@ function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdiv
|
|
|
5542
6637
|
}
|
|
5543
6638
|
if (rootBoundingVolume.box) {
|
|
5544
6639
|
if (rootBoundingVolume.s2VolumeInfo) {
|
|
5545
|
-
return
|
|
6640
|
+
return calculateS2ImplicitBoundingVolume(rootBoundingVolume, coordinates, subdivisionScheme);
|
|
6641
|
+
}
|
|
6642
|
+
if ((_a = rootBoundingVolume.extensions) == null ? void 0 : _a["3DTILES_shape_cylinder_region"]) {
|
|
6643
|
+
return {
|
|
6644
|
+
...rootBoundingVolume,
|
|
6645
|
+
box: [...rootBoundingVolume.box]
|
|
6646
|
+
};
|
|
5546
6647
|
}
|
|
5547
6648
|
const box = rootBoundingVolume.box;
|
|
5548
6649
|
const divisionCount = 2 ** coordinates.level;
|
|
@@ -5572,6 +6673,41 @@ function calculateImplicitBoundingVolume(rootBoundingVolume, coordinates, subdiv
|
|
|
5572
6673
|
}
|
|
5573
6674
|
throw new Error(`Unsupported implicit 3D Tiles bounding volume: ${JSON.stringify(rootBoundingVolume)}`);
|
|
5574
6675
|
}
|
|
6676
|
+
function calculateS2ImplicitBoundingVolume(rootBoundingVolume, coordinates, subdivisionScheme) {
|
|
6677
|
+
const rootS2VolumeInfo = rootBoundingVolume.s2VolumeInfo;
|
|
6678
|
+
const rootIndex = (0, import_s22.getS2IndexFromToken)(rootS2VolumeInfo.token);
|
|
6679
|
+
const descendantIndex = (0, import_s22.getS2DescendantIndex)(rootIndex, coordinates.level, coordinates.x, coordinates.y);
|
|
6680
|
+
const divisionCount = 2 ** coordinates.level;
|
|
6681
|
+
const heightSize = (rootS2VolumeInfo.maximumHeight - rootS2VolumeInfo.minimumHeight) / divisionCount;
|
|
6682
|
+
const childS2VolumeInfo = {
|
|
6683
|
+
token: (0, import_s22.getS2TokenFromIndex)(descendantIndex),
|
|
6684
|
+
minimumHeight: rootS2VolumeInfo.minimumHeight + (subdivisionScheme === "OCTREE" ? heightSize * coordinates.z : 0),
|
|
6685
|
+
maximumHeight: rootS2VolumeInfo.minimumHeight + (subdivisionScheme === "OCTREE" ? heightSize * (coordinates.z + 1) : heightSize * divisionCount)
|
|
6686
|
+
};
|
|
6687
|
+
const extensions = rootBoundingVolume.extensions ? { ...rootBoundingVolume.extensions } : void 0;
|
|
6688
|
+
if (extensions == null ? void 0 : extensions["3DTILES_bounding_volume_S2"]) {
|
|
6689
|
+
extensions["3DTILES_bounding_volume_S2"] = childS2VolumeInfo;
|
|
6690
|
+
}
|
|
6691
|
+
if (extensions == null ? void 0 : extensions["3DTILES_shape_s2"]) {
|
|
6692
|
+
extensions["3DTILES_shape_s2"] = childS2VolumeInfo;
|
|
6693
|
+
}
|
|
6694
|
+
return {
|
|
6695
|
+
...rootBoundingVolume,
|
|
6696
|
+
...extensions ? { extensions } : {},
|
|
6697
|
+
s2VolumeInfo: childS2VolumeInfo,
|
|
6698
|
+
box: convertS2BoundingVolumeToOBB(childS2VolumeInfo)
|
|
6699
|
+
};
|
|
6700
|
+
}
|
|
6701
|
+
function normalizeRegionLongitude(longitude) {
|
|
6702
|
+
let normalizedLongitude = longitude;
|
|
6703
|
+
while (normalizedLongitude > Math.PI) {
|
|
6704
|
+
normalizedLongitude -= 2 * Math.PI;
|
|
6705
|
+
}
|
|
6706
|
+
while (normalizedLongitude < -Math.PI) {
|
|
6707
|
+
normalizedLongitude += 2 * Math.PI;
|
|
6708
|
+
}
|
|
6709
|
+
return normalizedLongitude;
|
|
6710
|
+
}
|
|
5575
6711
|
function getImplicitTileType(contentUrl) {
|
|
5576
6712
|
var _a;
|
|
5577
6713
|
if (!contentUrl) {
|
|
@@ -5640,6 +6776,12 @@ var Tiles3DSource = class {
|
|
|
5640
6776
|
queryParams = {};
|
|
5641
6777
|
/** Final request URLs cached by unmodified tile content URL. */
|
|
5642
6778
|
tileUrlCache = /* @__PURE__ */ new Map();
|
|
6779
|
+
/** Original content descriptors retained across {@link Tile3D.unloadContent} calls. */
|
|
6780
|
+
tileContentHeaders = /* @__PURE__ */ new WeakMap();
|
|
6781
|
+
/** Source-local namespaces assigned to distinct embedded glTF package file collections. */
|
|
6782
|
+
packageNamespaces = /* @__PURE__ */ new WeakMap();
|
|
6783
|
+
/** Next source-local package namespace. */
|
|
6784
|
+
nextPackageNamespace = 0;
|
|
5643
6785
|
/** Parsed subtree requests keyed by final source URL for deduplication and LRU reuse. */
|
|
5644
6786
|
implicitSubtreeCache;
|
|
5645
6787
|
/** Mutable counters exposed as a defensive snapshot through {@link getImplicitTilingStats}. */
|
|
@@ -5654,6 +6796,10 @@ var Tiles3DSource = class {
|
|
|
5654
6796
|
extensionsUsed = [];
|
|
5655
6797
|
resolver;
|
|
5656
6798
|
rootTileset;
|
|
6799
|
+
/** CRS transformer shared by this source's headers and decoded glTF content. */
|
|
6800
|
+
spatialTransformer;
|
|
6801
|
+
/** Root header after composing source-frame transforms and rebuilding target bounds. */
|
|
6802
|
+
preparedRootHeader;
|
|
5657
6803
|
/**
|
|
5658
6804
|
* Creates a 3D Tiles source.
|
|
5659
6805
|
* @param input Root metadata request, or preloaded root metadata for tests and internal callers.
|
|
@@ -5711,8 +6857,8 @@ var Tiles3DSource = class {
|
|
|
5711
6857
|
if (!this.asset) {
|
|
5712
6858
|
throw new Error("Tileset must have an asset property.");
|
|
5713
6859
|
}
|
|
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
|
|
6860
|
+
if (this.rootTileset.formatVersion !== "2.0-draft" && this.asset.version !== "0.0" && this.asset.version !== "1.0" && this.asset.version !== "1.1") {
|
|
6861
|
+
throw new Error("The tileset must be 3D Tiles version 0.0, 1.0, 1.1, or 2.0-draft.");
|
|
5716
6862
|
}
|
|
5717
6863
|
if ("tilesetVersion" in this.asset) {
|
|
5718
6864
|
this.setQueryParameter("v", this.asset.tilesetVersion);
|
|
@@ -5748,12 +6894,26 @@ var Tiles3DSource = class {
|
|
|
5748
6894
|
async getRootTileset() {
|
|
5749
6895
|
return this.getMetadata().tileset;
|
|
5750
6896
|
}
|
|
6897
|
+
/** Prepare nonlinear CRS state before runtime headers are materialized. */
|
|
6898
|
+
async prepareTileset(tileset) {
|
|
6899
|
+
const spatialReference = tileset.spatialReference;
|
|
6900
|
+
if (spatialReference.status === "unresolved") {
|
|
6901
|
+
throw new Error(spatialReference.warnings[0] || "3D Tiles spatial operations cannot be resolved from the supplied metadata and options");
|
|
6902
|
+
}
|
|
6903
|
+
if (spatialReference.status !== "transformable" && spatialReference.status !== "transformed") {
|
|
6904
|
+
return;
|
|
6905
|
+
}
|
|
6906
|
+
this.spatialTransformer ||= new Tiles3DSpatialTransformer(spatialReference, tileset.options.spatial);
|
|
6907
|
+
tileset.spatialReference = markTilesetSpatialReferenceTransformed(spatialReference);
|
|
6908
|
+
this.preparedRootHeader = this.transformTileHeader(this.getMetadata().tileset.root, new import_core12.Matrix4());
|
|
6909
|
+
}
|
|
5751
6910
|
/**
|
|
5752
6911
|
* Builds explicit runtime headers while leaving implicit subtree references lazy.
|
|
5753
6912
|
*/
|
|
5754
6913
|
initializeTileHeaders(tileset, tilesetJson, parentTile) {
|
|
5755
6914
|
var _a;
|
|
5756
|
-
const
|
|
6915
|
+
const rootHeader = parentTile ? tilesetJson.root : this.preparedRootHeader || tilesetJson.root;
|
|
6916
|
+
const rootTile = new Tile3D(tileset, rootHeader, parentTile || void 0);
|
|
5757
6917
|
if (parentTile) {
|
|
5758
6918
|
parentTile.children.push(rootTile);
|
|
5759
6919
|
rootTile.depth = parentTile.depth + 1;
|
|
@@ -5789,7 +6949,13 @@ var Tiles3DSource = class {
|
|
|
5789
6949
|
* Loads binary content or nested tileset JSON for a runtime tile.
|
|
5790
6950
|
*/
|
|
5791
6951
|
async loadTileContent(tile) {
|
|
6952
|
+
var _a, _b, _c, _d, _e, _f;
|
|
5792
6953
|
const contentUrls = (tile.contentUrls || [tile.contentUrl]).filter(Boolean);
|
|
6954
|
+
const cachedContentHeaders = this.tileContentHeaders.get(tile);
|
|
6955
|
+
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] : []);
|
|
6956
|
+
if (!cachedContentHeaders) {
|
|
6957
|
+
this.tileContentHeaders.set(tile, contentHeaders);
|
|
6958
|
+
}
|
|
5793
6959
|
const tilesetLoaderOptions = this.loadOptions[this.loader.id] || {};
|
|
5794
6960
|
const options = {
|
|
5795
6961
|
...this.loadOptions,
|
|
@@ -5798,10 +6964,28 @@ var Tiles3DSource = class {
|
|
|
5798
6964
|
// Content bytes, rather than URL suffixes, distinguish external tilesets from renderable
|
|
5799
6965
|
// payloads. This is required for signed and extensionless resources.
|
|
5800
6966
|
isTileset: "auto",
|
|
5801
|
-
assetGltfUpAxis: this.asset && this.asset.gltfUpAxis || "Y"
|
|
6967
|
+
assetGltfUpAxis: this.asset && this.asset.gltfUpAxis || "Y",
|
|
6968
|
+
_tilesetOptions: {
|
|
6969
|
+
spatialReference: ((_c = tile.header) == null ? void 0 : _c._spatialReference) || ((_d = tile.tileset) == null ? void 0 : _d.spatialReference),
|
|
6970
|
+
spatialOptions: (_e = tile.tileset) == null ? void 0 : _e.options.spatial,
|
|
6971
|
+
spatialTransform: (_f = tile.header) == null ? void 0 : _f._spatialTransform
|
|
6972
|
+
}
|
|
5802
6973
|
}
|
|
5803
6974
|
};
|
|
5804
|
-
const contents = await Promise.all(contentUrls.map((contentUrl) =>
|
|
6975
|
+
const contents = await Promise.all(contentUrls.map((contentUrl, contentIndex) => {
|
|
6976
|
+
var _a2;
|
|
6977
|
+
const contentHeader = contentHeaders[contentIndex] || {};
|
|
6978
|
+
const vectorExtension = (_a2 = contentHeader.extensions) == null ? void 0 : _a2["3DTILES_content_gltf_vector"];
|
|
6979
|
+
const vectorContent = contentHeader._vectorContent || ((vectorExtension == null ? void 0 : vectorExtension.vector) === true ? { clip: vectorExtension.clip === true } : void 0);
|
|
6980
|
+
const contentOptions = vectorContent ? {
|
|
6981
|
+
...options,
|
|
6982
|
+
[this.loader.id]: {
|
|
6983
|
+
...options[this.loader.id],
|
|
6984
|
+
vectorContent
|
|
6985
|
+
}
|
|
6986
|
+
} : options;
|
|
6987
|
+
return this.loadContentResource(this.getTileUrl(contentUrl), contentHeader._resource, contentOptions);
|
|
6988
|
+
}));
|
|
5805
6989
|
tile.contents = contents;
|
|
5806
6990
|
tile.content = contents[0] || null;
|
|
5807
6991
|
const nestedTilesets = contents.filter((content) => (content == null ? void 0 : content.shape) === "tileset3d");
|
|
@@ -5812,6 +6996,34 @@ var Tiles3DSource = class {
|
|
|
5812
6996
|
nestedTilesets
|
|
5813
6997
|
};
|
|
5814
6998
|
}
|
|
6999
|
+
/** Transform a tile header and its eagerly declared descendants. */
|
|
7000
|
+
transformTileHeader(header, parentTransform = new import_core12.Matrix4()) {
|
|
7001
|
+
if (!this.spatialTransformer) {
|
|
7002
|
+
return header;
|
|
7003
|
+
}
|
|
7004
|
+
return this.transformTileHeaderWithTransformer(header, this.spatialTransformer, parentTransform);
|
|
7005
|
+
}
|
|
7006
|
+
/** Rebuilds one header subtree using an explicitly selected CRS transformer. */
|
|
7007
|
+
transformTileHeaderWithTransformer(header, transformer, parentTransform, spatialReference) {
|
|
7008
|
+
const localTransform = header.transform ? new import_core12.Matrix4(header.transform) : new import_core12.Matrix4();
|
|
7009
|
+
const composedTransform = new import_core12.Matrix4(parentTransform).multiplyRight(localTransform);
|
|
7010
|
+
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;
|
|
7011
|
+
return {
|
|
7012
|
+
...header,
|
|
7013
|
+
transform: void 0,
|
|
7014
|
+
boundingVolume: header.boundingVolume ? transformer.transformBoundingVolume(header.boundingVolume, composedTransform) : header.boundingVolume,
|
|
7015
|
+
_spatialReference: spatialReference,
|
|
7016
|
+
_spatialTransform: composedTransform.toArray(),
|
|
7017
|
+
content,
|
|
7018
|
+
children: Array.isArray(header.children) ? header.children.map((child) => this.transformTileHeaderWithTransformer(child, transformer, composedTransform, spatialReference)) : header.children
|
|
7019
|
+
};
|
|
7020
|
+
}
|
|
7021
|
+
transformContentHeader(content, composedTransform, transformer) {
|
|
7022
|
+
return {
|
|
7023
|
+
...content,
|
|
7024
|
+
boundingVolume: content.boundingVolume ? transformer.transformBoundingVolume(content.boundingVolume, composedTransform) : content.boundingVolume
|
|
7025
|
+
};
|
|
7026
|
+
}
|
|
5815
7027
|
/**
|
|
5816
7028
|
* Loads, materializes, and installs exactly one implicit subtree.
|
|
5817
7029
|
*
|
|
@@ -5830,7 +7042,7 @@ var Tiles3DSource = class {
|
|
|
5830
7042
|
return { loaded: false, tileCount: 0, childSubtreeCount: 0 };
|
|
5831
7043
|
}
|
|
5832
7044
|
const subtreeUrl = this.getTileUrl(reference.subtreeUrl);
|
|
5833
|
-
const subtree = await this.loadImplicitSubtreeResource(subtreeUrl);
|
|
7045
|
+
const subtree = await this.loadImplicitSubtreeResource(subtreeUrl, reference.resource);
|
|
5834
7046
|
if (this.destroyed || tile.isDestroyed()) {
|
|
5835
7047
|
return { loaded: false, tileCount: 0, childSubtreeCount: 0 };
|
|
5836
7048
|
}
|
|
@@ -5838,8 +7050,11 @@ var Tiles3DSource = class {
|
|
|
5838
7050
|
...reference,
|
|
5839
7051
|
subtreeUrl
|
|
5840
7052
|
});
|
|
5841
|
-
tile.
|
|
5842
|
-
const
|
|
7053
|
+
const nestedSpatialReference = tile.header._spatialReference;
|
|
7054
|
+
const subtreeTransformer = nestedSpatialReference ? new Tiles3DSpatialTransformer(nestedSpatialReference, tile.tileset.options.spatial) : this.spatialTransformer;
|
|
7055
|
+
const materializedRoot = subtreeTransformer ? this.transformTileHeaderWithTransformer(materializedSubtree.root, subtreeTransformer, new import_core12.Matrix4(), nestedSpatialReference) : materializedSubtree.root;
|
|
7056
|
+
tile.applyImplicitSubtreeHeader(materializedRoot);
|
|
7057
|
+
const materializedTileCount = this.initializeMaterializedChildren(tile.tileset, tile, materializedRoot.children);
|
|
5843
7058
|
this.implicitTilingStats.loadedSubtrees++;
|
|
5844
7059
|
this.implicitTilingStats.materializedTiles += materializedTileCount;
|
|
5845
7060
|
return {
|
|
@@ -5848,6 +7063,13 @@ var Tiles3DSource = class {
|
|
|
5848
7063
|
childSubtreeCount: materializedSubtree.childSubtreeCount
|
|
5849
7064
|
};
|
|
5850
7065
|
}
|
|
7066
|
+
/** Loads an implicit subtree for dataset traversal without camera state. */
|
|
7067
|
+
async loadTileChildrenForTraversal(tile, signal) {
|
|
7068
|
+
throwIfTraversalAborted(signal);
|
|
7069
|
+
const result = await this.loadTileChildren(tile, {});
|
|
7070
|
+
throwIfTraversalAborted(signal);
|
|
7071
|
+
return result;
|
|
7072
|
+
}
|
|
5851
7073
|
/**
|
|
5852
7074
|
* Returns a snapshot of implicit-subtree request, cache, and materialization counters.
|
|
5853
7075
|
*
|
|
@@ -5926,10 +7148,10 @@ var Tiles3DSource = class {
|
|
|
5926
7148
|
const { center } = rootTile.boundingVolume;
|
|
5927
7149
|
let cartographicCenter;
|
|
5928
7150
|
if (center && (center[0] !== 0 || center[1] !== 0 || center[2] !== 0)) {
|
|
5929
|
-
cartographicCenter = new
|
|
5930
|
-
|
|
7151
|
+
cartographicCenter = new import_core12.Vector3();
|
|
7152
|
+
import_geospatial10.Ellipsoid.WGS84.cartesianToCartographic(center, cartographicCenter);
|
|
5931
7153
|
} else {
|
|
5932
|
-
cartographicCenter = new
|
|
7154
|
+
cartographicCenter = new import_core12.Vector3(0, 0, -import_geospatial10.Ellipsoid.WGS84.radii[0]);
|
|
5933
7155
|
}
|
|
5934
7156
|
return {
|
|
5935
7157
|
asset: this.asset,
|
|
@@ -5960,16 +7182,66 @@ var Tiles3DSource = class {
|
|
|
5960
7182
|
if (extensionsRemoved.includes("KHR_draco_mesh_compression")) {
|
|
5961
7183
|
this.contentFormats.draco = true;
|
|
5962
7184
|
}
|
|
5963
|
-
if (extensionsRemoved.includes("EXT_meshopt_compression")) {
|
|
5964
|
-
this.contentFormats.meshopt = true;
|
|
7185
|
+
if (extensionsRemoved.includes("EXT_meshopt_compression")) {
|
|
7186
|
+
this.contentFormats.meshopt = true;
|
|
7187
|
+
}
|
|
7188
|
+
if (extensionsRemoved.includes("KHR_texture_basisu")) {
|
|
7189
|
+
this.contentFormats.ktx2 = true;
|
|
7190
|
+
}
|
|
7191
|
+
const nestedTilesets = loadResult.nestedTilesets || (loadResult.nestedTileset ? [loadResult.nestedTileset] : []);
|
|
7192
|
+
for (const nestedTileset of nestedTilesets) {
|
|
7193
|
+
tileset._initializeTileHeaders(this.prepareNestedTileset(tileset, nestedTileset), tile);
|
|
7194
|
+
}
|
|
7195
|
+
}
|
|
7196
|
+
/**
|
|
7197
|
+
* Resolves a nested tileset's CRS independently and adapts it to the owning tileset output frame.
|
|
7198
|
+
*
|
|
7199
|
+
* Nested resources may use a different source CRS from their parent. Their headers and glTF
|
|
7200
|
+
* payloads must therefore use a transformer built from the nested descriptor, while the parent
|
|
7201
|
+
* runtime continues to expose one requested output frame to traversal and rendering.
|
|
7202
|
+
*/
|
|
7203
|
+
prepareNestedTileset(tileset, nestedTileset) {
|
|
7204
|
+
const nestedSpatialReference = nestedTileset.spatialMetadata;
|
|
7205
|
+
const parentSpatialReference = tileset.spatialReference;
|
|
7206
|
+
if ((nestedSpatialReference == null ? void 0 : nestedSpatialReference.status) === "unresolved" || (nestedSpatialReference == null ? void 0 : nestedSpatialReference.crs.state) === "unknown") {
|
|
7207
|
+
throw new Error(nestedSpatialReference.warnings[0] || "Nested 3D Tiles CRS is explicitly unresolved and cannot be placed in the parent frame");
|
|
7208
|
+
}
|
|
7209
|
+
if (!nestedSpatialReference || !nestedSpatialReference.sourceCrs) {
|
|
7210
|
+
if (this.spatialTransformer && (parentSpatialReference.status === "transformable" || parentSpatialReference.status === "transformed")) {
|
|
7211
|
+
return {
|
|
7212
|
+
...nestedTileset,
|
|
7213
|
+
spatialMetadata: parentSpatialReference,
|
|
7214
|
+
root: this.transformTileHeaderWithTransformer(nestedTileset.root, this.spatialTransformer, new import_core12.Matrix4(), parentSpatialReference)
|
|
7215
|
+
};
|
|
7216
|
+
}
|
|
7217
|
+
return addNestedSpatialReference(nestedTileset, parentSpatialReference);
|
|
7218
|
+
}
|
|
7219
|
+
const parentCoordinateEpoch = parentSpatialReference.coordinateEpoch;
|
|
7220
|
+
const nestedCoordinateEpoch = nestedSpatialReference.coordinateEpoch;
|
|
7221
|
+
if (parentCoordinateEpoch !== void 0 && nestedCoordinateEpoch !== void 0 && parentCoordinateEpoch !== nestedCoordinateEpoch) {
|
|
7222
|
+
throw new Error(`Nested 3D Tiles coordinate epoch ${nestedCoordinateEpoch} differs from parent epoch ${parentCoordinateEpoch}; epoch-aware transformation is unavailable`);
|
|
5965
7223
|
}
|
|
5966
|
-
|
|
5967
|
-
|
|
7224
|
+
const outputCrs = parentSpatialReference.targetCrs || parentSpatialReference.sourceCrs;
|
|
7225
|
+
if (!outputCrs) {
|
|
7226
|
+
return addNestedSpatialReference(nestedTileset, nestedSpatialReference);
|
|
5968
7227
|
}
|
|
5969
|
-
const
|
|
5970
|
-
|
|
5971
|
-
|
|
7228
|
+
const nestedOutputReference = applyTilesetSpatialOptions(nestedSpatialReference, {
|
|
7229
|
+
...tileset.options.spatial,
|
|
7230
|
+
outputCoordinates: "target-crs",
|
|
7231
|
+
targetCrs: outputCrs
|
|
7232
|
+
});
|
|
7233
|
+
if (nestedOutputReference.status === "unresolved") {
|
|
7234
|
+
throw new Error(nestedOutputReference.warnings[0] || "Nested 3D Tiles CRS cannot be resolved in the parent output frame");
|
|
5972
7235
|
}
|
|
7236
|
+
if (nestedOutputReference.status === "native") {
|
|
7237
|
+
return addNestedSpatialReference(nestedTileset, nestedOutputReference);
|
|
7238
|
+
}
|
|
7239
|
+
const nestedTransformer = new Tiles3DSpatialTransformer(nestedOutputReference, tileset.options.spatial);
|
|
7240
|
+
return {
|
|
7241
|
+
...nestedTileset,
|
|
7242
|
+
spatialMetadata: nestedOutputReference,
|
|
7243
|
+
root: this.transformTileHeaderWithTransformer(nestedTileset.root, nestedTransformer, new import_core12.Matrix4(), nestedOutputReference)
|
|
7244
|
+
};
|
|
5973
7245
|
}
|
|
5974
7246
|
/**
|
|
5975
7247
|
* Loads data through injected core APIs so this module stays independent from `@loaders.gl/core`.
|
|
@@ -5998,13 +7270,84 @@ var Tiles3DSource = class {
|
|
|
5998
7270
|
}
|
|
5999
7271
|
return await this.loadWithCoreApi(url, options, loader);
|
|
6000
7272
|
}
|
|
7273
|
+
/** Loads a URL content reference or parses a buffer-view file retained from a glTF package. */
|
|
7274
|
+
async loadContentResource(url, packageResource, options) {
|
|
7275
|
+
if (!packageResource) {
|
|
7276
|
+
return await this.loadResourceData(url, options);
|
|
7277
|
+
}
|
|
7278
|
+
const file = packageResource.files[packageResource.fileIndex];
|
|
7279
|
+
if (!file) {
|
|
7280
|
+
throw new Error(`3D Tiles package references missing file ${packageResource.fileIndex}`);
|
|
7281
|
+
}
|
|
7282
|
+
if (file.uri) {
|
|
7283
|
+
return await this.loadResourceData(this.getTileUrl(file.uri), options);
|
|
7284
|
+
}
|
|
7285
|
+
if (!this.coreApi) {
|
|
7286
|
+
throw new Error("Tiles3DSource requires an injected coreApi to parse embedded package data");
|
|
7287
|
+
}
|
|
7288
|
+
const data = await this.getPackageFileData(file);
|
|
7289
|
+
const packageNamespace = this.getPackageNamespace(packageResource.files);
|
|
7290
|
+
const packageRootUrl = `gltf-package://${packageNamespace}/${packageResource.fileIndex}`;
|
|
7291
|
+
const fileName = file.name || "content";
|
|
7292
|
+
const directorySeparatorIndex = fileName.lastIndexOf("/");
|
|
7293
|
+
const packageBaseUrl = directorySeparatorIndex >= 0 ? `${packageRootUrl}/${fileName.slice(0, directorySeparatorIndex)}` : packageRootUrl;
|
|
7294
|
+
return await this.coreApi.parse(data, this.loader, options, {
|
|
7295
|
+
url: `${packageRootUrl}/${fileName}`,
|
|
7296
|
+
filename: fileName,
|
|
7297
|
+
baseUrl: packageBaseUrl,
|
|
7298
|
+
loaders: [this.loader],
|
|
7299
|
+
coreApi: this.coreApi,
|
|
7300
|
+
_parse: this.coreApi.parse,
|
|
7301
|
+
_tiles3dPackageFiles: packageResource.files,
|
|
7302
|
+
fetch: async (resource, init) => {
|
|
7303
|
+
const reference = resource.startsWith(`${packageRootUrl}/`) ? resource.slice(packageRootUrl.length + 1) : resource;
|
|
7304
|
+
const referencedFile = packageResource.files.find((packageFile) => packageFile.name === reference || packageFile.originalUri === reference);
|
|
7305
|
+
if (!referencedFile) {
|
|
7306
|
+
throw new Error(`3D Tiles glTF package does not contain file ${reference}`);
|
|
7307
|
+
}
|
|
7308
|
+
if (referencedFile.uri) {
|
|
7309
|
+
return await this.coreApi.fetchFile(this.getTileUrl(referencedFile.uri), init);
|
|
7310
|
+
}
|
|
7311
|
+
const referencedData = await this.getPackageFileData(referencedFile);
|
|
7312
|
+
return new Response(referencedData, {
|
|
7313
|
+
headers: { "content-type": referencedFile.mimeType }
|
|
7314
|
+
});
|
|
7315
|
+
}
|
|
7316
|
+
});
|
|
7317
|
+
}
|
|
7318
|
+
/** Returns a stable source-local namespace for one embedded glTF package file collection. */
|
|
7319
|
+
getPackageNamespace(files) {
|
|
7320
|
+
const existingNamespace = this.packageNamespaces.get(files);
|
|
7321
|
+
if (existingNamespace !== void 0) {
|
|
7322
|
+
return existingNamespace;
|
|
7323
|
+
}
|
|
7324
|
+
const packageNamespace = this.nextPackageNamespace++;
|
|
7325
|
+
this.packageNamespaces.set(files, packageNamespace);
|
|
7326
|
+
return packageNamespace;
|
|
7327
|
+
}
|
|
7328
|
+
/** Resolves a retained package-file byte range without eagerly copying other package files. */
|
|
7329
|
+
async getPackageFileData(file) {
|
|
7330
|
+
if (file.data) {
|
|
7331
|
+
return sliceArrayBuffer(file.data, file.byteOffset, file.byteLength);
|
|
7332
|
+
}
|
|
7333
|
+
if (file.bufferUri && this.coreApi) {
|
|
7334
|
+
const response = await this.coreApi.fetchFile(this.getTileUrl(file.bufferUri));
|
|
7335
|
+
if (!response.ok) {
|
|
7336
|
+
throw new Error(`Failed to fetch 3D Tiles package buffer: HTTP ${response.status}`);
|
|
7337
|
+
}
|
|
7338
|
+
const buffer = await response.arrayBuffer();
|
|
7339
|
+
return sliceArrayBuffer(buffer, file.byteOffset, file.byteLength);
|
|
7340
|
+
}
|
|
7341
|
+
throw new Error("3D Tiles package file has no available byte source");
|
|
7342
|
+
}
|
|
6001
7343
|
/**
|
|
6002
7344
|
* Returns a parsed subtree from the LRU cache or starts one source-managed request.
|
|
6003
7345
|
*
|
|
6004
7346
|
* @param subtreeUrl - Final subtree URL after query inheritance.
|
|
7347
|
+
* @param packageResource - Optional glTF package file satisfying the subtree reference.
|
|
6005
7348
|
* @returns Parsed subtree availability data.
|
|
6006
7349
|
*/
|
|
6007
|
-
async loadImplicitSubtreeResource(subtreeUrl) {
|
|
7350
|
+
async loadImplicitSubtreeResource(subtreeUrl, packageResource) {
|
|
6008
7351
|
const cachedSubtree = this.implicitSubtreeCache.get(subtreeUrl);
|
|
6009
7352
|
if (cachedSubtree) {
|
|
6010
7353
|
this.implicitTilingStats.cacheHits++;
|
|
@@ -6013,14 +7356,15 @@ var Tiles3DSource = class {
|
|
|
6013
7356
|
this.implicitTilingStats.requestedSubtrees++;
|
|
6014
7357
|
const loaderOptions = this.loadOptions[this.loader.id] || {};
|
|
6015
7358
|
return await this.implicitSubtreeCache.getOrLoad(subtreeUrl, async () => {
|
|
6016
|
-
|
|
7359
|
+
const options = {
|
|
6017
7360
|
...this.loadOptions,
|
|
6018
7361
|
[this.loader.id]: {
|
|
6019
7362
|
...loaderOptions,
|
|
6020
7363
|
isTileset: false,
|
|
6021
7364
|
isSubtree: true
|
|
6022
7365
|
}
|
|
6023
|
-
}
|
|
7366
|
+
};
|
|
7367
|
+
return await (packageResource ? this.loadContentResource(subtreeUrl, packageResource, options) : this.loadResourceData(subtreeUrl, options));
|
|
6024
7368
|
});
|
|
6025
7369
|
}
|
|
6026
7370
|
/**
|
|
@@ -6053,6 +7397,11 @@ var Tiles3DSource = class {
|
|
|
6053
7397
|
return materializedTileCount;
|
|
6054
7398
|
}
|
|
6055
7399
|
};
|
|
7400
|
+
function throwIfTraversalAborted(signal) {
|
|
7401
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
7402
|
+
throw signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
7403
|
+
}
|
|
7404
|
+
}
|
|
6056
7405
|
function isTilesetRequest(input) {
|
|
6057
7406
|
return Boolean(input && typeof input === "object" && "url" in input && "loader" in input && !("type" in input));
|
|
6058
7407
|
}
|
|
@@ -6071,10 +7420,22 @@ function normalizeTiles3DRequest(input) {
|
|
|
6071
7420
|
coreApi: input.coreApi
|
|
6072
7421
|
};
|
|
6073
7422
|
}
|
|
7423
|
+
function addNestedSpatialReference(nestedTileset, spatialReference) {
|
|
7424
|
+
const addToHeader = (header) => ({
|
|
7425
|
+
...header,
|
|
7426
|
+
_spatialReference: spatialReference,
|
|
7427
|
+
children: Array.isArray(header.children) ? header.children.map(addToHeader) : header.children
|
|
7428
|
+
});
|
|
7429
|
+
return {
|
|
7430
|
+
...nestedTileset,
|
|
7431
|
+
spatialMetadata: spatialReference,
|
|
7432
|
+
root: addToHeader(nestedTileset.root)
|
|
7433
|
+
};
|
|
7434
|
+
}
|
|
6074
7435
|
|
|
6075
7436
|
// dist/tileset-3d/format-i3s/i3s-source.js
|
|
6076
|
-
var
|
|
6077
|
-
var
|
|
7437
|
+
var import_geospatial12 = require("@math.gl/geospatial");
|
|
7438
|
+
var import_core14 = require("@math.gl/core");
|
|
6078
7439
|
|
|
6079
7440
|
// dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js
|
|
6080
7441
|
var I3SPendingTilesRegister = class {
|
|
@@ -6210,7 +7571,10 @@ var I3STilesetTraverser = class extends TilesetTraverser {
|
|
|
6210
7571
|
const childTiles = tile.children;
|
|
6211
7572
|
for (const child of children) {
|
|
6212
7573
|
const extendedId = `${child.id}-${frameState.viewport.id}`;
|
|
6213
|
-
const childTile = childTiles && childTiles.find((t) =>
|
|
7574
|
+
const childTile = childTiles && childTiles.find((t) => {
|
|
7575
|
+
var _a;
|
|
7576
|
+
return t.id === extendedId || ((_a = t.header) == null ? void 0 : _a.id) === child.id;
|
|
7577
|
+
});
|
|
6214
7578
|
if (!childTile) {
|
|
6215
7579
|
const request = () => this._loadTile(tile, child.id, frameState);
|
|
6216
7580
|
const cachedRequest = this._tileManager.find(extendedId);
|
|
@@ -6255,224 +7619,8 @@ var I3STilesetTraverser = class extends TilesetTraverser {
|
|
|
6255
7619
|
};
|
|
6256
7620
|
|
|
6257
7621
|
// 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
|
|
7622
|
+
var import_core13 = require("@math.gl/core");
|
|
7623
|
+
var import_geospatial11 = require("@math.gl/geospatial");
|
|
6476
7624
|
var I3SSpatialTransformer = class {
|
|
6477
7625
|
/** Descriptor attached to output after all adapter-owned spatial values have been transformed. */
|
|
6478
7626
|
spatialReference;
|
|
@@ -6667,7 +7815,7 @@ var I3SSpatialTransformer = class {
|
|
|
6667
7815
|
positions[index + 2] = transformed[2] - origin[2];
|
|
6668
7816
|
}
|
|
6669
7817
|
const isGeographic = this.targetCoordinateFrame === "geographic";
|
|
6670
|
-
const modelMatrix = isGeographic ? new
|
|
7818
|
+
const modelMatrix = isGeographic ? new import_core13.Matrix4() : new import_core13.Matrix4().translate(origin);
|
|
6671
7819
|
return {
|
|
6672
7820
|
positions,
|
|
6673
7821
|
sourcePositions: absoluteSourcePositions,
|
|
@@ -6695,7 +7843,7 @@ var I3SSpatialTransformer = class {
|
|
|
6695
7843
|
sourcePositions[index + 1],
|
|
6696
7844
|
sourcePositions[index + 2]
|
|
6697
7845
|
]);
|
|
6698
|
-
const inputNormal = new
|
|
7846
|
+
const inputNormal = new import_core13.Vector3([
|
|
6699
7847
|
normals[index],
|
|
6700
7848
|
normals[index + 1],
|
|
6701
7849
|
normals[index + 2]
|
|
@@ -6733,12 +7881,12 @@ var I3SSpatialTransformer = class {
|
|
|
6733
7881
|
}
|
|
6734
7882
|
/** Rebuild an I3S bound as a WGS84 ECEF box for generic `Tileset3D` traversal. */
|
|
6735
7883
|
transformBoundingVolumeToGeocentric(bounds) {
|
|
6736
|
-
const cartesianSamples = this.getGeographicBoundSamples(bounds).map((position) => Array.from(
|
|
7884
|
+
const cartesianSamples = this.getGeographicBoundSamples(bounds).map((position) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position))));
|
|
6737
7885
|
return { box: getAxisAlignedBox(cartesianSamples) };
|
|
6738
7886
|
}
|
|
6739
7887
|
/** Rebuild an I3S bound as WGS84 ECEF after asynchronous elevation placement. */
|
|
6740
7888
|
async transformBoundingVolumeToGeocentricAsync(bounds) {
|
|
6741
|
-
const cartesianSamples = (await this.getGeographicBoundSamplesAsync(bounds)).map((position) => Array.from(
|
|
7889
|
+
const cartesianSamples = (await this.getGeographicBoundSamplesAsync(bounds)).map((position) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position))));
|
|
6742
7890
|
return { box: getAxisAlignedBox(cartesianSamples) };
|
|
6743
7891
|
}
|
|
6744
7892
|
/** Return a WGS84 geographic MBS used by the I3S screen-threshold calculation. */
|
|
@@ -6765,7 +7913,7 @@ var I3SSpatialTransformer = class {
|
|
|
6765
7913
|
*/
|
|
6766
7914
|
async transformBoundsAsync(bounds) {
|
|
6767
7915
|
const geographicSamples = await this.getGeographicBoundSamplesAsync(bounds);
|
|
6768
|
-
const cartesianSamples = geographicSamples.map((position) => Array.from(
|
|
7916
|
+
const cartesianSamples = geographicSamples.map((position) => Array.from(import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position))));
|
|
6769
7917
|
const targetSamples = geographicSamples.map((position) => this.geographicToTargetTransformer.transformPosition(position));
|
|
6770
7918
|
return {
|
|
6771
7919
|
boundingVolume: { box: getAxisAlignedBox(cartesianSamples) },
|
|
@@ -6888,21 +8036,21 @@ var I3SSpatialTransformer = class {
|
|
|
6888
8036
|
if (this.targetCoordinateFrame === "geographic") {
|
|
6889
8037
|
return ecefVectorToLocalEnu(ecefNormal, geographic).normalize();
|
|
6890
8038
|
}
|
|
6891
|
-
const cartesian =
|
|
8039
|
+
const cartesian = import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(geographic));
|
|
6892
8040
|
const jacobianColumns = [];
|
|
6893
8041
|
for (const direction of getPositiveAxisDirections()) {
|
|
6894
|
-
const positiveGeographic =
|
|
6895
|
-
const negativeGeographic =
|
|
8042
|
+
const positiveGeographic = import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(new import_core13.Vector3(cartesian).add(direction));
|
|
8043
|
+
const negativeGeographic = import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(new import_core13.Vector3(cartesian).subtract(direction));
|
|
6896
8044
|
const positiveTarget = this.geographicToTargetTransformer.transformPosition(positiveGeographic);
|
|
6897
8045
|
const negativeTarget = this.geographicToTargetTransformer.transformPosition(negativeGeographic);
|
|
6898
8046
|
jacobianColumns.push((positiveTarget[0] - negativeTarget[0]) / 2, (positiveTarget[1] - negativeTarget[1]) / 2, (positiveTarget[2] - negativeTarget[2]) / 2);
|
|
6899
8047
|
}
|
|
6900
|
-
const normalMatrix = new
|
|
8048
|
+
const normalMatrix = new import_core13.Matrix3(jacobianColumns);
|
|
6901
8049
|
if (Math.abs(normalMatrix.determinant()) < 1e-12) {
|
|
6902
8050
|
throw new Error("Cannot transform an I3S normal through a singular local projection");
|
|
6903
8051
|
}
|
|
6904
8052
|
normalMatrix.invert().transpose();
|
|
6905
|
-
return new
|
|
8053
|
+
return new import_core13.Vector3(ecefNormal).transformByMatrix3(normalMatrix).normalize();
|
|
6906
8054
|
}
|
|
6907
8055
|
};
|
|
6908
8056
|
function getElevationProvider(mode, options) {
|
|
@@ -6934,17 +8082,17 @@ function getGeographicBoundingSphere(geographicSamples) {
|
|
|
6934
8082
|
if (!geographicSamples.length) {
|
|
6935
8083
|
throw new Error("I3S spatial transformation requires at least one bound sample");
|
|
6936
8084
|
}
|
|
6937
|
-
const cartesianSamples = geographicSamples.map((position) =>
|
|
6938
|
-
const cartesianCenter = new
|
|
8085
|
+
const cartesianSamples = geographicSamples.map((position) => import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(position)));
|
|
8086
|
+
const cartesianCenter = new import_core13.Vector3();
|
|
6939
8087
|
for (const sample of cartesianSamples) {
|
|
6940
8088
|
cartesianCenter.add(sample);
|
|
6941
8089
|
}
|
|
6942
8090
|
cartesianCenter.scale(1 / cartesianSamples.length);
|
|
6943
8091
|
let radius = 0;
|
|
6944
8092
|
for (const sample of cartesianSamples) {
|
|
6945
|
-
radius = Math.max(radius, new
|
|
8093
|
+
radius = Math.max(radius, new import_core13.Vector3(sample).subtract(cartesianCenter).magnitude());
|
|
6946
8094
|
}
|
|
6947
|
-
const geographicCenter =
|
|
8095
|
+
const geographicCenter = import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(cartesianCenter);
|
|
6948
8096
|
return [geographicCenter[0], geographicCenter[1], geographicCenter[2], radius];
|
|
6949
8097
|
}
|
|
6950
8098
|
function getSourceBoundSamples(bounds, sourceFrame, sourceToGeographicTransformer, sourceVerticalUnitScale) {
|
|
@@ -6953,28 +8101,28 @@ function getSourceBoundSamples(bounds, sourceFrame, sourceToGeographicTransforme
|
|
|
6953
8101
|
const center2 = Array.from(obb.center).slice(0, 3);
|
|
6954
8102
|
center2[2] *= sourceVerticalUnitScale;
|
|
6955
8103
|
const halfSize = Array.from(obb.halfSize).slice(0, 3);
|
|
6956
|
-
const quaternion = new
|
|
8104
|
+
const quaternion = new import_core13.Quaternion().fromArray(Array.from(obb.quaternion));
|
|
6957
8105
|
const axes = [
|
|
6958
|
-
new
|
|
6959
|
-
new
|
|
6960
|
-
new
|
|
8106
|
+
new import_core13.Vector3([halfSize[0], 0, 0]).transformByQuaternion(quaternion),
|
|
8107
|
+
new import_core13.Vector3([0, halfSize[1], 0]).transformByQuaternion(quaternion),
|
|
8108
|
+
new import_core13.Vector3([0, 0, halfSize[2]]).transformByQuaternion(quaternion)
|
|
6961
8109
|
];
|
|
6962
8110
|
if (sourceFrame === "geographic") {
|
|
6963
8111
|
const geographicCenter = sourceToGeographicTransformer.transformPosition(center2);
|
|
6964
|
-
const cartesianCenter =
|
|
8112
|
+
const cartesianCenter = import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(geographicCenter));
|
|
6965
8113
|
const cartesianAxes = bounds.normalReferenceFrame === "vertex-reference-frame" ? axes.map((axis) => localEnuVectorToEcef(axis, geographicCenter)) : axes;
|
|
6966
8114
|
return getBoxSigns().map((signs) => {
|
|
6967
|
-
const corner = new
|
|
8115
|
+
const corner = new import_core13.Vector3(cartesianCenter);
|
|
6968
8116
|
for (let axisIndex = 0; axisIndex < 3; axisIndex++) {
|
|
6969
|
-
corner.add(new
|
|
8117
|
+
corner.add(new import_core13.Vector3(cartesianAxes[axisIndex]).scale(signs[axisIndex]));
|
|
6970
8118
|
}
|
|
6971
|
-
return Array.from(
|
|
8119
|
+
return Array.from(import_geospatial11.Ellipsoid.WGS84.cartesianToCartographic(corner));
|
|
6972
8120
|
});
|
|
6973
8121
|
}
|
|
6974
8122
|
return getBoxSigns().map((signs) => {
|
|
6975
|
-
const corner = new
|
|
8123
|
+
const corner = new import_core13.Vector3(center2);
|
|
6976
8124
|
for (let axisIndex = 0; axisIndex < 3; axisIndex++) {
|
|
6977
|
-
corner.add(new
|
|
8125
|
+
corner.add(new import_core13.Vector3(axes[axisIndex]).scale(signs[axisIndex]));
|
|
6978
8126
|
}
|
|
6979
8127
|
return Array.from(corner);
|
|
6980
8128
|
});
|
|
@@ -6988,10 +8136,10 @@ function getSourceBoundSamples(bounds, sourceFrame, sourceToGeographicTransforme
|
|
|
6988
8136
|
const radius = mbs[3];
|
|
6989
8137
|
if (sourceFrame === "geographic") {
|
|
6990
8138
|
const geographicCenter = sourceToGeographicTransformer.transformPosition(center);
|
|
6991
|
-
const cartesianCenter =
|
|
6992
|
-
return getAxisDirections().map((direction) => Array.from(
|
|
8139
|
+
const cartesianCenter = import_geospatial11.Ellipsoid.WGS84.cartographicToCartesian(new import_core13.Vector3(geographicCenter));
|
|
8140
|
+
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
8141
|
}
|
|
6994
|
-
return getAxisDirections().map((direction) => Array.from(new
|
|
8142
|
+
return getAxisDirections().map((direction) => Array.from(new import_core13.Vector3(center).add(new import_core13.Vector3(direction).scale(radius))));
|
|
6995
8143
|
}
|
|
6996
8144
|
function getBoxSigns() {
|
|
6997
8145
|
return [-1, 1].flatMap((x) => [-1, 1].flatMap((y) => [-1, 1].map((z) => [x, y, z])));
|
|
@@ -7007,18 +8155,18 @@ function getAxisDirections() {
|
|
|
7007
8155
|
];
|
|
7008
8156
|
}
|
|
7009
8157
|
function getPositiveAxisDirections() {
|
|
7010
|
-
return [new
|
|
8158
|
+
return [new import_core13.Vector3([1, 0, 0]), new import_core13.Vector3([0, 1, 0]), new import_core13.Vector3([0, 0, 1])];
|
|
7011
8159
|
}
|
|
7012
8160
|
function localEnuVectorToEcef(vector, geographic) {
|
|
7013
8161
|
const longitude = geographic[0] * Math.PI / 180;
|
|
7014
8162
|
const latitude = geographic[1] * Math.PI / 180;
|
|
7015
|
-
const east = new
|
|
7016
|
-
const north = new
|
|
8163
|
+
const east = new import_core13.Vector3([-Math.sin(longitude), Math.cos(longitude), 0]);
|
|
8164
|
+
const north = new import_core13.Vector3([
|
|
7017
8165
|
-Math.sin(latitude) * Math.cos(longitude),
|
|
7018
8166
|
-Math.sin(latitude) * Math.sin(longitude),
|
|
7019
8167
|
Math.cos(latitude)
|
|
7020
8168
|
]);
|
|
7021
|
-
const up = new
|
|
8169
|
+
const up = new import_core13.Vector3([
|
|
7022
8170
|
Math.cos(latitude) * Math.cos(longitude),
|
|
7023
8171
|
Math.cos(latitude) * Math.sin(longitude),
|
|
7024
8172
|
Math.sin(latitude)
|
|
@@ -7028,18 +8176,18 @@ function localEnuVectorToEcef(vector, geographic) {
|
|
|
7028
8176
|
function ecefVectorToLocalEnu(vector, geographic) {
|
|
7029
8177
|
const longitude = geographic[0] * Math.PI / 180;
|
|
7030
8178
|
const latitude = geographic[1] * Math.PI / 180;
|
|
7031
|
-
const east = new
|
|
7032
|
-
const north = new
|
|
8179
|
+
const east = new import_core13.Vector3([-Math.sin(longitude), Math.cos(longitude), 0]);
|
|
8180
|
+
const north = new import_core13.Vector3([
|
|
7033
8181
|
-Math.sin(latitude) * Math.cos(longitude),
|
|
7034
8182
|
-Math.sin(latitude) * Math.sin(longitude),
|
|
7035
8183
|
Math.cos(latitude)
|
|
7036
8184
|
]);
|
|
7037
|
-
const up = new
|
|
8185
|
+
const up = new import_core13.Vector3([
|
|
7038
8186
|
Math.cos(latitude) * Math.cos(longitude),
|
|
7039
8187
|
Math.cos(latitude) * Math.sin(longitude),
|
|
7040
8188
|
Math.sin(latitude)
|
|
7041
8189
|
]);
|
|
7042
|
-
return new
|
|
8190
|
+
return new import_core13.Vector3([east.dot(vector), north.dot(vector), up.dot(vector)]);
|
|
7043
8191
|
}
|
|
7044
8192
|
function getAxisAlignedBox(positions) {
|
|
7045
8193
|
const minimum = [Infinity, Infinity, Infinity];
|
|
@@ -7250,7 +8398,17 @@ var I3SSource = class {
|
|
|
7250
8398
|
}
|
|
7251
8399
|
};
|
|
7252
8400
|
tile.content = await this.loadResourceData(contentUrl, options, this.contentLoader);
|
|
7253
|
-
|
|
8401
|
+
const contentEntry = {
|
|
8402
|
+
index: 0,
|
|
8403
|
+
uri: tile.contentUrl,
|
|
8404
|
+
type: tile.header.layerType,
|
|
8405
|
+
payload: tile.content,
|
|
8406
|
+
metadata: tile.header.metadata || null,
|
|
8407
|
+
boundingVolume: tile.boundingVolume,
|
|
8408
|
+
featureIds: tile.featureIdSets,
|
|
8409
|
+
renderable: Boolean(tile.content)
|
|
8410
|
+
};
|
|
8411
|
+
return { loaded: true, contents: [tile.content], contentEntries: [contentEntry] };
|
|
7254
8412
|
}
|
|
7255
8413
|
/**
|
|
7256
8414
|
* Loads child tile metadata on demand from node pages or `/nodes/{id}` resources.
|
|
@@ -7273,6 +8431,38 @@ var I3SSource = class {
|
|
|
7273
8431
|
const header = await this.loadResourceData(nodeUrl, options);
|
|
7274
8432
|
return await this.transformTileHeader(header);
|
|
7275
8433
|
}
|
|
8434
|
+
/** Loads all declared I3S child headers without camera or visibility state. */
|
|
8435
|
+
async loadTileChildrenForTraversal(parentTile, signal) {
|
|
8436
|
+
const childHeaders = parentTile.header.children || [];
|
|
8437
|
+
let loadedChildren = 0;
|
|
8438
|
+
const orderedChildren = [];
|
|
8439
|
+
for (const childHeader of childHeaders) {
|
|
8440
|
+
throwIfTraversalAborted2(signal);
|
|
8441
|
+
const childId = childHeader.id;
|
|
8442
|
+
if (typeof childId !== "string" && typeof childId !== "number") {
|
|
8443
|
+
throw new Error("I3S child header is missing its node ID");
|
|
8444
|
+
}
|
|
8445
|
+
const existingChild = parentTile.children.find((tile) => {
|
|
8446
|
+
var _a;
|
|
8447
|
+
return tile.id === String(childId) || ((_a = tile.header) == null ? void 0 : _a.id) === childId;
|
|
8448
|
+
});
|
|
8449
|
+
if (existingChild) {
|
|
8450
|
+
orderedChildren.push(existingChild);
|
|
8451
|
+
continue;
|
|
8452
|
+
}
|
|
8453
|
+
const childTileHeader = await this.loadChildTileHeader(parentTile, String(childId), null);
|
|
8454
|
+
throwIfTraversalAborted2(signal);
|
|
8455
|
+
const childTile = new Tile3D(parentTile.tileset, childTileHeader, parentTile, String(childId));
|
|
8456
|
+
orderedChildren.push(childTile);
|
|
8457
|
+
loadedChildren++;
|
|
8458
|
+
}
|
|
8459
|
+
const orderedChildSet = new Set(orderedChildren);
|
|
8460
|
+
parentTile.children = [
|
|
8461
|
+
...orderedChildren,
|
|
8462
|
+
...parentTile.children.filter((childTile) => !orderedChildSet.has(childTile))
|
|
8463
|
+
];
|
|
8464
|
+
return { loaded: true, tileCount: loadedChildren, childSubtreeCount: 0 };
|
|
8465
|
+
}
|
|
7276
8466
|
/**
|
|
7277
8467
|
* Resolves an I3S request URL with source-managed query parameters.
|
|
7278
8468
|
*/
|
|
@@ -7283,20 +8473,21 @@ var I3SSource = class {
|
|
|
7283
8473
|
if (!Object.keys(this.queryParams).length) {
|
|
7284
8474
|
return tilePath;
|
|
7285
8475
|
}
|
|
7286
|
-
const
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
const
|
|
7291
|
-
const
|
|
8476
|
+
const hashIndex = tilePath.indexOf("#");
|
|
8477
|
+
const hash = hashIndex >= 0 ? tilePath.slice(hashIndex) : "";
|
|
8478
|
+
const tilePathWithoutHash = hashIndex >= 0 ? tilePath.slice(0, hashIndex) : tilePath;
|
|
8479
|
+
const queryDelimiterIndex = tilePathWithoutHash.indexOf("?");
|
|
8480
|
+
const path = queryDelimiterIndex === -1 ? tilePathWithoutHash : tilePathWithoutHash.slice(0, queryDelimiterIndex);
|
|
8481
|
+
const existingQuery = queryDelimiterIndex === -1 ? "" : tilePathWithoutHash.slice(queryDelimiterIndex + 1);
|
|
8482
|
+
const existingQueryParams = new URLSearchParams(existingQuery);
|
|
7292
8483
|
const queryParams = new URLSearchParams();
|
|
7293
8484
|
for (const [key, value] of Object.entries(this.queryParams)) {
|
|
7294
|
-
if (!
|
|
8485
|
+
if (!existingQueryParams.has(key)) {
|
|
7295
8486
|
queryParams.set(key, value);
|
|
7296
8487
|
}
|
|
7297
8488
|
}
|
|
7298
8489
|
const queryString = queryParams.toString();
|
|
7299
|
-
return
|
|
8490
|
+
return `${path}${existingQuery ? `?${existingQuery}` : ""}${queryString ? `${existingQuery ? "&" : "?"}${queryString}` : ""}${hash}`;
|
|
7300
8491
|
}
|
|
7301
8492
|
/**
|
|
7302
8493
|
* Derives the default view state from full extent or store extent metadata.
|
|
@@ -7304,8 +8495,8 @@ var I3SSource = class {
|
|
|
7304
8495
|
getViewState(rootTile) {
|
|
7305
8496
|
var _a;
|
|
7306
8497
|
if (this.spatialTransformer && rootTile) {
|
|
7307
|
-
const center = new
|
|
7308
|
-
const cartographicCenter = new
|
|
8498
|
+
const center = new import_core14.Vector3(rootTile.boundingVolume.center);
|
|
8499
|
+
const cartographicCenter = new import_core14.Vector3(rootTile.header.i3sLodMbs.slice(0, 3));
|
|
7309
8500
|
if (this.spatialTransformer.targetCoordinateFrame === "geographic") {
|
|
7310
8501
|
return {
|
|
7311
8502
|
boundingVolume: rootTile.boundingVolume,
|
|
@@ -7325,9 +8516,9 @@ var I3SSource = class {
|
|
|
7325
8516
|
const fullExtent = metadata.tileset.fullExtent;
|
|
7326
8517
|
if (fullExtent) {
|
|
7327
8518
|
const { xmin, xmax, ymin, ymax, zmin, zmax } = fullExtent;
|
|
7328
|
-
const cartographicCenter = new
|
|
7329
|
-
const cartesianCenter = new
|
|
7330
|
-
|
|
8519
|
+
const cartographicCenter = new import_core14.Vector3(xmin + (xmax - xmin) / 2, ymin + (ymax - ymin) / 2, zmin + (zmax - zmin) / 2);
|
|
8520
|
+
const cartesianCenter = new import_core14.Vector3();
|
|
8521
|
+
import_geospatial12.Ellipsoid.WGS84.cartographicToCartesian(cartographicCenter, cartesianCenter);
|
|
7331
8522
|
return {
|
|
7332
8523
|
cartographicCenter,
|
|
7333
8524
|
cartesianCenter,
|
|
@@ -7337,9 +8528,9 @@ var I3SSource = class {
|
|
|
7337
8528
|
const extent = (_a = metadata.tileset.store) == null ? void 0 : _a.extent;
|
|
7338
8529
|
if (extent) {
|
|
7339
8530
|
const [xmin, ymin, xmax, ymax] = extent;
|
|
7340
|
-
const cartographicCenter = new
|
|
7341
|
-
const cartesianCenter = new
|
|
7342
|
-
|
|
8531
|
+
const cartographicCenter = new import_core14.Vector3(xmin + (xmax - xmin) / 2, ymin + (ymax - ymin) / 2, 0);
|
|
8532
|
+
const cartesianCenter = new import_core14.Vector3();
|
|
8533
|
+
import_geospatial12.Ellipsoid.WGS84.cartographicToCartesian(cartographicCenter, cartesianCenter);
|
|
7343
8534
|
return {
|
|
7344
8535
|
cartographicCenter,
|
|
7345
8536
|
cartesianCenter,
|
|
@@ -7348,7 +8539,7 @@ var I3SSource = class {
|
|
|
7348
8539
|
}
|
|
7349
8540
|
console.warn("Extent is not defined in the tileset header");
|
|
7350
8541
|
return {
|
|
7351
|
-
cartographicCenter: new
|
|
8542
|
+
cartographicCenter: new import_core14.Vector3(),
|
|
7352
8543
|
zoom: 1
|
|
7353
8544
|
};
|
|
7354
8545
|
}
|
|
@@ -7400,6 +8591,9 @@ var I3SSource = class {
|
|
|
7400
8591
|
* @param loadOptions Loader options that may contain an ArcGIS token.
|
|
7401
8592
|
*/
|
|
7402
8593
|
initializeQueryParams(loadOptions) {
|
|
8594
|
+
for (const [key, value] of Object.entries(loadOptions.searchParams || {})) {
|
|
8595
|
+
this.queryParams[key] = String(value);
|
|
8596
|
+
}
|
|
7403
8597
|
const i3sOptions = loadOptions.i3s;
|
|
7404
8598
|
if (i3sOptions && typeof i3sOptions === "object" && "token" in i3sOptions) {
|
|
7405
8599
|
const token = i3sOptions.token;
|
|
@@ -7439,6 +8633,11 @@ var I3SSource = class {
|
|
|
7439
8633
|
};
|
|
7440
8634
|
}
|
|
7441
8635
|
};
|
|
8636
|
+
function throwIfTraversalAborted2(signal) {
|
|
8637
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
8638
|
+
throw signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
8639
|
+
}
|
|
8640
|
+
}
|
|
7442
8641
|
function getI3SContentLoader(loader) {
|
|
7443
8642
|
return loader.contentLoader || loader;
|
|
7444
8643
|
}
|
|
@@ -8668,7 +9867,7 @@ function isAbortError3(error) {
|
|
|
8668
9867
|
}
|
|
8669
9868
|
|
|
8670
9869
|
// dist/point-cloud/point-cloud-tileset.js
|
|
8671
|
-
var
|
|
9870
|
+
var import_core15 = require("@math.gl/core");
|
|
8672
9871
|
var import_culling6 = require("@math.gl/culling");
|
|
8673
9872
|
|
|
8674
9873
|
// dist/point-cloud/point-cloud-tile.js
|
|
@@ -8832,7 +10031,7 @@ var PointCloudTileset = class {
|
|
|
8832
10031
|
const viewState = await ((_b = (_a = this.dataSource).getViewState) == null ? void 0 : _b.call(_a));
|
|
8833
10032
|
this.boundingVolume = (viewState == null ? void 0 : viewState.boundingVolume) || this.root.boundingVolume;
|
|
8834
10033
|
const center = (viewState == null ? void 0 : viewState.cartographicCenter) || this.root.boundingVolume.center;
|
|
8835
|
-
this.cartographicCenter = new
|
|
10034
|
+
this.cartographicCenter = new import_core15.Vector3(center);
|
|
8836
10035
|
this.zoom = (viewState == null ? void 0 : viewState.zoom) || this.estimateZoom(this.boundingVolume);
|
|
8837
10036
|
}
|
|
8838
10037
|
/**
|