@loaders.gl/tile-converter 3.3.0-alpha.1 → 3.3.0-alpha.10

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 (252) hide show
  1. package/dist/3d-tiles-attributes-worker.d.ts +3 -3
  2. package/dist/3d-tiles-attributes-worker.d.ts.map +1 -1
  3. package/dist/3d-tiles-attributes-worker.js +2 -3
  4. package/dist/3d-tiles-attributes-worker.js.map +3 -3
  5. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +8 -0
  6. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  7. package/dist/3d-tiles-converter/3d-tiles-converter.js +57 -43
  8. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +5 -5
  9. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  10. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +21 -17
  11. package/dist/converter-cli.js +29 -4
  12. package/dist/converter.min.js +24 -21
  13. package/dist/deps-installer/deps-installer.d.ts +5 -1
  14. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  15. package/dist/deps-installer/deps-installer.js +29 -1
  16. package/dist/dist.min.js +61034 -64112
  17. package/dist/es5/3d-tiles-attributes-worker.js +4 -7
  18. package/dist/es5/3d-tiles-attributes-worker.js.map +1 -1
  19. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +125 -210
  20. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  21. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +53 -85
  22. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  23. package/dist/es5/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +0 -8
  24. package/dist/es5/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +1 -1
  25. package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js +0 -5
  26. package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  27. package/dist/es5/3d-tiles-converter/json-templates/tileset.js +0 -6
  28. package/dist/es5/3d-tiles-converter/json-templates/tileset.js.map +1 -1
  29. package/dist/es5/bundle.js +0 -1
  30. package/dist/es5/bundle.js.map +1 -1
  31. package/dist/es5/constants.js.map +1 -1
  32. package/dist/es5/converter-cli.js +25 -58
  33. package/dist/es5/converter-cli.js.map +1 -1
  34. package/dist/es5/deps-installer/deps-installer.js +73 -28
  35. package/dist/es5/deps-installer/deps-installer.js.map +1 -1
  36. package/dist/es5/i3s-attributes-worker.js +3 -6
  37. package/dist/es5/i3s-attributes-worker.js.map +1 -1
  38. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +18 -29
  39. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  40. package/dist/es5/i3s-converter/helpers/coordinate-converter.js +8 -25
  41. package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  42. package/dist/es5/i3s-converter/helpers/create-scene-server-path.js +0 -11
  43. package/dist/es5/i3s-converter/helpers/create-scene-server-path.js.map +1 -1
  44. package/dist/es5/i3s-converter/helpers/feature-attributes.js +184 -0
  45. package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -0
  46. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +60 -51
  47. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  48. package/dist/es5/i3s-converter/helpers/geometry-converter.js +504 -350
  49. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  50. package/dist/es5/i3s-converter/helpers/gltf-attributes.js +57 -57
  51. package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  52. package/dist/es5/i3s-converter/helpers/node-debug.js +4 -23
  53. package/dist/es5/i3s-converter/helpers/node-debug.js.map +1 -1
  54. package/dist/es5/i3s-converter/helpers/node-index-document.js +507 -0
  55. package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -0
  56. package/dist/es5/i3s-converter/helpers/node-pages.js +478 -168
  57. package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
  58. package/dist/es5/i3s-converter/i3s-converter.js +794 -1125
  59. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  60. package/dist/es5/i3s-converter/json-templates/geometry-definitions.js +107 -0
  61. package/dist/es5/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
  62. package/dist/es5/i3s-converter/json-templates/layers.js +2 -107
  63. package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -1
  64. package/dist/es5/i3s-converter/json-templates/metadata.js +0 -2
  65. package/dist/es5/i3s-converter/json-templates/metadata.js.map +1 -1
  66. package/dist/es5/i3s-converter/json-templates/node.js +2 -12
  67. package/dist/es5/i3s-converter/json-templates/node.js.map +1 -1
  68. package/dist/es5/i3s-converter/json-templates/scene-server.js +0 -2
  69. package/dist/es5/i3s-converter/json-templates/scene-server.js.map +1 -1
  70. package/dist/es5/i3s-converter/json-templates/shared-resources.js +9 -32
  71. package/dist/es5/i3s-converter/json-templates/shared-resources.js.map +1 -1
  72. package/dist/es5/i3s-converter/json-templates/store.js.map +1 -1
  73. package/dist/es5/i3s-converter/types.js.map +1 -1
  74. package/dist/es5/i3s-server/app.js +0 -5
  75. package/dist/es5/i3s-server/app.js.map +1 -1
  76. package/dist/es5/i3s-server/controllers/index-controller.js +0 -16
  77. package/dist/es5/i3s-server/controllers/index-controller.js.map +1 -1
  78. package/dist/es5/i3s-server/routes/index.js +1 -10
  79. package/dist/es5/i3s-server/routes/index.js.map +1 -1
  80. package/dist/es5/index.js +0 -3
  81. package/dist/es5/index.js.map +1 -1
  82. package/dist/es5/lib/utils/compress-util.js +19 -74
  83. package/dist/es5/lib/utils/compress-util.js.map +1 -1
  84. package/dist/es5/lib/utils/file-utils.js +103 -47
  85. package/dist/es5/lib/utils/file-utils.js.map +1 -1
  86. package/dist/es5/lib/utils/lod-conversion-utils.js +0 -7
  87. package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
  88. package/dist/es5/lib/utils/queue.js +0 -14
  89. package/dist/es5/lib/utils/queue.js.map +1 -1
  90. package/dist/es5/lib/utils/statistic-utills.js +1 -46
  91. package/dist/es5/lib/utils/statistic-utills.js.map +1 -1
  92. package/dist/es5/lib/utils/write-queue.js +86 -87
  93. package/dist/es5/lib/utils/write-queue.js.map +1 -1
  94. package/dist/es5/pgm-loader.js +1 -8
  95. package/dist/es5/pgm-loader.js.map +1 -1
  96. package/dist/es5/workers/3d-tiles-attributes-worker.js +2 -9
  97. package/dist/es5/workers/3d-tiles-attributes-worker.js.map +1 -1
  98. package/dist/es5/workers/i3s-attributes-worker.js +2 -10
  99. package/dist/es5/workers/i3s-attributes-worker.js.map +1 -1
  100. package/dist/esm/3d-tiles-attributes-worker.js +4 -2
  101. package/dist/esm/3d-tiles-attributes-worker.js.map +1 -1
  102. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +60 -77
  103. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  104. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +29 -50
  105. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  106. package/dist/esm/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +1 -0
  107. package/dist/esm/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +1 -1
  108. package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js +1 -4
  109. package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  110. package/dist/esm/3d-tiles-converter/json-templates/tileset.js +0 -3
  111. package/dist/esm/3d-tiles-converter/json-templates/tileset.js.map +1 -1
  112. package/dist/esm/bundle.js +1 -1
  113. package/dist/esm/bundle.js.map +1 -1
  114. package/dist/esm/constants.js.map +1 -1
  115. package/dist/esm/converter-cli.js +26 -43
  116. package/dist/esm/converter-cli.js.map +1 -1
  117. package/dist/esm/deps-installer/deps-installer.js +30 -4
  118. package/dist/esm/deps-installer/deps-installer.js.map +1 -1
  119. package/dist/esm/i3s-attributes-worker.js +3 -1
  120. package/dist/esm/i3s-attributes-worker.js.map +1 -1
  121. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +20 -24
  122. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  123. package/dist/esm/i3s-converter/helpers/coordinate-converter.js +11 -12
  124. package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  125. package/dist/esm/i3s-converter/helpers/create-scene-server-path.js +1 -0
  126. package/dist/esm/i3s-converter/helpers/create-scene-server-path.js.map +1 -1
  127. package/dist/esm/i3s-converter/helpers/feature-attributes.js +158 -0
  128. package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -0
  129. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +39 -33
  130. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  131. package/dist/esm/i3s-converter/helpers/geometry-converter.js +286 -192
  132. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  133. package/dist/esm/i3s-converter/helpers/gltf-attributes.js +59 -48
  134. package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  135. package/dist/esm/i3s-converter/helpers/node-debug.js +3 -13
  136. package/dist/esm/i3s-converter/helpers/node-debug.js.map +1 -1
  137. package/dist/esm/i3s-converter/helpers/node-index-document.js +197 -0
  138. package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -0
  139. package/dist/esm/i3s-converter/helpers/node-pages.js +161 -87
  140. package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
  141. package/dist/esm/i3s-converter/i3s-converter.js +235 -508
  142. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  143. package/dist/esm/i3s-converter/json-templates/geometry-definitions.js +89 -0
  144. package/dist/esm/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
  145. package/dist/esm/i3s-converter/json-templates/layers.js +2 -95
  146. package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -1
  147. package/dist/esm/i3s-converter/json-templates/metadata.js.map +1 -1
  148. package/dist/esm/i3s-converter/json-templates/node.js +0 -4
  149. package/dist/esm/i3s-converter/json-templates/node.js.map +1 -1
  150. package/dist/esm/i3s-converter/json-templates/scene-server.js.map +1 -1
  151. package/dist/esm/i3s-converter/json-templates/shared-resources.js +3 -15
  152. package/dist/esm/i3s-converter/json-templates/shared-resources.js.map +1 -1
  153. package/dist/esm/i3s-converter/json-templates/store.js.map +1 -1
  154. package/dist/esm/i3s-converter/types.js.map +1 -1
  155. package/dist/esm/i3s-server/app.js +0 -5
  156. package/dist/esm/i3s-server/app.js.map +1 -1
  157. package/dist/esm/i3s-server/controllers/index-controller.js +0 -5
  158. package/dist/esm/i3s-server/controllers/index-controller.js.map +1 -1
  159. package/dist/esm/i3s-server/routes/index.js +0 -3
  160. package/dist/esm/i3s-server/routes/index.js.map +1 -1
  161. package/dist/esm/index.js.map +1 -1
  162. package/dist/esm/lib/utils/compress-util.js +19 -12
  163. package/dist/esm/lib/utils/compress-util.js.map +1 -1
  164. package/dist/esm/lib/utils/file-utils.js +54 -11
  165. package/dist/esm/lib/utils/file-utils.js.map +1 -1
  166. package/dist/esm/lib/utils/lod-conversion-utils.js +2 -6
  167. package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
  168. package/dist/esm/lib/utils/queue.js +0 -4
  169. package/dist/esm/lib/utils/queue.js.map +1 -1
  170. package/dist/esm/lib/utils/statistic-utills.js +0 -11
  171. package/dist/esm/lib/utils/statistic-utills.js.map +1 -1
  172. package/dist/esm/lib/utils/write-queue.js +29 -28
  173. package/dist/esm/lib/utils/write-queue.js.map +1 -1
  174. package/dist/esm/pgm-loader.js +3 -1
  175. package/dist/esm/pgm-loader.js.map +1 -1
  176. package/dist/esm/workers/3d-tiles-attributes-worker.js +4 -1
  177. package/dist/esm/workers/3d-tiles-attributes-worker.js.map +1 -1
  178. package/dist/esm/workers/i3s-attributes-worker.js +4 -1
  179. package/dist/esm/workers/i3s-attributes-worker.js.map +1 -1
  180. package/dist/i3s-attributes-worker.d.ts +7 -3
  181. package/dist/i3s-attributes-worker.d.ts.map +1 -1
  182. package/dist/i3s-attributes-worker.js +2 -3
  183. package/dist/i3s-attributes-worker.js.map +3 -3
  184. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +5 -6
  185. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
  186. package/dist/i3s-converter/helpers/batch-ids-extensions.js +18 -4
  187. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +2 -2
  188. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
  189. package/dist/i3s-converter/helpers/coordinate-converter.js +8 -6
  190. package/dist/i3s-converter/helpers/feature-attributes.d.ts +56 -0
  191. package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -0
  192. package/dist/i3s-converter/helpers/feature-attributes.js +216 -0
  193. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  194. package/dist/i3s-converter/helpers/geometry-attributes.js +42 -17
  195. package/dist/i3s-converter/helpers/geometry-converter.d.ts +18 -6
  196. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  197. package/dist/i3s-converter/helpers/geometry-converter.js +337 -92
  198. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
  199. package/dist/i3s-converter/helpers/gltf-attributes.js +51 -32
  200. package/dist/i3s-converter/helpers/node-index-document.d.ts +91 -0
  201. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -0
  202. package/dist/i3s-converter/helpers/node-index-document.js +242 -0
  203. package/dist/i3s-converter/helpers/node-pages.d.ts +81 -42
  204. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
  205. package/dist/i3s-converter/helpers/node-pages.js +200 -92
  206. package/dist/i3s-converter/i3s-converter.d.ts +52 -108
  207. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  208. package/dist/i3s-converter/i3s-converter.js +234 -420
  209. package/dist/i3s-converter/json-templates/geometry-definitions.d.ts +7 -0
  210. package/dist/i3s-converter/json-templates/geometry-definitions.d.ts.map +1 -0
  211. package/dist/i3s-converter/json-templates/geometry-definitions.js +87 -0
  212. package/dist/i3s-converter/json-templates/layers.d.ts +1 -30
  213. package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -1
  214. package/dist/i3s-converter/json-templates/layers.js +2 -86
  215. package/dist/i3s-converter/json-templates/shared-resources.js +3 -3
  216. package/dist/i3s-converter/types.d.ts +37 -55
  217. package/dist/i3s-converter/types.d.ts.map +1 -1
  218. package/dist/lib/utils/file-utils.d.ts +17 -1
  219. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  220. package/dist/lib/utils/file-utils.js +64 -7
  221. package/dist/lib/utils/write-queue.d.ts +19 -2
  222. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  223. package/dist/lib/utils/write-queue.js +26 -7
  224. package/dist/pgm-loader.d.ts.map +1 -1
  225. package/dist/pgm-loader.js +2 -1
  226. package/dist/workers/3d-tiles-attributes-worker.js +1 -1
  227. package/dist/workers/i3s-attributes-worker.js +1 -1
  228. package/package.json +18 -16
  229. package/src/3d-tiles-attributes-worker.ts +1 -1
  230. package/src/3d-tiles-converter/3d-tiles-converter.ts +71 -55
  231. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +25 -18
  232. package/src/converter-cli.ts +38 -4
  233. package/src/deps-installer/deps-installer.ts +38 -2
  234. package/src/i3s-attributes-worker.ts +5 -1
  235. package/src/i3s-converter/helpers/batch-ids-extensions.ts +38 -14
  236. package/src/i3s-converter/helpers/coordinate-converter.ts +10 -8
  237. package/src/i3s-converter/helpers/feature-attributes.ts +247 -0
  238. package/src/i3s-converter/helpers/geometry-attributes.ts +46 -18
  239. package/src/i3s-converter/helpers/geometry-converter.ts +405 -108
  240. package/src/i3s-converter/helpers/gltf-attributes.ts +55 -35
  241. package/src/i3s-converter/helpers/node-index-document.ts +306 -0
  242. package/src/i3s-converter/helpers/node-pages.ts +222 -109
  243. package/src/i3s-converter/i3s-converter.ts +279 -499
  244. package/src/i3s-converter/json-templates/geometry-definitions.ts +83 -0
  245. package/src/i3s-converter/json-templates/layers.ts +2 -91
  246. package/src/i3s-converter/json-templates/shared-resources.ts +3 -3
  247. package/src/i3s-converter/types.ts +31 -51
  248. package/src/lib/utils/file-utils.ts +62 -7
  249. package/src/lib/utils/write-queue.ts +43 -10
  250. package/src/pgm-loader.ts +2 -2
  251. package/src/workers/3d-tiles-attributes-worker.ts +1 -1
  252. package/src/workers/i3s-attributes-worker.ts +2 -1
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -15,13 +38,13 @@ const node_pages_1 = __importDefault(require("./helpers/node-pages"));
15
38
  const file_utils_1 = require("../lib/utils/file-utils");
