@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.
Files changed (106) hide show
  1. package/README.md +389 -0
  2. package/dist/converter.min.cjs +194 -175
  3. package/dist/i3s-server/bin/i3s-server.min.cjs +84 -84
  4. package/dist/index.cjs +37747 -0
  5. package/dist/index.js +37718 -0
  6. package/dist/v5/browser-sink.d.ts +37 -0
  7. package/dist/v5/browser-source.d.ts +38 -0
  8. package/dist/v5/browser-tileset-source.d.ts +70 -0
  9. package/dist/v5/browser.cjs +10165 -0
  10. package/dist/v5/browser.d.ts +30 -0
  11. package/dist/v5/browser.js +10140 -0
  12. package/dist/v5/conversion-api.d.ts +122 -0
  13. package/dist/v5/conversion-archive.d.ts +18 -0
  14. package/dist/v5/feature-arrow.d.ts +36 -0
  15. package/dist/v5/index.cjs +11446 -0
  16. package/dist/v5/index.d.ts +28 -0
  17. package/dist/v5/index.js +11410 -0
  18. package/dist/v5/mesh-conversion.d.ts +55 -0
  19. package/dist/v5/mesh-tileset-archive.d.ts +16 -0
  20. package/dist/v5/mesh-tileset-sink.d.ts +31 -0
  21. package/dist/v5/mesh.d.ts +73 -0
  22. package/dist/v5/point-cloud-conversion.d.ts +31 -0
  23. package/dist/v5/point-cloud-source-encoder.d.ts +49 -0
  24. package/dist/v5/point-cloud-source.d.ts +25 -0
  25. package/dist/v5/point-cloud.d.ts +24 -0
  26. package/dist/v5/resource-manifest.d.ts +58 -0
  27. package/dist/v5/spatial-conversion.d.ts +59 -0
  28. package/dist/v5/tileset-source.d.ts +21 -0
  29. package/package.json +41 -26
  30. package/src/common/README.md +5 -0
  31. package/src/index.ts +1 -2
  32. package/src/{3d-tiles-converter → v4/3d-tiles-converter}/3d-tiles-converter.ts +13 -2
  33. package/src/v4/3d-tiles-converter/helpers/validate-i3s-spatial-reference.ts +124 -0
  34. package/src/{deps-installer → v4/deps-installer}/deps-installer.ts +10 -7
  35. package/src/v4/i3s-converter/helpers/encode-string-attribute.ts +23 -0
  36. package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-converter.ts +15 -42
  37. package/src/{i3s-converter → v4/i3s-converter}/helpers/gltf-attributes.ts +5 -4
  38. package/src/{i3s-converter → v4/i3s-converter}/helpers/load-3d-tiles.ts +5 -9
  39. package/src/{i3s-converter → v4/i3s-converter}/i3s-converter.ts +6 -7
  40. package/src/{i3s-server → v4/i3s-server}/README.md +2 -2
  41. package/src/{i3s-server → v4/i3s-server}/routes/slpk-router.ts +1 -0
  42. package/src/v4/index.ts +2 -0
  43. package/src/v5/browser-sink.ts +130 -0
  44. package/src/v5/browser-source.ts +155 -0
  45. package/src/v5/browser-tileset-source.ts +328 -0
  46. package/src/v5/browser.ts +77 -0
  47. package/src/v5/conversion-api.ts +287 -0
  48. package/src/v5/conversion-archive.ts +51 -0
  49. package/src/v5/feature-arrow.ts +427 -0
  50. package/src/v5/index.ts +68 -0
  51. package/src/v5/mesh-conversion.ts +177 -0
  52. package/src/v5/mesh-tileset-archive.ts +48 -0
  53. package/src/v5/mesh-tileset-sink.ts +178 -0
  54. package/src/v5/mesh.ts +503 -0
  55. package/src/v5/point-cloud-conversion.ts +80 -0
  56. package/src/v5/point-cloud-source-encoder.ts +102 -0
  57. package/src/v5/point-cloud-source.ts +84 -0
  58. package/src/v5/point-cloud.ts +271 -0
  59. package/src/v5/resource-manifest.ts +213 -0
  60. package/src/v5/spatial-conversion.ts +305 -0
  61. package/src/v5/tileset-source.ts +54 -0
  62. /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/3d-tiles-content-converter.ts +0 -0
  63. /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/i3s-obb-to-3d-tiles-obb.ts +0 -0
  64. /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/load-i3s.ts +0 -0
  65. /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/texture-atlas.ts +0 -0
  66. /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/json-templates/tileset.ts +0 -0
  67. /package/src/{constants.ts → v4/constants.ts} +0 -0
  68. /package/src/{converter-cli.ts → v4/converter-cli.ts} +0 -0
  69. /package/src/{i3s-converter → v4/i3s-converter}/helpers/attribute-metadata-info.ts +0 -0
  70. /package/src/{i3s-converter → v4/i3s-converter}/helpers/batch-ids-extensions.ts +0 -0
  71. /package/src/{i3s-converter → v4/i3s-converter}/helpers/coordinate-converter.ts +0 -0
  72. /package/src/{i3s-converter → v4/i3s-converter}/helpers/create-scene-server-path.ts +0 -0
  73. /package/src/{i3s-converter → v4/i3s-converter}/helpers/feature-attributes.ts +0 -0
  74. /package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-attributes.ts +0 -0
  75. /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-debug.ts +0 -0
  76. /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-index-document.ts +0 -0
  77. /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-pages.ts +0 -0
  78. /package/src/{i3s-converter → v4/i3s-converter}/helpers/preprocess-3d-tiles.ts +0 -0
  79. /package/src/{i3s-converter → v4/i3s-converter}/helpers/progress.ts +0 -0
  80. /package/src/{i3s-converter → v4/i3s-converter}/helpers/tileset-traversal.ts +0 -0
  81. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/geometry-definitions.ts +0 -0
  82. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/layers.ts +0 -0
  83. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/metadata.ts +0 -0
  84. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/node.ts +0 -0
  85. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/scene-server.ts +0 -0
  86. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/shared-resources.ts +0 -0
  87. /package/src/{i3s-converter → v4/i3s-converter}/json-templates/store.ts +0 -0
  88. /package/src/{i3s-converter → v4/i3s-converter}/types.ts +0 -0
  89. /package/src/{i3s-server → v4/i3s-server}/app.ts +0 -0
  90. /package/src/{i3s-server → v4/i3s-server}/bin/www.ts +0 -0
  91. /package/src/{i3s-server → v4/i3s-server}/certs/cert.pem +0 -0
  92. /package/src/{i3s-server → v4/i3s-server}/certs/key.pem +0 -0
  93. /package/src/{i3s-server → v4/i3s-server}/controllers/slpk-controller.ts +0 -0
  94. /package/src/{i3s-server → v4/i3s-server}/utils/create-scene-server.ts +0 -0
  95. /package/src/{i3s-server → v4/i3s-server}/utils/server-utils.ts +0 -0
  96. /package/src/{lib → v4/lib}/json-schemas/conversion-dump-json-schema.ts +0 -0
  97. /package/src/{lib → v4/lib}/utils/cli-utils.ts +0 -0
  98. /package/src/{lib → v4/lib}/utils/compress-util.ts +0 -0
  99. /package/src/{lib → v4/lib}/utils/conversion-dump.ts +0 -0
  100. /package/src/{lib → v4/lib}/utils/file-utils.ts +0 -0
  101. /package/src/{lib → v4/lib}/utils/geometry-utils.ts +0 -0
  102. /package/src/{lib → v4/lib}/utils/lod-conversion-utils.ts +0 -0
  103. /package/src/{lib → v4/lib}/utils/queue.ts +0 -0
  104. /package/src/{lib → v4/lib}/utils/statistic-utils.ts +0 -0
  105. /package/src/{lib → v4/lib}/utils/write-queue.ts +0 -0
  106. /package/src/{pgm-loader.ts → v4/pgm-loader.ts} +0 -0
