@loaders.gl/tile-converter 4.0.0-alpha.5 → 4.0.0-alpha.7

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