@loaders.gl/tile-converter 4.2.0-alpha.1 → 4.2.0-alpha.2

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 (38) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +11 -0
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js +77 -27
  4. package/dist/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  5. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts +22 -1
  6. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -1
  7. package/dist/3d-tiles-converter/helpers/load-i3s.js +49 -4
  8. package/dist/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
  9. package/dist/converter-cli.js +2 -1
  10. package/dist/converter-cli.js.map +1 -1
  11. package/dist/converter.min.cjs +137 -130
  12. package/dist/deps-installer/deps-installer.js +1 -1
  13. package/dist/i3s-converter/helpers/load-3d-tiles.d.ts.map +1 -1
  14. package/dist/i3s-converter/helpers/load-3d-tiles.js +22 -2
  15. package/dist/i3s-converter/helpers/load-3d-tiles.js.map +1 -1
  16. package/dist/i3s-server/bin/i3s-server.min.cjs +86 -86
  17. package/dist/index.cjs +530 -66
  18. package/dist/lib/json-schemas/conversion-dump-json-schema.d.ts +463 -0
  19. package/dist/lib/json-schemas/conversion-dump-json-schema.d.ts.map +1 -0
  20. package/dist/lib/json-schemas/conversion-dump-json-schema.js +463 -0
  21. package/dist/lib/json-schemas/conversion-dump-json-schema.js.map +1 -0
  22. package/dist/lib/utils/conversion-dump.d.ts +12 -5
  23. package/dist/lib/utils/conversion-dump.d.ts.map +1 -1
  24. package/dist/lib/utils/conversion-dump.js +44 -24
  25. package/dist/lib/utils/conversion-dump.js.map +1 -1
  26. package/dist/lib/utils/file-utils.d.ts +6 -0
  27. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  28. package/dist/lib/utils/file-utils.js +7 -0
  29. package/dist/lib/utils/file-utils.js.map +1 -1
  30. package/dist/pgm-loader.js +1 -1
  31. package/package.json +15 -14
  32. package/src/3d-tiles-converter/3d-tiles-converter.ts +104 -31
  33. package/src/3d-tiles-converter/helpers/load-i3s.ts +86 -7
  34. package/src/converter-cli.ts +2 -1
  35. package/src/i3s-converter/helpers/load-3d-tiles.ts +52 -2
  36. package/src/lib/json-schemas/conversion-dump-json-schema.ts +285 -0
  37. package/src/lib/utils/conversion-dump.ts +79 -27
  38. package/src/lib/utils/file-utils.ts +13 -0
package/dist/index.cjs CHANGED
@@ -261,7 +261,7 @@ var import_core9 = require("@loaders.gl/core");
261
261
  var import_d_tiles2 = require("@loaders.gl/3d-tiles");
262
262
  var import_path7 = require("path");
263
263
  var import_uuid4 = require("uuid");
264
- var import_process3 = __toESM(require("process"), 1);
264
+ var import_process4 = __toESM(require("process"), 1);
265
265
  var import_json_map_transform8 = __toESM(require("json-map-transform"), 1);
266
266
  var import_md52 = __toESM(require("md5"), 1);
267
267
 
