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

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 +42714 -45782
  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 +517 -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 +770 -1131
  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 +202 -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 +217 -509
  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 +95 -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 +250 -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 +201 -93
  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 +223 -421
  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 +315 -0
  242. package/src/i3s-converter/helpers/node-pages.ts +222 -109
  243. package/src/i3s-converter/i3s-converter.ts +269 -500
  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,89 @@ 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
  }
354
384
  for (const sourceTile of sourceTiles) {
355
385
  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();
386
+ await this.convertNestedTileset({ parentNode, sourceTile, level });
365
387
  }
366
388
  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);
377
- }
389
+ await this.convertNode({ parentNode, sourceTile, level });
378
390
  }
379
391
  if (sourceTile.id) {
380
392
  console.log(sourceTile.id); // eslint-disable-line
381
393
  }
382
394
  }
383
395
  }
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
- }
414
- }
415
396
  /**
416
397
  * 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)
398
+ * @param parentNode - 3DNodeIndexDocument of parent node
399
+ * @param sourceTile - source 3DTile data
400
+ * @param level - tree level
421
401
  */
422
- async _createNode(parentTile, sourceTile, parentId, level) {
423
- if (this.validate) {
424
- this._checkAddRefinementTypeForTile(sourceTile);
425
- }
402
+ async _createNode(parentNode, sourceTile, level) {
403
+ this._checkAddRefinementTypeForTile(sourceTile);
426
404
  await this._updateTilesetOptions();
427
405
  await this.sourceTileset._loadTile(sourceTile);
428
406
  let boundingVolumes = (0, coordinate_converter_1.createBoundingVolumes)(sourceTile, this.geoidHeightModel);
429
- const batchTable = sourceTile?.content?.batchTableJson;
430
- if (batchTable) {
431
- this._convertAttributeStorageInfo(sourceTile.content);
407
+ const propertyTable = (0, geometry_converter_1.getPropertyTable)(sourceTile.content);
408
+ if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
409
+ this._convertPropertyTableToNodeAttributes(propertyTable);
432
410
  }
433
- const resourcesData = await this._convertResources(sourceTile);
411
+ const resourcesData = await this._convertResources(sourceTile, parentNode.inPageId, propertyTable);
434
412
  const nodes = [];
413
+ const nodeIds = [];
435
414
  const nodesInPage = [];
436
415
  const emptyResources = {
437
416
  geometry: null,
438
417
  compressedGeometry: null,
439
418
  texture: null,
419
+ hasUvRegions: false,
440
420
  sharedResources: null,
441
421
  meshMaterial: null,
442
422
  vertexCount: null,
@@ -451,63 +431,51 @@ class I3SConverter {
451
431
  }
452
432
  const lodSelection = (0, lod_conversion_utils_1.convertGeometricErrorToScreenThreshold)(sourceTile, boundingVolumes);
453
433
  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);
434
+ const nodeInPage = await this._updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentNode.inPageId, resources);
435
+ const nodeData = await node_index_document_1.NodeIndexDocument.createNodeIndexDocument(parentNode, boundingVolumes, lodSelection, nodeInPage, resources);
436
+ const node = await new node_index_document_1.NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
437
+ nodes.push(node);
456
438
  if (nodeInPage.mesh) {
457
- await this._writeResources(resources, node.path);
439
+ await this._writeResources(resources, node.id);
458
440
  }
459
441
  if (this.validate) {
460
- this.boundingVolumeWarnings = (0, node_debug_1.validateNodeBoundingVolumes)(node);
442
+ this.boundingVolumeWarnings = (0, node_debug_1.validateNodeBoundingVolumes)(nodeData);
461
443
  if (this.boundingVolumeWarnings && this.boundingVolumeWarnings.length) {
462
444
  console.warn('Bounding Volume Warnings: ', ...this.boundingVolumeWarnings); //eslint-disable-line
463
445
  }
464
446
  }
465
- nodes.push(node);
447
+ nodeIds.push(nodeInPage.index);
466
448
  nodesInPage.push(nodeInPage);
467
449
  }
468
450
  sourceTile.unloadContent();
469
451
  await this._addChildrenWithNeighborsAndWriteFile({
470
452
  parentNode: nodes[0],
471
453
  sourceTiles: sourceTile.children,
472
- parentId: nodesInPage[0].index,
473
454
  level: level + 1
474
455
  });