@@ -0,0 +1,55 @@
1
+ import type { TilesetSpatialReference } from '@loaders.gl/tiles';
2
+ import type { MeshGeometry } from '@loaders.gl/schema';
3
+ import type { TileConversionCodec } from './conversion-api.js';
4
+ import type { Tiles3DConversionSpatialContext } from './spatial-conversion.js';
5
+ import type { MeshTileMaterial } from './mesh.js';
6
+ /** Explicitly selected geometry, with positions already in the spatial context's source frame. */
7
+ export interface MeshConversionInput {
8
+ /** Caller-owned resource identifier, forwarded to the output sink. */
9
+ readonly id: string;
10
+ /** Triangle geometry with absolute packed Float32 or Float64 source positions. */
11
+ readonly mesh: MeshGeometry;
12
+ /** Optional single material with an embedded base-color image, mapped explicitly by the source adapter. */
13
+ readonly material?: MeshTileMaterial;
14
+ /** Finite xyz origin in the target frame, subtracted before float32 encoding. */
15
+ readonly origin: readonly [number, number, number];
16
+ }
17
+ /** A completed GLB resource and the metadata needed to place its local geometry. */
18
+ export interface EncodedMeshConversionResource {
19
+ /** Caller-owned resource identifier. */
20
+ readonly id: string;
21
+ /** Self-contained GLB with local positions and transformed normals. */
22
+ readonly glb: ArrayBuffer;
23
+ /** Target-frame translation to add to the encoded positions. */
24
+ readonly origin: readonly [number, number, number];
25
+ /** Target-frame bounds of the reconstructed encoded vertices, including float32 rounding. */
26
+ readonly boundingBox: readonly [readonly number[], readonly number[]];
27
+ /** Bounds of encoded local vertices before adding the origin, without absolute-coordinate cancellation. */
28
+ readonly localBoundingBox: readonly [readonly number[], readonly number[]];
29
+ /** Metadata describing the output coordinate operation and height reference. */
30
+ readonly spatialReference: TilesetSpatialReference;
31
+ /** Largest measured Euclidean reconstruction error in target coordinate units. */
32
+ readonly maximumPositionError: number;
33
+ }
34
+ /** Spatial policy used by the concrete mesh conversion codec. */
35
+ export interface MeshConversionCodecOptions {
36
+ /** Shared context that accepts absolute source positions and returns absolute target positions. */
37
+ readonly spatialContext: Tiles3DConversionSpatialContext;
38
+ /** Maximum Euclidean reconstruction error per vertex, in target coordinate units. */
39
+ readonly maxPositionError: number;
40
+ }
41
+ /**
42
+ * Creates a concrete mesh codec for `convertTileset`.
43
+ *
44
+ * Source adapters must select geometry and apply source placement before supplying absolute
45
+ * positions and matching normals. This codec applies the supplied spatial context once, rebases
46
+ * around each input's target origin, and rejects rounding above the explicit error budget.
47
+ * Geographic and unknown output frames are rejected. The returned origin/bounds/reference are
48
+ * external placement metadata; applications own axis conventions, hierarchy, and packaging.
49
+ * Input arrays are not mutated. Core input/output byte gates, cancellation, awaited writes, and
50
+ * destination finalize/abort handling apply when used through `convertTileset`.
51
+ *
52
+ * @param options - Resolved spatial context and finite nonnegative target-unit precision budget.
53
+ * @returns One GLB and matching metadata per input geometry.
54
+ */
55
+ export declare function createMeshConversionCodec<TInspection = unknown>(options: MeshConversionCodecOptions): TileConversionCodec<TInspection, MeshConversionInput, EncodedMeshConversionResource>;
@@ -0,0 +1,16 @@
1
+ import type { BrowserTileConversionFile } from './browser-sink.js';
2
+ /** Output-size budget for a single-mesh 3TZ archive. */
3
+ export interface SingleMeshTilesetArchiveOptions {
4
+ /** Maximum final archive bytes, including ZIP headers and index; not peak serialization memory. */
5
+ readonly maxArchiveBytes: number;
6
+ }
7
+ /**
8
+ * Packages the two unmodified files from a finalized single-mesh sink as a downloadable 3TZ Blob.
9
+ * The writer checks the complete archive budget before reading either Blob. Applications own
10
+ * object-URL creation/revocation and download UI. Retained input Blobs and transient ZIP buffers
11
+ * are additional memory. SLPK requires separately authored I3S scene-layer resources.
12
+ * @param files - Files returned by a successfully finalized createSingleMeshTilesetSink.
13
+ * @param options - Required final archive-size budget.
14
+ * @returns An indexed 3TZ Blob; save with the .3tz extension.
15
+ */
16
+ export declare function createSingleMeshTilesetArchive(files: readonly BrowserTileConversionFile[], options: SingleMeshTilesetArchiveOptions): Promise<Blob>;
@@ -0,0 +1,31 @@
1
+ import type { TileConversionSink } from './conversion-api.js';
2
+ import type { BrowserTileConversionFile } from './browser-sink.js';
3
+ import type { EncodedMeshConversionResource } from './mesh-conversion.js';
4
+ /** Limits and fidelity policy for one ECEF mesh tileset. */
5
+ export interface SingleMeshTilesetSinkOptions {
6
+ /** Maximum combined UTF-8 tileset JSON and GLB Blob bytes retained by the sink. */
7
+ readonly maxTotalBytes: number;
8
+ /** Explicit geometric error in meters, including source error and position rounding. */
9
+ readonly geometricError: number;
10
+ }
11
+ /** A single-tile output package retained as two named browser-native Blobs. */
12
+ export interface SingleMeshTilesetSink extends TileConversionSink<EncodedMeshConversionResource> {
13
+ /** Returns mesh.glb and tileset.json only after successful finalization; empty after abort. */
14
+ getFiles(): readonly BrowserTileConversionFile[];
15
+ }
16
+ /**
17
+ * Packages exactly one `createMeshConversionCodec` output as a 3D Tiles 1.1 tileset.
18
+ *
19
+ * Requires resolved EPSG:4978 output identified by the compact string, with ellipsoidal heights.
20
+ * The tile transform cancels the standard glTF y-up to z-up rotation and adds the ECEF origin.
21
+ * Bounds come from encoded local vertices, avoiding subtraction of large absolute coordinates.
22
+ * Fixed relative names keep the package deterministic. Save both files together or pass them to
23
+ * createSingleMeshTilesetArchive for 3TZ packaging. Applications own downloads, workers, and
24
+ * source-scene extraction.
25
+ * The byte limit bounds retained Blobs, not peak conversion/serialization memory. Input GLB and
26
+ * local bounds must be unmodified codec outputs; this sink does not independently validate GLB.
27
+ *
28
+ * @param options - Required retained-output budget and geometric error in meters.
29
+ * @returns A bounded sink that exposes files on finalization and clears them on abort.
30
+ */
31
+ export declare function createSingleMeshTilesetSink(options: SingleMeshTilesetSinkOptions): SingleMeshTilesetSink;
@@ -0,0 +1,73 @@
1
+ import type { MeshGeometry } from '@loaders.gl/schema';
2
+ /** Explicit glTF wrapping and filtering for the selected base-color image. */
3
+ export interface MeshTileSampler {
4
+ /** Horizontal wrapping: CLAMP_TO_EDGE, MIRRORED_REPEAT, or REPEAT; omitted values use REPEAT. */
5
+ readonly wrapS?: 33071 | 33648 | 10497;
6
+ /** Vertical wrapping: CLAMP_TO_EDGE, MIRRORED_REPEAT, or REPEAT; omitted values use REPEAT. */
7
+ readonly wrapT?: 33071 | 33648 | 10497;
8
+ /** Magnification: NEAREST or LINEAR; omission leaves filtering to the renderer. */
9
+ readonly magFilter?: 9728 | 9729;
10
+ /** Minification: NEAREST, LINEAR, or a glTF mipmap filter; omission leaves filtering to the renderer. */
11
+ readonly minFilter?: 9728 | 9729 | 9984 | 9985 | 9986 | 9987;
12
+ }
13
+ /** Selected KHR_texture_transform controls for TEXCOORD_0. */
14
+ export interface MeshTileTextureTransform {
15
+ /** Finite UV translation; omitted values use [0, 0]. */
16
+ readonly offset?: readonly [number, number];
17
+ /** Finite counterclockwise rotation in radians around the UV origin; omission uses 0. */
18
+ readonly rotation?: number;
19
+ /** Finite UV scale; zero and negative values are allowed, and omission uses [1, 1]. */
20
+ readonly scale?: readonly [number, number];
21
+ }
22
+ /** One already encoded base-color image using TEXCOORD_0. */
23
+ export interface MeshTileTexture {
24
+ /** Encoded PNG/JPEG bytes; a typed array subview selects only its own bytes. */
25
+ readonly data: Uint8Array;
26
+ /** Declared image format, checked against the encoded header. */
27
+ readonly mimeType: 'image/png' | 'image/jpeg';
28
+ /** Optional wrapping/filtering; omission retains glTF's implicit sampler. */
29
+ readonly sampler?: MeshTileSampler;
30
+ /** Optional UV transform, preserved as a required KHR_texture_transform extension. */
31
+ readonly transform?: MeshTileTextureTransform;
32
+ }
33
+ /** One glTF metallic-roughness material, shared by every triangle in the mesh. */
34
+ export interface MeshTileMaterial {
35
+ /** Linear RGBA base-color multiplier; components must be finite in [0, 1]. */
36
+ readonly baseColorFactor?: readonly [number, number, number, number];
37
+ /** Optional embedded image, multiplied by baseColorFactor and COLOR_0; requires TEXCOORD_0. */
38
+ readonly baseColorTexture?: MeshTileTexture;
39
+ /** Metallic weight in [0, 1]; omitted values use the glTF default of 1. */
40
+ readonly metallicFactor?: number;
41
+ /** Roughness weight in [0, 1]; omitted values use the glTF default of 1. */
42
+ readonly roughnessFactor?: number;
43
+ /** Alpha interpretation; omitted values use OPAQUE. */
44
+ readonly alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';
45
+ /** Finite nonnegative threshold, allowed only with MASK; omitted values use 0.5. */
46
+ readonly alphaCutoff?: number;
47
+ /** Whether both sides are rendered; omitted values use false. */
48
+ readonly doubleSided?: boolean;
49
+ }
50
+ /** Optional appearance for the single-mesh GLB profile. */
51
+ export interface MeshTileOptions {
52
+ /** Explicitly selected material; other texture maps and material extensions are unsupported. */
53
+ readonly material?: MeshTileMaterial;
54
+ }
55
+ /**
56
+ * Encodes one triangle mesh as a self-contained glTF 2.0 GLB resource.
57
+ *
58
+ * POSITION and optional NORMAL must contain packed finite Float32 xyz triples. COLOR_0 accepts
59
+ * packed Float32 linear RGB/RGBA in [0, 1] or normalized Uint8/Uint16 colors per vertex.
60
+ * Normals must have unit length within 0.0001. TEXCOORD_0 accepts packed finite Float32
61
+ * or normalized Uint8/Uint16 UV pairs per vertex. Optional indices use packed unsigned
62
+ * 8-, 16-, or 32-bit values.
63
+ * Unsupported attributes, layouts, and encoded transforms fail rather than being discarded.
64
+ * Coordinates are preserved: callers own CRS conversion, local origins, placement, source material mapping,
65
+ * feature mappings, and tileset packaging. Input arrays are never modified.
66
+ *
67
+ * @param mesh - Triangle-list geometry in the caller's selected local coordinate frame.
68
+ * @param options - Optional single material with an already encoded base-color image.
69
+ * @returns An embedded-buffer GLB containing one mesh, node, and default scene.
70
+ */
71
+ export declare function encodeMeshTile(mesh: MeshGeometry, options?: MeshTileOptions): ArrayBuffer;
72
+ /** Validates the shared mesh profile; spatial preparation may retain Float64 positions internally. */
73
+ export declare function validateMeshGeometry(mesh: MeshGeometry, allowFloat64Positions?: boolean): MeshGeometry;
@@ -0,0 +1,31 @@
1
+ import type { PointCloudTilesetSource } from '@loaders.gl/tiles';
2
+ import type { TileConversionProgress, TileConversionReport, TileConversionSink } from './conversion-api.js';
3
+ import type { PointCloudSourceTile } from './point-cloud-source.js';
4
+ import type { EncodedPointCloudSourceTile, EncodePointCloudSourceOptions } from './point-cloud-source-encoder.js';
5
+ /** Point-cloud encoding options and an application-owned output destination. */
6
+ export interface ConvertPointCloudSourceOptions extends EncodePointCloudSourceOptions {
7
+ /** Destination receiving PNTS resources and their source placement metadata. */
8
+ readonly sink: TileConversionSink<EncodedPointCloudSourceTile>;
9
+ /** Input byte accounting for each visited source tile, including tiles with null content. */
10
+ readonly measureInputBytes: (sourceTile: PointCloudSourceTile) => number;
11
+ /** Maximum caller-measured bytes in one decoded source tile, checked before PNTS encoding. */
12
+ readonly maxInputResourceBytes?: number;
13
+ /** Maximum bytes in one encoded PNTS resource. Defaults to no limit. */
14
+ readonly maxOutputResourceBytes?: number;
15
+ /** Receive conversion progress, including resource counts and caller-measured input bytes. */
16
+ readonly onProgress?: (progress: TileConversionProgress) => void;
17
+ }
18
+ /**
19
+ * Converts a point-cloud source to PNTS resources through the v5 output-sink lifecycle.
20
+ *
21
+ * Each write is awaited before reading the next source tile. The destination is finalized only
22
+ * after traversal and writes succeed, and aborted on read, encoding, write, or cancellation errors.
23
+ * Input resource counts include empty tiles; output counts and byte sizes describe emitted PNTS
24
+ * resources. Applications supply input byte accounting because source tiles contain decoded Arrow
25
+ * data rather than transport bytes. The caller retains ownership of the input source.
26
+ *
27
+ * @param source - An I3S, COPC, or compatible point-cloud source to initialize and traverse.
28
+ * @param options - Destination, byte accounting, traversal limits, and per-tile encoding options.
29
+ * @returns The shared v5 conversion report after destination finalization.
30
+ */
31
+ export declare function convertPointCloudSource(source: PointCloudTilesetSource, options: ConvertPointCloudSourceOptions): Promise<TileConversionReport>;
@@ -0,0 +1,49 @@
1
+ import type { PointCloudBoundingVolume, PointCloudCoordinateSystem, PointCloudTilesetSource, TilesetSpatialReference } from '@loaders.gl/tiles';
2
+ import type { EncodePointCloudTileOptions } from './point-cloud.js';
3
+ import type { PointCloudSourceTile, TraversePointCloudSourceOptions } from './point-cloud-source.js';
4
+ /** Traversal and per-tile encoding options for a point-cloud source. */
5
+ export type EncodePointCloudSourceOptions = TraversePointCloudSourceOptions & {
6
+ /** Select encoder options for each source tile with content, using its header and decoded data. */
7
+ readonly getTileEncodingOptions?: (sourceTile: PointCloudSourceTile) => EncodePointCloudTileOptions;
8
+ };
9
+ /** A PNTS resource paired with the source placement metadata needed to package its tile. */
10
+ export type EncodedPointCloudSourceTile = {
11
+ /** Stable source tile identifier. */
12
+ readonly id: string;
13
+ /** Original source hierarchy and bounds. */
14
+ readonly header: PointCloudSourceTile['header'];
15
+ /** Encoded point-cloud tile content. */
16
+ readonly pnts: ArrayBuffer;
17
+ /** Number of point records encoded. */
18
+ readonly pointCount: number;
19
+ /** Coordinate system used by the returned point positions. */
20
+ readonly coordinateSystem: PointCloudCoordinateSystem;
21
+ /** Origin to add to source-relative point positions. */
22
+ readonly cartographicOrigin: readonly number[];
23
+ /** Optional placement transform supplied by the point-cloud source. */
24
+ readonly modelMatrix?: readonly number[];
25
+ /** Optional source or target CRS metadata. */
26
+ readonly spatialReference?: TilesetSpatialReference;
27
+ /** Optional output-frame tile bounds supplied by the source. */
28
+ readonly spatialBoundingVolume?: PointCloudBoundingVolume;
29
+ };
30
+ /**
31
+ * Encodes a point-cloud source as a stream of PNTS resources, one for each non-empty source tile.
32
+ *
33
+ * @param source - An I3S, COPC, or compatible point-cloud tileset source.
34
+ * @param options - Optional traversal depth limit, cancellation signal, and per-tile encoder options.
35
+ * @returns Encoded source tiles in deterministic depth-first order.
36
+ */
37
+ export declare function encodePointCloudSource(source: PointCloudTilesetSource, options?: EncodePointCloudSourceOptions): AsyncIterableIterator<EncodedPointCloudSourceTile>;
38
+ /**
39
+ * Encodes one decoded source tile as PNTS and retains its hierarchy and placement metadata.
40
+ *
41
+ * Positions use the source coordinate system, with an optional RTC center subtracted before float32
42
+ * encoding and stored in the PNTS feature table. Source placement metadata is retained so callers
43
+ * can assemble the output tileset. This function does not transform the source CRS.
44
+ *
45
+ * @param sourceTile - Tile header and decoded Arrow point content from `traversePointCloudSource`.
46
+ * @param options - Optional RTC center, batch-table values, and constant color override.
47
+ * @returns An encoded source tile, or null when the source tile has no content.
48
+ */
49
+ export declare function encodePointCloudSourceTile(sourceTile: PointCloudSourceTile, options?: EncodePointCloudTileOptions): EncodedPointCloudSourceTile | null;
@@ -0,0 +1,25 @@
1
+ import type { PointCloudTileContent, PointCloudTileHeader, PointCloudTilesetSource } from '@loaders.gl/tiles';
2
+ /** A source tile and its decoded point content, including null content when no payload exists. */
3
+ export type PointCloudSourceTile = {
4
+ /** Header with the source tile's hierarchy, bounds, and LOD metadata. */
5
+ readonly header: PointCloudTileHeader;
6
+ /** Arrow point data and its coordinate metadata, or null for an empty tile. */
7
+ readonly content: PointCloudTileContent | null;
8
+ };
9
+ /** Options for camera-independent point-cloud source traversal. */
10
+ export type TraversePointCloudSourceOptions = {
11
+ /** Stop descending after this source tile level. Defaults to the complete hierarchy. */
12
+ readonly maxDepth?: number;
13
+ /** Cancel traversal between source operations. */
14
+ readonly signal?: AbortSignal;
15
+ };
16
+ /**
17
+ * Reads a point-cloud source in deterministic depth-first order, independent of a render camera.
18
+ * Each yielded value retains its tile header and Arrow content metadata so callers can apply the
19
+ * source coordinate frame and placement when encoding output tiles.
20
+ *
21
+ * @param source - An I3S, COPC, or compatible point-cloud tileset source.
22
+ * @param options - Optional depth limit and cancellation signal.
23
+ * @returns One header and decoded payload for each reachable source tile.
24
+ */
25
+ export declare function traversePointCloudSource(source: PointCloudTilesetSource, options?: TraversePointCloudSourceOptions): AsyncIterableIterator<PointCloudSourceTile>;
@@ -0,0 +1,24 @@
1
+ import type { Mesh, MeshArrowTable } from '@loaders.gl/schema';
2
+ /** Options for encoding one Arrow or mesh point batch as a 3D Tiles point tile. */
3
+ export interface EncodePointCloudTileOptions {
4
+ /** Optional origin subtracted from absolute positions and stored as the PNTS RTC_CENTER. */
5
+ readonly rtcCenter?: readonly [number, number, number];
6
+ /** Optional source-wide RGBA color stored as the PNTS CONSTANT_RGBA property. */
7
+ readonly constantRGBA?: readonly number[];
8
+ /** Optional per-point values indexed by the tile's `BATCH_ID` attribute. */
9
+ readonly batchTableJson?: Readonly<Record<string, readonly (string | number)[]>>;
10
+ }
11
+ /**
12
+ * Encodes one mesh or Mesh Arrow point batch as a PNTS resource.
13
+ *
14
+ * The input position field must be named `POSITION` and contain xyz values. `COLOR_0` or `COLOR`
15
+ * is written when present; `constantRGBA` supplies a fallback PNTS `CONSTANT_RGBA` feature-table
16
+ * property. `NORMAL` and `BATCH_ID` are also written when present. Arrow batches should be passed
17
+ * one at a time so callers can bound memory and apply their own tiling and output policy.
18
+ * Unsupported attributes, including a second color attribute, fail instead of being discarded.
19
+ *
20
+ * @param pointBatch - Point data produced by a LAS, COPC, I3S, or other point source.
21
+ * @param options - Optional RTC center and batch-table values.
22
+ * @returns A 3D Tiles PNTS resource.
23
+ */
24
+ export declare function encodePointCloudTile(pointBatch: Mesh | MeshArrowTable, options?: EncodePointCloudTileOptions): ArrayBuffer;
@@ -0,0 +1,58 @@
1
+ import type { TileConversionReport, TileConversionSink } from './conversion-api.js';
2
+ /** Durable record for one successfully written, deterministic output resource. */
3
+ export interface TileResourceManifestEntry {
4
+ /** Stable resource identifier supplied by the output profile. */
5
+ readonly resourceId: string;
6
+ /** Byte length of the output resource. */
7
+ readonly byteLength: number;
8
+ /** Stable caller-computed content fingerprint, such as a SHA-256 digest. */
9
+ readonly fingerprint: string;
10
+ }
11
+ /** Versioned progress record used to resume deterministic output packaging. */
12
+ export interface TileResourceManifest {
13
+ /** Manifest format version. */
14
+ readonly version: 1;
15
+ /** True only after the destination and report have been finalized successfully. */
16
+ readonly complete: boolean;
17
+ /** Resources durably written before interruption or completion. */
18
+ readonly resources: readonly TileResourceManifestEntry[];
19
+ /** Conversion summary saved after successful destination finalization. */
20
+ readonly report?: TileConversionReport;
21
+ }
22
+ /** Application-owned persistence for a conversion manifest. */
23
+ export interface TileResourceManifestStore {
24
+ /** Loads the previous manifest, or returns null when starting a new conversion. */
25
+ load(): Promise<TileResourceManifest | null>;
26
+ /** Atomically replaces the saved manifest with the supplied snapshot. */
27
+ save(manifest: TileResourceManifest): Promise<void>;
28
+ }
29
+ /** Options for decorating a resource sink with restart-safe manifest tracking. */
30
+ export interface ManifestBackedTileConversionSinkOptions<TResource> {
31
+ /** Output destination with deterministic, idempotent resource writes. */
32
+ readonly sink: TileConversionSink<TResource>;
33
+ /** Persistence adapter for snapshots written after each resource. */
34
+ readonly manifestStore: TileResourceManifestStore;
35
+ /** Stable profile-specific path or resource key. */
36
+ readonly getResourceId: (resource: TResource) => string;
37
+ /** Byte length used to detect changed content under an existing resource ID. */
38
+ readonly measureResourceBytes: (resource: TResource) => number;
39
+ /** Stable fingerprint used to detect changed content under an existing resource ID. */
40
+ readonly fingerprintResource: (resource: TResource) => string;
41
+ }
42
+ /**
43
+ * Creates a sink that skips matching checkpointed resources when a process restarts.
44
+ *
45
+ * The destination must write resources idempotently by the ID returned from `getResourceId`.
46
+ * The manifest is persisted after every successful write; the store should replace snapshots
47
+ * atomically. Existing IDs must retain their byte length and fingerprint or the resumed job fails
48
+ * rather than silently mixing output from different conversion inputs. Writes are serialized even
49
+ * when callers issue them concurrently. Reports count resources processed by the current run,
50
+ * including writes skipped because the matching resource was already present. A graceful abort
51
+ * clears the manifest checkpoint before asking the destination to clean partial output, so the
52
+ * next run starts cleanly. A process interruption that does not call `abort` can resume from its
53
+ * last saved checkpoint.
54
+ *
55
+ * @param options - Destination, manifest store, stable IDs, byte measurement, and fingerprinting.
56
+ * @returns A `TileConversionSink` with resumable per-resource progress.
57
+ */
58
+ export declare function createManifestBackedTileConversionSink<TResource>(options: ManifestBackedTileConversionSinkOptions<TResource>): Promise<TileConversionSink<TResource>>;
@@ -0,0 +1,59 @@
1
+ import type { CreateTilesetSpatialReferenceOptions, I3SSpatialBounds, I3STransformedPositions, Tiles3DSpatialBoundingVolume, TilesetSpatialOptions, TilesetSpatialReference } from '@loaders.gl/tiles';
2
+ /** Portable coordinate operations and output metadata for a 3D Tiles conversion. */
3
+ export interface Tiles3DConversionSpatialContext {
4
+ /** Source and selected target CRS, height reference, units, and transformation state. */
5
+ readonly spatialReference: TilesetSpatialReference;
6
+ /** Transform packed absolute xyz positions using double precision output. */
7
+ transformPositions(positions: ArrayLike<number>): Float64Array;
8
+ /** Transform packed normals using the corresponding source positions. */
9
+ transformNormals(normals: ArrayLike<number>, positions: ArrayLike<number>): Float32Array;
10
+ /** Rebuild a conservative bound in the selected target coordinate frame. */
11
+ transformBoundingVolume(volume: Tiles3DSpatialBoundingVolume, sourceTransform?: ArrayLike<number>): Tiles3DSpatialBoundingVolume;
12
+ }
13
+ /** Portable coordinate operations and output metadata for an I3S conversion. */
14
+ export interface I3SConversionSpatialContext {
15
+ /** Source and selected target CRS, height reference, units, and transformation state. */
16
+ readonly spatialReference: TilesetSpatialReference;
17
+ /** Transform absolute I3S positions after applying declared height units and placement. */
18
+ transformPositions(positions: ArrayLike<number>, sourceOrigin: ArrayLike<number>): I3STransformedPositions;
19
+ /** Transform absolute I3S positions when terrain or scene sampling is asynchronous. */
20
+ transformPositionsAsync(positions: ArrayLike<number>, sourceOrigin: ArrayLike<number>): Promise<I3STransformedPositions>;
21
+ /** Transform packed normals using the corresponding source positions. */
22
+ transformNormals(normals: ArrayLike<number>, positions: ArrayLike<number>, normalReferenceFrame?: string): Float32Array;
23
+ /** Rebuild a conservative I3S bound in the selected target frame. */
24
+ transformBoundingVolume(bounds: I3SSpatialBounds): I3SSpatialBounds | {
25
+ box?: number[];
26
+ region?: number[];
27
+ };
28
+ /** Rebuild a bound when terrain or scene sampling is asynchronous. */
29
+ transformBoundingVolumeAsync(bounds: I3SSpatialBounds): Promise<I3SSpatialBounds | {
30
+ box?: number[];
31
+ region?: number[];
32
+ }>;
33
+ }
34
+ /**
35
+ * Creates the shared spatial operations used to write 3D Tiles in a selected CRS and height frame.
36
+ *
37
+ * Source discovery remains format-specific and should use `get3DTilesSpatialReference` or the
38
+ * initialized source's spatial metadata. Target choices on a normalized, transformable reference
39
+ * are retained unless overridden in `options`. Do not reuse a reference already marked
40
+ * `transformed`; that would apply the operation twice. The returned reference is the metadata to
41
+ * publish with transformed output; unresolved requests fail instead of guessing a CRS or height datum.
42
+ *
43
+ * @param discovered - Source CRS, units, coordinate epoch, and height metadata.
44
+ * @param options - Target CRS, height reference, and explicitly supplied geoid resources.
45
+ * @returns Shared position, normal, and bound operations with matching output metadata.
46
+ */
47
+ export declare function createTiles3DConversionSpatialContext(discovered: CreateTilesetSpatialReferenceOptions | TilesetSpatialReference, options?: TilesetSpatialOptions): Tiles3DConversionSpatialContext;
48
+ /**
49
+ * Creates the shared spatial operations used to write I3S in a selected CRS and height frame.
50
+ *
51
+ * I3S height units, vertical datum, elevation placement, and bounds use the same transformer as
52
+ * the source-backed tile runtime. Terrain or scene elevation providers are explicit application
53
+ * inputs and may make position and bound operations asynchronous.
54
+ *
55
+ * @param discovered - Source CRS, vertical units, height reference, and elevation mode.
56
+ * @param options - Target CRS, height reference, geoid, or explicit elevation providers.
57
+ * @returns Shared position, normal, bound, and output-metadata operations.
58
+ */
59
+ export declare function createI3SConversionSpatialContext(discovered: CreateTilesetSpatialReferenceOptions | TilesetSpatialReference, options?: TilesetSpatialOptions): I3SConversionSpatialContext;
@@ -0,0 +1,21 @@
1
+ import type { Tileset3D, TilesetContentTraversalItem, TilesetSourceMetadata, TraverseTilesetContentsOptions } from '@loaders.gl/tiles';
2
+ import type { TileConversionSource } from './conversion-api.js';
3
+ /** Decoded-content lifetime options for source-backed conversion. */
4
+ export type TilesetConversionSourceOptions = Pick<TraverseTilesetContentsOptions, 'unloadContent'>;
5
+ /**
6
+ * Adapts a source-backed tileset to the portable v5 conversion source contract.
7
+ *
8
+ * Inspection waits for initialization and returns the source's normalized metadata. Reading uses
9
+ * camera-independent shared traversal, retaining each placement and its ordered decoded contents.
10
+ * Source adapters own content, subtree, node-page, nested tileset, and archive resolution.
11
+ *
12
+ * Enable `unloadContent` on a dedicated runtime to release newly loaded payloads after the codec
13
+ * and awaited writes finish, or iteration closes on failure. Preloaded payloads remain attached.
14
+ * Applications own tileset destruction, format codecs, byte accounting, and output packaging.
15
+ * This adapter does not impose an aggregate input memory limit or transform coordinates.
16
+ *
17
+ * @param tileset - An initializing or initialized runtime backed by a 3D Tiles or I3S source.
18
+ * @param options - Optional cleanup of content loaded during conversion.
19
+ * @returns A source accepted by `inspectTileset` and `convertTileset`.
20
+ */
21
+ export declare function createTilesetConversionSource(tileset: Tileset3D, options?: TilesetConversionSourceOptions): TileConversionSource<TilesetSourceMetadata, TilesetContentTraversalItem>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/tile-converter",
3
- "version": "5.0.0-alpha.7",
3
+ "version": "5.0.0-alpha.9",
4
4
  "description": "Converter",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,6 +24,16 @@
