@loaders.gl/tile-converter 4.3.0-alpha.4 → 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.
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +4 -1
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
- package/dist/converter-cli.js +0 -13
- package/dist/converter.min.cjs +89 -89
- package/dist/deps-installer/deps-installer.js +1 -1
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-index-document.js +6 -14
- package/dist/i3s-converter/helpers/node-pages.d.ts +1 -1
- package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-pages.js +14 -40
- package/dist/i3s-converter/i3s-converter.d.ts +24 -23
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +60 -130
- package/dist/i3s-server/app.d.ts +2 -1
- package/dist/i3s-server/app.d.ts.map +1 -1
- package/dist/i3s-server/app.js +7 -10
- package/dist/i3s-server/bin/i3s-server.min.cjs +71 -71
- package/dist/i3s-server/bin/www.js +5 -0
- package/dist/index.cjs +82 -194
- package/dist/index.cjs.map +2 -2
- package/dist/lib/utils/statistic-utills.d.ts +4 -1
- package/dist/lib/utils/statistic-utills.d.ts.map +1 -1
- package/dist/lib/utils/statistic-utills.js +4 -23
- package/dist/pgm-loader.js +1 -1
- package/package.json +19 -20
- package/src/3d-tiles-converter/3d-tiles-converter.ts +2 -1
- package/src/converter-cli.ts +0 -19
- package/src/i3s-converter/helpers/node-index-document.ts +16 -26
- package/src/i3s-converter/helpers/node-pages.ts +20 -46
- package/src/i3s-converter/i3s-converter.ts +88 -154
- package/src/i3s-server/app.ts +7 -10
- package/src/i3s-server/bin/www.ts +6 -0
- package/src/lib/utils/statistic-utills.ts +5 -27
- package/bin/slpk-extractor.js +0 -2
- package/dist/i3s-server/controllers/index-controller.d.ts +0 -8
- package/dist/i3s-server/controllers/index-controller.d.ts.map +0 -1
- package/dist/i3s-server/controllers/index-controller.js +0 -31
- package/dist/i3s-server/routes/index.d.ts +0 -2
- package/dist/i3s-server/routes/index.d.ts.map +0 -1
- package/dist/i3s-server/routes/index.js +0 -17
- package/dist/slpk-extractor/slpk-extractor.d.ts +0 -23
- package/dist/slpk-extractor/slpk-extractor.d.ts.map +0 -1
- package/dist/slpk-extractor/slpk-extractor.js +0 -73
- package/dist/slpk-extractor-cli.d.ts +0 -17
- package/dist/slpk-extractor-cli.d.ts.map +0 -1
- package/dist/slpk-extractor-cli.js +0 -105
- package/dist/slpk-extractor.min.cjs +0 -344
- package/src/i3s-server/controllers/index-controller.ts +0 -32
- package/src/i3s-server/routes/index.ts +0 -18
- package/src/slpk-extractor/slpk-extractor.ts +0 -102
- 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:
|
|
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,26 +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
|
-
noEgm?: boolean;
|
|
207
|
-
}): Promise<string> {
|
|
206
|
+
async convert(options: ConverterProps): Promise<string> {
|
|
208
207
|
if (isBrowser) {
|
|
209
208
|
console.log(BROWSER_ERROR_MESSAGE); // eslint-disable-line no-console
|
|
210
209
|
return BROWSER_ERROR_MESSAGE;
|
|
@@ -212,13 +211,11 @@ export default class I3SConverter {
|
|
|
212
211
|
this.conversionStartTime = process.hrtime();
|
|
213
212
|
const {
|
|
214
213
|
tilesetName,
|
|
215
|
-
slpk,
|
|
216
214
|
egmFilePath,
|
|
217
215
|
inputUrl,
|
|
218
216
|
validate,
|
|
219
217
|
outputPath,
|
|
220
218
|
draco = true,
|
|
221
|
-
sevenZipExe,
|
|
222
219
|
maxDepth,
|
|
223
220
|
token,
|
|
224
221
|
generateTextures,
|
|
@@ -234,8 +231,6 @@ export default class I3SConverter {
|
|
|
234
231
|
outputPath,
|
|
235
232
|
tilesetName,
|
|
236
233
|
maxDepth,
|
|
237
|
-
slpk,
|
|
238
|
-
sevenZipExe,
|
|
239
234
|
egmFilePath,
|
|
240
235
|
draco,
|
|
241
236
|
token,
|
|
@@ -263,9 +258,7 @@ export default class I3SConverter {
|
|
|
263
258
|
console.log('Loading egm file completed!'); // eslint-disable-line
|
|
264
259
|
}
|
|
265
260
|
|
|
266
|
-
|
|
267
|
-
this.nodePages.useWriteFunction(writeFileForSlpk);
|
|
268
|
-
}
|
|
261
|
+
this.nodePages.useWriteFunction(writeFileForSlpk);
|
|
269
262
|
|
|
270
263
|
try {
|
|
271
264
|
const preloadOptions = await this._fetchPreloadOptions();
|
|
@@ -285,7 +278,7 @@ export default class I3SConverter {
|
|
|
285
278
|
const selectMetadataClassResult = await this.selectMetadataClass();
|
|
286
279
|
if (selectMetadataClassResult) {
|
|
287
280
|
await this._createAndSaveTileset(outputPath, tilesetName);
|
|
288
|
-
await this._finishConversion({
|
|
281
|
+
await this._finishConversion({outputPath, tilesetName});
|
|
289
282
|
}
|
|
290
283
|
}
|
|
291
284
|
} catch (error) {
|
|
@@ -596,17 +589,11 @@ export default class I3SConverter {
|
|
|
596
589
|
* Write 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md in file
|
|
597
590
|
*/
|
|
598
591
|
private async _writeLayers0(): Promise<void> {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
});
|
|
605
|
-
} else {
|
|
606
|
-
await this.writeQueue.enqueue({
|
|
607
|
-
writePromise: () => writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
608
|
-
});
|
|
609
|
-
}
|
|
592
|
+
await this.writeQueue.enqueue({
|
|
593
|
+
archiveKey: '3dSceneLayer.json.gz',
|
|
594
|
+
writePromise: () =>
|
|
595
|
+
writeFileForSlpk(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
|
|
596
|
+
});
|
|
610
597
|
}
|
|
611
598
|
|
|
612
599
|
/**
|
|
@@ -615,20 +602,18 @@ export default class I3SConverter {
|
|
|
615
602
|
*/
|
|
616
603
|
private async _createSlpk(tilesetPath: string): Promise<void> {
|
|
617
604
|
await this.conversionDump.deleteDumpFile();
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
// do nothing
|
|
631
|
-
}
|
|
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
|
|
632
617
|
}
|
|
633
618
|
}
|
|
634
619
|
|
|
@@ -977,9 +962,9 @@ export default class I3SConverter {
|
|
|
977
962
|
propertyTable,
|
|
978
963
|
featuresHashArray: this.featuresHashArray,
|
|
979
964
|
attributeStorageInfo: this.attributeMetadataInfo.attributeStorageInfo,
|
|
980
|
-
draco: this.options.draco,
|
|
965
|
+
draco: this.options.draco ?? false,
|
|
981
966
|
generateBoundingVolumes: this.generateBoundingVolumes,
|
|
982
|
-
shouldMergeMaterials: this.options.mergeMaterials,
|
|
967
|
+
shouldMergeMaterials: this.options.mergeMaterials ?? false,
|
|
983
968
|
geoidHeightModel: this.geoidHeightModel,
|
|
984
969
|
libraries: this.loadOptions.modules as Record<string, string>,
|
|
985
970
|
metadataClass: this.options.metadataClass
|
|
@@ -1166,47 +1151,27 @@ export default class I3SConverter {
|
|
|
1166
1151
|
|
|
1167
1152
|
this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.GEOMETRY, false);
|
|
1168
1153
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
});
|
|
1178
|
-
} else {
|
|
1179
|
-
const geometryPath = join(childPath, 'geometries/0/');
|
|
1180
|
-
await this.writeQueue.enqueue({
|
|
1181
|
-
sourceId,
|
|
1182
|
-
outputId: nodeId,
|
|
1183
|
-
resourceType: ResourceType.GEOMETRY,
|
|
1184
|
-
writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
1185
|
-
});
|
|
1186
|
-
}
|
|
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
|
+
});
|
|
1187
1162
|
|
|
1188
1163
|
if (this.options.draco && compressedGeometry) {
|
|
1189
1164
|
this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.DRACO_GEOMETRY, false);
|
|
1190
1165
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
});
|
|
1201
|
-
} else {
|
|
1202
|
-
const compressedGeometryPath = join(childPath, 'geometries/1/');
|
|
1203
|
-
await this.writeQueue.enqueue({
|
|
1204
|
-
sourceId,
|
|
1205
|
-
outputId: nodeId,
|
|
1206
|
-
resourceType: ResourceType.DRACO_GEOMETRY,
|
|
1207
|
-
writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
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
|
+
});
|
|
1210
1175
|
}
|
|
1211
1176
|
}
|
|
1212
1177
|
|
|
@@ -1241,24 +1206,14 @@ export default class I3SConverter {
|
|
|
1241
1206
|
const sharedData = transform(sharedResources, sharedResourcesTemplate());
|
|
1242
1207
|
const sharedDataStr = JSON.stringify(sharedData);
|
|
1243
1208
|
this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.SHARED, false);
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
});
|
|
1253
|
-
} else {
|
|
1254
|
-
const sharedPath = join(childPath, 'shared/');
|
|
1255
|
-
await this.writeQueue.enqueue({
|
|
1256
|
-
sourceId,
|
|
1257
|
-
outputId: nodeId,
|
|
1258
|
-
resourceType: ResourceType.SHARED,
|
|
1259
|
-
writePromise: () => writeFile(sharedPath, sharedDataStr)
|
|
1260
|
-
});
|
|
1261
|
-
}
|
|
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
|
+
});
|
|
1262
1217
|
}
|
|
1263
1218
|
|
|
1264
1219
|
/**
|
|
@@ -1423,27 +1378,17 @@ export default class I3SConverter {
|
|
|
1423
1378
|
sourceId: string;
|
|
1424
1379
|
nodeId: number;
|
|
1425
1380
|
}): Promise<void> {
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
});
|
|
1438
|
-
} else {
|
|
1439
|
-
const texturePath = join(childPath, `textures/${name}/`);
|
|
1440
|
-
await this.writeQueue.enqueue({
|
|
1441
|
-
sourceId,
|
|
1442
|
-
outputId: nodeId,
|
|
1443
|
-
resourceType: `${ResourceType.TEXTURE}/${format}`,
|
|
1444
|
-
writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
|
|
1445
|
-
});
|
|
1446
|
-
}
|
|
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
|
+
});
|
|
1447
1392
|
}
|
|
1448
1393
|
|
|
1449
1394
|
/**
|
|
@@ -1476,24 +1421,14 @@ export default class I3SConverter {
|
|
|
1476
1421
|
`${ResourceType.ATTRIBUTES}/${folderName}`,
|
|
1477
1422
|
false
|
|
1478
1423
|
);
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
});
|
|
1488
|
-
} else {
|
|
1489
|
-
const attributesPath = join(childPath, `attributes/${folderName}/0`);
|
|
1490
|
-
await this.writeQueue.enqueue({
|
|
1491
|
-
sourceId,
|
|
1492
|
-
outputId: nodeId,
|
|
1493
|
-
resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
|
|
1494
|
-
writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
1495
|
-
});
|
|
1496
|
-
}
|
|
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
|
+
});
|
|
1497
1432
|
}
|
|
1498
1433
|
}
|
|
1499
1434
|
}
|
|
@@ -1586,7 +1521,6 @@ export default class I3SConverter {
|
|
|
1586
1521
|
* @param params - output files data
|
|
1587
1522
|
*/
|
|
1588
1523
|
private async _finishConversion(params: {
|
|
1589
|
-
slpk: boolean;
|
|
1590
1524
|
outputPath: string;
|
|
1591
1525
|
tilesetName: string;
|
|
1592
1526
|
}): Promise<void> {
|
|
@@ -1616,7 +1550,7 @@ export default class I3SConverter {
|
|
|
1616
1550
|
const options = {
|
|
1617
1551
|
'cesium-ion': {accessToken: this.options.token || ION_DEFAULT_TOKEN}
|
|
1618
1552
|
};
|
|
1619
|
-
const preloadOptions = await this.Loader.preload(this.options.inputUrl, options);
|
|
1553
|
+
const preloadOptions = await this.Loader.preload(this.options.inputUrl ?? '', options);
|
|
1620
1554
|
this.refreshTokenTime = process.hrtime();
|
|
1621
1555
|
return {...options, ...preloadOptions};
|
|
1622
1556
|
}
|
package/src/i3s-server/app.ts
CHANGED
|
@@ -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
|
|
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
|
|
|
@@ -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 {
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
}
|
package/bin/slpk-extractor.js
DELETED
|
@@ -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 +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"}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { isBrowser } from '@loaders.gl/core';
|
|
2
|
-
import { BROWSER_ERROR_MESSAGE } from "../constants.js";
|
|
3
|
-
import { path } from '@loaders.gl/loader-utils';
|
|
4
|
-
import { FileHandleFile } from '@loaders.gl/loader-utils';
|
|
5
|
-
import { parseZipLocalFileHeader } from '@loaders.gl/zip';
|
|
6
|
-
import { GZipCompression } from '@loaders.gl/compression';
|
|
7
|
-
import { writeFile } from "../lib/utils/file-utils.js";
|
|
8
|
-
const indexNames = [
|
|
9
|
-
'3dSceneLayer.json.gz',
|
|
10
|
-
'3dNodeIndexDocument.json.gz',
|
|
11
|
-
'sharedResource.json.gz'
|
|
12
|
-
];
|
|
13
|
-
/**
|
|
14
|
-
* Converter from slpk to i3s
|
|
15
|
-
*/
|
|
16
|
-
export default class SLPKExtractor {
|
|
17
|
-
/**
|
|
18
|
-
* Extract slpk to i3s
|
|
19
|
-
* @param options
|
|
20
|
-
* @param options.inputUrl the url to read SLPK file
|
|
21
|
-
* @param options.outputPath the output filename
|
|
22
|
-
*/
|
|
23
|
-
async extract(options) {
|
|
24
|
-
if (isBrowser) {
|
|
25
|
-
// eslint-disable-next-line no-console
|
|
26
|
-
console.log(BROWSER_ERROR_MESSAGE);
|
|
27
|
-
return BROWSER_ERROR_MESSAGE;
|
|
28
|
-
}
|
|
29
|
-
const { inputUrl } = options;
|
|
30
|
-
const provider = new FileHandleFile(inputUrl);
|
|
31
|
-
let localHeader = await parseZipLocalFileHeader(0n, provider);
|
|
32
|
-
while (localHeader) {
|
|
33
|
-
await this.writeFile(await this.unGzip({
|
|
34
|
-
name: this.correctIndexNames(localHeader.fileName),
|
|
35
|
-
data: await provider.slice(localHeader.fileDataOffset, localHeader.fileDataOffset + localHeader.compressedSize)
|
|
36
|
-
}), options.outputPath);
|
|
37
|
-
localHeader = await parseZipLocalFileHeader(localHeader.fileDataOffset + localHeader?.compressedSize, provider);
|
|
38
|
-
}
|
|
39
|
-
return 'success';
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Defines file name and path for i3s format
|
|
43
|
-
* @param fileName initial file name and path
|
|
44
|
-
*/
|
|
45
|
-
correctIndexNames(fileName) {
|
|
46
|
-
if (indexNames.includes(path.filename(path.join('/', fileName)))) {
|
|
47
|
-
return path.join(path.dirname(fileName), 'index.json.gz');
|
|
48
|
-
}
|
|
49
|
-
// finds path with name part and extention part
|
|
50
|
-
const parts = /^(.*\/[^\/\.]*)(\..+)$/.exec(fileName);
|
|
51
|
-
if (!parts) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
return `${parts?.at(1)}/index${parts?.at(2)}`;
|
|
55
|
-
}
|
|
56
|
-
async unGzip(file) {
|
|
57
|
-
if (/\.gz$/.test(file.name ?? '')) {
|
|
58
|
-
const compression = new GZipCompression();
|
|
59
|
-
const decompressedData = await compression.decompress(file.data);
|
|
60
|
-
return { data: decompressedData, name: (file.name ?? '').slice(0, -3) };
|
|
61
|
-
}
|
|
62
|
-
return Promise.resolve(file);
|
|
63
|
-
}
|
|
64
|
-
async writeFile(options, outputPath) {
|
|
65
|
-
if (!options.name) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const finalPath = path.join(outputPath, options.name);
|
|
69
|
-
const dirName = path.dirname(finalPath);
|
|
70
|
-
const fileName = path.filename(finalPath);
|
|
71
|
-
await writeFile(dirName, options.data, fileName);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import '@loaders.gl/polyfills';
|
|
2
|
-
type SLPKExtractionOptions = {
|
|
3
|
-
/** "tileset.json" file (3DTiles) / "http://..../SceneServer/layers/0" resource (I3S) */
|
|
4
|
-
tileset?: string;
|
|
5
|
-
/** Output folder. This folder will be created by converter if doesn't exist. It is relative to the converter path.
|
|
6
|
-
* Default: "data" folder */
|
|
7
|
-
output?: string;
|
|
8
|
-
};
|
|
9
|
-
export type ValidatedSLPKExtractionOptions = SLPKExtractionOptions & {
|
|
10
|
-
/** slpk file */
|
|
11
|
-
tileset: string;
|
|
12
|
-
/** Output folder. This folder will be created by converter if doesn't exist. It is relative to the converter path.
|
|
13
|
-
* Default: "data" folder */
|
|
14
|
-
output: string;
|
|
15
|
-
};
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=slpk-extractor-cli.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slpk-extractor-cli.d.ts","sourceRoot":"","sources":["../src/slpk-extractor-cli.ts"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAC;AAI/B,KAAK,qBAAqB,GAAG;IAC3B,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;gCAC4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAGF,MAAM,MAAM,8BAA8B,GAAG,qBAAqB,GAAG;IACnE,gBAAgB;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB;gCAC4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
|