@loaders.gl/tile-converter 5.0.0-alpha.7 → 5.0.0-alpha.9
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 +389 -0
- package/dist/converter.min.cjs +194 -175
- package/dist/i3s-server/bin/i3s-server.min.cjs +84 -84
- package/dist/index.cjs +37747 -0
- package/dist/index.js +37718 -0
- package/dist/v5/browser-sink.d.ts +37 -0
- package/dist/v5/browser-source.d.ts +38 -0
- package/dist/v5/browser-tileset-source.d.ts +70 -0
- package/dist/v5/browser.cjs +10165 -0
- package/dist/v5/browser.d.ts +30 -0
- package/dist/v5/browser.js +10140 -0
- package/dist/v5/conversion-api.d.ts +122 -0
- package/dist/v5/conversion-archive.d.ts +18 -0
- package/dist/v5/feature-arrow.d.ts +36 -0
- package/dist/v5/index.cjs +11446 -0
- package/dist/v5/index.d.ts +28 -0
- package/dist/v5/index.js +11410 -0
- package/dist/v5/mesh-conversion.d.ts +55 -0
- package/dist/v5/mesh-tileset-archive.d.ts +16 -0
- package/dist/v5/mesh-tileset-sink.d.ts +31 -0
- package/dist/v5/mesh.d.ts +73 -0
- package/dist/v5/point-cloud-conversion.d.ts +31 -0
- package/dist/v5/point-cloud-source-encoder.d.ts +49 -0
- package/dist/v5/point-cloud-source.d.ts +25 -0
- package/dist/v5/point-cloud.d.ts +24 -0
- package/dist/v5/resource-manifest.d.ts +58 -0
- package/dist/v5/spatial-conversion.d.ts +59 -0
- package/dist/v5/tileset-source.d.ts +21 -0
- package/package.json +41 -26
- package/src/common/README.md +5 -0
- package/src/index.ts +1 -2
- package/src/{3d-tiles-converter → v4/3d-tiles-converter}/3d-tiles-converter.ts +13 -2
- package/src/v4/3d-tiles-converter/helpers/validate-i3s-spatial-reference.ts +124 -0
- package/src/{deps-installer → v4/deps-installer}/deps-installer.ts +10 -7
- package/src/v4/i3s-converter/helpers/encode-string-attribute.ts +23 -0
- package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-converter.ts +15 -42
- package/src/{i3s-converter → v4/i3s-converter}/helpers/gltf-attributes.ts +5 -4
- package/src/{i3s-converter → v4/i3s-converter}/helpers/load-3d-tiles.ts +5 -9
- package/src/{i3s-converter → v4/i3s-converter}/i3s-converter.ts +6 -7
- package/src/{i3s-server → v4/i3s-server}/README.md +2 -2
- package/src/{i3s-server → v4/i3s-server}/routes/slpk-router.ts +1 -0
- package/src/v4/index.ts +2 -0
- package/src/v5/browser-sink.ts +130 -0
- package/src/v5/browser-source.ts +155 -0
- package/src/v5/browser-tileset-source.ts +328 -0
- package/src/v5/browser.ts +77 -0
- package/src/v5/conversion-api.ts +287 -0
- package/src/v5/conversion-archive.ts +51 -0
- package/src/v5/feature-arrow.ts +427 -0
- package/src/v5/index.ts +68 -0
- package/src/v5/mesh-conversion.ts +177 -0
- package/src/v5/mesh-tileset-archive.ts +48 -0
- package/src/v5/mesh-tileset-sink.ts +178 -0
- package/src/v5/mesh.ts +503 -0
- package/src/v5/point-cloud-conversion.ts +80 -0
- package/src/v5/point-cloud-source-encoder.ts +102 -0
- package/src/v5/point-cloud-source.ts +84 -0
- package/src/v5/point-cloud.ts +271 -0
- package/src/v5/resource-manifest.ts +213 -0
- package/src/v5/spatial-conversion.ts +305 -0
- package/src/v5/tileset-source.ts +54 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/3d-tiles-content-converter.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/i3s-obb-to-3d-tiles-obb.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/load-i3s.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/texture-atlas.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/json-templates/tileset.ts +0 -0
- /package/src/{constants.ts → v4/constants.ts} +0 -0
- /package/src/{converter-cli.ts → v4/converter-cli.ts} +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/attribute-metadata-info.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/batch-ids-extensions.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/coordinate-converter.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/create-scene-server-path.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/feature-attributes.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-attributes.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-debug.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-index-document.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-pages.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/preprocess-3d-tiles.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/progress.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/tileset-traversal.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/geometry-definitions.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/layers.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/metadata.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/node.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/scene-server.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/shared-resources.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/store.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/types.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/app.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/bin/www.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/certs/cert.pem +0 -0
- /package/src/{i3s-server → v4/i3s-server}/certs/key.pem +0 -0
- /package/src/{i3s-server → v4/i3s-server}/controllers/slpk-controller.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/utils/create-scene-server.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/utils/server-utils.ts +0 -0
- /package/src/{lib → v4/lib}/json-schemas/conversion-dump-json-schema.ts +0 -0
- /package/src/{lib → v4/lib}/utils/cli-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/compress-util.ts +0 -0
- /package/src/{lib → v4/lib}/utils/conversion-dump.ts +0 -0
- /package/src/{lib → v4/lib}/utils/file-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/geometry-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/lod-conversion-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/queue.ts +0 -0
- /package/src/{lib → v4/lib}/utils/statistic-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/write-queue.ts +0 -0
- /package/src/{pgm-loader.ts → v4/pgm-loader.ts} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Tiles3DArchiveWriter} from '@loaders.gl/3d-tiles/3d-tiles-archive-writer';
|
|
6
|
+
import {TileConversionError} from './conversion-api.js';
|
|
7
|
+
import type {BrowserTileConversionFile} from './browser-sink.js';
|
|
8
|
+
|
|
9
|
+
/** Output-size budget for a single-mesh 3TZ archive. */
|
|
10
|
+
export interface SingleMeshTilesetArchiveOptions {
|
|
11
|
+
/** Maximum final archive bytes, including ZIP headers and index; not peak serialization memory. */
|
|
12
|
+
readonly maxArchiveBytes: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Packages the two unmodified files from a finalized single-mesh sink as a downloadable 3TZ Blob.
|
|
17
|
+
* The writer checks the complete archive budget before reading either Blob. Applications own
|
|
18
|
+
* object-URL creation/revocation and download UI. Retained input Blobs and transient ZIP buffers
|
|
19
|
+
* are additional memory. SLPK requires separately authored I3S scene-layer resources.
|
|
20
|
+
* @param files - Files returned by a successfully finalized createSingleMeshTilesetSink.
|
|
21
|
+
* @param options - Required final archive-size budget.
|
|
22
|
+
* @returns An indexed 3TZ Blob; save with the .3tz extension.
|
|
23
|
+
*/
|
|
24
|
+
export async function createSingleMeshTilesetArchive(
|
|
25
|
+
files: readonly BrowserTileConversionFile[],
|
|
26
|
+
options: SingleMeshTilesetArchiveOptions
|
|
27
|
+
): Promise<Blob> {
|
|
28
|
+
const {maxArchiveBytes} = options;
|
|
29
|
+
if (!Number.isSafeInteger(maxArchiveBytes) || maxArchiveBytes < 0) {
|
|
30
|
+
throw new TileConversionError(
|
|
31
|
+
'INVALID_ARCHIVE_BYTE_LIMIT',
|
|
32
|
+
'Archive byte limit must be a non-negative safe integer'
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
files.length !== 2 ||
|
|
37
|
+
!files.some(file => file.resourceId === 'mesh.glb') ||
|
|
38
|
+
!files.some(file => file.resourceId === 'tileset.json')
|
|
39
|
+
) {
|
|
40
|
+
throw new TileConversionError(
|
|
41
|
+
'INVALID_SINGLE_MESH_ARCHIVE',
|
|
42
|
+
'Expected mesh.glb and tileset.json from a finalized single-mesh sink'
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
const resources = Object.fromEntries(files.map(file => [file.resourceId, file.blob]));
|
|
46
|
+
const archive = await Tiles3DArchiveWriter.encode(resources, {'3tz': {maxArchiveBytes}});
|
|
47
|
+
return new Blob([archive], {type: Tiles3DArchiveWriter.mimeTypes[0]});
|
|
48
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {Tiles3DTilesetJSON, Tiles3DTileJSON} from '@loaders.gl/3d-tiles';
|
|
6
|
+
import {TileConversionError} from './conversion-api.js';
|
|
7
|
+
import type {TileConversionSink} from './conversion-api.js';
|
|
8
|
+
import {createBoundedMemoryTileConversionSink} from './browser-sink.js';
|
|
9
|
+
import type {BrowserTileConversionFile} from './browser-sink.js';
|
|
10
|
+
import type {EncodedMeshConversionResource} from './mesh-conversion.js';
|
|
11
|
+
|
|
12
|
+
/** Limits and fidelity policy for one ECEF mesh tileset. */
|
|
13
|
+
export interface SingleMeshTilesetSinkOptions {
|
|
14
|
+
/** Maximum combined UTF-8 tileset JSON and GLB Blob bytes retained by the sink. */
|
|
15
|
+
readonly maxTotalBytes: number;
|
|
16
|
+
/** Explicit geometric error in meters, including source error and position rounding. */
|
|
17
|
+
readonly geometricError: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** A single-tile output package retained as two named browser-native Blobs. */
|
|
21
|
+
export interface SingleMeshTilesetSink extends TileConversionSink<EncodedMeshConversionResource> {
|
|
22
|
+
/** Returns mesh.glb and tileset.json only after successful finalization; empty after abort. */
|
|
23
|
+
getFiles(): readonly BrowserTileConversionFile[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Packages exactly one `createMeshConversionCodec` output as a 3D Tiles 1.1 tileset.
|
|
28
|
+
*
|
|
29
|
+
* Requires resolved EPSG:4978 output identified by the compact string, with ellipsoidal heights.
|
|
30
|
+
* The tile transform cancels the standard glTF y-up to z-up rotation and adds the ECEF origin.
|
|
31
|
+
* Bounds come from encoded local vertices, avoiding subtraction of large absolute coordinates.
|
|
32
|
+
* Fixed relative names keep the package deterministic. Save both files together or pass them to
|
|
33
|
+
* createSingleMeshTilesetArchive for 3TZ packaging. Applications own downloads, workers, and
|
|
34
|
+
* source-scene extraction.
|
|
35
|
+
* The byte limit bounds retained Blobs, not peak conversion/serialization memory. Input GLB and
|
|
36
|
+
* local bounds must be unmodified codec outputs; this sink does not independently validate GLB.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Required retained-output budget and geometric error in meters.
|
|
39
|
+
* @returns A bounded sink that exposes files on finalization and clears them on abort.
|
|
40
|
+
*/
|
|
41
|
+
export function createSingleMeshTilesetSink(
|
|
42
|
+
options: SingleMeshTilesetSinkOptions
|
|
43
|
+
): SingleMeshTilesetSink {
|
|
44
|
+
const {geometricError} = options;
|
|
45
|
+
if (!Number.isFinite(geometricError) || geometricError < 0) {
|
|
46
|
+
throw new TileConversionError(
|
|
47
|
+
'MESH_GEOMETRIC_ERROR_INVALID',
|
|
48
|
+
'geometricError must be finite and nonnegative, in meters'
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const memorySink = createBoundedMemoryTileConversionSink(options);
|
|
52
|
+
let state: 'empty' | 'writing' | 'written' | 'closed' = 'empty';
|
|
53
|
+
let completed = false;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
getFiles() {
|
|
57
|
+
return completed ? memorySink.getFiles() : [];
|
|
58
|
+
},
|
|
59
|
+
async write(resource, signal) {
|
|
60
|
+
signal?.throwIfAborted();
|
|
61
|
+
if (state !== 'empty') {
|
|
62
|
+
throw new TileConversionError(
|
|
63
|
+
'SINGLE_MESH_SINK_UNAVAILABLE',
|
|
64
|
+
'The sink accepts exactly one mesh before finalization or abort'
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
const json = JSON.stringify(createMeshTileset(resource, geometricError));
|
|
68
|
+
state = 'writing';
|
|
69
|
+
await memorySink.write(
|
|
70
|
+
{resourceId: 'mesh.glb', parts: [resource.glb], contentType: 'model/gltf-binary'},
|
|
71
|
+
signal
|
|
72
|
+
);
|
|
73
|
+
await memorySink.write(
|
|
74
|
+
{resourceId: 'tileset.json', parts: [json], contentType: 'application/json'},
|
|
75
|
+
signal
|
|
76
|
+
);
|
|
77
|
+
state = 'written';
|
|
78
|
+
},
|
|
79
|
+
async finalize(report) {
|
|
80
|
+
if (state !== 'written') {
|
|
81
|
+
throw new TileConversionError(
|
|
82
|
+
'SINGLE_MESH_SINK_INCOMPLETE',
|
|
83
|
+
'Finalization requires exactly one successfully written mesh'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
await memorySink.finalize(report);
|
|
87
|
+
state = 'closed';
|
|
88
|
+
completed = true;
|
|
89
|
+
},
|
|
90
|
+
async abort(error) {
|
|
91
|
+
state = 'closed';
|
|
92
|
+
completed = false;
|
|
93
|
+
await memorySink.abort(error);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Builds placement and local bounds for a trusted single-mesh codec output. */
|
|
99
|
+
function createMeshTileset(
|
|
100
|
+
resource: EncodedMeshConversionResource,
|
|
101
|
+
geometricError: number
|
|
102
|
+
): Omit<Tiles3DTilesetJSON, 'root'> & {root: Omit<Tiles3DTileJSON, 'children'>} {
|
|
103
|
+
const reference = resource.spatialReference;
|
|
104
|
+
const outputCrs = reference.targetCrs || reference.sourceCrs;
|
|
105
|
+
const heightReference =
|
|
106
|
+
reference.targetHeightReference === 'native'
|
|
107
|
+
? reference.heightReference
|
|
108
|
+
: reference.targetHeightReference;
|
|
109
|
+
if (
|
|
110
|
+
!['native', 'transformed'].includes(reference.status) ||
|
|
111
|
+
outputCrs !== 'EPSG:4978' ||
|
|
112
|
+
heightReference !== 'ellipsoidal' ||
|
|
113
|
+
(reference.status === 'native' &&
|
|
114
|
+
(reference.coordinateFrame !== 'geocentric' ||
|
|
115
|
+
reference.axisOrder !== 'xyz' ||
|
|
116
|
+
reference.verticalUnitScale !== 1 ||
|
|
117
|
+
reference.units?.some(unit => unit !== 'meter')))
|
|
118
|
+
) {
|
|
119
|
+
throw new TileConversionError(
|
|
120
|
+
'MESH_TILESET_FRAME_UNSUPPORTED',
|
|
121
|
+
'Single-mesh tilesets require resolved EPSG:4978 xyz coordinates in meters with ellipsoidal heights'
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (
|
|
125
|
+
!Number.isFinite(resource.maximumPositionError) ||
|
|
126
|
+
resource.maximumPositionError < 0 ||
|
|
127
|
+
resource.maximumPositionError > geometricError
|
|
128
|
+
) {
|
|
129
|
+
throw new TileConversionError(
|
|
130
|
+
'MESH_GEOMETRIC_ERROR_INVALID',
|
|
131
|
+
'geometricError must include the measured position reconstruction error'
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
const origin = [...resource.origin];
|
|
135
|
+
const [minimum, maximum] = resource.localBoundingBox.map(bound => [...bound]);
|
|
136
|
+
if (
|
|
137
|
+
origin.length !== 3 ||
|
|
138
|
+
minimum.length !== 3 ||
|
|
139
|
+
maximum.length !== 3 ||
|
|
140
|
+
[...origin, ...minimum, ...maximum].some(value => !Number.isFinite(value)) ||
|
|
141
|
+
minimum.some((value, axis) => value > maximum[axis])
|
|
142
|
+
) {
|
|
143
|
+
throw new TileConversionError(
|
|
144
|
+
'MESH_TILESET_BOUNDS_INVALID',
|
|
145
|
+
'Origin and local bounds must be finite xyz coordinates with ordered bounds'
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
const center = minimum.map((value, axis) => value / 2 + maximum[axis] / 2);
|
|
149
|
+
const halfSize = minimum.map((value, axis) => maximum[axis] / 2 - value / 2);
|
|
150
|
+
return {
|
|
151
|
+
asset: {version: '1.1'},
|
|
152
|
+
geometricError,
|
|
153
|
+
root: {
|
|
154
|
+
// 3D Tiles applies y-up -> z-up to GLB content before the tile transform.
|
|
155
|
+
transform: [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, ...origin, 1],
|
|
156
|
+
boundingVolume: {
|
|
157
|
+
// Bounds use the same y-up -> z-up rotation before the inverse tile rotation.
|
|
158
|
+
box: [
|
|
159
|
+
center[0],
|
|
160
|
+
-center[2],
|
|
161
|
+
center[1],
|
|
162
|
+
halfSize[0],
|
|
163
|
+
0,
|
|
164
|
+
0,
|
|
165
|
+
0,
|
|
166
|
+
0,
|
|
167
|
+
halfSize[1],
|
|
168
|
+
0,
|
|
169
|
+
-halfSize[2],
|
|
170
|
+
0
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
geometricError,
|
|
174
|
+
refine: 'REPLACE',
|
|
175
|
+
content: {uri: 'mesh.glb'}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|