24
24
  "types": "./dist/index.d.ts",
25
25
  "import": "./dist/index.js",
26
26
  "require": "./dist/index.cjs"
27
+ },
28
+ "./v5": {
29
+ "types": "./dist/v5/index.d.ts",
30
+ "import": "./dist/v5/index.js",
31
+ "require": "./dist/v5/index.cjs"
32
+ },
33
+ "./v5/browser": {
34
+ "types": "./dist/v5/browser.d.ts",
35
+ "import": "./dist/v5/browser.js",
36
+ "require": "./dist/v5/browser.cjs"
27
37
  }
28
38
  },
29
39
  "sideEffects": false,
@@ -45,30 +55,35 @@
45
55
  "process": false
46
56
  },
47
57
  "scripts": {
48
- "pre-build": "npm run build-converter-bundle && npm run build-i3s-server-bundle && npm run copy-certificates",
49
- "build-converter-bundle": "esbuild src/converter-cli.ts --outfile=dist/converter.min.cjs --platform=node --target=esnext,node14 --external:join-images --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\"",
50
- "build-i3s-server-bundle": "esbuild src/i3s-server/bin/www.ts --outfile=dist/i3s-server/bin/i3s-server.min.cjs --platform=node --target=esnext,node14 --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\"",
51
- "copy-certificates": "cp -R src/i3s-server/certs dist/i3s-server"
58
+ "pre-build": "npm run build-package-entrypoints && npm run build-converter-bundle && npm run build-i3s-server-bundle && npm run copy-certificates",
59
+ "build-package-entrypoints": "esbuild src/index.ts --bundle --packages=external --platform=node --format=esm --outfile=dist/index.js && esbuild src/index.ts --bundle --packages=external --platform=node --format=cjs --outfile=dist/index.cjs && esbuild src/v5/index.ts --bundle --packages=external --platform=node --format=esm --outfile=dist/v5/index.js && esbuild src/v5/index.ts --bundle --packages=external --platform=node --format=cjs --outfile=dist/v5/index.cjs && esbuild src/v5/browser.ts --bundle --packages=external --platform=browser --format=esm --outfile=dist/v5/browser.js && esbuild src/v5/browser.ts --bundle --packages=external --platform=browser --format=cjs --outfile=dist/v5/browser.cjs && npm run build-v5-declarations",
60
+ "build-v5-declarations": "tsc --ignoreConfig --declaration --emitDeclarationOnly --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext --rootDir src/v5 --outDir dist/v5 src/v5/index.ts src/v5/browser.ts",
61
+ "build-converter-bundle": "esbuild src/v4/converter-cli.ts --outfile=dist/converter.min.cjs --platform=node --target=esnext,node14 --external:join-images --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\"",
62
+ "build-i3s-server-bundle": "esbuild src/v4/i3s-server/bin/www.ts --outfile=dist/i3s-server/bin/i3s-server.min.cjs --platform=node --target=esnext,node14 --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\"",
63
+ "copy-certificates": "cp -R src/v4/i3s-server/certs dist/i3s-server"
52
64
  },
