@loaders.gl/tile-converter 4.3.0-alpha.3 → 4.3.0-alpha.5

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 (61) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +4 -1
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  3. package/dist/converter-cli.js +6 -14
  4. package/dist/converter.min.cjs +94 -95
  5. package/dist/deps-installer/deps-installer.js +1 -1
  6. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +2 -2
  7. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
  8. package/dist/i3s-converter/helpers/coordinate-converter.js +9 -5
  9. package/dist/i3s-converter/helpers/geometry-converter.d.ts +1 -1
  10. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  11. package/dist/i3s-converter/helpers/geometry-converter.js +4 -2
  12. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  13. package/dist/i3s-converter/helpers/node-index-document.js +6 -14
  14. package/dist/i3s-converter/helpers/node-pages.d.ts +1 -1
  15. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
  16. package/dist/i3s-converter/helpers/node-pages.js +14 -40
  17. package/dist/i3s-converter/i3s-converter.d.ts +24 -22
  18. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  19. package/dist/i3s-converter/i3s-converter.js +67 -132
  20. package/dist/i3s-server/app.d.ts +2 -1
  21. package/dist/i3s-server/app.d.ts.map +1 -1
  22. package/dist/i3s-server/app.js +7 -10
  23. package/dist/i3s-server/bin/i3s-server.min.cjs +71 -71
  24. package/dist/i3s-server/bin/www.js +5 -0
  25. package/dist/i3s-server/routes/slpk-router.js +7 -1
  26. package/dist/index.cjs +98 -200
  27. package/dist/index.cjs.map +2 -2
  28. package/dist/lib/utils/statistic-utills.d.ts +4 -1
  29. package/dist/lib/utils/statistic-utills.d.ts.map +1 -1
  30. package/dist/lib/utils/statistic-utills.js +4 -23
  31. package/dist/pgm-loader.js +1 -1
  32. package/package.json +19 -20
  33. package/src/3d-tiles-converter/3d-tiles-converter.ts +2 -1
  34. package/src/converter-cli.ts +8 -20
  35. package/src/i3s-converter/helpers/coordinate-converter.ts +13 -7
  36. package/src/i3s-converter/helpers/geometry-converter.ts +6 -4
  37. package/src/i3s-converter/helpers/node-index-document.ts +16 -26
  38. package/src/i3s-converter/helpers/node-pages.ts +20 -46
  39. package/src/i3s-converter/i3s-converter.ts +101 -161
  40. package/src/i3s-server/app.ts +7 -10
  41. package/src/i3s-server/bin/www.ts +6 -0
  42. package/src/i3s-server/routes/slpk-router.ts +6 -1
  43. package/src/lib/utils/statistic-utills.ts +5 -27
  44. package/bin/slpk-extractor.js +0 -2
  45. package/dist/i3s-server/controllers/index-controller.d.ts +0 -8
  46. package/dist/i3s-server/controllers/index-controller.d.ts.map +0 -1
  47. package/dist/i3s-server/controllers/index-controller.js +0 -31
  48. package/dist/i3s-server/routes/index.d.ts +0 -2
  49. package/dist/i3s-server/routes/index.d.ts.map +0 -1
  50. package/dist/i3s-server/routes/index.js +0 -17
  51. package/dist/slpk-extractor/slpk-extractor.d.ts +0 -23
  52. package/dist/slpk-extractor/slpk-extractor.d.ts.map +0 -1
  53. package/dist/slpk-extractor/slpk-extractor.js +0 -73
  54. package/dist/slpk-extractor-cli.d.ts +0 -17
  55. package/dist/slpk-extractor-cli.d.ts.map +0 -1
  56. package/dist/slpk-extractor-cli.js +0 -105
  57. package/dist/slpk-extractor.min.cjs +0 -344
  58. package/src/i3s-server/controllers/index-controller.ts +0 -32
  59. package/src/i3s-server/routes/index.ts +0 -18
  60. package/src/slpk-extractor/slpk-extractor.ts +0 -102
  61. package/src/slpk-extractor-cli.ts +0 -136
@@ -80,6 +80,7 @@ import {analyzeTileContent, mergePreprocessData} from './helpers/preprocess-3d-t
80
80
  import {Progress} from './helpers/progress';
81
81
  import {composeHashFile, createZip} from '@loaders.gl/zip';
82
82
  import {ConversionDump, ConversionDumpOptions, DumpMetadata} from '../lib/utils/conversion-dump';
