@loaders.gl/tile-converter 4.2.0-alpha.4 → 4.2.0-alpha.6

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 (192) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +4 -4
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js +349 -293
  4. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  5. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +261 -200
  6. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +14 -5
  7. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -1
  8. package/dist/3d-tiles-converter/helpers/load-i3s.js +83 -77
  9. package/dist/3d-tiles-converter/helpers/texture-atlas.js +44 -21
  10. package/dist/3d-tiles-converter/json-templates/tileset.js +32 -33
  11. package/dist/constants.js +0 -1
  12. package/dist/converter-cli.js +257 -234
  13. package/dist/converter.min.cjs +95 -105
  14. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  15. package/dist/deps-installer/deps-installer.js +78 -59
  16. package/dist/i3s-converter/helpers/attribute-metadata-info.js +210 -153
  17. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +1 -1
  18. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
  19. package/dist/i3s-converter/helpers/batch-ids-extensions.js +146 -103
  20. package/dist/i3s-converter/helpers/coordinate-converter.js +100 -65
  21. package/dist/i3s-converter/helpers/create-scene-server-path.js +14 -9
  22. package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -1
  23. package/dist/i3s-converter/helpers/feature-attributes.js +170 -105
  24. package/dist/i3s-converter/helpers/geometry-attributes.d.ts +1 -1
  25. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  26. package/dist/i3s-converter/helpers/geometry-attributes.js +205 -212
  27. package/dist/i3s-converter/helpers/geometry-converter.d.ts +17 -3
  28. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  29. package/dist/i3s-converter/helpers/geometry-converter.js +1189 -830
  30. package/dist/i3s-converter/helpers/gltf-attributes.d.ts +1 -1
  31. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
  32. package/dist/i3s-converter/helpers/gltf-attributes.js +109 -97
  33. package/dist/i3s-converter/helpers/load-3d-tiles.js +103 -66
  34. package/dist/i3s-converter/helpers/node-debug.js +98 -54
  35. package/dist/i3s-converter/helpers/node-index-document.d.ts +11 -4
  36. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  37. package/dist/i3s-converter/helpers/node-index-document.js +255 -177
  38. package/dist/i3s-converter/helpers/node-pages.d.ts +1 -1
  39. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
  40. package/dist/i3s-converter/helpers/node-pages.js +299 -193
  41. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts +1 -1
  42. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -1
  43. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +92 -60
  44. package/dist/i3s-converter/helpers/progress.d.ts.map +1 -1
  45. package/dist/i3s-converter/helpers/progress.js +139 -83
  46. package/dist/i3s-converter/helpers/tileset-traversal.d.ts +9 -2
  47. package/dist/i3s-converter/helpers/tileset-traversal.d.ts.map +1 -1
  48. package/dist/i3s-converter/helpers/tileset-traversal.js +33 -13
  49. package/dist/i3s-converter/i3s-converter.d.ts +7 -7
  50. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  51. package/dist/i3s-converter/i3s-converter.js +1165 -895
  52. package/dist/i3s-converter/json-templates/geometry-definitions.js +70 -79
  53. package/dist/i3s-converter/json-templates/layers.js +120 -121
  54. package/dist/i3s-converter/json-templates/metadata.js +19 -20
  55. package/dist/i3s-converter/json-templates/node.js +73 -71
  56. package/dist/i3s-converter/json-templates/scene-server.js +25 -26
  57. package/dist/i3s-converter/json-templates/shared-resources.js +107 -108
  58. package/dist/i3s-converter/json-templates/store.js +96 -94
  59. package/dist/i3s-converter/types.js +35 -23
  60. package/dist/i3s-server/app.js +15 -12
  61. package/dist/i3s-server/bin/i3s-server.min.cjs +69 -69
  62. package/dist/i3s-server/bin/www.js +16 -7
  63. package/dist/i3s-server/controllers/index-controller.js +18 -15
  64. package/dist/i3s-server/controllers/slpk-controller.d.ts.map +1 -1
  65. package/dist/i3s-server/controllers/slpk-controller.js +24 -11
  66. package/dist/i3s-server/routes/index.js +13 -9
  67. package/dist/i3s-server/routes/slpk-router.d.ts.map +1 -1
  68. package/dist/i3s-server/routes/slpk-router.js +26 -19
  69. package/dist/i3s-server/utils/create-scene-server.js +15 -10
  70. package/dist/i3s-server/utils/server-utils.d.ts.map +1 -1
  71. package/dist/i3s-server/utils/server-utils.js +52 -32
  72. package/dist/index.cjs +616 -967
  73. package/dist/index.cjs.map +7 -0
  74. package/dist/index.d.ts +2 -2
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +0 -1
  77. package/dist/lib/json-schemas/conversion-dump-json-schema.js +243 -421
  78. package/dist/lib/utils/cli-utils.d.ts.map +1 -1
  79. package/dist/lib/utils/cli-utils.js +65 -36
  80. package/dist/lib/utils/compress-util.js +20 -15
  81. package/dist/lib/utils/conversion-dump.d.ts +10 -2
  82. package/dist/lib/utils/conversion-dump.d.ts.map +1 -1
  83. package/dist/lib/utils/conversion-dump.js +242 -197
  84. package/dist/lib/utils/file-utils.d.ts +1 -1
  85. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  86. package/dist/lib/utils/file-utils.js +120 -74
  87. package/dist/lib/utils/geometry-utils.js +13 -7
  88. package/dist/lib/utils/lod-conversion-utils.js +65 -33
  89. package/dist/lib/utils/queue.js +12 -13
  90. package/dist/lib/utils/statistic-utills.d.ts +6 -23
  91. package/dist/lib/utils/statistic-utills.d.ts.map +1 -1
  92. package/dist/lib/utils/statistic-utills.js +58 -55
  93. package/dist/lib/utils/write-queue.d.ts +2 -2
  94. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  95. package/dist/lib/utils/write-queue.js +72 -86
  96. package/dist/pgm-loader.js +17 -13
  97. package/dist/slpk-extractor/slpk-extractor.d.ts.map +1 -1
  98. package/dist/slpk-extractor/slpk-extractor.js +60 -50
  99. package/dist/slpk-extractor-cli.d.ts.map +1 -1
  100. package/dist/slpk-extractor-cli.js +90 -59
  101. package/dist/slpk-extractor.min.cjs +1 -1
  102. package/package.json +27 -26
  103. package/src/3d-tiles-converter/3d-tiles-converter.ts +21 -10
  104. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +1 -0
  105. package/src/3d-tiles-converter/helpers/load-i3s.ts +3 -27
  106. package/src/converter-cli.ts +4 -2
  107. package/src/deps-installer/deps-installer.ts +7 -0
  108. package/src/i3s-converter/helpers/attribute-metadata-info.ts +1 -1
  109. package/src/i3s-converter/helpers/batch-ids-extensions.ts +3 -1
  110. package/src/i3s-converter/helpers/coordinate-converter.ts +2 -2
  111. package/src/i3s-converter/helpers/feature-attributes.ts +5 -2
  112. package/src/i3s-converter/helpers/geometry-attributes.ts +6 -5
  113. package/src/i3s-converter/helpers/geometry-converter.ts +118 -72
  114. package/src/i3s-converter/helpers/gltf-attributes.ts +12 -13
  115. package/src/i3s-converter/helpers/node-index-document.ts +18 -10
  116. package/src/i3s-converter/helpers/node-pages.ts +27 -29
  117. package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +1 -0
  118. package/src/i3s-converter/helpers/progress.ts +1 -0
  119. package/src/i3s-converter/helpers/tileset-traversal.ts +22 -13
  120. package/src/i3s-converter/i3s-converter.ts +173 -114
  121. package/src/i3s-converter/json-templates/node.ts +1 -1
  122. package/src/i3s-server/bin/www.ts +6 -4
  123. package/src/i3s-server/controllers/slpk-controller.ts +4 -2
  124. package/src/i3s-server/routes/index.ts +10 -7
  125. package/src/i3s-server/routes/slpk-router.ts +22 -16
  126. package/src/i3s-server/utils/server-utils.ts +6 -4
  127. package/src/lib/utils/cli-utils.ts +2 -0
  128. package/src/lib/utils/conversion-dump.ts +35 -20
  129. package/src/lib/utils/file-utils.ts +11 -11
  130. package/src/lib/utils/statistic-utills.ts +5 -6
  131. package/src/lib/utils/write-queue.ts +2 -2
  132. package/src/slpk-extractor/slpk-extractor.ts +2 -1
  133. package/src/slpk-extractor-cli.ts +16 -8
  134. package/dist/3d-tiles-converter/3d-tiles-converter.js.map +0 -1
  135. package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +0 -1
  136. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +0 -1
  137. package/dist/3d-tiles-converter/helpers/load-i3s.js.map +0 -1
  138. package/dist/3d-tiles-converter/helpers/texture-atlas.js.map +0 -1
  139. package/dist/3d-tiles-converter/json-templates/tileset.js.map +0 -1
  140. package/dist/constants.js.map +0 -1
  141. package/dist/converter-cli.js.map +0 -1
  142. package/dist/deps-installer/deps-installer.js.map +0 -1
  143. package/dist/i3s-converter/helpers/attribute-metadata-info.js.map +0 -1
  144. package/dist/i3s-converter/helpers/batch-ids-extensions.js.map +0 -1
  145. package/dist/i3s-converter/helpers/coordinate-converter.js.map +0 -1
  146. package/dist/i3s-converter/helpers/create-scene-server-path.js.map +0 -1
  147. package/dist/i3s-converter/helpers/feature-attributes.js.map +0 -1
  148. package/dist/i3s-converter/helpers/geometry-attributes.js.map +0 -1
  149. package/dist/i3s-converter/helpers/geometry-converter.js.map +0 -1
  150. package/dist/i3s-converter/helpers/gltf-attributes.js.map +0 -1
  151. package/dist/i3s-converter/helpers/load-3d-tiles.js.map +0 -1
  152. package/dist/i3s-converter/helpers/node-debug.js.map +0 -1
  153. package/dist/i3s-converter/helpers/node-index-document.js.map +0 -1
  154. package/dist/i3s-converter/helpers/node-pages.js.map +0 -1
  155. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js.map +0 -1
  156. package/dist/i3s-converter/helpers/progress.js.map +0 -1
  157. package/dist/i3s-converter/helpers/tileset-traversal.js.map +0 -1
  158. package/dist/i3s-converter/i3s-converter.js.map +0 -1
  159. package/dist/i3s-converter/json-templates/geometry-definitions.js.map +0 -1
  160. package/dist/i3s-converter/json-templates/layers.js.map +0 -1
  161. package/dist/i3s-converter/json-templates/metadata.js.map +0 -1
  162. package/dist/i3s-converter/json-templates/node.js.map +0 -1
  163. package/dist/i3s-converter/json-templates/scene-server.js.map +0 -1
  164. package/dist/i3s-converter/json-templates/shared-resources.js.map +0 -1
  165. package/dist/i3s-converter/json-templates/store.js.map +0 -1
  166. package/dist/i3s-converter/types.js.map +0 -1
  167. package/dist/i3s-server/README.md +0 -63
  168. package/dist/i3s-server/app.js.map +0 -1
  169. package/dist/i3s-server/bin/www.js.map +0 -1
  170. package/dist/i3s-server/certs/cert.pem +0 -19
  171. package/dist/i3s-server/certs/key.pem +0 -27
  172. package/dist/i3s-server/controllers/index-controller.js.map +0 -1
  173. package/dist/i3s-server/controllers/slpk-controller.js.map +0 -1
  174. package/dist/i3s-server/routes/index.js.map +0 -1
  175. package/dist/i3s-server/routes/slpk-router.js.map +0 -1
  176. package/dist/i3s-server/utils/create-scene-server.js.map +0 -1
  177. package/dist/i3s-server/utils/server-utils.js.map +0 -1
  178. package/dist/index.js.map +0 -1
  179. package/dist/lib/json-schemas/conversion-dump-json-schema.js.map +0 -1
  180. package/dist/lib/utils/cli-utils.js.map +0 -1
  181. package/dist/lib/utils/compress-util.js.map +0 -1
  182. package/dist/lib/utils/conversion-dump.js.map +0 -1
  183. package/dist/lib/utils/file-utils.js.map +0 -1
  184. package/dist/lib/utils/geometry-utils.js.map +0 -1
  185. package/dist/lib/utils/lod-conversion-utils.js.map +0 -1
  186. package/dist/lib/utils/queue.js.map +0 -1
  187. package/dist/lib/utils/statistic-utills.js.map +0 -1
  188. package/dist/lib/utils/write-queue.js.map +0 -1
  189. package/dist/pgm-loader.js.map +0 -1
  190. package/dist/slpk-extractor/slpk-extractor.js.map +0 -1
  191. package/dist/slpk-extractor-cli.js.map +0 -1
  192. package/src/lib/utils/statistic-utills.d.ts +0 -25