53
65
  "dependencies": {
54
- "@loaders.gl/3d-tiles": "5.0.0-alpha.7",
55
- "@loaders.gl/compression": "5.0.0-alpha.7",
56
- "@loaders.gl/crypto": "5.0.0-alpha.7",
57
- "@loaders.gl/draco": "5.0.0-alpha.7",
58
- "@loaders.gl/gltf": "5.0.0-alpha.7",
59
- "@loaders.gl/i3s": "5.0.0-alpha.7",
60
- "@loaders.gl/images": "5.0.0-alpha.7",
61
- "@loaders.gl/loader-utils": "5.0.0-alpha.7",
62
- "@loaders.gl/polyfills": "5.0.0-alpha.7",
63
- "@loaders.gl/textures": "5.0.0-alpha.7",
64
- "@loaders.gl/tiles": "5.0.0-alpha.7",
65
- "@loaders.gl/worker-utils": "5.0.0-alpha.7",
66
- "@loaders.gl/zip": "5.0.0-alpha.7",
67
- "@math.gl/core": "5.0.0-alpha.9",
68
- "@math.gl/culling": "5.0.0-alpha.9",
69
- "@math.gl/geoid": "5.0.0-alpha.9",
70
- "@math.gl/geometry-utils": "5.0.0-alpha.9",
71
- "@math.gl/geospatial": "5.0.0-alpha.9",
66
+ "@loaders.gl/3d-tiles": "5.0.0-alpha.9",
67
+ "@loaders.gl/compression": "5.0.0-alpha.9",
68
+ "@loaders.gl/crypto": "5.0.0-alpha.9",
69
+ "@loaders.gl/draco": "5.0.0-alpha.9",
70
+ "@loaders.gl/gltf": "5.0.0-alpha.9",
71
+ "@loaders.gl/i3s": "5.0.0-alpha.9",
72
+ "@loaders.gl/images": "5.0.0-alpha.9",
73
+ "@loaders.gl/loader-utils": "5.0.0-alpha.9",
74
+ "@loaders.gl/polyfills": "5.0.0-alpha.9",
75
+ "@loaders.gl/schema": "5.0.0-alpha.9",
76
+ "@loaders.gl/schema-utils": "5.0.0-alpha.9",
77
+ "@loaders.gl/textures": "5.0.0-alpha.9",
78
+ "@loaders.gl/tiles": "5.0.0-alpha.9",
79
+ "@loaders.gl/worker-utils": "5.0.0-alpha.9",
80
+ "@loaders.gl/zip": "5.0.0-alpha.9",
81
+ "@math.gl/core": "5.0.0-alpha.12",
82
+ "@math.gl/crs": "5.0.0-alpha.12",
83
+ "@math.gl/culling": "5.0.0-alpha.12",
84
+ "@math.gl/geoid": "5.0.0-alpha.12",
85
+ "@math.gl/geometry-utils": "5.0.0-alpha.12",
86
+ "@math.gl/geospatial": "5.0.0-alpha.12",
72
87
  "ajv": "^8.12.0",
73
88
  "archiver": "^5.0.0",
74
89
  "cors": "^2.8.5",
@@ -77,7 +92,6 @@
77
92
  "express": "~4.19.2",
78
93
  "inquirer": "^8.0.0",
79
94
  "json-map-transform": "^1.2.6",
80
- "jszip": "^3.5.0",
81
95
  "md5": "^2.3.0",
82
96
  "morgan": "~1.9.1",
83
97
  "uuid": "^9.0.0"
@@ -88,10 +102,11 @@
88
102
  },