475
456
  return nodes;
476
457
  }
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
458
  /**
491
459
  * Convert tile to one or more I3S nodes
492
460
  * @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
461
+ * @param parentId - id of parent node in node pages
462
+ * @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
463
+ * @returns - converted node resources
501
464
  */
502
- async _convertResources(sourceTile) {
465
+ async _convertResources(sourceTile, parentId, propertyTable) {
503
466
  if (!this.isContentSupported(sourceTile)) {
504
467
  return null;
505
468
  }
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);
469
+ const draftObb = {
470
+ center: [],
471
+ halfSize: [],
472
+ quaternion: []
473
+ };
474
+ 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
475
  return resourcesData;
508
476
  }
509
477
  /**
510
- * Create a new node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
478
+ * Update node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
511
479
  * in node pages (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodePage.cmn.md)
512
480
  * @param maxScreenThresholdSQ - Level of Details (LOD) metric
513
481
  * @param boundingVolumes - Bounding volumes
@@ -518,10 +486,11 @@ class I3SConverter {
518
486
  * @param resources.texture - texture image
519
487
  * @param resources.vertexCount - number of vertices in geometry
520
488
  * @param resources.featureCount - number of features
489
+ * @param resources.geometry - Uint8Array with geometry attributes
521
490
  * @return the node object in node pages
522
491
  */