83
+ import {PromptModule} from 'inquirer';
83
84
 
84
85
  const ION_DEFAULT_TOKEN = process.env?.IonToken;
85
86
  const HARDCODED_NODES_PER_PAGE = 64;
@@ -90,13 +91,32 @@ const CESIUM_DATASET_PREFIX = 'https://';
90
91
  // const FS_FILE_TOO_LARGE = 'ERR_FS_FILE_TOO_LARGE';
91
92
  const PROGRESS_PHASE1_COUNT = 'phase1-count';
92
93
 
94
+ type ConverterProps = {
95
+ inputUrl: string;
96
+ outputPath: string;
97
+ tilesetName: string;
98
+ egmFilePath: string;
99
+ maxDepth?: number;
100
+ token?: string;
101
+ draco?: boolean;
102
+ mergeMaterials?: boolean;
103
+ validate?: boolean;
104
+ generateTextures?: boolean;
105
+ generateBoundingVolumes?: boolean;
106
+ instantNodeWriting?: boolean;
107
+ inquirer?: {prompt: PromptModule};
108
+ metadataClass?: string;
109
+ analyze?: boolean;
110
+ noEgm?: boolean;
111
+ };
112
+
93
113
  /**
94
114
  * Converter from 3d-tiles tileset to i3s layer
95
115
  */