89
103
  "devDependencies": {
90
104
  "@types/express": "^4.17.17",
91
- "@types/inquirer": "^9.0.7"
105
+ "@types/inquirer": "^9.0.7",
106
+ "typescript": "^6.0.3"
92
107
  },
93
108
  "peerDependencies": {
94
109
  "@loaders.gl/core": "~5.0.0-alpha.0"
95
110
  },
96
- "gitHead": "e1e6174f9e66f4f3e695e8778f769429508342f1"
111
+ "gitHead": "c3be3766791d30e79a9aa1d9b326962f264cbbe7"
97
112
  }
@@ -0,0 +1,5 @@
1
+ # Shared tile-converter code
2
+
3
+ Place code here when it is intentionally shared by multiple converter versions.
4
+ Version-specific implementations belong in `v4/` or `v5/` so their APIs and
5
+ runtime requirements remain independent.
package/src/index.ts CHANGED
@@ -1,2 +1 @@
1
- export {default as I3SConverter} from './i3s-converter/i3s-converter';
2
- export {default as Tiles3DConverter} from './3d-tiles-converter/3d-tiles-converter';
1
+ export * from './v4/index.js';
@@ -14,6 +14,7 @@ import {load, isBrowser} from '@loaders.gl/core';
14
14
  import {I3SLoader, I3SAttributeLoader, COORDINATE_SYSTEM} from '@loaders.gl/i3s';