16
39
  const compress_util_1 = require("../lib/utils/compress-util");
17
40
  const statistic_utills_1 = require("../lib/utils/statistic-utills");
18
- const geometry_converter_1 = __importDefault(require("./helpers/geometry-converter"));
41
+ const geometry_converter_1 = __importStar(require("./helpers/geometry-converter"));
19
42
  const coordinate_converter_1 = require("./helpers/coordinate-converter");
20
43
  const create_scene_server_path_1 = require("./helpers/create-scene-server-path");
21
44
  const lod_conversion_utils_1 = require("../lib/utils/lod-conversion-utils");
22
45
  const pgm_loader_1 = require("../pgm-loader");
23
46
  const layers_1 = require("./json-templates/layers");
24
- const node_1 = require("./json-templates/node");
47
+ const geometry_definitions_1 = require("./json-templates/geometry-definitions");
25
48
  const shared_resources_1 = require("./json-templates/shared-resources");
26
49
  const node_debug_1 = require("./helpers/node-debug");
27
50
  const textures_1 = require("@loaders.gl/textures");
@@ -31,15 +54,13 @@ const draco_1 = require("@loaders.gl/draco");
31
54
  const write_queue_1 = __importDefault(require("../lib/utils/write-queue"));
32
55
  const i3s_attributes_worker_1 = require("../i3s-attributes-worker");