96
116
  export default class I3SConverter {
97
117
  attributeMetadataInfo: AttributeMetadataInfo;
98
118
  nodePages: NodePages;
99
- options: any;
119
+ options: Partial<ConverterProps>;
100
120
  layers0Path: string;
101
121
  materialMap: Map<string, number>;
102
122
  materialDefinitions: I3SMaterialDefinition[];
@@ -174,8 +194,6 @@ export default class I3SConverter {
174
194
  * @param options.outputPath the output filename
175
195
  * @param options.tilesetName the output name of the tileset
176
196
  * @param options.maxDepth The max tree depth of conversion
177
- * @param options.slpk Generate slpk (Scene Layer Packages) output file
178
- * @param options.sevenZipExe Location of 7z.exe archiver to create slpk on Windows
179
197
  * @param options.egmFilePath location of *.pgm file to convert heights from ellipsoidal to gravity-related format
180
198
  * @param options.token Token for Cesium ION tilesets authentication
181
199
  * @param options.draco Generate I3S 1.7 draco compressed geometries
@@ -185,25 +203,7 @@ export default class I3SConverter {
185
203
  * @param options.instantNodeWriting - Keep created 3DNodeIndexDocument files on disk instead of memory. This option reduce memory usage but decelerates conversion speed
186
204
  */
187
205
  // eslint-disable-next-line max-statements, complexity
188
- async convert(options: {
189
- inputUrl: string;
190
- outputPath: string;
191
- tilesetName: string;
192
- sevenZipExe: string;
193
- egmFilePath: string;
194
- maxDepth?: number;
195
- slpk?: boolean;
196
- token?: string;
197
- draco?: boolean;
198
- mergeMaterials?: boolean;
199
- validate?: boolean;
200
- generateTextures?: boolean;
201
- generateBoundingVolumes?: boolean;
202
- instantNodeWriting?: boolean;
203
- inquirer?: Promise<unknown>;
204
- metadataClass?: string;
205
- analyze?: boolean;
206
- }): Promise<string> {
206
+ async convert(options: ConverterProps): Promise<string> {
207
207
  if (isBrowser) {
208
208
  console.log(BROWSER_ERROR_MESSAGE); // eslint-disable-line no-console
209
209
  return BROWSER_ERROR_MESSAGE;
@@ -211,13 +211,11 @@ export default class I3SConverter {
211
211
  this.conversionStartTime = process.hrtime();
212
212
  const {
213
213
  tilesetName,
214
- slpk,
215
214
  egmFilePath,
216
215
  inputUrl,
217
216
  validate,
218
217
  outputPath,
219
218
  draco = true,
220
- sevenZipExe,
221
219
  maxDepth,
222
220
  token,
223
221
  generateTextures,
@@ -226,14 +224,13 @@ export default class I3SConverter {
226
224
  mergeMaterials = true,
227
225
  inquirer,
228
226
  metadataClass,
229
- analyze = false
227
+ analyze = false,
228
+ noEgm = false
230
229
  } = options;
231
230
  this.options = {
232
231
  outputPath,
233
232
  tilesetName,
234
233
  maxDepth,
235
- slpk,
236
- sevenZipExe,
237
234
  egmFilePath,
238
235
  draco,
239
236
  token,
@@ -253,14 +250,16 @@ export default class I3SConverter {
253
250
  this.writeQueue = new WriteQueue(this.conversionDump);
254
251
  this.writeQueue.startListening();
255
252
 
256
- console.log('Loading egm file...'); // eslint-disable-line
257
- this.geoidHeightModel = await load(egmFilePath, PGMLoader);
258
- console.log('Loading egm file completed!'); // eslint-disable-line
259
-
260
- if (slpk) {
261
- this.nodePages.useWriteFunction(writeFileForSlpk);
253
+ if (!noEgm) {
254
+ console.log('--no-egm option selected, skip loading egm file'); // eslint-disable-line
255
+ } else {
256
+ console.log('Loading egm file...'); // eslint-disable-line
257
+ this.geoidHeightModel = await load(egmFilePath, PGMLoader);
258
+ console.log('Loading egm file completed!'); // eslint-disable-line
262
259
  }
263
260
 
261
+ this.nodePages.useWriteFunction(writeFileForSlpk);
262
+
264
263
  try {
265
264
  const preloadOptions = await this._fetchPreloadOptions();
266
265
  let tilesetUrl = inputUrl;
@@ -279,7 +278,7 @@ export default class I3SConverter {
279
278
  const selectMetadataClassResult = await this.selectMetadataClass();
280
279
  if (selectMetadataClassResult) {
281
280
  await this._createAndSaveTileset(outputPath, tilesetName);
282
- await this._finishConversion({slpk: Boolean(slpk), outputPath, tilesetName});
281
+ await this._finishConversion({outputPath, tilesetName});
283
282
  }
284
283
  }
285
284
  } catch (error) {
@@ -486,7 +485,7 @@ export default class I3SConverter {
486
485
  this.sourceTileset?.root?.boundingVolume?.region
487
486
  );
488
487
 
489
- const boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel!);
488
+ const boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel);
490
489
 
491
490
  await this.nodePages.push({
492
491
  index: 0,
@@ -590,17 +589,11 @@ export default class I3SConverter {
590
589
  * Write 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md in file
591
590
  */
592
591
  private async _writeLayers0(): Promise<void> {
593
- if (this.options.slpk) {
594
- await this.writeQueue.enqueue({
595
- archiveKey: '3dSceneLayer.json.gz',
596
- writePromise: () =>
597
- writeFileForSlpk(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
598
- });
599
- } else {
600
- await this.writeQueue.enqueue({
601
- writePromise: () => writeFile(this.layers0Path, JSON.stringify(this.layers0))
602
- });
603
- }
592
+ await this.writeQueue.enqueue({
593
+ archiveKey: '3dSceneLayer.json.gz',
594
+ writePromise: () =>
595
+ writeFileForSlpk(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
596
+ });
604
597
  }
605
598
 
606
599
  /**
@@ -609,20 +602,18 @@ export default class I3SConverter {
609
602
  */
610
603
  private async _createSlpk(tilesetPath: string): Promise<void> {
611
604
  await this.conversionDump.deleteDumpFile();
612
- if (this.options.slpk) {
613
- const slpkTilesetPath = join(tilesetPath, 'SceneServer', 'layers', '0');
614
- const slpkFileName = `${tilesetPath}.slpk`;
615
-
616
- await createZip(slpkTilesetPath, slpkFileName, async (fileList) => ({
617
- path: '@specialIndexFileHASH128@',
618
- file: await composeHashFile(fileList)
619
- }));
620
-
621
- try {
622
- await removeDir(tilesetPath);
623
- } catch (e) {
624
- // do nothing
625
- }
605
+ const slpkTilesetPath = join(tilesetPath, 'SceneServer', 'layers', '0');
606
+ const slpkFileName = `${tilesetPath}.slpk`;
607
+
608
+ await createZip(slpkTilesetPath, slpkFileName, async (fileList) => ({
609
+ path: '@specialIndexFileHASH128@',
610
+ file: await composeHashFile(fileList)
611
+ }));
612
+
613
+ try {
614
+ await removeDir(tilesetPath);
615
+ } catch (e) {
616
+ // do nothing
626
617
  }
627
618
  }
628
619
 
@@ -793,7 +784,7 @@ export default class I3SConverter {
793
784
  transformationMatrix,
794
785
  null
795
786
  );
796
- const boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel!);
787
+ const boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel);
797
788
  const nodes: NodeIndexDocument[] = [];
798
789
  for (const convertedNode of this.conversionDump.tilesConverted[sourceTile.id].nodes) {
799
790
  const {node} = await this._generateNodeIndexDocument(
@@ -846,7 +837,7 @@ export default class I3SConverter {
846
837
  transformationMatrix,
847
838
  null
848
839
  );
849
- const boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel!);
840
+ const boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel);
850
841
 
851
842
  const propertyTable = getPropertyTable(tileContent, this.options.metadataClass);
852
843
  this.createAttributeStorageInfo(tileContent, propertyTable);
@@ -971,10 +962,10 @@ export default class I3SConverter {
971
962
  propertyTable,
972
963
  featuresHashArray: this.featuresHashArray,
973
964
  attributeStorageInfo: this.attributeMetadataInfo.attributeStorageInfo,
974
- draco: this.options.draco,
965
+ draco: this.options.draco ?? false,
975
966
  generateBoundingVolumes: this.generateBoundingVolumes,
976
- shouldMergeMaterials: this.options.mergeMaterials,
977
- geoidHeightModel: this.geoidHeightModel!,
967
+ shouldMergeMaterials: this.options.mergeMaterials ?? false,
968
+ geoidHeightModel: this.geoidHeightModel,
978
969
  libraries: this.loadOptions.modules as Record<string, string>,
979
970
  metadataClass: this.options.metadataClass
980
971
  });
@@ -1160,47 +1151,27 @@ export default class I3SConverter {
1160
1151
 
1161
1152
  this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.GEOMETRY, false);
1162
1153
 
1163
- if (this.options.slpk) {
1164
- const slpkGeometryPath = join(childPath, 'geometries');
1165
- await this.writeQueue.enqueue({
1166
- archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
1167
- sourceId,
1168
- outputId: nodeId,
1169
- resourceType: ResourceType.GEOMETRY,
1170
- writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
1171
- });
1172
- } else {
1173
- const geometryPath = join(childPath, 'geometries/0/');
1174
- await this.writeQueue.enqueue({
1175
- sourceId,
1176
- outputId: nodeId,
1177
- resourceType: ResourceType.GEOMETRY,
1178
- writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
1179
- });
1180
- }
1154
+ const slpkGeometryPath = join(childPath, 'geometries');
1155
+ await this.writeQueue.enqueue({
1156
+ archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
1157
+ sourceId,
1158
+ outputId: nodeId,
1159
+ resourceType: ResourceType.GEOMETRY,
1160
+ writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
1161
+ });
1181
1162
 
1182
1163
  if (this.options.draco && compressedGeometry) {
1183
1164
  this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.DRACO_GEOMETRY, false);
1184
1165
 
1185
- if (this.options.slpk) {
1186
- const slpkCompressedGeometryPath = join(childPath, 'geometries');
1187
- await this.writeQueue.enqueue({
1188
- archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
1189
- sourceId,
1190
- outputId: nodeId,
1191
- resourceType: ResourceType.DRACO_GEOMETRY,
1192
- writePromise: () =>
1193
- writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
1194
- });
1195
- } else {
1196
- const compressedGeometryPath = join(childPath, 'geometries/1/');
1197
- await this.writeQueue.enqueue({
1198
- sourceId,
1199
- outputId: nodeId,
1200
- resourceType: ResourceType.DRACO_GEOMETRY,
1201
- writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
1202
- });
1203
- }
1166
+ const slpkCompressedGeometryPath = join(childPath, 'geometries');
1167
+ await this.writeQueue.enqueue({
1168
+ archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
1169
+ sourceId,
1170
+ outputId: nodeId,
1171
+ resourceType: ResourceType.DRACO_GEOMETRY,
1172
+ writePromise: () =>
1173
+ writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
1174
+ });
1204
1175
  }
1205
1176
  }
1206
1177
 
@@ -1235,24 +1206,14 @@ export default class I3SConverter {
1235
1206
  const sharedData = transform(sharedResources, sharedResourcesTemplate());
1236
1207
  const sharedDataStr = JSON.stringify(sharedData);
1237
1208
  this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.SHARED, false);
1238
- if (this.options.slpk) {
1239
- const slpkSharedPath = join(childPath, 'shared');
1240
- await this.writeQueue.enqueue({
1241
- archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
1242
- sourceId,
1243
- outputId: nodeId,
1244
- resourceType: ResourceType.SHARED,
1245
- writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
1246
- });
1247
- } else {
1248
- const sharedPath = join(childPath, 'shared/');
1249
- await this.writeQueue.enqueue({
1250
- sourceId,
1251
- outputId: nodeId,
1252
- resourceType: ResourceType.SHARED,
1253
- writePromise: () => writeFile(sharedPath, sharedDataStr)
1254
- });
1255
- }
1209
+ const slpkSharedPath = join(childPath, 'shared');
1210
+ await this.writeQueue.enqueue({
1211
+ archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
1212
+ sourceId,
1213
+ outputId: nodeId,
1214
+ resourceType: ResourceType.SHARED,
1215
+ writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
1216
+ });
1256
1217
  }
1257
1218
 
1258
1219
  /**
@@ -1417,27 +1378,17 @@ export default class I3SConverter {
1417
1378
  sourceId: string;
1418
1379
  nodeId: number;
1419
1380
  }): Promise<void> {
1420
- if (this.options.slpk) {
1421
- const slpkTexturePath = join(childPath, 'textures');
1422
- const compress = false;
1423
-
1424
- await this.writeQueue.enqueue({
1425
- archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
1426
- sourceId,
1427
- outputId: nodeId,
1428
- resourceType: `${ResourceType.TEXTURE}/${format}`,
1429
- writePromise: () =>
1430
- writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
1431
- });
1432
- } else {
1433
- const texturePath = join(childPath, `textures/${name}/`);
1434
- await this.writeQueue.enqueue({
1435
- sourceId,
1436
- outputId: nodeId,
1437
- resourceType: `${ResourceType.TEXTURE}/${format}`,
1438
- writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
1439
- });
1440
- }
1381
+ const slpkTexturePath = join(childPath, 'textures');
1382
+ const compress = false;
1383
+
1384
+ await this.writeQueue.enqueue({
1385
+ archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
1386
+ sourceId,
1387
+ outputId: nodeId,
1388
+ resourceType: `${ResourceType.TEXTURE}/${format}`,
1389
+ writePromise: () =>
1390
+ writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
1391
+ });
1441
1392
  }
1442
1393
 
1443
1394
  /**
@@ -1470,24 +1421,14 @@ export default class I3SConverter {
1470
1421
  `${ResourceType.ATTRIBUTES}/${folderName}`,
1471
1422
  false
1472
1423
  );
1473
- if (this.options.slpk) {
1474
- const slpkAttributesPath = join(childPath, 'attributes', folderName);
1475
- await this.writeQueue.enqueue({
1476
- archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
1477
- sourceId,
1478
- outputId: nodeId,
1479
- resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
1480
- writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
1481
- });
1482
- } else {
1483
- const attributesPath = join(childPath, `attributes/${folderName}/0`);
1484
- await this.writeQueue.enqueue({
1485
- sourceId,
1486
- outputId: nodeId,
1487
- resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
1488
- writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
1489
- });
1490
- }
1424
+ const slpkAttributesPath = join(childPath, 'attributes', folderName);
1425
+ await this.writeQueue.enqueue({
1426
+ archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
1427
+ sourceId,
1428
+ outputId: nodeId,
1429
+ resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
1430
+ writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
1431
+ });
1491
1432
  }
1492
1433
  }
1493
1434
  }
@@ -1580,7 +1521,6 @@ export default class I3SConverter {
1580
1521
  * @param params - output files data
1581
1522
  */
1582
1523
  private async _finishConversion(params: {
1583
- slpk: boolean;
1584
1524
  outputPath: string;
1585
1525
  tilesetName: string;
1586
1526
  }): Promise<void> {
@@ -1610,7 +1550,7 @@ export default class I3SConverter {
1610
1550
  const options = {
1611
1551
  'cesium-ion': {accessToken: this.options.token || ION_DEFAULT_TOKEN}
1612
1552
  };
1613
- const preloadOptions = await this.Loader.preload(this.options.inputUrl, options);
1553
+ const preloadOptions = await this.Loader.preload(this.options.inputUrl ?? '', options);
1614
1554
  this.refreshTokenTime = process.hrtime();
1615
1555
  return {...options, ...preloadOptions};
1616
1556
  }
@@ -5,7 +5,6 @@ import cors from 'cors';
5
5
  // For local debug
6
6
  // import {fileURLToPath} from 'url';
7
7
  import {loadArchive} from './controllers/slpk-controller';
8
- import {router as indexRouter} from './routes';
9
8
  import {sceneServerRouter, router} from './routes/slpk-router';
10
9
 
11
10
  // For local debug
@@ -15,15 +14,15 @@ import {sceneServerRouter, router} from './routes/slpk-router';
15
14
  const I3S_LAYER_PATH = process.env.I3sLayerPath || ''; // eslint-disable-line no-process-env, no-undef
16
15
  const FULL_LAYER_PATH = path.join(process.cwd(), I3S_LAYER_PATH); // eslint-disable-line no-undef
17
16
 
18
- export const app = express();
19
-
20
- app.use(logger('dev'));
21
- app.use(express.json());
22
- app.use(express.urlencoded({extended: false}));
23
- app.use(express.static(path.join(__dirname, 'public')));
24
- app.use(cors());
17
+ export let app: ReturnType<typeof express> | undefined;
25
18
 
26
19
  if (/\.slpk$/.test(I3S_LAYER_PATH)) {
20
+ app = express();
21
+ app.use(logger('dev'));
22
+ app.use(express.json());
23
+ app.use(express.urlencoded({extended: false}));
24
+ app.use(express.static(path.join(__dirname, 'public')));
25
+ app.use(cors());
27
26
  let filePath = FULL_LAYER_PATH;
28
27
  // Checks if the first character is not a point to indicate absolute path
29
28
  const absolutePath = /^[^.]/.exec(I3S_LAYER_PATH);
@@ -33,6 +32,4 @@ if (/\.slpk$/.test(I3S_LAYER_PATH)) {
33
32
  loadArchive(filePath);
34
33
  app.use('/SceneServer/layers/0', router);
35
34
  app.use('/SceneServer', sceneServerRouter);
36
- } else {
37
- app.use('/', indexRouter);
38
35
  }
@@ -33,6 +33,12 @@ const options = {
33
33
  cert: fs.readFileSync(path.join(__dirname, '../certs/cert.pem'))
34
34
  };
35
35
 
36
+ if (!app) {
37
+ // eslint-disable-next-line no-console
38
+ console.error('This server supports *.slpk files only');
39
+ process.exit(1); // eslint-disable-line no-process-exit
40
+ }
41
+
36
42
  const httpServer = http.createServer(app);
37
43
  const httpsServer = https.createServer(options, app);
38
44
 
@@ -25,7 +25,12 @@ router.get('*', (req, res, next) => {
25
25
  async function routerCallback(req, res, next) {
26
26
  const file = await getFileByUrl(req.path.replace(/\/+$/, ''));
27
27
  if (file) {
28
- res.send(Buffer.from(file));
28
+ try {
29
+ const json = JSON.parse(textDecoder.decode(file));
30
+ res.send(json);
31
+ } catch (e) {
32
+ res.send(Buffer.from(file));
33
+ }
29
34
  } else {
30
35
  res.status(404);
31
36
  res.send('File not found');
@@ -49,38 +49,16 @@ function timeConverterFromSecondsAndMilliseconds(timeInSeconds: number, millisec
49
49
  return result;
50
50
  }
51
51
 
52
- export async function calculateFilesSize(params) {
53
- const {slpk, outputPath, tilesetName} = params;
52
+ export async function calculateFilesSize(params: {outputPath: string; tilesetName: string}) {
53
+ const {outputPath, tilesetName} = params;
54
54
  const fullOutputPath = getAbsoluteFilePath(outputPath);
55
55
 
56
56
  try {
57
- if (slpk) {
58
- const slpkPath = join(fullOutputPath, `${tilesetName}.slpk`);
59
- const stat = await fs.stat(slpkPath);
60
- return stat.size;
61
- }
62
-
63
- const directoryPath = join(fullOutputPath, tilesetName);
64
- const totalSize = await getTotalFilesSize(directoryPath);
65
- return totalSize;
57
+ const slpkPath = join(fullOutputPath, `${tilesetName}.slpk`);
58
+ const stat = await fs.stat(slpkPath);
59
+ return stat.size;
66
60
  } catch (error) {
67
61
  console.log('Calculate file sizes error: ', error); // eslint-disable-line
68
62
  return null;
69
63
  }
70
64
  }
71
-
72
- async function getTotalFilesSize(dirPath) {
73
- let totalFileSize = 0;
74
-
75
- const files = await fs.readdir(dirPath);
76
-
77
- for (const file of files) {
78
- const fileStat = await fs.stat(join(dirPath, file));
79
- if (fileStat.isDirectory()) {
80
- totalFileSize += await getTotalFilesSize(join(dirPath, file));
81
- } else {
82
- totalFileSize += fileStat.size;
83
- }
84
- }
85
- return totalFileSize;
86
- }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import '../dist/slpk-extractor.min.cjs';
@@ -1,8 +0,0 @@
1
- /**
2
- * Get local file name by input HTTP URL
3
- * @param url - I3S HTTP service url
4
- * @param i3sLayerPath - I3S layer path
5
- * @returns - local file name
6
- */
7
- export declare function getFileNameByUrl(url: string, i3sLayerPath?: string): Promise<string | null>;
8
- //# sourceMappingURL=index-controller.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-controller.d.ts","sourceRoot":"","sources":["../../../src/i3s-server/controllers/index-controller.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,SAAK,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoB7F"}
@@ -1,31 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs';
3
- const { promises } = fs;
4
- /**
5
- * Get local file name by input HTTP URL
6
- * @param url - I3S HTTP service url
7
- * @param i3sLayerPath - I3S layer path
8
- * @returns - local file name
9
- */
10
- export async function getFileNameByUrl(url, i3sLayerPath = '') {
11
- i3sLayerPath = i3sLayerPath || process.env.I3sLayerPath || '';
12
- const extensions = ['json', 'bin', 'jpg', 'jpeg', 'png', 'bin.dds', 'ktx2'];
13
- let filePath = process.cwd();
14
- // Checks if the first character is not a point to indicate absolute path
15
- const absolutePath = /^[^.]/.exec(i3sLayerPath);
16
- if (absolutePath) {
17
- filePath = '';
18
- }
19
- const FULL_LAYER_PATH = path.join(filePath, i3sLayerPath, url);
20
- for (const ext of extensions) {
21
- const fileName = `${FULL_LAYER_PATH}/index.${ext}`;
22
- try {
23
- await promises.access(fileName);
24
- return fileName;
25
- }
26
- catch {
27
- continue; // eslint-disable-line no-continue
28
- }
29
- }
30
- return null;
31
- }
@@ -1,2 +0,0 @@
1
- export declare const router: import("express-serve-static-core").Router;
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/i3s-server/routes/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,4CAAmB,CAAC"}
@@ -1,17 +0,0 @@
1
- import express from 'express';
2
- import { getFileNameByUrl } from "../controllers/index-controller.js";
3
- export const router = express.Router();
4
- /* GET home page. */
5
- router.get('*', (req, res, next) => {
6
- async function routerCallback(req, res, next) {
7
- const fileName = await getFileNameByUrl(req.path);
8
- if (fileName) {
9
- res.sendFile(fileName);
10
- }
11
- else {
12
- res.status(404);
13
- res.send('File not found');
14
- }
15
- }
16
- routerCallback(req, res, next);
17
- });
@@ -1,23 +0,0 @@
1
- /**
2
- * Converter from slpk to i3s
3
- */
4
- export default class SLPKExtractor {
5
- /**
6
- * Extract slpk to i3s
7
- * @param options
8
- * @param options.inputUrl the url to read SLPK file
9
- * @param options.outputPath the output filename
10
- */
11
- extract(options: {
12
- inputUrl: string;
13
- outputPath: string;
14
- }): Promise<string>;
15
- /**
16
- * Defines file name and path for i3s format
17
- * @param fileName initial file name and path
18
- */
19
- private correctIndexNames;
20
- private unGzip;
21
- private writeFile;
22
- }
23
- //# sourceMappingURL=slpk-extractor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slpk-extractor.d.ts","sourceRoot":"","sources":["../../src/slpk-extractor/slpk-extractor.ts"],"names":[],"mappings":"AAuBA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC;;;;;OAKG;IACU,OAAO,CAAC,OAAO,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IA+BtF;;;OAGG;IAEH,OAAO,CAAC,iBAAiB;YAYX,MAAM;YAWN,SAAS;CASxB"}