@@ -17,312 +17,368 @@ import { getNodeCount, loadFromArchive, loadI3SContent, openSLPK } from "./helpe
17
17
  import { ConversionDump } from "../lib/utils/conversion-dump.js";
18
18
  import { Progress } from "../i3s-converter/helpers/progress.js";
19
19
  const I3S = 'I3S';
20
+ /**
21
+ * Converter from i3s to 3d-tiles
22
+ */
20
23
  export default class Tiles3DConverter {
21
- constructor() {
22
- this.options = void 0;
23
- this.tilesetPath = void 0;
24
- this.vertexCounter = void 0;
25
- this.conversionStartTime = void 0;
26
- this.geoidHeightModel = void 0;
27
- this.sourceTileset = void 0;
28
- this.attributeStorageInfo = void 0;
29
- this.workerSource = {};
30
- this.slpkFilesystem = null;
31
- this.loaderOptions = {
32
- _nodeWorkers: true,
33
- reuseWorkers: true,
34
- worker: false,
35
- i3s: {
36
- coordinateSystem: COORDINATE_SYSTEM.LNGLAT_OFFSETS,
37
- decodeTextures: false
38
- },
39
- 'i3s-content': {
40
- workerUrl: './modules/i3s/dist/i3s-content-worker-node.js'
41
- }
42
- };
43
- this.conversionDump = void 0;
44
- this.progress = void 0;
45
- this.options = {};
46
- this.tilesetPath = '';
47
- this.vertexCounter = 0;
48
- this.conversionStartTime = [0, 0];
49
- this.geoidHeightModel = null;
50
- this.sourceTileset = null;
51
- this.attributeStorageInfo = null;
52
- this.workerSource = {};
53
- this.conversionDump = new ConversionDump();
54
- this.progress = new Progress();
55
- }
56
- async convert(options) {
57
- var _this$sourceTileset;
58
- if (isBrowser) {
59
- console.log(BROWSER_ERROR_MESSAGE);
60
- return BROWSER_ERROR_MESSAGE;
61
- }
62
- const {
63
- inputUrl,
64
- outputPath,
65
- tilesetName,
66
- maxDepth,
67
- egmFilePath,
68
- inquirer,
69
- analyze
70
- } = options;
71
- this.conversionStartTime = process.hrtime();
72
- this.options = {
73
- maxDepth,
74
- inquirer
75
- };
76
- console.log('Loading egm file...');
77
- this.geoidHeightModel = await load(egmFilePath, PGMLoader);
78
- console.log('Loading egm file completed!');
79
- this.slpkFilesystem = await openSLPK(inputUrl);
80
- let preprocessResult = true;
81
- if (analyze || this.slpkFilesystem) {
82
- preprocessResult = await this.preprocessConversion();
83
- if (!preprocessResult || analyze) {
84
- return;
85
- }
86
- }
87
- this.progress.startMonitoring();
88
- this.sourceTileset = await loadFromArchive(inputUrl, I3SLoader, {
89
- ...this.loaderOptions,
90
- i3s: {
91
- ...this.loaderOptions.i3s,
92
- isTileset: true
93
- }
94
- }, this.slpkFilesystem);
95
- if (!this.sourceTileset) {
96
- return;
97
- }
98
- const rootNode = (_this$sourceTileset = this.sourceTileset) === null || _this$sourceTileset === void 0 ? void 0 : _this$sourceTileset.root;
99
- if (!rootNode.obb) {
100
- rootNode.obb = createObbFromMbs(rootNode.mbs);
101
- }
102
- this.tilesetPath = join(`${outputPath}`, `${tilesetName}`);
103
- this.attributeStorageInfo = this.sourceTileset.attributeStorageInfo;
104
- await this.conversionDump.createDump(options);
105
- if (this.conversionDump.restored && this.options.inquirer) {
106
- const result = await this.options.inquirer.prompt([{
107
- name: 'resumeConversion',
108
- type: 'confirm',
109
- message: 'Dump file of the previous conversion exists, do you want to resume that conversion?'
110
- }]);
111
- if (!result.resumeConversion) {
112
- this.conversionDump.reset();
113
- }
114
- }
115
- if (!this.conversionDump.restored) {
116
- try {
117
- await removeDir(this.tilesetPath);
118
- } catch (e) {}
119
- }
120
- const rootTile = {
121
- boundingVolume: {
122
- box: i3sObbTo3dTilesObb(rootNode.obb, this.geoidHeightModel)
123
- },
124
- geometricError: convertScreenThresholdToGeometricError(rootNode),
125
- children: [],
126
- refine: 'REPLACE'
24
+ options;
25
+ tilesetPath;
26
+ vertexCounter;
27
+ conversionStartTime;
28
+ geoidHeightModel;
29
+ sourceTileset;
30
+ attributeStorageInfo;
31
+ workerSource = {};
32
+ slpkFilesystem = null;
33
+ loaderOptions = {
34
+ _nodeWorkers: true,
35
+ reuseWorkers: true,
36
+ // TODO: converter freezes in the end because of i3s-content-worker
37
+ worker: false,
38
+ i3s: { coordinateSystem: COORDINATE_SYSTEM.LNGLAT_OFFSETS, decodeTextures: false },
39
+ // We need to load local fs workers because nodejs can't load workers from the Internet
40
+ 'i3s-content': {
41
+ workerUrl: './modules/i3s/dist/i3s-content-worker-node.js'
42
+ }
127
43
  };
128
- await this._addChildren(rootNode, rootTile, 1);
129
- const tileset = transform({
130
- root: rootTile
131
- }, tilesetTemplate());
132
- await writeFile(this.tilesetPath, JSON.stringify(tileset), 'tileset.json');
133
- await this.conversionDump.deleteDumpFile();
134
- this.progress.stopMonitoring();
135
- await this._finishConversion({
136
- slpk: false,
137
- outputPath,
138
- tilesetName
139
- });
140
- if (this.slpkFilesystem) {
141
- this.slpkFilesystem.destroy();
44
+ conversionDump;
45
+ progress;
46
+ constructor() {
47
+ this.options = {};
48
+ this.tilesetPath = '';
49
+ this.vertexCounter = 0;
50
+ this.conversionStartTime = [0, 0];
51
+ this.geoidHeightModel = null;
52
+ this.sourceTileset = null;
53
+ this.attributeStorageInfo = null;
54
+ this.workerSource = {};
55
+ this.conversionDump = new ConversionDump();
56
+ this.progress = new Progress();
142
57
  }
143
- const workerFarm = WorkerFarm.getWorkerFarm({});
144
- workerFarm.destroy();
145
- }
146
- async preprocessConversion() {
147
- console.log(`Analyze source layer`);
148
- const nodesCount = await getNodeCount(this.slpkFilesystem);
149
- this.progress.stepsTotal = nodesCount;
150
- console.log(`------------------------------------------------`);
151
- console.log(`Preprocess results:`);
152
- if (this.slpkFilesystem) {
153
- console.log(`Node count: ${nodesCount}`);
154
- if (nodesCount === 0) {
155
- console.log('Node count is 0. The conversion will be interrupted.');
156
- console.log(`------------------------------------------------`);
157
- return false;
158
- }
159
- } else {
160
- console.log(`Node count cannot be calculated for the remote dataset`);
58
+ /**
59
+ * Convert i3s format data to 3dTiles
60
+ * @param options
61
+ * @param options.inputUrl the url to read the tileset from
62
+ * @param options.outputPath the output filename
63
+ * @param options.tilesetName the output name of the tileset
64
+ * @param options.egmFilePath location of *.pgm file to convert heights from ellipsoidal to gravity-related format
65
+ * @param options.maxDepth The max tree depth of conversion
66
+ */
67
+ // eslint-disable-next-line complexity, max-statements
68
+ async convert(options) {
69
+ if (isBrowser) {
70
+ console.log(BROWSER_ERROR_MESSAGE); // eslint-disable-line no-console
71
+ return BROWSER_ERROR_MESSAGE;
72
+ }
73
+ const { inputUrl, outputPath, tilesetName, maxDepth, egmFilePath, inquirer, analyze } = options;
74
+ this.conversionStartTime = process.hrtime();
75
+ this.options = { maxDepth, inquirer };
76
+ console.log('Loading egm file...'); // eslint-disable-line
77
+ this.geoidHeightModel = await load(egmFilePath, PGMLoader);
78
+ console.log('Loading egm file completed!'); // eslint-disable-line
79
+ this.slpkFilesystem = await openSLPK(inputUrl);
80
+ let preprocessResult = true;
81
+ if (analyze || this.slpkFilesystem) {
82
+ preprocessResult = await this.preprocessConversion();
83
+ if (!preprocessResult || analyze) {
84
+ return undefined;
85
+ }
86
+ }
87
+ this.progress.startMonitoring();
88
+ this.sourceTileset = await loadFromArchive(inputUrl, I3SLoader, {
89
+ ...this.loaderOptions,
90
+ // @ts-expect-error `isTileset` can be boolean of 'auto' but TS expects a string
91
+ i3s: { ...this.loaderOptions.i3s, isTileset: true }
92
+ }, this.slpkFilesystem);
93
+ if (!this.sourceTileset) {
94
+ return undefined;
95
+ }
96
+ const rootNode = this.sourceTileset?.root;
97
+ if (!rootNode.obb) {
98
+ rootNode.obb = createObbFromMbs(rootNode.mbs);
99
+ }
100
+ this.tilesetPath = join(`${outputPath}`, `${tilesetName}`);
101
+ this.attributeStorageInfo = this.sourceTileset.attributeStorageInfo;
102
+ await this.conversionDump.createDump(options);
103
+ if (this.conversionDump.restored && this.options.inquirer) {
104
+ const result = await this.options.inquirer.prompt([
105
+ {
106
+ name: 'resumeConversion',
107
+ type: 'confirm',
108
+ message: 'Dump file of the previous conversion exists, do you want to resume that conversion?'
109
+ }
110
+ ]);
111
+ if (!result.resumeConversion) {
112
+ this.conversionDump.reset();
113
+ }
114
+ }
115
+ // Removing the tilesetPath needed to exclude erroneous files after conversion
116
+ if (!this.conversionDump.restored) {
117
+ try {
118
+ await removeDir(this.tilesetPath);
119
+ }
120
+ catch (e) {
121
+ // do nothing
122
+ }
123
+ }
124
+ const rootTile = {
125
+ boundingVolume: {
126
+ box: i3sObbTo3dTilesObb(rootNode.obb, this.geoidHeightModel)
127
+ },
128
+ geometricError: convertScreenThresholdToGeometricError(rootNode),
129
+ children: [],
130
+ refine: 'REPLACE'
131
+ };
132
+ await this._addChildren(rootNode, rootTile, 1);
133
+ const tileset = transform({ root: rootTile }, tilesetTemplate());
134
+ await writeFile(this.tilesetPath, JSON.stringify(tileset), 'tileset.json');
135
+ await this.conversionDump.deleteDumpFile();
136
+ this.progress.stopMonitoring();
137
+ await this._finishConversion({ slpk: false, outputPath, tilesetName });
138
+ if (this.slpkFilesystem) {
139
+ this.slpkFilesystem.destroy();
140
+ }
141
+ // Clean up worker pools
142
+ const workerFarm = WorkerFarm.getWorkerFarm({});
143
+ workerFarm.destroy();
144
+ return undefined;
161
145
  }
162
- console.log(`------------------------------------------------`);
163
- return true;
164
- }
165
- async convertChildNode(parentSourceNode, parentNode, level, childNodeInfo) {
166
- let nextParentNode = parentNode;
167
- const sourceChild = await this._loadChildNode(parentSourceNode, childNodeInfo);
168
- if (sourceChild.contentUrl) {
169
- if (this.conversionDump.restored && this.conversionDump.isFileConversionComplete(`${sourceChild.id}.b3dm`) && (sourceChild.obb || sourceChild.mbs)) {
170
- const {
171
- child
172
- } = this._createChildAndBoundingVolume(sourceChild);
173
- parentNode.children.push(child);
174
- await this._addChildren(sourceChild, child, level + 1);
175
- return;
176
- }
177
- const content = await loadI3SContent(this.sourceTileset, sourceChild, this.loaderOptions, this.slpkFilesystem);
178
- if (!content) {
179
- await this._addChildren(sourceChild, parentNode, level + 1);
180
- return;
181
- }
182
- this.vertexCounter += (content === null || content === void 0 ? void 0 : content.vertexCount) || 0;
183
- let featureAttributes = null;
184
- if (this.attributeStorageInfo) {
185
- featureAttributes = await this._loadChildAttributes(sourceChild, this.attributeStorageInfo);
186
- }
187
- const {
188
- child,
189
- boundingVolume
190
- } = this._createChildAndBoundingVolume(sourceChild);
191
- const i3sAttributesData = {
192
- tileContent: content,
193
- box: boundingVolume.box || [],
194
- textureFormat: sourceChild.textureFormat
195
- };
196
- const b3dmConverter = new B3dmConverter();
197
- const b3dm = await b3dmConverter.convert(i3sAttributesData, featureAttributes);
198
- await this.conversionDump.addNode(`${sourceChild.id}.b3dm`, sourceChild.id);
199
- await writeFile(this.tilesetPath, new Uint8Array(b3dm), `${sourceChild.id}.b3dm`);
200
- await this.conversionDump.updateConvertedNodesDumpFile(`${sourceChild.id}.b3dm`, sourceChild.id, true);
201
- parentNode.children.push(child);
202
- nextParentNode = child;
146
+ /**
147
+ * Preprocess stage of the tile converter. Calculate number of nodes
148
+ * @returns true - the conversion is possible, false - the tileset's content is not supported
149
+ */
150
+ async preprocessConversion() {
151
+ // eslint-disable-next-line no-console
152
+ console.log('Analyze source layer');
153
+ const nodesCount = await getNodeCount(this.slpkFilesystem);
154
+ this.progress.stepsTotal = nodesCount;
155
+ // eslint-disable-next-line no-console
156
+ console.log('------------------------------------------------');
157
+ // eslint-disable-next-line no-console
158
+ console.log('Preprocess results:');
159
+ if (this.slpkFilesystem) {
160
+ // eslint-disable-next-line no-console
161
+ console.log(`Node count: ${nodesCount}`);
162
+ if (nodesCount === 0) {
163
+ // eslint-disable-next-line no-console
164
+ console.log('Node count is 0. The conversion will be interrupted.');
165
+ // eslint-disable-next-line no-console
166
+ console.log('------------------------------------------------');
167
+ return false;
168
+ }
169
+ }
170
+ else {
171
+ // eslint-disable-next-line no-console
172
+ console.log('Node count cannot be calculated for the remote dataset');
173
+ }
174
+ // eslint-disable-next-line no-console
175
+ console.log('------------------------------------------------');
176
+ return true;
203
177
  }
204
- this.progress.stepsDone += 1;
205
- let timeRemainingString = 'Calculating time left...';
206
- const timeRemaining = this.progress.getTimeRemainingString();
207
- if (timeRemaining) {
208
- timeRemainingString = `${timeRemaining} left`;
178
+ /**
179
+ * Convert particular I3S Node
180
+ * @param parentSourceNode the parent node tile object (@loaders.gl/tiles/Tile3D)
181
+ * @param parentNode object in resulting tileset
182
+ * @param level a current level of a tree depth
183
+ * @param childNodeInfo child node to convert
184
+ */
185
+ // eslint-disable-next-line complexity, max-statements
186
+ async convertChildNode(parentSourceNode, parentNode, level, childNodeInfo) {
187
+ let nextParentNode = parentNode;
188
+ const sourceChild = await this._loadChildNode(parentSourceNode, childNodeInfo);
189
+ if (sourceChild.contentUrl) {
190
+ if (this.conversionDump.restored &&
191
+ this.conversionDump.isFileConversionComplete(`${sourceChild.id}.b3dm`) &&
192
+ (sourceChild.obb || sourceChild.mbs)) {
193
+ const { child } = this._createChildAndBoundingVolume(sourceChild);
194
+ parentNode.children.push(child);
195
+ await this._addChildren(sourceChild, child, level + 1);
196
+ return;
197
+ }
198
+ const content = await loadI3SContent(this.sourceTileset, sourceChild, this.loaderOptions, this.slpkFilesystem);
199
+ if (!content) {
200
+ await this._addChildren(sourceChild, parentNode, level + 1);
201
+ return;
202
+ }
203
+ this.vertexCounter += content?.vertexCount || 0;
204
+ let featureAttributes = null;
205
+ if (this.attributeStorageInfo) {
206
+ featureAttributes = await this._loadChildAttributes(sourceChild, this.attributeStorageInfo);
207
+ }
208
+ const { child, boundingVolume } = this._createChildAndBoundingVolume(sourceChild);
209
+ const i3sAttributesData = {
210
+ tileContent: content,
211
+ box: boundingVolume.box || [],
212
+ textureFormat: sourceChild.textureFormat
213
+ };
214
+ const b3dmConverter = new B3dmConverter();
215
+ const b3dm = await b3dmConverter.convert(i3sAttributesData, featureAttributes);
216
+ await this.conversionDump.addNode(`${sourceChild.id}.b3dm`, sourceChild.id);
217
+ await writeFile(this.tilesetPath, new Uint8Array(b3dm), `${sourceChild.id}.b3dm`);
218
+ await this.conversionDump.updateConvertedNodesDumpFile(`${sourceChild.id}.b3dm`, sourceChild.id, true);
219
+ parentNode.children.push(child);
220
+ nextParentNode = child;
221
+ }
222
+ this.progress.stepsDone += 1;
223
+ let timeRemainingString = 'Calculating time left...';
224
+ const timeRemaining = this.progress.getTimeRemainingString();
225
+ if (timeRemaining) {
226
+ timeRemainingString = `${timeRemaining} left`;
227
+ }
228
+ const percentString = this.progress.getPercentString();
229
+ const progressString = percentString ? ` ${percentString}%, ${timeRemainingString}` : '';
230
+ console.log(`[converted${progressString}]: ${childNodeInfo.id}`); // eslint-disable-line
231
+ await this._addChildren(sourceChild, nextParentNode, level + 1);
209
232
  }
210
- const percentString = this.progress.getPercentString();
211
- const progressString = percentString ? ` ${percentString}%, ${timeRemainingString}` : '';
212
- console.log(`[converted${progressString}]: ${childNodeInfo.id}`);
213
- await this._addChildren(sourceChild, nextParentNode, level + 1);
214
- }
215
- async _addChildren(parentSourceNode, parentNode, level) {
216
- if (this.options.maxDepth && level > this.options.maxDepth) {
217
- return;
233
+ /**
234
+ * The recursive function of traversal of a nodes tree
235
+ * @param parentSourceNode the parent node tile object (@loaders.gl/tiles/Tile3D)
236
+ * @param parentNode object in resulting tileset
237
+ * @param level a current level of a tree depth
238
+ */
239
+ async _addChildren(parentSourceNode, parentNode, level) {
240
+ if (this.options.maxDepth && level > this.options.maxDepth) {
241
+ return;
242
+ }
243
+ for (const childNodeInfo of parentSourceNode.children || []) {
244
+ await this.convertChildNode(parentSourceNode, parentNode, level, childNodeInfo);
245
+ }
218
246
  }
219
- for (const childNodeInfo of parentSourceNode.children || []) {
220
- await this.convertChildNode(parentSourceNode, parentNode, level, childNodeInfo);
247
+ /**
248
+ * Load a child node having information from the node header
249
+ * @param parentNode a parent node tile object (@loaders.gl/tiles/Tile3D)
250
+ * @param childNodeInfo child information from 3DNodeIndexDocument
251
+ * (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodeReference.cmn.md)
252
+ */
253
+ async _loadChildNode(parentNode, childNodeInfo) {
254
+ let header;
255
+ if (this.sourceTileset?.nodePagesTile) {
256
+ console.log(`Node conversion: ${childNodeInfo.id}`); // eslint-disable-line no-console,no-undef
257
+ header = await this.sourceTileset.nodePagesTile.formTileFromNodePages(parseInt(childNodeInfo.id));
258
+ }
259
+ else {
260
+ const nodeUrl = this._relativeUrlToFullUrl(parentNode.url, childNodeInfo.href);
261
+ // load metadata
262
+ const options = {
263
+ i3s: {
264
+ ...this.loaderOptions,
265
+ // @ts-expect-error
266
+ isTileHeader: true,
267
+ loadContent: false
268
+ }
269
+ };
270
+ console.log(`Node conversion: ${nodeUrl}`); // eslint-disable-line no-console,no-undef
271
+ header = await loadFromArchive(nodeUrl, I3SLoader, options, this.slpkFilesystem);
272
+ }
273
+ return header;
221
274
  }
222
- }
223
- async _loadChildNode(parentNode, childNodeInfo) {
224
- var _this$sourceTileset2;
225
- let header;
226
- if ((_this$sourceTileset2 = this.sourceTileset) !== null && _this$sourceTileset2 !== void 0 && _this$sourceTileset2.nodePagesTile) {
227
- console.log(`Node conversion: ${childNodeInfo.id}`);
228
- header = await this.sourceTileset.nodePagesTile.formTileFromNodePages(parseInt(childNodeInfo.id));
229
- } else {
230
- const nodeUrl = this._relativeUrlToFullUrl(parentNode.url, childNodeInfo.href);
231
- const options = {
232
- i3s: {
233
- ...this.loaderOptions,
234
- isTileHeader: true,
235
- loadContent: false
275
+ /**
276
+ * Create child and child's boundingVolume for the converted node
277
+ * @param sourceChild
278
+ * @returns child and child's boundingVolume
279
+ */
280
+ _createChildAndBoundingVolume(sourceChild) {
281
+ if (!sourceChild.obb) {
282
+ sourceChild.obb = createObbFromMbs(sourceChild.mbs);
236
283
  }
237
- };
238
- console.log(`Node conversion: ${nodeUrl}`);
239
- header = await loadFromArchive(nodeUrl, I3SLoader, options, this.slpkFilesystem);
284
+ const boundingVolume = {
285
+ box: i3sObbTo3dTilesObb(sourceChild.obb, this.geoidHeightModel)
286
+ };
287
+ const child = {
288
+ boundingVolume,
289
+ geometricError: convertScreenThresholdToGeometricError(sourceChild),
290
+ children: [],
291
+ content: {
292
+ uri: `${sourceChild.id}.b3dm`,
293
+ boundingVolume
294
+ }
295
+ };
296
+ return { boundingVolume, child };
240
297
  }
241
- return header;
242
- }
243
- _createChildAndBoundingVolume(sourceChild) {
244
- if (!sourceChild.obb) {
245
- sourceChild.obb = createObbFromMbs(sourceChild.mbs);
298
+ /**
299
+ * Make an url of a resource from its relative url having the base url
300
+ * @param baseUrl the base url. A resulting url will be related from this url
301
+ * @param relativeUrl a realtive url of a resource
302
+ */
303
+ _relativeUrlToFullUrl(baseUrl = '', relativeUrl) {
304
+ let resultArray = baseUrl.split('/');
305
+ const relativeUrlArray = relativeUrl.split('/');
306
+ for (const folder of relativeUrlArray) {
307
+ switch (folder) {
308
+ case '.':
309
+ continue; // eslint-disable-line no-continue
310
+ case '..':
311
+ resultArray = resultArray.slice(0, -1);
312
+ break;
313
+ default:
314
+ resultArray.push(folder);
315
+ }
316
+ }
317
+ return resultArray.join('/');
246
318
  }
247
- const boundingVolume = {
248
- box: i3sObbTo3dTilesObb(sourceChild.obb, this.geoidHeightModel)
249
- };
250
- const child = {
251
- boundingVolume,
252
- geometricError: convertScreenThresholdToGeometricError(sourceChild),
253
- children: [],
254
- content: {
255
- uri: `${sourceChild.id}.b3dm`,
256
- boundingVolume
257
- }
258
- };
259
- return {
260
- boundingVolume,
261
- child
262
- };
263
- }
264
- _relativeUrlToFullUrl() {
265
- let baseUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
266
- let relativeUrl = arguments.length > 1 ? arguments[1] : undefined;
267
- let resultArray = baseUrl.split('/');
268
- const relativeUrlArray = relativeUrl.split('/');
269
- for (const folder of relativeUrlArray) {
270
- switch (folder) {
271
- case '.':
272
- continue;
273
- case '..':
274
- resultArray = resultArray.slice(0, -1);
275
- break;
276
- default:
277
- resultArray.push(folder);
278
- }
319
+ /**
320
+ * Do loading all attributes related to particular node.
321
+ * @param sourceChild
322
+ * @param attributeStorageInfo
323
+ * @returns Promise of attributes object.
324
+ */
325
+ async _loadChildAttributes(sourceChild, attributeStorageInfo) {
326
+ const promises = [];
327
+ const { attributeUrls = [] } = sourceChild;
328
+ for (let index = 0; index < attributeUrls.length; index++) {
329
+ const inputUrl = attributeUrls[index];
330
+ const attribute = attributeStorageInfo[index];
331
+ const options = {
332
+ attributeName: attribute.name,
333
+ attributeType: this._getAttributeType(attribute)
334
+ };
335
+ promises.push(loadFromArchive(inputUrl, I3SAttributeLoader, options, this.slpkFilesystem));
336
+ }
337
+ const attributesList = await Promise.all(promises);
338
+ this._replaceNestedArrays(attributesList);
339
+ return Object.assign({}, ...attributesList);
279
340
  }
280
- return resultArray.join('/');
281
- }
282
- async _loadChildAttributes(sourceChild, attributeStorageInfo) {
283
- const promises = [];
284
- const {
285
- attributeUrls = []
286
- } = sourceChild;
287
- for (let index = 0; index < attributeUrls.length; index++) {
288
- const inputUrl = attributeUrls[index];
289
- const attribute = attributeStorageInfo[index];
290
- const options = {
291
- attributeName: attribute.name,
292
- attributeType: this._getAttributeType(attribute)
293
- };
294
- promises.push(loadFromArchive(inputUrl, I3SAttributeLoader, options, this.slpkFilesystem));
341
+ /**
342
+ * Returns attribute type for loading attributes
343
+ * @param attribute
344
+ * Workaround for I3S v1.6. There is no attribute.attributeValues.valueType field in attribute.
345
+ * There is an 'Oid32' type if attribute has objectIds property.
346
+ * Doc: https://github.com/Esri/i3s-spec/blob/master/docs/1.6/attributeStorageInfo.cmn.md
347
+ */
348
+ _getAttributeType(attribute) {
349
+ if (attribute.attributeValues) {
350
+ return attribute.attributeValues.valueType;
351
+ }
352
+ else if (attribute.objectIds) {
353
+ return 'Oid32';
354
+ }
355
+ return '';
295
356
  }
296
- const attributesList = await Promise.all(promises);
297
- this._replaceNestedArrays(attributesList);
298
- return Object.assign({}, ...attributesList);
299
- }
300
- _getAttributeType(attribute) {
301
- if (attribute.attributeValues) {
302
- return attribute.attributeValues.valueType;
303
- } else if (attribute.objectIds) {
304
- return 'Oid32';
357
+ /**
358
+ * Make simple arrays from attribute typed arrays.
359
+ * @param attributesList
360
+ */
361
+ _replaceNestedArrays(attributesList) {
362
+ for (let index = 0; index < attributesList.length; index++) {
363
+ const attributeObject = attributesList[index];
364
+ for (const key in attributeObject) {
365
+ attributeObject[key] = Array.from(attributeObject[key]);
366
+ }
367
+ }
305
368
  }
306
- return '';
307
- }
308
- _replaceNestedArrays(attributesList) {
309
- for (let index = 0; index < attributesList.length; index++) {
310
- const attributeObject = attributesList[index];
311
- for (const key in attributeObject) {
312
- attributeObject[key] = Array.from(attributeObject[key]);
313
- }
369
+ /**
370
+ * Print statistics in the end of conversion
371
+ * @param params - output files data
372
+ */
373
+ async _finishConversion(params) {
374
+ const filesSize = await calculateFilesSize(params);
375
+ const diff = process.hrtime(this.conversionStartTime);
376
+ const conversionTime = timeConverter(diff);
377
+ console.log(`------------------------------------------------`); // eslint-disable-line
378
+ console.log(`Finish conversion of ${I3S}`); // eslint-disable-line
379
+ console.log(`Total conversion time: ${conversionTime}`); // eslint-disable-line
380
+ console.log(`Vertex count: `, this.vertexCounter); // eslint-disable-line
381
+ console.log(`File(s) size: `, filesSize, ' bytes'); // eslint-disable-line
382
+ console.log(`------------------------------------------------`); // eslint-disable-line
314
383
  }
315
- }
316
- async _finishConversion(params) {
317
- const filesSize = await calculateFilesSize(params);
318
- const diff = process.hrtime(this.conversionStartTime);
319
- const conversionTime = timeConverter(diff);
320
- console.log(`------------------------------------------------`);
321
- console.log(`Finish conversion of ${I3S}`);
322
- console.log(`Total conversion time: ${conversionTime}`);
323
- console.log(`Vertex count: `, this.vertexCounter);
324
- console.log(`File(s) size: `, filesSize, ' bytes');
325
- console.log(`------------------------------------------------`);
326
- }
327
384
  }
328
- //# sourceMappingURL=3d-tiles-converter.js.map