33
56
  const constants_1 = require("../constants");
57
+ const feature_attributes_1 = require("./helpers/feature-attributes");
58
+ const node_index_document_1 = require("./helpers/node-index-document");
34
59
  const ION_DEFAULT_TOKEN = process_1.default.env?.IonToken || // eslint-disable-line
35
60
  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlYWMxMzcyYy0zZjJkLTQwODctODNlNi01MDRkZmMzMjIxOWIiLCJpZCI6OTYyMCwic2NvcGVzIjpbImFzbCIsImFzciIsImdjIl0sImlhdCI6MTU2Mjg2NjI3M30.1FNiClUyk00YH_nWfSGpiQAjR5V2OvREDq1PJ5QMjWQ'; // eslint-disable-line
36
61
  const HARDCODED_NODES_PER_PAGE = 64;
37
62
  const _3D_TILES = '3DTILES';
38
63
  const _3D_OBJECT_LAYER_TYPE = '3DObject';
39
- const STRING_TYPE = 'string';
40
- const SHORT_INT_TYPE = 'Int32';
41
- const DOUBLE_TYPE = 'double';
42
- const OBJECT_ID_TYPE = 'OBJECTID';
43
64
  const REFRESH_TOKEN_TIMEOUT = 1800; // 30 minutes in seconds
44
65
  const CESIUM_DATASET_PREFIX = 'https://';
45
66
  // const FS_FILE_TOO_LARGE = 'ERR_FS_FILE_TOO_LARGE';