@@ -393,6 +393,13 @@ function removeFile(path) {
393
393
  function getAbsoluteFilePath(filePath) {
394
394
  return (0, import_path.isAbsolute)(filePath) ? filePath : (0, import_path.join)(process.cwd(), filePath);
395
395
  }
396
+ async function renameFile(oldPath, newPath) {
397
+ try {
398
+ await import_fs2.promises.rename(oldPath, newPath);
399
+ } catch (err) {
400
+ console.log("Can't rename file", err);
401
+ }
402
+ }
396
403
 
397
404
  // src/i3s-converter/helpers/node-pages.ts
398
405
  var NodePages = class {
@@ -3559,6 +3566,8 @@ var NodeIndexDocument = class {
3559
3566
  // src/i3s-converter/helpers/load-3d-tiles.ts
3560
3567
  var import_d_tiles = require("@loaders.gl/3d-tiles");
3561
3568
  var import_core7 = require("@loaders.gl/core");
3569
+ var import_loader_utils4 = require("@loaders.gl/loader-utils");
3570
+ var import_zip = require("@loaders.gl/zip");
3562
3571
  var loadNestedTileset = async (sourceTileset, sourceTile, tilesetLoadOptions) => {
3563
3572
  const isTileset = isNestedTileset(sourceTile);
3564
3573
  if (!sourceTileset || !sourceTile.contentUrl || !isTileset) {
@@ -3616,7 +3625,10 @@ async function loadFromArchive(url, loader, loadOptions) {
3616
3625
  }
3617
3626
  if (filename) {
3618
3627
  const tz3Path = `${tz3UrlParts[0]}.3tz`;
3619
- const fileSystem = new import_d_tiles.Tiles3DArchiveFileSystem(tz3Path);
3628
+ const fileProvider = new import_loader_utils4.FileHandleFile(tz3Path);
3629
+ const hashTable = await loadHashTable(fileProvider);
3630
+ const archive = new import_d_tiles.Tiles3DArchive(fileProvider, hashTable, tz3Path);
3631
+ const fileSystem = new import_zip.ZipFileSystem(archive);
3620
3632
  const content = await (0, import_core7.load)(filename, loader, {
3621
3633
  ...loadOptions,
3622
3634
  fetch: fileSystem.fetch.bind(fileSystem)
@@ -3629,6 +3641,27 @@ async function loadFromArchive(url, loader, loadOptions) {
3629
3641
  function isNestedTileset(tile) {
3630
3642
  return (tile == null ? void 0 : tile.type) === "json" || (tile == null ? void 0 : tile.type) === "3tz";
3631
3643
  }
3644
+ async function loadHashTable(fileProvider) {
3645
+ let hashTable;
3646
+ const hashCDOffset = await (0, import_zip.searchFromTheEnd)(fileProvider, import_zip.CD_HEADER_SIGNATURE);
3647
+ const cdFileHeader = await (0, import_zip.parseZipCDFileHeader)(hashCDOffset, fileProvider);
3648
+ if ((cdFileHeader == null ? void 0 : cdFileHeader.fileName) === "@3dtilesIndex1@") {
3649
+ const localFileHeader = await (0, import_zip.parseZipLocalFileHeader)(
3650
+ cdFileHeader.localHeaderOffset,
3651
+ fileProvider
3652
+ );
3653
+ if (!localFileHeader) {
3654
+ throw new Error("corrupted 3tz");
3655
+ }
3656
+ const fileDataOffset = localFileHeader.fileDataOffset;
3657
+ const hashFile = await fileProvider.slice(
3658
+ fileDataOffset,
3659
+ fileDataOffset + localFileHeader.compressedSize
3660
+ );
3661
+ hashTable = (0, import_zip.parseHashTable)(hashFile);
3662
+ }
3663
+ return hashTable;
3664
+ }
3632
3665
 
3633
3666
  // src/i3s-converter/i3s-converter.ts
3634
3667
  var import_core10 = require("@math.gl/core");
@@ -3875,17 +3908,306 @@ var Progress = class {
3875
3908
  };
3876
3909
 
3877
3910
  // src/i3s-converter/i3s-converter.ts
3878
- var import_zip = require("@loaders.gl/zip");
3911
+ var import_zip2 = require("@loaders.gl/zip");
3879
3912
 
3880
3913
  // src/lib/utils/conversion-dump.ts
3881
3914
  var import_util = require("util");
3882
3915
  var import_path6 = require("path");
3916
+ var import_process3 = __toESM(require("process"), 1);
3917
+ var import_ajv = __toESM(require("ajv"), 1);
3918
+
3919
+ // src/lib/json-schemas/conversion-dump-json-schema.ts
3920
+ var dumpJsonSchema = {
3921
+ type: "object",
3922
+ properties: {
3923
+ options: {
3924
+ type: "object",
3925
+ properties: {
3926
+ inputUrl: { type: "string" },
3927
+ outputPath: { type: "string" },
3928
+ tilesetName: { type: "string" },
3929
+ maxDepth: { type: "number" },
3930
+ slpk: { type: "boolean" },
3931
+ egmFilePath: { type: "string" },
3932
+ token: { type: "string" },
3933
+ draco: { type: "boolean" },
3934
+ mergeMaterials: { type: "boolean" },
3935
+ generateTextures: { type: "boolean" },
3936
+ generateBoundingVolumes: { type: "boolean" },
3937
+ metadataClass: { type: "string" },
3938
+ analyze: { type: "boolean" }
3939
+ },
3940
+ required: ["inputUrl", "outputPath", "tilesetName"]
3941
+ },
3942
+ tilesConverted: {
3943
+ type: "object",
3944
+ patternProperties: {
3945
+ ".*": {
3946
+ type: "object",
3947
+ properties: {
3948
+ nodes: {
3949
+ type: "array",
3950
+ items: {
3951
+ type: "object",
3952
+ properties: {
3953
+ nodeId: { type: ["number", "string"] },
3954
+ done: { type: "boolean" },
3955
+ progress: { type: "object", patternProperties: { ".*": { type: "boolean" } } },
3956
+ dumpMetadata: {
3957
+ type: "object",
3958
+ properties: {
3959
+ boundingVolumes: {
3960
+ type: ["object", "null"],
3961
+ properties: {
3962
+ mbs: {
3963
+ type: "array",
3964
+ minItems: 4,
3965
+ maxItems: 4,
3966
+ items: { type: "number" }
3967
+ },
3968
+ obb: {
3969
+ type: "object",
3970
+ properties: {
3971
+ center: {
3972
+ type: "array",
3973
+ minItems: 3,
3974
+ maxItems: 3,
3975
+ items: { type: "number" }
3976
+ },
3977
+ halfSize: {
3978
+ type: "array",
3979
+ minItems: 3,
3980
+ maxItems: 3,
3981
+ items: { type: "number" }
3982
+ },
3983
+ quaternion: {
3984
+ type: "array",
3985
+ minItems: 4,
3986
+ maxItems: 4,
3987
+ items: { type: "number" }
3988
+ }
3989
+ },
3990
+ required: ["center", "halfSize", "quaternion"]
3991
+ }
3992
+ },
3993
+ required: ["mbs", "obb"]
3994
+ },
3995
+ attributesCount: { type: "number" },
3996
+ featureCount: { type: "number" },
3997
+ geometry: { type: "boolean" },
3998
+ hasUvRegions: { type: "boolean" },
3999
+ materialId: { type: "number" },
4000
+ texelCountHint: { type: "number" },
4001
+ vertexCount: { type: "number" }
4002
+ },
4003
+ required: [
4004
+ "boundingVolumes",
4005
+ "featureCount",
4006
+ "geometry",
4007
+ "hasUvRegions",
4008
+ "materialId",
4009
+ "vertexCount"
4010
+ ]
4011
+ }
4012
+ },
4013
+ required: ["nodeId", "done"]
4014
+ }
4015
+ }
4016
+ },
4017
+ required: ["nodes"]
4018
+ }
4019
+ }
4020
+ },
4021
+ textureSetDefinitions: {
4022
+ type: "array",
4023
+ items: {
4024
+ type: "object",
4025
+ properties: {
4026
+ formats: {
4027
+ type: "array",
4028
+ items: {
4029
+ type: "object",
4030
+ properties: {
4031
+ name: { type: "string" },
4032
+ format: { enum: ["jpg", "png", "ktx-etc2", "dds", "ktx2"] }
4033
+ },
4034
+ required: ["name", "format"]
4035
+ }
4036
+ },
4037
+ atlas: { type: "boolean" }
4038
+ },
4039
+ required: ["formats"]
4040
+ }
4041
+ },
4042
+ attributeMetadataInfo: {
4043
+ type: "object",
4044
+ properties: {
4045
+ attributeStorageInfo: {
4046
+ type: "array",
4047
+ items: {
4048
+ type: "object",
4049
+ properties: {
4050
+ key: { type: "string" },
4051
+ name: { type: "string" },
4052
+ header: {
4053
+ type: "array",
4054
+ items: {
4055
+ type: "object",
4056
+ properties: { property: { type: "string" }, valueType: { type: "string" } },
4057
+ required: ["property", "valueType"]
4058
+ }
4059
+ },
4060
+ ordering: { type: "array", items: { type: "string" } },
4061
+ attributeValues: { $ref: "#/$defs/AttributeValue" },
4062
+ attributeByteCounts: { $ref: "#/$defs/AttributeValue" },
4063
+ objectIds: { $ref: "#/$defs/AttributeValue" }
4064
+ },
4065
+ required: ["key", "name", "header"]
4066
+ }
4067
+ },
4068
+ fields: {
4069
+ type: "array",
4070
+ items: {
4071
+ type: "object",
4072
+ properties: {
4073
+ name: { type: "string" },
4074
+ type: { $ref: "#/$defs/ESRIField" },
4075
+ alias: { type: "string" },
4076
+ domain: { $ref: "#/$defs/Domain" }
4077
+ },
4078
+ required: ["name", "type"]
4079
+ }
4080
+ },
4081
+ popupInfo: {
4082
+ type: "object",
4083
+ properties: {
4084
+ title: { type: "string" },
4085
+ description: { type: "string" },
4086
+ expressionInfos: { type: "array", items: {} },
4087
+ fieldInfos: { type: "array", items: { $ref: "#/$defs/FieldInfo" } },
4088
+ mediaInfos: { type: "array", items: {} },
4089
+ popupElements: {
4090
+ type: "array",
4091
+ items: {
4092
+ type: "object",
4093
+ properties: {
4094
+ text: { type: "string" },
4095
+ type: { type: "string" },
4096
+ fieldInfos: { type: "array", items: { $ref: "#/$defs/FieldInfo" } }
4097
+ }
4098
+ }
4099
+ }
4100
+ }
4101
+ }
4102
+ },
4103
+ required: ["attributeStorageInfo", "fields"]
4104
+ },
4105
+ materialDefinitions: {
4106
+ type: "array",
4107
+ items: {
4108
+ type: "object",
4109
+ properties: {
4110
+ pbrMetallicRoughness: {
4111
+ type: "object",
4112
+ properties: {
4113
+ baseColorFactor: {
4114
+ type: "array",
4115
+ minItems: 4,
4116
+ maxItems: 4,
4117
+ items: { type: "number" }
4118
+ },
4119
+ baseColorTexture: { $ref: "#/$defs/I3SMaterialTexture" },
4120
+ metallicFactor: { type: "number" },
4121
+ roughnessFactor: { type: "number" },
4122
+ metallicRoughnessTexture: { $ref: "#/$defs/I3SMaterialTexture" }
4123
+ },
4124
+ required: ["metallicFactor", "roughnessFactor"]
4125
+ },
4126
+ normalTexture: { $ref: "#/$defs/I3SMaterialTexture" },
4127
+ occlusionTexture: { $ref: "#/$defs/I3SMaterialTexture" },
4128
+ emissiveTexture: { $ref: "#/$defs/I3SMaterialTexture" },
4129
+ emissiveFactor: { type: "array", minItems: 3, maxItems: 3, items: { type: "number" } },
4130
+ alphaMode: { enum: ["opaque", "mask", "blend"] },
4131
+ alphaCutoff: { type: "number" },
4132
+ doubleSided: { type: "boolean" },
4133
+ cullFace: { enum: ["none", "front", "back"] }
4134
+ },
4135
+ required: ["pbrMetallicRoughness", "alphaMode"]
4136
+ }
4137
+ }
4138
+ },
4139
+ required: ["options", "tilesConverted"],
4140
+ $defs: {
4141
+ AttributeValue: {
4142
+ type: "object",
4143
+ properties: {
4144
+ valueType: { type: "string" },
4145
+ encoding: { type: "string" },
4146
+ valuesPerElement: { type: "number" }
4147
+ },
4148
+ required: ["valueType"]
4149
+ },
4150
+ ESRIField: {
4151
+ enum: [
4152
+ "esriFieldTypeDate",
4153
+ "esriFieldTypeSingle",
4154
+ "esriFieldTypeDouble",
4155
+ "esriFieldTypeGUID",
4156
+ "esriFieldTypeGlobalID",
4157
+ "esriFieldTypeInteger",
4158
+ "esriFieldTypeOID",
4159
+ "esriFieldTypeSmallInteger",
4160
+ "esriFieldTypeString"
4161
+ ]
4162
+ },
4163
+ Domain: {
4164
+ type: "object",
4165
+ properties: {
4166
+ type: { type: "string" },
4167
+ name: { type: "string" },
4168
+ description: { type: "string" },
4169
+ fieldType: { type: "string" },
4170
+ range: { type: "array", items: { type: "number" } },
4171
+ codedValues: {
4172
+ type: "array",
4173
+ items: {
4174
+ type: "object",
4175
+ properties: { name: { type: "string" }, code: { type: ["string", "number"] } },
4176
+ required: ["name", "code"]
4177
+ }
4178
+ },
4179
+ mergePolicy: { type: "string" },
4180
+ splitPolicy: { type: "string" }
4181
+ },
4182
+ required: ["type", "name"]
4183
+ },
4184
+ FieldInfo: {
4185
+ type: "object",
4186
+ properties: {
4187
+ fieldName: { type: "string" },
4188
+ visible: { type: "boolean" },
4189
+ isEditable: { type: "boolean" },
4190
+ label: { type: "string" }
4191
+ },
4192
+ required: ["fieldName", "visible", "isEditable", "label"]
4193
+ },
4194
+ I3SMaterialTexture: {
4195
+ type: "object",
4196
+ properties: {
4197
+ textureSetDefinitionId: { type: "number" },
4198
+ texCoord: { type: "number" },
4199
+ factor: { type: "number" }
4200
+ },
4201
+ required: ["textureSetDefinitionId"]
4202
+ }
4203
+ }
4204
+ };
4205
+
4206
+ // src/lib/utils/conversion-dump.ts
3883
4207
  var ConversionDump = class {
3884
4208
  constructor() {
3885
4209
  /**Restored/resumed dump indicator */
3886
4210
  this.restored = false;
3887
- /** Array of materials definitions */
3888
- this.materialDefinitions = [];
3889
4211
  this.tilesConverted = {};
3890
4212
  }
3891
4213
  /**
@@ -3929,23 +4251,31 @@ var ConversionDump = class {
3929
4251
  `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
3930
4252
  );
3931
4253
  if (await isFileExists(dumpFilename)) {
3932
- const {
3933
- options,
3934
- tilesConverted,
3935
- textureSetDefinitions,
3936
- attributeMetadataInfo,
3937
- materialDefinitions
3938
- } = await openJson(
3939
- (0, import_path6.join)(this.options.outputPath, this.options.tilesetName),
3940
- `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
3941
- );
3942
- if ((0, import_util.isDeepStrictEqual)(options, JSON.parse(JSON.stringify(this.options)))) {
3943
- this.tilesConverted = tilesConverted;
3944
- this.textureSetDefinitions = textureSetDefinitions;
3945
- this.attributeMetadataInfo = attributeMetadataInfo;
3946
- this.materialDefinitions = materialDefinitions;
3947
- this.restored = true;
3948
- return;
4254
+ try {
4255
+ const dump = await openJson(
4256
+ (0, import_path6.join)(this.options.outputPath, this.options.tilesetName),
4257
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
4258
+ );
4259
+ const {
4260
+ options,
4261
+ tilesConverted,
4262
+ textureSetDefinitions,
4263
+ attributeMetadataInfo,
4264
+ materialDefinitions
4265
+ } = dump;
4266
+ const ajv = new import_ajv.default();
4267
+ const dumpJsonValidate = ajv.compile(dumpJsonSchema);
4268
+ const isDumpValid = dumpJsonValidate(dump);
4269
+ if (isDumpValid && (0, import_util.isDeepStrictEqual)(options, JSON.parse(JSON.stringify(this.options)))) {
4270
+ this.tilesConverted = tilesConverted;
4271
+ this.textureSetDefinitions = textureSetDefinitions;
4272
+ this.attributeMetadataInfo = attributeMetadataInfo;
4273
+ this.materialDefinitions = materialDefinitions;
4274
+ this.restored = true;
4275
+ return;
4276
+ }
4277
+ } catch (error) {
4278
+ console.log("Can't open dump file", error);
3949
4279
  }
3950
4280
  }
3951
4281
  await this.deleteDumpFile();
@@ -3962,8 +4292,8 @@ var ConversionDump = class {
3962
4292
  if (this.attributeMetadataInfo) {
3963
4293
  delete this.attributeMetadataInfo;
3964
4294
  }
3965
- if (this.materialDefinitions.length > 0) {
3966
- this.materialDefinitions = [];
4295
+ if (this.materialDefinitions) {
4296
+ delete this.materialDefinitions;
3967
4297
  }
3968
4298
  }
3969
4299
  /**
@@ -3973,6 +4303,7 @@ var ConversionDump = class {
3973
4303
  var _a2;
3974
4304
  if (((_a2 = this.options) == null ? void 0 : _a2.outputPath) && this.options.tilesetName) {
3975
4305
  try {
4306
+ const time = import_process3.default.hrtime();
3976
4307
  await writeFile(
3977
4308
  (0, import_path6.join)(this.options.outputPath, this.options.tilesetName),
3978
4309
  JSON.stringify({
@@ -3982,7 +4313,19 @@ var ConversionDump = class {
3982
4313
  attributeMetadataInfo: this.attributeMetadataInfo,
3983
4314
  materialDefinitions: this.materialDefinitions
3984
4315
  }),
3985
- `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
4316
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}.${time[0]}.${time[1]}`
4317
+ );
4318
+ await renameFile(
4319
+ (0, import_path6.join)(
4320
+ this.options.outputPath,
4321
+ this.options.tilesetName,
4322
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}.${time[0]}.${time[1]}`
4323
+ ),
4324
+ (0, import_path6.join)(
4325
+ this.options.outputPath,
4326
+ this.options.tilesetName,
4327
+ `${this.options.tilesetName}${DUMP_FILE_SUFFIX}`
4328
+ )
3986
4329
  );
3987
4330
  } catch (error) {
3988
4331
  console.log("Can't update dump file", error);
@@ -4033,7 +4376,7 @@ var ConversionDump = class {
4033
4376
  */
4034
4377
  async addNode(filename, nodeId, dumpMetadata) {
4035
4378
  const { nodes } = this.getRecord(filename) || { nodes: [] };
4036
- nodes.push({ nodeId, done: false, progress: {}, dumpMetadata });
4379
+ nodes.push({ nodeId, done: false, dumpMetadata });
4037
4380
  if (nodes.length === 1) {
4038
4381
  this.setRecord(filename, { nodes });
4039
4382
  }
@@ -4106,6 +4449,22 @@ var ConversionDump = class {
4106
4449
  }
4107
4450
  await this.updateDumpFile();
4108
4451
  }
4452
+ /**
4453
+ * Update 3d-tiles-converter dump file
4454
+ * @param filename - source filename
4455
+ * @param nodeId - nodeId
4456
+ * @param done - conversion status
4457
+ */
4458
+ async updateConvertedNodesDumpFile(filename, nodeId, done) {
4459
+ var _a2;
4460
+ const nodeDump = (_a2 = this.tilesConverted[filename]) == null ? void 0 : _a2.nodes.find(
4461
+ (element) => element.nodeId === nodeId
4462
+ );
4463
+ if (nodeDump) {
4464
+ nodeDump.done = done;
4465
+ await this.updateDumpFile();
4466
+ }
4467
+ }
4109
4468
  /**
4110
4469
  * Check is source file conversion complete
4111
4470
  * @param filename - source filename
@@ -4133,7 +4492,7 @@ var ConversionDump = class {
4133
4492
 
4134
4493
  // src/i3s-converter/i3s-converter.ts
4135
4494
  var _a;
4136
- var ION_DEFAULT_TOKEN = (_a = import_process3.default.env) == null ? void 0 : _a.IonToken;
4495
+ var ION_DEFAULT_TOKEN = (_a = import_process4.default.env) == null ? void 0 : _a.IonToken;
4137
4496
  var HARDCODED_NODES_PER_PAGE = 64;
4138
4497
  var _3D_TILES = "3DTILES";
4139
4498
  var _3D_OBJECT_LAYER_TYPE = "3DObject";
@@ -4214,7 +4573,7 @@ var I3SConverter = class {
4214
4573
  console.log(BROWSER_ERROR_MESSAGE);
4215
4574
  return BROWSER_ERROR_MESSAGE;
4216
4575
  }
4217
- this.conversionStartTime = import_process3.default.hrtime();
4576
+ this.conversionStartTime = import_process4.default.hrtime();
4218
4577
  const {
4219
4578
  tilesetName,
4220
4579
  slpk,
@@ -4549,9 +4908,9 @@ var I3SConverter = class {
4549
4908
  if (this.options.slpk) {
4550
4909
  const slpkTilesetPath = (0, import_path7.join)(tilesetPath, "SceneServer", "layers", "0");
4551
4910
  const slpkFileName = `${tilesetPath}.slpk`;
4552
- await (0, import_zip.createZip)(slpkTilesetPath, slpkFileName, async (fileList) => ({
4911
+ await (0, import_zip2.createZip)(slpkTilesetPath, slpkFileName, async (fileList) => ({
4553
4912
  path: "@specialIndexFileHASH128@",
4554
- file: await (0, import_zip.composeHashFile)(fileList)
4913
+ file: await (0, import_zip2.composeHashFile)(fileList)
4555
4914
  }));
4556
4915
  try {
4557
4916
  await removeDir(tilesetPath);
@@ -5315,7 +5674,7 @@ var I3SConverter = class {
5315
5674
  const { tilesCount, tilesWithAddRefineCount } = this.refinementCounter;
5316
5675
  const addRefinementPercentage = tilesWithAddRefineCount ? tilesWithAddRefineCount / tilesCount * 100 : 0;
5317
5676
  const filesSize = await calculateFilesSize(params);
5318
- const diff = import_process3.default.hrtime(this.conversionStartTime);
5677
+ const diff = import_process4.default.hrtime(this.conversionStartTime);
5319
5678
  const conversionTime = timeConverter(diff);
5320
5679
  console.log(`------------------------------------------------`);
5321
5680
  console.log(`Finishing conversion of ${_3D_TILES}`);
@@ -5336,18 +5695,18 @@ var I3SConverter = class {
5336
5695
  "cesium-ion": { accessToken: this.options.token || ION_DEFAULT_TOKEN }
5337
5696
  };
5338
5697
  const preloadOptions = await this.Loader.preload(this.options.inputUrl, options);
5339
- this.refreshTokenTime = import_process3.default.hrtime();
5698
+ this.refreshTokenTime = import_process4.default.hrtime();
5340
5699
  return { ...options, ...preloadOptions };
5341
5700
  }
5342
5701
  /**
5343
5702
  * Update options of source tileset
5344
5703
  */
5345
5704
  async _updateTilesetOptions() {
5346
- const diff = import_process3.default.hrtime(this.refreshTokenTime);
5705
+ const diff = import_process4.default.hrtime(this.refreshTokenTime);
5347
5706
  if (diff[0] < REFRESH_TOKEN_TIMEOUT) {
5348
5707
  return;
5349
5708
  }
5350
- this.refreshTokenTime = import_process3.default.hrtime();
5709
+ this.refreshTokenTime = import_process4.default.hrtime();
5351
5710
  const preloadOptions = await this._fetchPreloadOptions();
5352
5711
  if (preloadOptions.headers) {
5353
5712
  this.loadOptions.fetch = {
@@ -5380,7 +5739,7 @@ var I3SConverter = class {
5380
5739
 
5381
5740
  // src/3d-tiles-converter/3d-tiles-converter.ts
5382
5741
  var import_path8 = require("path");
5383
- var import_process4 = __toESM(require("process"), 1);
5742
+ var import_process5 = __toESM(require("process"), 1);
5384
5743
  var import_json_map_transform10 = __toESM(require("json-map-transform"), 1);
5385
5744
  var import_core15 = require("@loaders.gl/core");
5386
5745
  var import_i3s2 = require("@loaders.gl/i3s");
@@ -5756,7 +6115,9 @@ var B3dmConverter = class {
5756
6115
  // src/3d-tiles-converter/helpers/load-i3s.ts
5757
6116
  var import_core14 = require("@loaders.gl/core");
5758
6117
  var import_i3s = require("@loaders.gl/i3s");
5759
- var loadI3SContent = async (sourceTileset, sourceTile, tilesetLoadOptions) => {
6118
+ var import_loader_utils5 = require("@loaders.gl/loader-utils");
6119
+ var import_zip3 = require("@loaders.gl/zip");
6120
+ var loadI3SContent = async (sourceTileset, sourceTile, tilesetLoadOptions, slpkFilesystem) => {
5760
6121
  if (!sourceTileset || !sourceTile.contentUrl) {
5761
6122
  return null;
5762
6123
  }
@@ -5764,10 +6125,12 @@ var loadI3SContent = async (sourceTileset, sourceTile, tilesetLoadOptions) => {
5764
6125
  ...tilesetLoadOptions,
5765
6126
  i3s: {
5766
6127
  ...tilesetLoadOptions.i3s,
6128
+ // @ts-expect-error
5767
6129
  isTileset: false,
6130
+ // @ts-expect-error
5768
6131
  isTileHeader: false,
5769
6132
  _tileOptions: {
5770
- attributeUrls: sourceTile.attributeUrls,
6133
+ attributeUrls: sourceTile.attributeUrls || [],
5771
6134
  textureUrl: sourceTile.textureUrl,
5772
6135
  textureFormat: sourceTile.textureFormat,
5773
6136
  textureLoaderOptions: sourceTile.textureLoaderOptions,
@@ -5777,20 +6140,64 @@ var loadI3SContent = async (sourceTileset, sourceTile, tilesetLoadOptions) => {
5777
6140
  },
5778
6141
  _tilesetOptions: {
5779
6142
  store: sourceTileset.store,
6143
+ // @ts-expect-error
5780
6144
  attributeStorageInfo: sourceTileset.attributeStorageInfo,
6145
+ // @ts-expect-error
5781
6146
  fields: sourceTileset.fields
5782
6147
  }
5783
6148
  }
5784
6149
  };
5785
- const tileContent = await (0, import_core14.load)(sourceTile.contentUrl, import_i3s.I3SLoader, loadOptions);
6150
+ const tileContent = await loadFromArchive2(
6151
+ sourceTile.contentUrl,
6152
+ import_i3s.I3SLoader,
6153
+ loadOptions,
6154
+ slpkFilesystem
6155
+ );
5786
6156
  return tileContent;
5787
6157
  };
6158
+ async function openSLPK(url) {
6159
+ const slpkUrlParts = url.split(".slpk");
6160
+ const { slpkFileName } = getSlpkUrlParts(url) || {};
6161
+ if (slpkFileName) {
6162
+ const slpkFileName2 = `${slpkUrlParts[0]}.slpk`;
6163
+ const fileProvider = new import_loader_utils5.FileHandleFile(slpkFileName2);
6164
+ const archive = await (0, import_i3s.parseSLPKArchive)(fileProvider, void 0, slpkFileName2);
6165
+ const fileSystem = new import_zip3.ZipFileSystem(archive);
6166
+ return fileSystem;
6167
+ }
6168
+ return null;
6169
+ }
6170
+ async function loadFromArchive2(url, loader, loadOptions, fileSystem) {
6171
+ const slpkUrlParts = getSlpkUrlParts(url);
6172
+ if (fileSystem !== null && slpkUrlParts !== null) {
6173
+ const { internalFileName } = slpkUrlParts;
6174
+ const content = await (0, import_core14.load)(internalFileName, loader, {
6175
+ ...loadOptions,
6176
+ fetch: fileSystem.fetch.bind(fileSystem)
6177
+ });
6178
+ return content;
6179
+ }
6180
+ return await (0, import_core14.load)(url, loader, loadOptions);
6181
+ }
6182
+ function getSlpkUrlParts(url) {
6183
+ const slpkUrlParts = url.split(".slpk");
6184
+ let result;
6185
+ if (slpkUrlParts.length === 1) {
6186
+ result = null;
6187
+ } else if (slpkUrlParts.length === 2) {
6188
+ result = { slpkFileName: `${slpkUrlParts[0]}.slpk`, internalFileName: slpkUrlParts[1].slice(1) };
6189
+ } else {
6190
+ throw new Error("Unexpected URL format");
6191
+ }
6192
+ return result;
6193
+ }
5788
6194
 
5789
6195
  // src/3d-tiles-converter/3d-tiles-converter.ts
5790
6196
  var I3S = "I3S";
5791
6197
  var Tiles3DConverter = class {
5792
6198
  constructor() {
5793
6199
  this.workerSource = {};
6200
+ this.slpkFilesystem = null;
5794
6201
  this.loaderOptions = {
5795
6202
  _nodeWorkers: true,
5796
6203
  reuseWorkers: true,
@@ -5810,6 +6217,7 @@ var Tiles3DConverter = class {
5810
6217
  this.sourceTileset = null;
5811
6218
  this.attributeStorageInfo = null;
5812
6219
  this.workerSource = {};
6220
+ this.conversionDump = new ConversionDump();
5813
6221
  }
5814
6222
  /**
5815
6223
  * Convert i3s format data to 3dTiles
@@ -5826,13 +6234,23 @@ var Tiles3DConverter = class {
5826
6234
  console.log(BROWSER_ERROR_MESSAGE);
5827
6235
  return BROWSER_ERROR_MESSAGE;
5828
6236
  }
5829
- const { inputUrl, outputPath, tilesetName, maxDepth, egmFilePath } = options;
5830
- this.conversionStartTime = import_process4.default.hrtime();
5831
- this.options = { maxDepth };
6237
+ const { inputUrl, outputPath, tilesetName, maxDepth, egmFilePath, inquirer } = options;
6238
+ this.conversionStartTime = import_process5.default.hrtime();
6239
+ this.options = { maxDepth, inquirer };
5832
6240
  console.log("Loading egm file...");
5833
6241
  this.geoidHeightModel = await (0, import_core15.load)(egmFilePath, PGMLoader);
5834
6242
  console.log("Loading egm file completed!");
5835
- this.sourceTileset = await (0, import_core15.load)(inputUrl, import_i3s2.I3SLoader, this.loaderOptions);
6243
+ this.slpkFilesystem = await openSLPK(inputUrl);
6244
+ this.sourceTileset = await loadFromArchive2(
6245
+ inputUrl,
6246
+ import_i3s2.I3SLoader,
6247
+ {
6248
+ ...this.loaderOptions,
6249
+ // @ts-expect-error `isTileset` can be boolean of 'auto' but TS expects a string
6250
+ i3s: { ...this.loaderOptions.i3s, isTileset: true }
6251
+ },
6252
+ this.slpkFilesystem
6253
+ );
5836
6254
  if (!this.sourceTileset) {
5837
6255
  return;
5838
6256
  }
@@ -5842,9 +6260,24 @@ var Tiles3DConverter = class {
5842
6260
  }
5843
6261
  this.tilesetPath = (0, import_path8.join)(`${outputPath}`, `${tilesetName}`);
5844
6262
  this.attributeStorageInfo = this.sourceTileset.attributeStorageInfo;
5845
- try {
5846
- await removeDir(this.tilesetPath);
5847
- } catch (e) {
6263
+ await this.conversionDump.createDump(options);
6264
+ if (this.conversionDump.restored && this.options.inquirer) {
6265
+ const result = await this.options.inquirer.prompt([
6266
+ {
6267
+ name: "resumeConversion",
6268
+ type: "confirm",
6269
+ message: "Dump file of the previous conversion exists, do you want to resume that conversion?"
6270
+ }
6271
+ ]);
6272
+ if (!result.resumeConversion) {
6273
+ this.conversionDump.reset();
6274
+ }
6275
+ }
6276
+ if (!this.conversionDump.restored) {
6277
+ try {
6278
+ await removeDir(this.tilesetPath);
6279
+ } catch (e) {
6280
+ }
5848
6281
  }
5849
6282
  const rootTile = {
5850
6283
  boundingVolume: {
@@ -5857,7 +6290,11 @@ var Tiles3DConverter = class {
5857
6290
  await this._addChildren(rootNode, rootTile, 1);
5858
6291
  const tileset = (0, import_json_map_transform10.default)({ root: rootTile }, TILESET());
5859
6292
  await writeFile(this.tilesetPath, JSON.stringify(tileset), "tileset.json");
5860
- this._finishConversion({ slpk: false, outputPath, tilesetName });
6293
+ await this.conversionDump.deleteDumpFile();
6294
+ await this._finishConversion({ slpk: false, outputPath, tilesetName });
6295
+ if (this.slpkFilesystem) {
6296
+ this.slpkFilesystem.destroy();
6297
+ }
5861
6298
  const workerFarm = import_worker_utils2.WorkerFarm.getWorkerFarm({});
5862
6299
  workerFarm.destroy();
5863
6300
  }
@@ -5871,7 +6308,18 @@ var Tiles3DConverter = class {
5871
6308
  async convertChildNode(parentSourceNode, parentNode, level, childNodeInfo) {
5872
6309
  const sourceChild = await this._loadChildNode(parentSourceNode, childNodeInfo);
5873
6310
  if (sourceChild.contentUrl) {
5874
- const content = await loadI3SContent(this.sourceTileset, sourceChild, this.loaderOptions);
6311
+ if (this.conversionDump.restored && this.conversionDump.isFileConversionComplete(`${sourceChild.id}.b3dm`) && (sourceChild.obb || sourceChild.mbs)) {
6312
+ const { child: child2 } = this._createChildAndBoundingVolume(sourceChild);
6313
+ parentNode.children.push(child2);
6314
+ await this._addChildren(sourceChild, child2, level + 1);
6315
+ return;
6316
+ }
6317
+ const content = await loadI3SContent(
6318
+ this.sourceTileset,
6319
+ sourceChild,
6320
+ this.loaderOptions,
6321
+ this.slpkFilesystem
6322
+ );
5875
6323
  if (!content) {
5876
6324
  await this._addChildren(sourceChild, parentNode, level + 1);
5877
6325
  return;
@@ -5881,29 +6329,21 @@ var Tiles3DConverter = class {
5881
6329
  if (this.attributeStorageInfo) {
5882
6330
  featureAttributes = await this._loadChildAttributes(sourceChild, this.attributeStorageInfo);
5883
6331
  }
5884
- if (!sourceChild.obb) {
5885
- sourceChild.obb = createObbFromMbs(sourceChild.mbs);
5886
- }
5887
- const boundingVolume = {
5888
- box: i3sObbTo3dTilesObb(sourceChild.obb, this.geoidHeightModel)
5889
- };
5890
- const child = {
5891
- boundingVolume,
5892
- geometricError: convertScreenThresholdToGeometricError(sourceChild),
5893
- children: []
5894
- };
6332
+ const { child, boundingVolume } = this._createChildAndBoundingVolume(sourceChild);
5895
6333
  const i3sAttributesData = {
5896
6334
  tileContent: content,
5897
- box: boundingVolume.box,
6335
+ box: boundingVolume.box || [],
5898
6336
  textureFormat: sourceChild.textureFormat
5899
6337
  };
5900
6338
  const b3dmConverter = new B3dmConverter();
5901
6339
  const b3dm = await b3dmConverter.convert(i3sAttributesData, featureAttributes);
5902
- child.content = {
5903
- uri: `${sourceChild.id}.b3dm`,
5904
- boundingVolume
5905
- };
6340
+ await this.conversionDump.addNode(`${sourceChild.id}.b3dm`, sourceChild.id);
5906
6341
  await writeFile(this.tilesetPath, new Uint8Array(b3dm), `${sourceChild.id}.b3dm`);
6342
+ await this.conversionDump.updateConvertedNodesDumpFile(
6343
+ `${sourceChild.id}.b3dm`,
6344
+ sourceChild.id,
6345
+ true
6346
+ );
5907
6347
  parentNode.children.push(child);
5908
6348
  await this._addChildren(sourceChild, child, level + 1);
5909
6349
  } else {
@@ -5943,15 +6383,39 @@ var Tiles3DConverter = class {
5943
6383
  const options = {
5944
6384
  i3s: {
5945
6385
  ...this.loaderOptions,
6386
+ // @ts-expect-error
5946
6387
  isTileHeader: true,
5947
6388
  loadContent: false
5948
6389
  }
5949
6390
  };
5950
6391
  console.log(`Node conversion: ${nodeUrl}`);
5951
- header = await (0, import_core15.load)(nodeUrl, import_i3s2.I3SLoader, options);
6392
+ header = await loadFromArchive2(nodeUrl, import_i3s2.I3SLoader, options, this.slpkFilesystem);
5952
6393
  }
5953
6394
  return header;
5954
6395
  }
6396
+ /**
6397
+ * Create child and child's boundingVolume for the converted node
6398
+ * @param sourceChild
6399
+ * @returns child and child's boundingVolume
6400
+ */
6401
+ _createChildAndBoundingVolume(sourceChild) {
6402
+ if (!sourceChild.obb) {
6403
+ sourceChild.obb = createObbFromMbs(sourceChild.mbs);
6404
+ }
6405
+ const boundingVolume = {
6406
+ box: i3sObbTo3dTilesObb(sourceChild.obb, this.geoidHeightModel)
6407
+ };
6408
+ const child = {
6409
+ boundingVolume,
6410
+ geometricError: convertScreenThresholdToGeometricError(sourceChild),
6411
+ children: [],
6412
+ content: {
6413
+ uri: `${sourceChild.id}.b3dm`,
6414
+ boundingVolume
6415
+ }
6416
+ };
6417
+ return { boundingVolume, child };
6418
+ }
5955
6419
  /**
5956
6420
  * Make an url of a resource from its relative url having the base url
5957
6421
  * @param baseUrl the base url. A resulting url will be related from this url
@@ -5989,7 +6453,7 @@ var Tiles3DConverter = class {
5989
6453
  attributeName: attribute.name,
5990
6454
  attributeType: this._getAttributeType(attribute)
5991
6455
  };
5992
- promises.push((0, import_core15.load)(inputUrl, import_i3s2.I3SAttributeLoader, options));
6456
+ promises.push(loadFromArchive2(inputUrl, import_i3s2.I3SAttributeLoader, options, this.slpkFilesystem));
5993
6457
  }
5994
6458
  const attributesList = await Promise.all(promises);
5995
6459
  this._replaceNestedArrays(attributesList);
@@ -6028,7 +6492,7 @@ var Tiles3DConverter = class {
6028
6492
  */
6029
6493
  async _finishConversion(params) {
6030
6494
  const filesSize = await calculateFilesSize(params);
6031
- const diff = import_process4.default.hrtime(this.conversionStartTime);
6495
+ const diff = import_process5.default.hrtime(this.conversionStartTime);
6032
6496
  const conversionTime = timeConverter(diff);
6033
6497
  console.log(`------------------------------------------------`);
6034
6498
  console.log(`Finish conversion of ${I3S}`);