523
- _createNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentId, resources) {
524
- const { meshMaterial, texture, vertexCount, featureCount, geometry } = resources;
492
+ async _updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentId, resources) {
493
+ const { meshMaterial, texture, vertexCount, featureCount, geometry, hasUvRegions } = resources;
525
494
  const nodeInPage = {
526
495
  index: 0,
527
496
  lodThreshold: maxScreenThresholdSQ.maxError,
@@ -531,7 +500,7 @@ class I3SConverter {
531
500
  if (geometry && this.isContentSupported(sourceTile)) {
532
501
  nodeInPage.mesh = {
533
502
  geometry: {
534
- definition: texture ? 0 : 1,
503
+ definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
535
504
  resource: 0
536
505
  },
537
506
  attribute: {
@@ -542,69 +511,31 @@ class I3SConverter {
542
511
  }
543
512
  };
544
513
  }
545
- const nodeId = this.nodePages.push(nodeInPage, parentId);
514
+ let nodeId = resources.nodeId;
515
+ let node;
516
+ if (!nodeId) {
517
+ node = await this.nodePages.push(nodeInPage, parentId);
518
+ }
519
+ else {
520
+ node = await this.nodePages.getNodeById(nodeId);
521
+ }
522
+ node_pages_1.default.updateAll(node, nodeInPage);
546
523
  if (meshMaterial) {
547
- this.nodePages.updateMaterialByNodeId(nodeId, this._findOrCreateMaterial(meshMaterial));
524
+ node_pages_1.default.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
548
525
  }
549
526
  if (texture) {
550
527
  const texelCountHint = texture.image.height * texture.image.width;
551
- this.nodePages.updateTexelCountHintByNodeId(nodeId, texelCountHint);
528
+ node_pages_1.default.updateTexelCountHintByNodeId(node, texelCountHint);
552
529
  }
553
530
  if (vertexCount) {
554
531
  this.vertexCounter += vertexCount;
555
- this.nodePages.updateVertexCountByNodeId(nodeId, vertexCount);
532
+ node_pages_1.default.updateVertexCountByNodeId(node, vertexCount);
556
533
  }
557
- this.nodePages.updateNodeAttributeByNodeId(nodeId);
534
+ node_pages_1.default.updateNodeAttributeByNodeId(node);
558
535
  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
- }
536
+ node_pages_1.default.updateFeatureCountByNodeId(node, featureCount);
607
537
  }
538
+ this.nodePages.saveNode(node);
608
539
  return node;
609
540
  }
610
541
  /**
@@ -636,29 +567,29 @@ class I3SConverter {
636
567
  async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath) {
637
568
  if (this.options.slpk) {
638
569
  const slpkGeometryPath = (0, path_1.join)(childPath, 'geometries');
639
- this.writeQueue.enqueue({
570
+ await this.writeQueue.enqueue({
640
571
  archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
641
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkGeometryPath, geometryBuffer, '0.bin')
572
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkGeometryPath, geometryBuffer, '0.bin')
642
573
  });
643
574
  }
644
575
  else {
645
576
  const geometryPath = (0, path_1.join)(childPath, 'geometries/0/');
646
- this.writeQueue.enqueue({
647
- writePromise: (0, file_utils_1.writeFile)(geometryPath, geometryBuffer, 'index.bin')
577
+ await this.writeQueue.enqueue({
578
+ writePromise: () => (0, file_utils_1.writeFile)(geometryPath, geometryBuffer, 'index.bin')
648
579
  });
649
580
  }
650
581
  if (this.options.draco) {
651
582
  if (this.options.slpk) {
652
583
  const slpkCompressedGeometryPath = (0, path_1.join)(childPath, 'geometries');
653
- this.writeQueue.enqueue({
584
+ await this.writeQueue.enqueue({
654
585
  archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
655
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
586
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
656
587
  });
657
588
  }
658
589
  else {
659
590
  const compressedGeometryPath = (0, path_1.join)(childPath, 'geometries/1/');
660
- this.writeQueue.enqueue({
661
- writePromise: (0, file_utils_1.writeFile)(compressedGeometryPath, compressedGeometry, 'index.bin')
591
+ await this.writeQueue.enqueue({
592
+ writePromise: () => (0, file_utils_1.writeFile)(compressedGeometryPath, compressedGeometry, 'index.bin')
662
593
  });
663
594
  }
664
595
  }
@@ -679,14 +610,14 @@ class I3SConverter {
679
610
  const sharedDataStr = JSON.stringify(sharedData);
680
611
  if (this.options.slpk) {
681
612
  const slpkSharedPath = (0, path_1.join)(childPath, 'shared');
682
- this.writeQueue.enqueue({
613
+ await this.writeQueue.enqueue({
683
614
  archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
684
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkSharedPath, sharedDataStr, 'sharedResource.json')
615
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkSharedPath, sharedDataStr, 'sharedResource.json')
685
616
  });
686
617
  }
687
618
  else {
688
619
  const sharedPath = (0, path_1.join)(childPath, 'shared/');
689
- this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(sharedPath, sharedDataStr) });
620
+ await this.writeQueue.enqueue({ writePromise: () => (0, file_utils_1.writeFile)(sharedPath, sharedDataStr) });
690
621
  }
691
622
  }
692
623
  /**
@@ -732,6 +663,7 @@ class I3SConverter {
732
663
  }
733
664
  if (!this.layers0.textureSetDefinitions.length) {
734
665
  this.layers0.textureSetDefinitions.push({ formats });
666
+ this.layers0.textureSetDefinitions.push({ formats, atlas: true });
735
667
  }
736
668
  }
737
669
  }
@@ -747,15 +679,15 @@ class I3SConverter {
747
679
  if (this.options.slpk) {
748
680
  const slpkTexturePath = (0, path_1.join)(childPath, 'textures');
749
681
  const compress = false;
750
- this.writeQueue.enqueue({
682
+ await this.writeQueue.enqueue({
751
683
  archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
752
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkTexturePath, textureData, `${name}.${format}`, compress)
684
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkTexturePath, textureData, `${name}.${format}`, compress)
753
685
  });
754
686
  }
755
687
  else {
756
688
  const texturePath = (0, path_1.join)(childPath, `textures/${name}/`);
757
- this.writeQueue.enqueue({
758
- writePromise: (0, file_utils_1.writeFile)(texturePath, textureData, `index.${format}`)
689
+ await this.writeQueue.enqueue({
690
+ writePromise: () => (0, file_utils_1.writeFile)(texturePath, textureData, `index.${format}`)
759
691
  });
760
692
  }
761
693
  }
@@ -772,15 +704,15 @@ class I3SConverter {
772
704
  const fileBuffer = new Uint8Array(attributes[index]);
773
705
  if (this.options.slpk) {
774
706
  const slpkAttributesPath = (0, path_1.join)(childPath, 'attributes', folderName);
775
- this.writeQueue.enqueue({
707
+ await this.writeQueue.enqueue({
776
708
  archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
777
- writePromise: (0, file_utils_1.writeFileForSlpk)(slpkAttributesPath, fileBuffer, '0.bin')
709
+ writePromise: () => (0, file_utils_1.writeFileForSlpk)(slpkAttributesPath, fileBuffer, '0.bin')
778
710
  });
779
711
  }
780
712
  else {
781
713
  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')
714
+ await this.writeQueue.enqueue({
715
+ writePromise: () => (0, file_utils_1.writeFile)(attributesPath, fileBuffer, 'index.bin')
784
716
  });
785
717
  }
786
718
  }
@@ -810,127 +742,46 @@ class I3SConverter {
810
742
  _findOrCreateMaterial(material) {
811
743
  const hash = (0, md5_1.default)(JSON.stringify(material));
812
744
  if (this.materialMap.has(hash)) {
813
- return this.materialMap.get(hash);
745
+ return this.materialMap.get(hash) || 0;
814
746
  }
815
747
  const newMaterialId = this.materialDefinitions.push(material) - 1;
816
748
  this.materialMap.set(hash, newMaterialId);
817
749
  return newMaterialId;
818
750
  }
819
751
  /**
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
752
+ * Get unique geometry configuration index
753
+ * In the end of conversion configurations will be transformed to geometryDefinitions array
754
+ * @param hasTexture
755
+ * @param hasUvRegions
756
+ * @returns
855
757
  */
856
- getAttributeType(key, attribute) {
857
- if (key === OBJECT_ID_TYPE) {
858
- return OBJECT_ID_TYPE;
859
- }
860
- if (typeof attribute === STRING_TYPE) {
861
- return STRING_TYPE;
758
+ findOrCreateGeometryDefinition(hasTexture, hasUvRegions) {
759
+ const geometryConfig = { hasTexture, hasUvRegions };
760
+ const hash = (0, md5_1.default)(JSON.stringify(geometryConfig));
761
+ if (this.geometryMap.has(hash)) {
762
+ return this.geometryMap.get(hash) || 0;
862
763
  }
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
- };
904
- }
905
- /**
906
- * Setup field attribute for map segmentation.
907
- * @param key - attribute for map segmentation.
908
- * @param fieldAttributeType - esri attribute type ('esriFieldTypeString' or 'esriFieldTypeOID').
909
- */
910
- _createFieldAttribute(key, fieldAttributeType) {
911
- return {
912
- name: key,
913
- type: fieldAttributeType,
914
- alias: key
915
- };
764
+ const newGeometryId = this.geometryConfigs.push(geometryConfig) - 1;
765
+ this.geometryMap.set(hash, newGeometryId);
766
+ return newGeometryId;
916
767
  }
917
768
  /**
918
- * Do conversion of 3DTiles batch table to I3s node attributes.
919
- * @param batchTable - Table with layer meta data.
769
+ * Do conversion of 3DTiles property table to I3s node attributes.
770
+ * @param propertyTable - Table with layer meta data.
920
771
  */
921
- _convertBatchTableInfoToNodeAttributes(batchTable) {
772
+ _convertPropertyTableToNodeAttributes(propertyTable) {
922
773
  let attributeIndex = 0;
923
- const batchTableWithObjectId = {
774
+ const propertyTableWithObjectId = {
924
775
  OBJECTID: [0],
925
- ...batchTable
776
+ ...propertyTable
926
777
  };
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);
778
+ for (const key in propertyTableWithObjectId) {
779
+ const firstAttribute = propertyTableWithObjectId[key][0];
780
+ const attributeType = (0, feature_attributes_1.getAttributeType)(key, firstAttribute);
781
+ const storageAttribute = (0, feature_attributes_1.createdStorageAttribute)(attributeIndex, key, attributeType);
782
+ const fieldAttributeType = (0, feature_attributes_1.getFieldAttributeType)(attributeType);
783
+ const fieldAttribute = (0, feature_attributes_1.createFieldAttribute)(key, fieldAttributeType);
784
+ const popupInfo = (0, feature_attributes_1.createPopupInfo)(propertyTableWithObjectId);
934
785
  this.layers0.attributeStorageInfo.push(storageAttribute);
935
786
  this.layers0.fields.push(fieldAttribute);
936
787
  this.layers0.popupInfo = popupInfo;
@@ -938,55 +789,6 @@ class I3SConverter {
938
789
  attributeIndex += 1;
939
790
  }
940
791
  }
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
792
  /**
991
793
  * Print statistics in the end of conversion
992
794
  * @param params - output files data