@@ -56,11 +77,14 @@ class I3SConverter {
56
77
  this.Loader = _3d_tiles_1.Tiles3DLoader;
57
78
  this.workerSource = {};
58
79
  this.writeQueue = new write_queue_1.default();
59
- this.nodePages = new node_pages_1.default(file_utils_1.writeFile, HARDCODED_NODES_PER_PAGE);
80
+ this.compressList = null;
81
+ this.nodePages = new node_pages_1.default(file_utils_1.writeFile, HARDCODED_NODES_PER_PAGE, this);
60
82
  this.options = {};
61
83
  this.layers0Path = '';
62
84
  this.materialMap = new Map();
63
85
  this.materialDefinitions = [];
86
+ this.geometryMap = new Map();
87
+ this.geometryConfigs = [];
64
88
  this.vertexCounter = 0;
65
89
  this.layers0 = null;
66
90
  this.featuresHashArray = [];
@@ -72,6 +96,7 @@ class I3SConverter {
72
96
  this.generateTextures = false;
73
97
  this.generateBoundingVolumes = false;
74
98
  this.layersHasTexture = false;
99
+ this.compressList = null;
75
100
  }
76
101
  /**
77
102
  * Convert a 3d tileset
@@ -86,6 +111,9 @@ class I3SConverter {
86
111
  * @param options.token Token for Cesium ION tilesets authentication
87
112
  * @param options.draco Generate I3S 1.7 draco compressed geometries
88
113
  * @param options.validate -enable validation
114
+ * @param options.generateTextures - generate alternative type of textures (to have non-compressed jpeg/png and compressed ktx2)
115
+ * @param options.generateBoundingVolumes - generate bounding volumes from vertices coordinates instead of source tiles bounding volumes
116
+ * @param options.instantNodeWriting - Keep created 3DNodeIndexDocument files on disk instead of memory. This option reduce memory usage but decelerates conversion speed
89
117
  */
90
118
  async convert(options) {
91
119
  if (core_1.isBrowser) {
@@ -93,8 +121,19 @@ class I3SConverter {
93
121
  return constants_1.BROWSER_ERROR_MESSAGE;
94
122
  }
95
123
  this.conversionStartTime = process_1.default.hrtime();
96
- const { tilesetName, slpk, egmFilePath, inputUrl, validate, outputPath, draco, sevenZipExe, maxDepth, token, generateTextures, generateBoundingVolumes } = options;
97
- this.options = { maxDepth, slpk, sevenZipExe, egmFilePath, draco, token, inputUrl };
124
+ const { tilesetName, slpk, egmFilePath, inputUrl, validate, outputPath, draco = true, sevenZipExe, maxDepth, token, generateTextures, generateBoundingVolumes, instantNodeWriting = false, mergeMaterials = true } = options;
125
+ this.options = {
126
+ maxDepth,
127
+ slpk,
128
+ sevenZipExe,
129
+ egmFilePath,
130
+ draco,
131
+ token,
132
+ inputUrl,
133
+ instantNodeWriting,
134
+ mergeMaterials
135
+ };
136
+ this.compressList = (this.options.instantNodeWriting && []) || null;
98
137
  this.validate = Boolean(validate);
99
138
  this.Loader = inputUrl.indexOf(CESIUM_DATASET_PREFIX) !== -1 ? _3d_tiles_1.CesiumIonLoader : _3d_tiles_1.Tiles3DLoader;
100
139
  this.generateTextures = Boolean(generateTextures);
@@ -110,7 +149,18 @@ class I3SConverter {
110
149
  await this.loadWorkers();
111
150
  try {
112
151
  const preloadOptions = await this._fetchPreloadOptions();
113
- const tilesetOptions = { loadOptions: { basis: { format: 'rgba32' } } };
152
+ const tilesetOptions = {
153
+ loadOptions: {
154
+ _nodeWorkers: true,
155
+ reuseWorkers: true,
156
+ basis: { format: 'rgba32' },
157
+ 'basis-nodejs': {
158
+ format: 'rgba32',
159
+ workerUrl: './modules/textures/dist/basis-nodejs-worker.js'
160
+ },
161
+ 'draco-nodejs': { workerUrl: './modules/draco/dist/draco-nodejs-worker.js' }
162
+ }
163
+ };
114
164
  if (preloadOptions.headers) {
115
165
  tilesetOptions.loadOptions.fetch = { headers: preloadOptions.headers };
116
166
  }
@@ -118,7 +168,7 @@ class I3SConverter {
118
168
  const sourceTilesetJson = await (0, core_1.load)(inputUrl, this.Loader, tilesetOptions.loadOptions);
119
169
  // console.log(tilesetJson); // eslint-disable-line
120
170
  this.sourceTileset = new tiles_1.Tileset3D(sourceTilesetJson, tilesetOptions);
121
- await this._createAndSaveTileset(outputPath, tilesetName);
171
+ await this._createAndSaveTileset(outputPath, tilesetName, sourceTilesetJson?.root?.boundingVolume?.region);
122
172
  await this._finishConversion({ slpk: Boolean(slpk), outputPath, tilesetName });
123
173
  return sourceTilesetJson;
124
174
  }
@@ -136,7 +186,7 @@ class I3SConverter {
136
186
  * @param outputPath - path to save output data
137
187
  * @param tilesetName - new tileset path
138
188
  */
139
- async _createAndSaveTileset(outputPath, tilesetName) {
189
+ async _createAndSaveTileset(outputPath, tilesetName, boundingVolumeRegion) {
140
190
  const tilesetPath = (0, path_1.join)(`${outputPath}`, `${tilesetName}`);
141
191
  // Removing the tilesetPath needed to exclude erroneous files after conversion
142
192
  try {
@@ -146,29 +196,35 @@ class I3SConverter {
146
196
  // do nothing
147
197
  }
148
198
  this.layers0Path = (0, path_1.join)(tilesetPath, 'SceneServer', 'layers', '0');
149
- this._formLayers0(tilesetName);
199
+ this._formLayers0(tilesetName, boundingVolumeRegion);
150
200
  this.materialDefinitions = [];
151
201
  this.materialMap = new Map();
152
202
  const sourceRootTile = this.sourceTileset.root;
153
203
  const boundingVolumes = (0, coordinate_converter_1.createBoundingVolumes)(sourceRootTile, this.geoidHeightModel);
154
- const parentId = this.nodePages.push({
204
+ await this.nodePages.push({
155
205
  index: 0,
156
206
  lodThreshold: 0,
157
207
  obb: boundingVolumes.obb,
158
208
  children: []
159
209
  });
160
- const isCreateSlpk = this.options.slpk;
161
- const root0 = this._formRootNodeIndexDocument(boundingVolumes);
162
- await this._convertNodesTree(root0, sourceRootTile, parentId, boundingVolumes);
210
+ const rootNode = await node_index_document_1.NodeIndexDocument.createRootNode(boundingVolumes, this);
211
+ await this._convertNodesTree(rootNode, sourceRootTile);
163
212
  this.layers0.materialDefinitions = this.materialDefinitions;
213
+ // @ts-ignore
214
+ this.layers0.geometryDefinitions = (0, json_map_transform_1.default)(this.geometryConfigs.map((config) => ({
215
+ geometryConfig: { ...config, draco: this.options.draco }
216
+ })), (0, geometry_definitions_1.GEOMETRY_DEFINITION)());
164
217
  if (this.layersHasTexture === false) {
165
218
  this.layers0.store.defaultGeometrySchema.ordering =
166
219
  this.layers0.store.defaultGeometrySchema.ordering.filter((attribute) => attribute !== 'uv0');
167
220
  }
168
221
  await this._writeLayers0();
169
222
  (0, create_scene_server_path_1.createSceneServerPath)(tilesetName, this.layers0, tilesetPath);
170
- await this._writeNodeIndexDocument(root0, 'root', (0, path_1.join)(this.layers0Path, 'nodes', 'root'));
171
- await this.nodePages.save(this.layers0Path, this.writeQueue, isCreateSlpk);
223
+ for (const filePath of this.compressList || []) {
224
+ await (0, compress_util_1.compressFileWithGzip)(filePath);
225
+ await (0, file_utils_1.removeFile)(filePath);
226
+ }
227
+ await this.nodePages.save();
172
228
  await this.writeQueue.finalize();
173
229
  await this._createSlpk(tilesetPath);
174
230
  }
@@ -176,8 +232,12 @@ class I3SConverter {
176
232
  * Form object of 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
177
233
  * @param tilesetName - Name of layer
178
234
  */
179
- _formLayers0(tilesetName) {
235
+ _formLayers0(tilesetName, boundingVolumeRegion) {
180
236
  const fullExtent = (0, coordinate_converter_1.convertBoundingVolumeToI3SFullExtent)(this.sourceTileset?.boundingVolume || this.sourceTileset?.root?.boundingVolume);
237
+ if (boundingVolumeRegion) {
238
+ fullExtent.zmin = boundingVolumeRegion[4];
239
+ fullExtent.zmax = boundingVolumeRegion[5];
240
+ }
181
241
  const extent = [fullExtent.xmin, fullExtent.ymin, fullExtent.xmax, fullExtent.ymax];
182
242
  const layers0data = {
183
243
  version: `{${(0, uuid_1.v4)().toUpperCase()}}`,
@@ -196,99 +256,46 @@ class I3SConverter {
196
256
  };
197
257
  this.layers0 = (0, json_map_transform_1.default)(layers0data, (0, layers_1.LAYERS)());
198
258
  }
199
- /**
200
- * Convert and save the layer and embedded tiles
201
- * @param boundingVolumes - mbs and obb data about node's bounding volume
202
- * @return 3DNodeIndexDocument data https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
203
- */
204
- _formRootNodeIndexDocument(boundingVolumes) {
205
- const root0data = {
206
- version: `{${(0, uuid_1.v4)().toUpperCase()}}`,
207
- id: 'root',
208
- level: 0,
209
- lodSelection: [
210
- {
211
- metricType: 'maxScreenThresholdSQ',
212
- maxError: 0
213
- },
214
- {
215
- metricType: 'maxScreenThreshold',
216
- maxError: 0
217
- }
218
- ],
219
- ...boundingVolumes,
220
- children: []
221
- };
222
- return (0, json_map_transform_1.default)(root0data, (0, node_1.NODE)());
223
- }
224
259
  /**
225
260
  * Form object of 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
226
- * @param root0 - 3DNodeIndexDocument of root node https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
261
+ * @param rootNode - 3DNodeIndexDocument of root node https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
227
262
  * @param sourceRootTile - Source (3DTile) tile data
228
- * @param parentId - node id in node pages
229
- * @param boundingVolumes - mbs and obb data about node's bounding volume
230
263
  */
231
- async _convertNodesTree(root0, sourceRootTile, parentId, boundingVolumes) {
264
+ async _convertNodesTree(rootNode, sourceRootTile) {
232
265
  await this.sourceTileset._loadTile(sourceRootTile);
233
266
  if (this.isContentSupported(sourceRootTile)) {
234
- root0.children = root0.children || [];
235
- root0.children.push({
236
- id: '1',
237
- href: './1',
238
- ...boundingVolumes
239
- });
240
- const [child] = await this._createNode(root0, sourceRootTile, parentId, 0);
241
- const childPath = (0, path_1.join)(this.layers0Path, 'nodes', child.path);
242
- if (this.options.slpk) {
243
- this.writeQueue.enqueue({
244
- archiveKey: 'nodes/1/3dNodeIndexDocument.json.gz',
245
- writePromise: (0, file_utils_1.writeFileForSlpk)(childPath, JSON.stringify(child), '3dNodeIndexDocument.json')
246
- });
247
- }
248
- else {
249
- this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(childPath, JSON.stringify(child)) });
267
+ const childNodes = await this._createNode(rootNode, sourceRootTile, 0);
268
+ for (const childNode of childNodes) {
269
+ await childNode.save();
250
270
  }
271
+ await rootNode.addChildren(childNodes);
251
272
  }
252
273
  else {
253
274
  await this._addChildrenWithNeighborsAndWriteFile({
254
- parentNode: root0,
275
+ parentNode: rootNode,
255
276
  sourceTiles: sourceRootTile.children,
256
- parentId,
257
277
  level: 1
258
278
  });
259
279
  }
260
280
  await sourceRootTile.unloadContent();
281
+ await rootNode.save();
261
282
  }
262
283
  /**
263
284
  * Write 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md in file
264
285
  */
265
286
  async _writeLayers0() {
266
287
  if (this.options.slpk) {
267
- this.writeQueue.enqueue({
288
+ await this.writeQueue.enqueue({
268
289
  archiveKey: '3dSceneLayer.json.gz',
269
- writePromise: (0, file_utils_1.writeFileForSlpk)(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
290
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
270
291
  });
271
292
  }
272
293
  else {
273
- this.writeQueue.enqueue({
274
- writePromise: (0, file_utils_1.writeFile)(this.layers0Path, JSON.stringify(this.layers0))
294
+ await this.writeQueue.enqueue({
295
+ writePromise: () => (0, file_utils_1.writeFile)(this.layers0Path, JSON.stringify(this.layers0))
275
296
  });
276
297
  }
277
298
  }
278
- /**
279
- * Write 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md in file
280
- */
281
- async _writeNodeIndexDocument(root0, nodePath, rootPath) {
282
- if (this.options.slpk) {
283
- this.writeQueue.enqueue({
284
- archiveKey: `nodes/${nodePath}/3dNodeIndexDocument.json.gz`,
285
- writePromise: (0, file_utils_1.writeFileForSlpk)(rootPath, JSON.stringify(root0), '3dNodeIndexDocument.json')
286
- });
287
- }
288
- else {
289
- this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(rootPath, JSON.stringify(root0)) });
290
- }
291
- }
292
299
  /**
293
300
  * Pack files into *.slpk archive
294
301
  * @param tilesetPath - Path to save file
@@ -327,116 +334,101 @@ class I3SConverter {
327
334
  /**
328
335
  * Add child nodes recursively and write them to files
329
336
  * @param data - arguments
337
+ * @param data.parentNode - 3DNodeIndexDocument of parent node
330
338
  * @param data.sourceTiles - array of source child nodes
331
- * @param data.parentNode - 3DNodeIndexDocument of parent node for processing child nodes
332
- * @param data.parentId - id of parent node in node pages
333
339
  * @param data.level - level of node (distanse to root node in the tree)
334
340
  */
335
341
  async _addChildrenWithNeighborsAndWriteFile(data) {
336
- const childNodes = [];
337
- await this._addChildren({ ...data, childNodes });
338
- await this._addNeighborsAndWriteFile(data.parentNode, childNodes);
342
+ await this._addChildren(data);
343
+ await data.parentNode.addNeighbors();
344
+ }
345
+ /**
346
+ * Convert nested subtree of 3DTiles dataset
347
+ * @param param0
348
+ * @param data.parentNode - 3DNodeIndexDocument of parent node
349
+ * @param param0.sourceTile - source 3DTile data
350
+ * @param param0.level - tree level
351
+ */
352
+ async convertNestedTileset({ parentNode, sourceTile, level }) {
353
+ await this.sourceTileset._loadTile(sourceTile);
354
+ await this._addChildren({
355
+ parentNode,
356
+ sourceTiles: sourceTile.children,
357
+ level: level + 1
358
+ });
359
+ await sourceTile.unloadContent();
360
+ }
361
+ /**
362
+ * Convert 3DTiles tile to I3S node
363
+ * @param param0
364
+ * @param param0.parentNode - 3DNodeIndexDocument of parent node
365
+ * @param param0.sourceTile - source 3DTile data
366
+ * @param param0.level - tree level
367
+ */
368
+ async convertNode({ parentNode, sourceTile, level }) {
369
+ const childNodes = await this._createNode(parentNode, sourceTile, level);
370
+ await parentNode.addChildren(childNodes);
339
371
  }
340
372
  /**
341
373
  * Add child nodes recursively and write them to files
342
- * @param data - arguments
343
- * @param data.childNodes - array of target child nodes
344
- * @param data.sourceTiles - array of source child nodes
345
- * @param data.parentNode - 3DNodeIndexDocument of parent node for processing child nodes
346
- * @param data.parentId - id of parent node in node pages
347
- * @param data.level - level of node (distanse to root node in the tree)
374
+ * @param param0 - arguments
375
+ * @param param0.parentNode - 3DNodeIndexDocument of parent node
376
+ * @param param0.sourceTile - source 3DTile data
377
+ * @param param0.level - tree level
348
378
  */
349
379
  async _addChildren(data) {
350
- const { childNodes, sourceTiles, parentNode, parentId, level } = data;
380
+ const { sourceTiles, parentNode, level } = data;
351
381
  if (this.options.maxDepth && level > this.options.maxDepth) {
352
382
  return;
353
383
  }
384
+ const promises = [];
354
385
  for (const sourceTile of sourceTiles) {
355
386
  if (sourceTile.type === 'json') {
356
- await this.sourceTileset._loadTile(sourceTile);
357
- await this._addChildren({
358
- parentNode,
359
- sourceTiles: sourceTile.children,
360
- childNodes,
361
- parentId,
362
- level: level + 1
363
- });
364
- await sourceTile.unloadContent();
387
+ if (this.options.instantNodeWriting) {
388
+ await this.convertNestedTileset({ parentNode, sourceTile, level });
389
+ }
390
+ else {
391
+ promises.push(this.convertNestedTileset({ parentNode, sourceTile, level }));
392
+ }
365
393
  }
366
394
  else {
367
- const children = await this._createNode(parentNode, sourceTile, parentId, level);
368
- parentNode.children = parentNode.children || [];
369
- for (const child of children) {
370
- parentNode.children.push({
371
- id: child.id,
372
- href: `../${child.path}`,
373
- obb: child.obb,
374
- mbs: child.mbs
375
- });
376
- childNodes.push(child);
395
+ if (this.options.instantNodeWriting) {
396
+ await this.convertNode({ parentNode, sourceTile, level });
397
+ }
398
+ else {
399
+ promises.push(this.convertNode({ parentNode, sourceTile, level }));
377
400
  }
378
401
  }
379
402
  if (sourceTile.id) {
380
403
  console.log(sourceTile.id); // eslint-disable-line
381
404
  }
382
405
  }
383
- }
384
- /**
385
- * Add neightbors to 3DNodeIndexDocument and write it in a file
386
- * @param parentNode - arguments
387
- * @param childNodes - array of target child nodes
388
- */
389
- async _addNeighborsAndWriteFile(parentNode, childNodes) {
390
- for (const node of childNodes) {
391
- const childPath = (0, path_1.join)(this.layers0Path, 'nodes', node.path);
392
- const nodePath = node.path;
393
- delete node.path;
394
- // Don't do large amount of "neightbors" to avoid big memory consumption
395
- if (Number(parentNode?.children?.length) < 1000) {
396
- for (const neighbor of parentNode.children || []) {
397
- // eslint-disable-next-line max-depth
398
- if (node.id === neighbor.id) {
399
- continue; // eslint-disable-line
400
- }
401
- if (node.neighbors) {
402
- node.neighbors.push({ ...neighbor });
403
- }
404
- }
405
- }
406
- else {
407
- // eslint-disable-next-line no-console, no-undef
408
- console.warn(`Node ${node.id}: neighbors attribute is omited because of large number of neigbors`);
409
- delete node.neighbors;
410
- }
411
- await this._writeNodeIndexDocument(node, nodePath, childPath);
412
- node.neighbors = [];
413
- }
406
+ await Promise.all(promises);
414
407
  }
415
408
  /**
416
409
  * Convert tile to one or more I3S nodes
417
- * @param parentTile - parent 3DNodeIndexDocument
418
- * @param sourceTile - source tile (3DTile)
419
- * @param parentId - id of parent node in node pages
420
- * @param level - level of node (distanse to root node in the tree)
410
+ * @param parentNode - 3DNodeIndexDocument of parent node
411
+ * @param sourceTile - source 3DTile data
412
+ * @param level - tree level
421
413
  */
422
- async _createNode(parentTile, sourceTile, parentId, level) {
423
- if (this.validate) {
424
- this._checkAddRefinementTypeForTile(sourceTile);
425
- }
414
+ async _createNode(parentNode, sourceTile, level) {
415
+ this._checkAddRefinementTypeForTile(sourceTile);
426
416
  await this._updateTilesetOptions();
427
417
  await this.sourceTileset._loadTile(sourceTile);
428
418
  let boundingVolumes = (0, coordinate_converter_1.createBoundingVolumes)(sourceTile, this.geoidHeightModel);
429
- const batchTable = sourceTile?.content?.batchTableJson;
430
- if (batchTable) {
431
- this._convertAttributeStorageInfo(sourceTile.content);
419
+ const propertyTable = (0, geometry_converter_1.getPropertyTable)(sourceTile.content);
420
+ if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
421
+ this._convertPropertyTableToNodeAttributes(propertyTable);
432
422
  }
433
- const resourcesData = await this._convertResources(sourceTile);
423
+ const resourcesData = await this._convertResources(sourceTile, parentNode.inPageId, propertyTable);
434
424
  const nodes = [];
425
+ const nodeIds = [];
435
426
  const nodesInPage = [];
436
427
  const emptyResources = {
437
428
  geometry: null,
438
429
  compressedGeometry: null,
439
430
  texture: null,
431
+ hasUvRegions: false,
440
432
  sharedResources: null,
441
433
  meshMaterial: null,
442
434
  vertexCount: null,
@@ -451,63 +443,51 @@ class I3SConverter {
451
443
  }
452
444
  const lodSelection = (0, lod_conversion_utils_1.convertGeometricErrorToScreenThreshold)(sourceTile, boundingVolumes);
453
445
  const maxScreenThresholdSQ = lodSelection.find((val) => val.metricType === 'maxScreenThresholdSQ') || { maxError: 0 };
454
- const nodeInPage = this._createNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentId, resources);
455
- const node = this._createNodeIndexDocument(parentTile, boundingVolumes, lodSelection, nodeInPage, resources);
446
+ const nodeInPage = await this._updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentNode.inPageId, resources);
447
+ const nodeData = await node_index_document_1.NodeIndexDocument.createNodeIndexDocument(parentNode, boundingVolumes, lodSelection, nodeInPage, resources);
448
+ const node = await new node_index_document_1.NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
449
+ nodes.push(node);
456
450
  if (nodeInPage.mesh) {
457
- await this._writeResources(resources, node.path);
451
+ await this._writeResources(resources, node.id);
458
452
  }
459
453
  if (this.validate) {
460
- this.boundingVolumeWarnings = (0, node_debug_1.validateNodeBoundingVolumes)(node);
454
+ this.boundingVolumeWarnings = (0, node_debug_1.validateNodeBoundingVolumes)(nodeData);
461
455
  if (this.boundingVolumeWarnings && this.boundingVolumeWarnings.length) {
462
456
  console.warn('Bounding Volume Warnings: ', ...this.boundingVolumeWarnings); //eslint-disable-line
463
457
  }
464
458
  }
465
- nodes.push(node);
459
+ nodeIds.push(nodeInPage.index);
466
460
  nodesInPage.push(nodeInPage);
467
461
  }
468
462
  sourceTile.unloadContent();
469
463
  await this._addChildrenWithNeighborsAndWriteFile({
470
464
  parentNode: nodes[0],
471
465
  sourceTiles: sourceTile.children,
472
- parentId: nodesInPage[0].index,
473
466
  level: level + 1
474
467
  });
475
468
  return nodes;
476
469
  }
477
- /**
478
- * Convert attributesStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
479
- * from B3DM batch table
480
- * @param sourceTileContent - tile content of 3DTile
481
- * @return {void}
482
- */
483
- _convertAttributeStorageInfo(sourceTileContent) {
484
- // In legacy b3dm files sometimes sourceTileContent is null.
485
- const batchTable = sourceTileContent && sourceTileContent.batchTableJson;
486
- if (batchTable && !this.layers0?.attributeStorageInfo?.length) {
487
- this._convertBatchTableInfoToNodeAttributes(batchTable);
488
- }
489
- }
490
470
  /**
491
471
  * Convert tile to one or more I3S nodes
492
472
  * @param sourceTile - source tile (3DTile)
493
- * result.geometry - ArrayBuffer with geometry attributes
494
- * result.compressedGeometry - ArrayBuffer with compressed (draco) geometry
495
- * result.texture - texture image
496
- * result.sharedResources - shared resource data object
497
- * result.meshMaterial - PBR-like material object
498
- * result.vertexCount - number of vertices in geometry
499
- * result.attributes - feature attributes
500
- * result.featureCount - number of features
473
+ * @param parentId - id of parent node in node pages
474
+ * @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
475
+ * @returns - converted node resources
501
476
  */
502
- async _convertResources(sourceTile) {
477
+ async _convertResources(sourceTile, parentId, propertyTable) {
503
478
  if (!this.isContentSupported(sourceTile)) {
504
479
  return null;
505
480
  }
506
- const resourcesData = await (0, geometry_converter_1.default)(sourceTile.content, Number(this.nodePages.nodesCounter), this.featuresHashArray, this.layers0?.attributeStorageInfo, this.options.draco, this.generateBoundingVolumes, this.geoidHeightModel, this.workerSource);
481
+ const draftObb = {
482
+ center: [],
483
+ halfSize: [],
484
+ quaternion: []
485
+ };
486
+ const resourcesData = await (0, geometry_converter_1.default)(sourceTile.content, async () => (await this.nodePages.push({ index: 0, obb: draftObb }, parentId)).index, propertyTable, this.featuresHashArray, this.layers0?.attributeStorageInfo, this.options.draco, this.generateBoundingVolumes, this.options.mergeMaterials, this.geoidHeightModel, this.workerSource);
507
487
  return resourcesData;
508
488
  }
509
489
  /**
510
- * Create a new node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
490
+ * Update node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
511
491
  * in node pages (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodePage.cmn.md)
512
492
  * @param maxScreenThresholdSQ - Level of Details (LOD) metric
513
493
  * @param boundingVolumes - Bounding volumes
@@ -518,10 +498,11 @@ class I3SConverter {
518
498
  * @param resources.texture - texture image
519
499
  * @param resources.vertexCount - number of vertices in geometry
520
500
  * @param resources.featureCount - number of features
501
+ * @param resources.geometry - Uint8Array with geometry attributes
521
502
  * @return the node object in node pages
522
503
  */
523
- _createNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentId, resources) {
524
- const { meshMaterial, texture, vertexCount, featureCount, geometry } = resources;
504
+ async _updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentId, resources) {
505
+ const { meshMaterial, texture, vertexCount, featureCount, geometry, hasUvRegions } = resources;
525
506
  const nodeInPage = {
526
507
  index: 0,
527
508
  lodThreshold: maxScreenThresholdSQ.maxError,
@@ -531,7 +512,7 @@ class I3SConverter {
531
512
  if (geometry && this.isContentSupported(sourceTile)) {
532
513
  nodeInPage.mesh = {
533
514
  geometry: {
534
- definition: texture ? 0 : 1,
515
+ definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
535
516
  resource: 0
536
517
  },
537
518
  attribute: {
@@ -542,69 +523,31 @@ class I3SConverter {
542
523
  }
543
524
  };
544
525
  }
545
- const nodeId = this.nodePages.push(nodeInPage, parentId);
526
+ let nodeId = resources.nodeId;
527
+ let node;
528
+ if (!nodeId) {
529
+ node = await this.nodePages.push(nodeInPage, parentId);
530
+ }
531
+ else {
532
+ node = await this.nodePages.getNodeById(nodeId);
533
+ }
534
+ node_pages_1.default.updateAll(node, nodeInPage);
546
535
  if (meshMaterial) {
547
- this.nodePages.updateMaterialByNodeId(nodeId, this._findOrCreateMaterial(meshMaterial));
536
+ node_pages_1.default.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
548
537
  }
549
538
  if (texture) {
550
539
  const texelCountHint = texture.image.height * texture.image.width;
551
- this.nodePages.updateTexelCountHintByNodeId(nodeId, texelCountHint);
540
+ node_pages_1.default.updateTexelCountHintByNodeId(node, texelCountHint);
552
541
  }
553
542
  if (vertexCount) {
554
543
  this.vertexCounter += vertexCount;
555
- this.nodePages.updateVertexCountByNodeId(nodeId, vertexCount);
544
+ node_pages_1.default.updateVertexCountByNodeId(node, vertexCount);
556
545
  }
557
- this.nodePages.updateNodeAttributeByNodeId(nodeId);
546
+ node_pages_1.default.updateNodeAttributeByNodeId(node);
558
547
  if (featureCount) {
559
- this.nodePages.updateFeatureCountByNodeId(nodeId, featureCount);
560
- }
561
- return nodeInPage;
562
- }
563
- /**
564
- * Create a new node page object in node pages
565
- * @param parentNode - 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object of the parent node
566
- * @param boundingVolumes - Bounding volumes
567
- * @param lodSelection - Level of Details (LOD) metrics
568
- * @param nodeInPage - corresponding node object in a node page
569
- * @param resources - the node resources data
570
- * @param resources.texture - texture image
571
- * @param resources.attributes - feature attributes
572
- * @return 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object
573
- */
574
- _createNodeIndexDocument(parentNode, boundingVolumes, lodSelection, nodeInPage, resources) {
575
- const { texture, attributes } = resources;
576
- const nodeId = nodeInPage.index;
577
- const nodeData = {
578
- version: parentNode.version,
579
- id: nodeId.toString(),
580
- path: nodeId.toString(),
581
- level: parentNode.level + 1,
582
- ...boundingVolumes,
583
- lodSelection,
584
- parentNode: {
585
- id: parentNode.id,
586
- href: `../${parentNode.id}`,
587
- mbs: parentNode.mbs,
588
- obb: parentNode.obb
589
- },
590
- children: [],
591
- neighbors: []
592
- };
593
- const node = (0, json_map_transform_1.default)(nodeData, (0, node_1.NODE)());
594
- if (nodeInPage.mesh) {
595
- node.geometryData = [{ href: './geometries/0' }];
596
- node.sharedResource = { href: './shared' };
597
- if (texture) {
598
- node.textureData = [{ href: './textures/0' }, { href: './textures/1' }];
599
- }
600
- if (attributes && attributes.length && this.layers0?.attributeStorageInfo?.length) {
601
- node.attributeData = [];
602
- for (let index = 0; index < attributes.length; index++) {
603
- const folderName = this.layers0.attributeStorageInfo[index].key;
604
- node.attributeData.push({ href: `./attributes/${folderName}/0` });
605
- }
606
- }
548
+ node_pages_1.default.updateFeatureCountByNodeId(node, featureCount);
607
549
  }
550
+ this.nodePages.saveNode(node);
608
551
  return node;
609
552
  }
610
553
  /**
@@ -636,29 +579,29 @@ class I3SConverter {
636
579
  async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath) {
637
580
  if (this.options.slpk) {
638
581
  const slpkGeometryPath = (0, path_1.join)(childPath, 'geometries');
639
- this.writeQueue.enqueue({
582
+ await this.writeQueue.enqueue({
640
583
  archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
641
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkGeometryPath, geometryBuffer, '0.bin')
584
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkGeometryPath, geometryBuffer, '0.bin')
642
585
  });
643
586
  }
644
587
  else {
645
588
  const geometryPath = (0, path_1.join)(childPath, 'geometries/0/');
646
- this.writeQueue.enqueue({
647
- writePromise: (0, file_utils_1.writeFile)(geometryPath, geometryBuffer, 'index.bin')
589
+ await this.writeQueue.enqueue({
590
+ writePromise: () => (0, file_utils_1.writeFile)(geometryPath, geometryBuffer, 'index.bin')
648
591
  });
649
592
  }
650
593
  if (this.options.draco) {
651
594
  if (this.options.slpk) {
652
595
  const slpkCompressedGeometryPath = (0, path_1.join)(childPath, 'geometries');
653
- this.writeQueue.enqueue({
596
+ await this.writeQueue.enqueue({
654
597
  archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
655
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
598
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
656
599
  });
657
600
  }
658
601
  else {
659
602
  const compressedGeometryPath = (0, path_1.join)(childPath, 'geometries/1/');
660
- this.writeQueue.enqueue({
661
- writePromise: (0, file_utils_1.writeFile)(compressedGeometryPath, compressedGeometry, 'index.bin')
603
+ await this.writeQueue.enqueue({
604
+ writePromise: () => (0, file_utils_1.writeFile)(compressedGeometryPath, compressedGeometry, 'index.bin')
662
605
  });
663
606
  }
664
607
  }
@@ -679,14 +622,14 @@ class I3SConverter {
679
622
  const sharedDataStr = JSON.stringify(sharedData);
680
623
  if (this.options.slpk) {
681
624
  const slpkSharedPath = (0, path_1.join)(childPath, 'shared');
682
- this.writeQueue.enqueue({
625
+ await this.writeQueue.enqueue({
683
626
  archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
684
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkSharedPath, sharedDataStr, 'sharedResource.json')
627
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkSharedPath, sharedDataStr, 'sharedResource.json')
685
628
  });
686
629
  }
687
630
  else {
688
631
  const sharedPath = (0, path_1.join)(childPath, 'shared/');
689
- this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(sharedPath, sharedDataStr) });
632
+ await this.writeQueue.enqueue({ writePromise: () => (0, file_utils_1.writeFile)(sharedPath, sharedDataStr) });
690
633
  }
691
634
  }
692
635
  /**
@@ -732,6 +675,7 @@ class I3SConverter {
732
675
  }
733
676
  if (!this.layers0.textureSetDefinitions.length) {
734
677
  this.layers0.textureSetDefinitions.push({ formats });
678
+ this.layers0.textureSetDefinitions.push({ formats, atlas: true });
735
679
  }
736
680
  }
737
681
  }
@@ -747,15 +691,15 @@ class I3SConverter {
747
691
  if (this.options.slpk) {
748
692
  const slpkTexturePath = (0, path_1.join)(childPath, 'textures');
749
693
  const compress = false;
750
- this.writeQueue.enqueue({
694
+ await this.writeQueue.enqueue({
751
695
  archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
752
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkTexturePath, textureData, `${name}.${format}`, compress)
696
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkTexturePath, textureData, `${name}.${format}`, compress)
753
697
  });
754
698
  }
755
699
  else {
756
700
  const texturePath = (0, path_1.join)(childPath, `textures/${name}/`);
757
- this.writeQueue.enqueue({
758
- writePromise: (0, file_utils_1.writeFile)(texturePath, textureData, `index.${format}`)
701
+ await this.writeQueue.enqueue({
702
+ writePromise: () => (0, file_utils_1.writeFile)(texturePath, textureData, `index.${format}`)
759
703
  });
760
704
  }
761
705
  }
@@ -772,15 +716,15 @@ class I3SConverter {
772
716
  const fileBuffer = new Uint8Array(attributes[index]);
773
717
  if (this.options.slpk) {
774
718
  const slpkAttributesPath = (0, path_1.join)(childPath, 'attributes', folderName);
775
- this.writeQueue.enqueue({
719
+ await this.writeQueue.enqueue({
776
720
  archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
777
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkAttributesPath, fileBuffer, '0.bin')
721
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkAttributesPath, fileBuffer, '0.bin')
778
722
  });
779
723
  }
780
724
  else {
781
725
  const attributesPath = (0, path_1.join)(childPath, `attributes/${folderName}/0`);
782
- this.writeQueue.enqueue({
783
- writePromise: (0, file_utils_1.writeFile)(attributesPath, fileBuffer, 'index.bin')
726
+ await this.writeQueue.enqueue({
727
+ writePromise: () => (0, file_utils_1.writeFile)(attributesPath, fileBuffer, 'index.bin')
784
728
  });
785
729
  }
786
730
  }
@@ -810,127 +754,46 @@ class I3SConverter {
810
754
  _findOrCreateMaterial(material) {
811
755
  const hash = (0, md5_1.default)(JSON.stringify(material));
812
756
  if (this.materialMap.has(hash)) {
813
- return this.materialMap.get(hash);
757
+ return this.materialMap.get(hash) || 0;
814
758
  }
815
759
  const newMaterialId = this.materialDefinitions.push(material) - 1;
816
760
  this.materialMap.set(hash, newMaterialId);
817
761
  return newMaterialId;
818
762
  }
819
763
  /**
820
- * Generate storage attribute for map segmentation.
821
- * @param attributeIndex - order index of attribute (f_0, f_1 ...).
822
- * @param key - attribute key from batch table.\
823
- * @param attributeType - attribute type.
824
- * @return Updated storageAttribute.
825
- */
826
- _createdStorageAttribute(attributeIndex, key, attributeType) {
827
- const storageAttribute = {
828
- key: `f_${attributeIndex}`,
829
- name: key,
830
- ordering: ['attributeValues'],
831
- header: [{ property: 'count', valueType: 'UInt32' }],
832
- attributeValues: { valueType: 'Int32', valuesPerElement: 1 }
833
- };
834
- switch (attributeType) {
835
- case OBJECT_ID_TYPE:
836
- this._setupIdAttribute(storageAttribute);
837
- break;
838
- case STRING_TYPE:
839
- this._setupStringAttribute(storageAttribute);
840
- break;
841
- case DOUBLE_TYPE:
842
- this._setupDoubleAttribute(storageAttribute);
843
- break;
844
- case SHORT_INT_TYPE:
845
- break;
846
- default:
847
- this._setupStringAttribute(storageAttribute);
848
- }
849
- return storageAttribute;
850
- }
851
- /**
852
- * Get the attribute type for attributeStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
853
- * @param key - attribute's key
854
- * @param attribute - attribute's type in batchTable
764
+ * Get unique geometry configuration index
765
+ * In the end of conversion configurations will be transformed to geometryDefinitions array
766
+ * @param hasTexture
767
+ * @param hasUvRegions
768
+ * @returns
855
769
  */
856
- getAttributeType(key, attribute) {
857
- if (key === OBJECT_ID_TYPE) {
858
- return OBJECT_ID_TYPE;
770
+ findOrCreateGeometryDefinition(hasTexture, hasUvRegions) {
771
+ const geometryConfig = { hasTexture, hasUvRegions };
772
+ const hash = (0, md5_1.default)(JSON.stringify(geometryConfig));
773
+ if (this.geometryMap.has(hash)) {
774
+ return this.geometryMap.get(hash) || 0;
859
775
  }
860
- if (typeof attribute === STRING_TYPE) {
861
- return STRING_TYPE;
862
- }
863
- else if (typeof attribute === 'number') {
864
- return Number.isInteger(attribute) ? SHORT_INT_TYPE : DOUBLE_TYPE;
865
- }
866
- return STRING_TYPE;
867
- }
868
- /**
869
- * Setup storage attribute as string.
870
- * @param storageAttribute - attribute for map segmentation.
871
- */
872
- _setupStringAttribute(storageAttribute) {
873
- storageAttribute.ordering.unshift('attributeByteCounts');
874
- storageAttribute.header.push({ property: 'attributeValuesByteCount', valueType: 'UInt32' });
875
- storageAttribute.attributeValues = {
876
- valueType: 'String',
877
- encoding: 'UTF-8',
878
- valuesPerElement: 1
879
- };
880
- storageAttribute.attributeByteCounts = {
881
- valueType: 'UInt32',
882
- valuesPerElement: 1
883
- };
884
- }
885
- /**
886
- * Setup Id attribute for map segmentation.
887
- * @param storageAttribute - attribute for map segmentation .
888
- */
889
- _setupIdAttribute(storageAttribute) {
890
- storageAttribute.attributeValues = {
891
- valueType: 'Oid32',
892
- valuesPerElement: 1
893
- };
894
- }
895
- /**
896
- * Setup double attribute for map segmentation.
897
- * @param storageAttribute - attribute for map segmentation .
898
- */
899
- _setupDoubleAttribute(storageAttribute) {
900
- storageAttribute.attributeValues = {
901
- valueType: 'Float64',
902
- valuesPerElement: 1
903
- };
776
+ const newGeometryId = this.geometryConfigs.push(geometryConfig) - 1;
777
+ this.geometryMap.set(hash, newGeometryId);
778
+ return newGeometryId;
904
779
  }
905
780
  /**
906
- * Setup field attribute for map segmentation.
907
- * @param key - attribute for map segmentation.
908
- * @param fieldAttributeType - esri attribute type ('esriFieldTypeString' or 'esriFieldTypeOID').
781
+ * Do conversion of 3DTiles property table to I3s node attributes.
782
+ * @param propertyTable - Table with layer meta data.
909
783
  */
910
- _createFieldAttribute(key, fieldAttributeType) {
911
- return {
912
- name: key,
913
- type: fieldAttributeType,
914
- alias: key
915
- };
916
- }
917
- /**
918
- * Do conversion of 3DTiles batch table to I3s node attributes.
919
- * @param batchTable - Table with layer meta data.
920
- */
921
- _convertBatchTableInfoToNodeAttributes(batchTable) {
784
+ _convertPropertyTableToNodeAttributes(propertyTable) {
922
785
  let attributeIndex = 0;
923
- const batchTableWithObjectId = {
786
+ const propertyTableWithObjectId = {
924
787
  OBJECTID: [0],
925
- ...batchTable
788
+ ...propertyTable
926
789
  };
927
- for (const key in batchTableWithObjectId) {
928
- const firstAttribute = batchTableWithObjectId[key][0];
929
- const attributeType = this.getAttributeType(key, firstAttribute);
930
- const storageAttribute = this._createdStorageAttribute(attributeIndex, key, attributeType);
931
- const fieldAttributeType = this._getFieldAttributeType(attributeType);
932
- const fieldAttribute = this._createFieldAttribute(key, fieldAttributeType);
933
- const popupInfo = this._createPopupInfo(batchTableWithObjectId);
790
+ for (const key in propertyTableWithObjectId) {
791
+ const firstAttribute = propertyTableWithObjectId[key][0];
792
+ const attributeType = (0, feature_attributes_1.getAttributeType)(key, firstAttribute);
793
+ const storageAttribute = (0, feature_attributes_1.createdStorageAttribute)(attributeIndex, key, attributeType);
794
+ const fieldAttributeType = (0, feature_attributes_1.getFieldAttributeType)(attributeType);
795
+ const fieldAttribute = (0, feature_attributes_1.createFieldAttribute)(key, fieldAttributeType);
796
+ const popupInfo = (0, feature_attributes_1.createPopupInfo)(propertyTableWithObjectId);
934
797
  this.layers0.attributeStorageInfo.push(storageAttribute);
935
798
  this.layers0.fields.push(fieldAttribute);
936
799
  this.layers0.popupInfo = popupInfo;
@@ -938,55 +801,6 @@ class I3SConverter {
938
801
  attributeIndex += 1;
939
802
  }
940
803
  }
941
- /**
942
- * Find and return attribute type based on key form Batch table.
943
- * @param attributeType
944
- */
945
- _getFieldAttributeType(attributeType) {
946
- switch (attributeType) {
947
- case OBJECT_ID_TYPE:
948
- return 'esriFieldTypeOID';
949
- case STRING_TYPE:
950
- return 'esriFieldTypeString';
951
- case SHORT_INT_TYPE:
952
- return 'esriFieldTypeInteger';
953
- case DOUBLE_TYPE:
954
- return 'esriFieldTypeDouble';
955
- default:
956
- return 'esriFieldTypeString';
957
- }
958
- }
959
- /**
960
- * Generate popup info to show metadata on the map.
961
- * @param batchTable - Batch table data with OBJECTID.
962
- * @return data for correct rendering of popup.
963
- */
964
- _createPopupInfo(batchTable) {
965
- const title = '{OBJECTID}';
966
- const mediaInfos = [];
967
- const fieldInfos = [];
968
- const popupElements = [];
969
- const expressionInfos = [];
970
- for (const key in batchTable) {
971
- fieldInfos.push({
972
- fieldName: key,
973
- visible: true,
974
- isEditable: false,
975
- label: key
976
- });
977
- }
978
- popupElements.push({
979
- fieldInfos,
980
- type: 'fields'
981
- });
982
- return {
983
- title,
984
- mediaInfos,
985
- popupElements,
986
- fieldInfos,
987
- expressionInfos
988
- };
989
- }
990
804
  /**
991
805
  * Print statistics in the end of conversion
992
806
  * @param params - output files data