15
15
  import {Geoid} from '@math.gl/geoid';
16
16
 
17
+ import {validateI3SConversionSpatialReference} from './helpers/validate-i3s-spatial-reference';
17
18
  import {PGMLoader} from '../pgm-loader';
18
19
  import {i3sObbTo3dTilesObb} from './helpers/i3s-obb-to-3d-tiles-obb';
19
20
  import {convertScreenThresholdToGeometricError} from '../lib/utils/lod-conversion-utils';
@@ -134,8 +135,6 @@ export default class Tiles3DConverter {
134
135
  }
135
136
  }
136
137
 
137
- this.progress.startMonitoring();
138
-
139
138
  this.sourceTileset = await loadFromArchive(
140
139
  inputUrl,
141
140
  I3SLoader,
@@ -151,6 +150,18 @@ export default class Tiles3DConverter {
151
150
  return undefined;
152
151
  }
153
152
 
153
+ try {
154
+ validateI3SConversionSpatialReference(this.sourceTileset);
155
+ } catch (error) {
156
+ try {
157
+ await this.slpkFilesystem?.destroy();
158
+ } finally {
159
+ this.slpkFilesystem = null;
160
+ }
161
+ throw error;
162
+ }
163
+ this.progress.startMonitoring();
164
+
154
165
  const rootNode = this.sourceTileset?.root;
155
166
  if (!rootNode.obb) {
156
167
  rootNode.obb = createObbFromMbs(rootNode.mbs);