@loaders.gl/tile-converter 4.0.0-alpha.9 → 4.0.0-beta.2

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 (300) hide show
  1. package/bin/i3s-server.js +4 -0
  2. package/bin/slpk-extractor.js +4 -0
  3. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +5 -5
  4. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  5. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +10 -5
  6. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  7. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts +10 -0
  8. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -0
  9. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts +2 -1
  10. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts.map +1 -1
  11. package/dist/converter.min.js +172 -103
  12. package/dist/deps-installer/deps-installer.d.ts +3 -2
  13. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  14. package/dist/dist.min.js +32715 -32567
  15. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +97 -117
  16. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  17. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +24 -22
  18. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  19. package/dist/es5/3d-tiles-converter/helpers/load-i3s.js +63 -0
  20. package/dist/es5/3d-tiles-converter/helpers/load-i3s.js.map +1 -0
  21. package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  22. package/dist/es5/converter-cli.js +25 -65
  23. package/dist/es5/converter-cli.js.map +1 -1
  24. package/dist/es5/deps-installer/deps-installer.js +113 -39
  25. package/dist/es5/deps-installer/deps-installer.js.map +1 -1
  26. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +45 -15
  27. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  28. package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  29. package/dist/es5/i3s-converter/helpers/feature-attributes.js +8 -18
  30. package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -1
  31. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +83 -43
  32. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  33. package/dist/es5/i3s-converter/helpers/geometry-converter.js +100 -102
  34. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  35. package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  36. package/dist/es5/i3s-converter/helpers/load-3d-tiles.js +70 -4
  37. package/dist/es5/i3s-converter/helpers/load-3d-tiles.js.map +1 -1
  38. package/dist/es5/i3s-converter/helpers/node-index-document.js +3 -2
  39. package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -1
  40. package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js +47 -12
  41. package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
  42. package/dist/es5/i3s-converter/i3s-converter.js +187 -174
  43. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  44. package/dist/es5/i3s-converter/types.js +11 -11
  45. package/dist/es5/i3s-converter/types.js.map +1 -1
  46. package/dist/es5/i3s-server/README.md +46 -2
  47. package/dist/es5/i3s-server/app.js +23 -15
  48. package/dist/es5/i3s-server/app.js.map +1 -1
  49. package/dist/es5/i3s-server/bin/www.js +33 -0
  50. package/dist/es5/i3s-server/bin/www.js.map +1 -0
  51. package/dist/es5/i3s-server/controllers/index-controller.js +23 -22
  52. package/dist/es5/i3s-server/controllers/index-controller.js.map +1 -1
  53. package/dist/es5/i3s-server/controllers/slpk-controller.js +35 -38
  54. package/dist/es5/i3s-server/controllers/slpk-controller.js.map +1 -1
  55. package/dist/es5/i3s-server/routes/index.js +2 -2
  56. package/dist/es5/i3s-server/routes/index.js.map +1 -1
  57. package/dist/es5/i3s-server/routes/slpk-router.js +14 -13
  58. package/dist/es5/i3s-server/routes/slpk-router.js.map +1 -1
  59. package/dist/es5/i3s-server/utils/create-scene-server.js +7 -4
  60. package/dist/es5/i3s-server/utils/create-scene-server.js.map +1 -1
  61. package/dist/es5/i3s-server/utils/server-utils.js +49 -0
  62. package/dist/es5/i3s-server/utils/server-utils.js.map +1 -0
  63. package/dist/es5/lib/utils/cli-utils.js +57 -0
  64. package/dist/es5/lib/utils/cli-utils.js.map +1 -0
  65. package/dist/es5/lib/utils/compress-util.js +1 -1
  66. package/dist/es5/lib/utils/compress-util.js.map +1 -1
  67. package/dist/es5/lib/utils/lod-conversion-utils.js +10 -4
  68. package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
  69. package/dist/es5/pgm-loader.js +11 -3
  70. package/dist/es5/pgm-loader.js.map +1 -1
  71. package/dist/es5/slpk-extractor/slpk-extractor.js +171 -0
  72. package/dist/es5/slpk-extractor/slpk-extractor.js.map +1 -0
  73. package/dist/es5/slpk-extractor-cli.js +117 -0
  74. package/dist/es5/slpk-extractor-cli.js.map +1 -0
  75. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +51 -58
  76. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  77. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +12 -11
  78. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  79. package/dist/esm/3d-tiles-converter/helpers/load-i3s.js +32 -0
  80. package/dist/esm/3d-tiles-converter/helpers/load-i3s.js.map +1 -0
  81. package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  82. package/dist/esm/converter-cli.js +8 -48
  83. package/dist/esm/converter-cli.js.map +1 -1
  84. package/dist/esm/deps-installer/deps-installer.js +38 -12
  85. package/dist/esm/deps-installer/deps-installer.js.map +1 -1
  86. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +28 -11
  87. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  88. package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  89. package/dist/esm/i3s-converter/helpers/feature-attributes.js +10 -8
  90. package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -1
  91. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +77 -34
  92. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  93. package/dist/esm/i3s-converter/helpers/geometry-converter.js +60 -61
  94. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  95. package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  96. package/dist/esm/i3s-converter/helpers/load-3d-tiles.js +33 -4
  97. package/dist/esm/i3s-converter/helpers/load-3d-tiles.js.map +1 -1
  98. package/dist/esm/i3s-converter/helpers/node-index-document.js +2 -1
  99. package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -1
  100. package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js +37 -12
  101. package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
  102. package/dist/esm/i3s-converter/i3s-converter.js +101 -73
  103. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  104. package/dist/esm/i3s-converter/types.js +9 -9
  105. package/dist/esm/i3s-converter/types.js.map +1 -1
  106. package/dist/esm/i3s-server/README.md +46 -2
  107. package/dist/esm/i3s-server/app.js +13 -11
  108. package/dist/esm/i3s-server/app.js.map +1 -1
  109. package/dist/esm/i3s-server/bin/i3s-server.min.js +516 -0
  110. package/dist/esm/i3s-server/bin/www.js +30 -0
  111. package/dist/esm/i3s-server/bin/www.js.map +1 -0
  112. package/dist/esm/i3s-server/controllers/index-controller.js +4 -7
  113. package/dist/esm/i3s-server/controllers/index-controller.js.map +1 -1
  114. package/dist/esm/i3s-server/controllers/slpk-controller.js +9 -26
  115. package/dist/esm/i3s-server/controllers/slpk-controller.js.map +1 -1
  116. package/dist/esm/i3s-server/routes/index.js +1 -1
  117. package/dist/esm/i3s-server/routes/index.js.map +1 -1
  118. package/dist/esm/i3s-server/routes/slpk-router.js +5 -11
  119. package/dist/esm/i3s-server/routes/slpk-router.js.map +1 -1
  120. package/dist/esm/i3s-server/utils/create-scene-server.js +2 -5
  121. package/dist/esm/i3s-server/utils/create-scene-server.js.map +1 -1
  122. package/dist/esm/i3s-server/utils/server-utils.js +40 -0
  123. package/dist/esm/i3s-server/utils/server-utils.js.map +1 -0
  124. package/dist/esm/lib/utils/cli-utils.js +47 -0
  125. package/dist/esm/lib/utils/cli-utils.js.map +1 -0
  126. package/dist/esm/lib/utils/compress-util.js +1 -1
  127. package/dist/esm/lib/utils/compress-util.js.map +1 -1
  128. package/dist/esm/lib/utils/lod-conversion-utils.js +6 -4
  129. package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
  130. package/dist/esm/pgm-loader.js +7 -4
  131. package/dist/esm/pgm-loader.js.map +1 -1
  132. package/dist/esm/slpk-extractor/slpk-extractor.js +63 -0
  133. package/dist/esm/slpk-extractor/slpk-extractor.js.map +1 -0
  134. package/dist/esm/slpk-extractor-cli.js +74 -0
  135. package/dist/esm/slpk-extractor-cli.js.map +1 -0
  136. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +15 -2
  137. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
  138. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +1 -2
  139. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
  140. package/dist/i3s-converter/helpers/feature-attributes.d.ts +8 -8
  141. package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -1
  142. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  143. package/dist/i3s-converter/helpers/geometry-converter.d.ts +9 -9
  144. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  145. package/dist/i3s-converter/helpers/gltf-attributes.d.ts +3 -3
  146. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
  147. package/dist/i3s-converter/helpers/load-3d-tiles.d.ts +15 -0
  148. package/dist/i3s-converter/helpers/load-3d-tiles.d.ts.map +1 -1
  149. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  150. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts +4 -5
  151. package/dist/i3s-converter/helpers/preprocess-3d-tiles.d.ts.map +1 -1
  152. package/dist/i3s-converter/i3s-converter.d.ts +3 -2
  153. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  154. package/dist/i3s-converter/types.d.ts +48 -7
  155. package/dist/i3s-converter/types.d.ts.map +1 -1
  156. package/dist/i3s-server/app.d.ts +1 -2
  157. package/dist/i3s-server/app.d.ts.map +1 -1
  158. package/dist/i3s-server/bin/www.d.ts +3 -0
  159. package/dist/i3s-server/bin/www.d.ts.map +1 -0
  160. package/dist/i3s-server/controllers/index-controller.d.ts +6 -1
  161. package/dist/i3s-server/controllers/index-controller.d.ts.map +1 -1
  162. package/dist/i3s-server/controllers/slpk-controller.d.ts +13 -2
  163. package/dist/i3s-server/controllers/slpk-controller.d.ts.map +1 -1
  164. package/dist/i3s-server/routes/index.d.ts +1 -2
  165. package/dist/i3s-server/routes/index.d.ts.map +1 -1
  166. package/dist/i3s-server/routes/slpk-router.d.ts +2 -2
  167. package/dist/i3s-server/routes/slpk-router.d.ts.map +1 -1
  168. package/dist/i3s-server/utils/create-scene-server.d.ts +11 -5
  169. package/dist/i3s-server/utils/create-scene-server.d.ts.map +1 -1
  170. package/dist/i3s-server/utils/server-utils.d.ts +24 -0
  171. package/dist/i3s-server/utils/server-utils.d.ts.map +1 -0
  172. package/dist/lib/utils/cli-utils.d.ts +34 -0
  173. package/dist/lib/utils/cli-utils.d.ts.map +1 -0
  174. package/dist/lib/utils/lod-conversion-utils.d.ts +2 -2
  175. package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -1
  176. package/dist/pgm-loader.d.ts +9 -2
  177. package/dist/pgm-loader.d.ts.map +1 -1
  178. package/dist/slpk-extractor/slpk-extractor.d.ts +23 -0
  179. package/dist/slpk-extractor/slpk-extractor.d.ts.map +1 -0
  180. package/dist/slpk-extractor-cli.d.ts +17 -0
  181. package/dist/slpk-extractor-cli.d.ts.map +1 -0
  182. package/dist/slpk-extractor.min.js +189 -0
  183. package/package.json +27 -21
  184. package/src/3d-tiles-converter/3d-tiles-converter.ts +65 -69
  185. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +23 -19
  186. package/src/3d-tiles-converter/helpers/load-i3s.ts +52 -0
  187. package/src/3d-tiles-converter/helpers/texture-atlas.ts +6 -2
  188. package/src/converter-cli.ts +16 -74
  189. package/src/deps-installer/deps-installer.ts +56 -11
  190. package/src/i3s-converter/helpers/batch-ids-extensions.ts +77 -32
  191. package/src/i3s-converter/helpers/coordinate-converter.ts +1 -2
  192. package/src/i3s-converter/helpers/feature-attributes.ts +23 -18
  193. package/src/i3s-converter/helpers/geometry-attributes.ts +81 -44
  194. package/src/i3s-converter/helpers/geometry-converter.ts +149 -126
  195. package/src/i3s-converter/helpers/gltf-attributes.ts +9 -10
  196. package/src/i3s-converter/helpers/load-3d-tiles.ts +61 -5
  197. package/src/i3s-converter/helpers/node-index-document.ts +5 -1
  198. package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +70 -21
  199. package/src/i3s-converter/i3s-converter.ts +145 -73
  200. package/src/i3s-converter/types.ts +49 -7
  201. package/src/i3s-server/README.md +46 -2
  202. package/src/i3s-server/{app.js → app.ts} +11 -9
  203. package/src/i3s-server/bin/www.ts +38 -0
  204. package/src/i3s-server/controllers/{index-controller.js → index-controller.ts} +10 -9
  205. package/src/i3s-server/controllers/slpk-controller.ts +32 -0
  206. package/src/i3s-server/routes/{index.js → index.ts} +2 -1
  207. package/src/i3s-server/routes/{slpk-router.js → slpk-router.ts} +5 -10
  208. package/src/i3s-server/utils/create-scene-server.ts +20 -0
  209. package/src/i3s-server/utils/server-utils.ts +70 -0
  210. package/src/lib/utils/cli-utils.ts +78 -0
  211. package/src/lib/utils/compress-util.ts +1 -1
  212. package/src/lib/utils/lod-conversion-utils.ts +10 -6
  213. package/src/pgm-loader.ts +15 -7
  214. package/src/slpk-extractor/slpk-extractor.ts +101 -0
  215. package/src/slpk-extractor-cli.ts +128 -0
  216. package/dist/3d-tiles-attributes-worker.d.ts +0 -28
  217. package/dist/3d-tiles-attributes-worker.d.ts.map +0 -1
  218. package/dist/3d-tiles-attributes-worker.js +0 -3
  219. package/dist/3d-tiles-attributes-worker.js.map +0 -7
  220. package/dist/3d-tiles-converter/3d-tiles-converter.js +0 -288
  221. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +0 -269
  222. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +0 -23
  223. package/dist/3d-tiles-converter/helpers/texture-atlas.js +0 -52
  224. package/dist/3d-tiles-converter/json-templates/tileset.js +0 -43
  225. package/dist/bundle.js +0 -5
  226. package/dist/constants.js +0 -4
  227. package/dist/converter-cli.js +0 -280
  228. package/dist/deps-installer/deps-installer.js +0 -63
  229. package/dist/es5/3d-tiles-attributes-worker.js +0 -25
  230. package/dist/es5/3d-tiles-attributes-worker.js.map +0 -1
  231. package/dist/es5/i3s-attributes-worker.js +0 -25
  232. package/dist/es5/i3s-attributes-worker.js.map +0 -1
  233. package/dist/es5/i3s-server/bin/www +0 -102
  234. package/dist/es5/workers/3d-tiles-attributes-worker.js +0 -28
  235. package/dist/es5/workers/3d-tiles-attributes-worker.js.map +0 -1
  236. package/dist/es5/workers/i3s-attributes-worker.js +0 -30
  237. package/dist/es5/workers/i3s-attributes-worker.js.map +0 -1
  238. package/dist/esm/3d-tiles-attributes-worker.js +0 -16
  239. package/dist/esm/3d-tiles-attributes-worker.js.map +0 -1
  240. package/dist/esm/i3s-attributes-worker.js +0 -16
  241. package/dist/esm/i3s-attributes-worker.js.map +0 -1
  242. package/dist/esm/i3s-server/bin/www +0 -102
  243. package/dist/esm/workers/3d-tiles-attributes-worker.js +0 -8
  244. package/dist/esm/workers/3d-tiles-attributes-worker.js.map +0 -1
  245. package/dist/esm/workers/i3s-attributes-worker.js +0 -7
  246. package/dist/esm/workers/i3s-attributes-worker.js.map +0 -1
  247. package/dist/i3s-attributes-worker.d.ts +0 -45
  248. package/dist/i3s-attributes-worker.d.ts.map +0 -1
  249. package/dist/i3s-attributes-worker.js +0 -9
  250. package/dist/i3s-attributes-worker.js.map +0 -7
  251. package/dist/i3s-converter/helpers/batch-ids-extensions.js +0 -138
  252. package/dist/i3s-converter/helpers/coordinate-converter.js +0 -123
  253. package/dist/i3s-converter/helpers/create-scene-server-path.js +0 -28
  254. package/dist/i3s-converter/helpers/feature-attributes.js +0 -216
  255. package/dist/i3s-converter/helpers/geometry-attributes.js +0 -202
  256. package/dist/i3s-converter/helpers/geometry-converter.js +0 -1225
  257. package/dist/i3s-converter/helpers/gltf-attributes.js +0 -128
  258. package/dist/i3s-converter/helpers/load-3d-tiles.js +0 -53
  259. package/dist/i3s-converter/helpers/node-debug.js +0 -120
  260. package/dist/i3s-converter/helpers/node-index-document.js +0 -268
  261. package/dist/i3s-converter/helpers/node-pages.js +0 -316
  262. package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +0 -76
  263. package/dist/i3s-converter/helpers/tileset-traversal.js +0 -29
  264. package/dist/i3s-converter/i3s-converter.js +0 -911
  265. package/dist/i3s-converter/json-templates/geometry-definitions.js +0 -87
  266. package/dist/i3s-converter/json-templates/layers.js +0 -139
  267. package/dist/i3s-converter/json-templates/metadata.js +0 -25
  268. package/dist/i3s-converter/json-templates/node.js +0 -89
  269. package/dist/i3s-converter/json-templates/scene-server.js +0 -31
  270. package/dist/i3s-converter/json-templates/shared-resources.js +0 -129
  271. package/dist/i3s-converter/json-templates/store.js +0 -103
  272. package/dist/i3s-converter/types.js +0 -17
  273. package/dist/i3s-server/app.js +0 -22
  274. package/dist/i3s-server/controllers/index-controller.js +0 -23
  275. package/dist/i3s-server/controllers/slpk-controller.js +0 -32
  276. package/dist/i3s-server/routes/index.js +0 -16
  277. package/dist/i3s-server/routes/slpk-router.js +0 -33
  278. package/dist/i3s-server/utils/create-scene-server.js +0 -14
  279. package/dist/index.js +0 -10
  280. package/dist/lib/utils/compress-util.js +0 -257
  281. package/dist/lib/utils/file-utils.js +0 -139
  282. package/dist/lib/utils/geometry-utils.js +0 -18
  283. package/dist/lib/utils/lod-conversion-utils.js +0 -76
  284. package/dist/lib/utils/queue.js +0 -18
  285. package/dist/lib/utils/statistic-utills.js +0 -64
  286. package/dist/lib/utils/write-queue.js +0 -80
  287. package/dist/pgm-loader.js +0 -24
  288. package/dist/workers/3d-tiles-attributes-worker.d.ts +0 -2
  289. package/dist/workers/3d-tiles-attributes-worker.d.ts.map +0 -1
  290. package/dist/workers/3d-tiles-attributes-worker.js +0 -9
  291. package/dist/workers/i3s-attributes-worker.d.ts +0 -2
  292. package/dist/workers/i3s-attributes-worker.d.ts.map +0 -1
  293. package/dist/workers/i3s-attributes-worker.js +0 -5
  294. package/src/3d-tiles-attributes-worker.ts +0 -43
  295. package/src/i3s-attributes-worker.ts +0 -59
  296. package/src/i3s-server/bin/www +0 -102
  297. package/src/i3s-server/controllers/slpk-controller.js +0 -38
  298. package/src/i3s-server/utils/create-scene-server.js +0 -15
  299. package/src/workers/3d-tiles-attributes-worker.ts +0 -6
  300. package/src/workers/i3s-attributes-worker.ts +0 -7
@@ -4,7 +4,8 @@ import type {
4
4
  Tiles3DTileJSONPostprocessed,
5
5
  Tiles3DTilesetJSONPostprocessed
6
6
  } from '@loaders.gl/3d-tiles';
7
- import {load} from '@loaders.gl/core';
7
+ import {Tiles3DArchiveFileSystem} from '@loaders.gl/3d-tiles';
8
+ import {LoaderWithParser, load} from '@loaders.gl/core';
8
9
 
9
10
  /**
10
11
  * Load nested 3DTiles tileset. If the sourceTile is not nested tileset - do nothing
@@ -18,7 +19,7 @@ export const loadNestedTileset = async (
18
19
  sourceTile: Tiles3DTileJSONPostprocessed,
19
20
  tilesetLoadOptions: Tiles3DLoaderOptions
20
21
  ): Promise<void> => {
21
- const isTileset = sourceTile.type === 'json';
22
+ const isTileset = isNestedTileset(sourceTile);
22
23
  if (!sourceTileset || !sourceTile.contentUrl || !isTileset) {
23
24
  return;
24
25
  }
@@ -30,7 +31,11 @@ export const loadNestedTileset = async (
30
31
  assetGltfUpAxis: (sourceTileset.asset && sourceTileset.asset.gltfUpAxis) || 'Y'
31
32
  }
32
33
  };
33
- const tileContent = await load(sourceTile.contentUrl, sourceTileset.loader, loadOptions);
34
+ const tileContent = await loadFromArchive(
35
+ sourceTile.contentUrl,
36
+ sourceTileset.loader,
37
+ loadOptions
38
+ );
34
39
 
35
40
  if (tileContent.root) {
36
41
  sourceTile.children = [tileContent.root];
@@ -49,7 +54,7 @@ export const loadTile3DContent = async (
49
54
  sourceTile: Tiles3DTileJSONPostprocessed,
50
55
  tilesetLoadOptions: Tiles3DLoaderOptions
51
56
  ): Promise<Tiles3DTileContent | null> => {
52
- const isTileset = sourceTile.type === 'json';
57
+ const isTileset = isNestedTileset(sourceTile);
53
58
  if (!sourceTileset || !sourceTile.contentUrl || isTileset) {
54
59
  return null;
55
60
  }
@@ -62,7 +67,58 @@ export const loadTile3DContent = async (
62
67
  assetGltfUpAxis: (sourceTileset.asset && sourceTileset.asset.gltfUpAxis) || 'Y'
63
68
  }
64
69
  };
65
- const tileContent = await load(sourceTile.contentUrl, sourceTileset.loader, loadOptions);
70
+ const tileContent = await loadFromArchive(
71
+ sourceTile.contentUrl,
72
+ sourceTileset.loader,
73
+ loadOptions
74
+ );
66
75
 
67
76
  return tileContent;
68
77
  };
78
+
79
+ /**
80
+ * Load a resource with load options and .3tz format support
81
+ * @param url - resource URL
82
+ * @param loader - loader to parse data (Tiles3DLoader / CesiumIonLoader)
83
+ * @param loadOptions - 3d-tiles loader options
84
+ * @returns 3d-tiles resource
85
+ */
86
+ export async function loadFromArchive(
87
+ url: string,
88
+ loader: LoaderWithParser,
89
+ loadOptions: Tiles3DLoaderOptions
90
+ ) {
91
+ const tz3UrlParts = url.split('.3tz');
92
+ let filename: string | null;
93
+ // No '.3tz'. The file will be loaded with global fetch function
94
+ if (tz3UrlParts.length === 1) {
95
+ filename = null;
96
+ } else if (tz3UrlParts.length === 2) {
97
+ filename = tz3UrlParts[1].slice(1);
98
+ if (filename === '') {
99
+ filename = 'tileset.json';
100
+ }
101
+ } else {
102
+ throw new Error('Unexpected URL format');
103
+ }
104
+ if (filename) {
105
+ const tz3Path = `${tz3UrlParts[0]}.3tz`;
106
+ const fileSystem = new Tiles3DArchiveFileSystem(tz3Path);
107
+ const content = await load(filename, loader, {
108
+ ...loadOptions,
109
+ fetch: fileSystem.fetch.bind(fileSystem)
110
+ });
111
+ await fileSystem.destroy();
112
+ return content;
113
+ }
114
+ return await load(url, loader, loadOptions);
115
+ }
116
+
117
+ /**
118
+ * Check if tile is nested tileset
119
+ * @param tile - 3DTiles header data
120
+ * @returns true if tile is nested tileset
121
+ */
122
+ export function isNestedTileset(tile: Tiles3DTileJSONPostprocessed) {
123
+ return tile?.type === 'json' || tile?.type === '3tz';
124
+ }
@@ -323,7 +323,11 @@ export class NodeIndexDocument {
323
323
  parentNode.converter.layers0?.attributeStorageInfo?.length
324
324
  ) {
325
325
  node.attributeData = [];
326
- for (let index = 0; index < attributes.length; index++) {
326
+ const minimumLength =
327
+ attributes.length < parentNode.converter.layers0.attributeStorageInfo.length
328
+ ? attributes.length
329
+ : parentNode.converter.layers0.attributeStorageInfo.length;
330
+ for (let index = 0; index < minimumLength; index++) {
327
331
  const folderName = parentNode.converter.layers0.attributeStorageInfo[index].key;
328
332
  node.attributeData.push({href: `./attributes/${folderName}/0`});
329
333
  }
@@ -1,38 +1,44 @@
1
- import {Tiles3DTileContent, Tiles3DTileJSONPostprocessed} from '@loaders.gl/3d-tiles';
2
- import {GltfPrimitiveModeString, PreprocessData} from '../types';
3
- import {GLTF, GLTFLoader} from '@loaders.gl/gltf';
1
+ import {Tiles3DTileContent} from '@loaders.gl/3d-tiles';
2
+ import {GLTFPrimitiveModeString, PreprocessData} from '../types';
3
+ import {
4
+ EXT_STRUCTURAL_METADATA,
5
+ GLTF,
6
+ GLTFLoader,
7
+ GLTF_EXT_feature_metadata_GLTF,
8
+ GLTF_EXT_structural_metadata_GLTF
9
+ } from '@loaders.gl/gltf';
4
10
  import {parse} from '@loaders.gl/core';
11
+ import {EXT_FEATURE_METADATA} from '@loaders.gl/gltf';
5
12
 
6
13
  /**
7
14
  * glTF primitive modes
8
15
  * @see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_mode
9
16
  */
10
17
  export const GLTF_PRIMITIVE_MODES = [
11
- GltfPrimitiveModeString.POINTS, // 0
12
- GltfPrimitiveModeString.LINES, // 1
13
- GltfPrimitiveModeString.LINE_LOOP, // 2
14
- GltfPrimitiveModeString.LINE_STRIP, // 3
15
- GltfPrimitiveModeString.TRIANGLES, // 4
16
- GltfPrimitiveModeString.TRIANGLE_STRIP, // 5
17
- GltfPrimitiveModeString.TRIANGLE_FAN // 6
18
+ GLTFPrimitiveModeString.POINTS, // 0
19
+ GLTFPrimitiveModeString.LINES, // 1
20
+ GLTFPrimitiveModeString.LINE_LOOP, // 2
21
+ GLTFPrimitiveModeString.LINE_STRIP, // 3
22
+ GLTFPrimitiveModeString.TRIANGLES, // 4
23
+ GLTFPrimitiveModeString.TRIANGLE_STRIP, // 5
24
+ GLTFPrimitiveModeString.TRIANGLE_FAN // 6
18
25
  ];
19
26
 
20
27
  /**
21
28
  * Analyze tile content. This function is used during preprocess stage of
22
29
  * conversion
23
- * @param tile - 3DTiles tile JSON metadata
24
30
  * @param tileContent - 3DTiles tile content ArrayBuffer
25
31
  * @returns
26
32
  */
27
33
  export const analyzeTileContent = async (
28
- tile: Tiles3DTileJSONPostprocessed,
29
34
  tileContent: Tiles3DTileContent | null
30
35
  ): Promise<PreprocessData> => {
31
- const result: PreprocessData = {
32
- meshTopologyTypes: new Set()
36
+ const defaultResult = {
37
+ meshTopologyTypes: new Set<GLTFPrimitiveModeString>(),
38
+ metadataClasses: new Set<string>()
33
39
  };
34
40
  if (!tileContent?.gltfArrayBuffer) {
35
- return result;
41
+ return defaultResult;
36
42
  }
37
43
 
38
44
  const gltfData = await parse(tileContent.gltfArrayBuffer, GLTFLoader, {
@@ -41,11 +47,14 @@ export const analyzeTileContent = async (
41
47
  const gltf = gltfData.json;
42
48
 
43
49
  if (!gltf) {
44
- return result;
50
+ return defaultResult;
45
51
  }
46
- const meshTypes = getMeshTypesFromGltf(gltf);
47
- result.meshTopologyTypes = meshTypes;
48
- return result;
52
+ const meshTopologyTypes = getMeshTypesFromGLTF(gltf);
53
+ const metadataClasses = getMetadataClassesFromGLTF(gltf);
54
+ return {
55
+ meshTopologyTypes,
56
+ metadataClasses
57
+ };
49
58
  };
50
59
 
51
60
  /**
@@ -53,8 +62,8 @@ export const analyzeTileContent = async (
53
62
  * @param gltfJson - JSON part of GLB content
54
63
  * @returns array of mesh types found
55
64
  */
56
- const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GltfPrimitiveModeString> => {
57
- const result: Set<GltfPrimitiveModeString> = new Set();
65
+ const getMeshTypesFromGLTF = (gltfJson: GLTF): Set<GLTFPrimitiveModeString> => {
66
+ const result: Set<GLTFPrimitiveModeString> = new Set();
58
67
  for (const mesh of gltfJson.meshes || []) {
59
68
  for (const primitive of mesh.primitives) {
60
69
  let {mode} = primitive;
@@ -67,6 +76,41 @@ const getMeshTypesFromGltf = (gltfJson: GLTF): Set<GltfPrimitiveModeString> => {
67
76
  return result;
68
77
  };
69
78
 
79
+ /**
80
+ * Get feature metadata classes from glTF
81
+ * The tileset might contain multiple metadata classes provided by EXT_feature_metadata and EXT_structural_metadata extensions.
82
+ * Every class is a set of properties. But I3S can consume only one set of properties.
83
+ * On the pre-process we collect all classes from the tileset in order to show the prompt to select one class for conversion to I3S.
84
+ * @param gltfJson - JSON part of GLB content
85
+ * @returns array of classes
86
+ */
87
+ const getMetadataClassesFromGLTF = (gltfJson: GLTF): Set<string> => {
88
+ const result: Set<string> = new Set();
89
+
90
+ // Try to parse from EXT_feature_metadata
91
+ const extFeatureMetadataClasses = (
92
+ gltfJson.extensions?.[EXT_FEATURE_METADATA] as GLTF_EXT_feature_metadata_GLTF
93
+ )?.schema?.classes;
94
+
95
+ if (extFeatureMetadataClasses) {
96
+ for (const classKey of Object.keys(extFeatureMetadataClasses)) {
97
+ result.add(classKey);
98
+ }
99
+ }
100
+
101
+ // Try to parse from EXT_structural_metadata
102
+ const extStructuralMetadataClasses = (
103
+ gltfJson.extensions?.[EXT_STRUCTURAL_METADATA] as GLTF_EXT_structural_metadata_GLTF
104
+ )?.schema?.classes;
105
+ if (extStructuralMetadataClasses) {
106
+ for (const classKey of Object.keys(extStructuralMetadataClasses)) {
107
+ result.add(classKey);
108
+ }
109
+ }
110
+
111
+ return result;
112
+ };
113
+
70
114
  /**
71
115
  * Merge object2 into object1
72
116
  * @param object1
@@ -78,4 +122,9 @@ export const mergePreprocessData = (object1: PreprocessData, object2: Preprocess
78
122
  for (const type of object2.meshTopologyTypes) {
79
123
  object1.meshTopologyTypes.add(type);
80
124
  }
125
+
126
+ // Merge feature metadata classes
127
+ for (const metadataClass of object2.metadataClasses) {
128
+ object1.metadataClasses.add(metadataClass);
129
+ }
81
130
  };
@@ -12,9 +12,10 @@ import type {
12
12
  SceneLayer3D,
13
13
  BoundingVolumes,
14
14
  MaxScreenThresholdSQ,
15
- NodeInPage
15
+ NodeInPage,
16
+ AttributeStorageInfo
16
17
  } from '@loaders.gl/i3s';
17
- import {load, encode, fetchFile, getLoaderOptions, isBrowser} from '@loaders.gl/core';
18
+ import {load, encode, isBrowser} from '@loaders.gl/core';
18
19
  import {CesiumIonLoader, Tiles3DLoader} from '@loaders.gl/3d-tiles';
19
20
  import {Geoid} from '@math.gl/geoid';
20
21
  import {join} from 'path';
@@ -51,15 +52,13 @@ import {I3SMaterialDefinition, TextureSetDefinitionFormats} from '@loaders.gl/i3
51
52
  import {ImageWriter} from '@loaders.gl/images';
52
53
  import {GLTFImagePostprocessed} from '@loaders.gl/gltf';
53
54
  import {
54
- GltfPrimitiveModeString,
55
+ GLTFPrimitiveModeString,
55
56
  I3SConvertedResources,
56
57
  PreprocessData,
57
58
  SharedResourcesArrays
58
59
  } from './types';
59
- import {getWorkerURL, WorkerFarm} from '@loaders.gl/worker-utils';
60
- import {DracoWriterWorker} from '@loaders.gl/draco';
60
+ import {WorkerFarm} from '@loaders.gl/worker-utils';
61
61
  import WriteQueue from '../lib/utils/write-queue';
62
- import {I3SAttributesWorker} from '../i3s-attributes-worker';
63
62
  import {BROWSER_ERROR_MESSAGE} from '../constants';
64
63
  import {
65
64
  createdStorageAttribute,
@@ -69,16 +68,19 @@ import {
69
68
  getFieldAttributeType
70
69
  } from './helpers/feature-attributes';
71
70
  import {NodeIndexDocument} from './helpers/node-index-document';
72
- import {loadNestedTileset, loadTile3DContent} from './helpers/load-3d-tiles';
71
+ import {
72
+ isNestedTileset,
73
+ loadNestedTileset,
74
+ loadTile3DContent,
75
+ loadFromArchive
76
+ } from './helpers/load-3d-tiles';
73
77
  import {Matrix4} from '@math.gl/core';
74
78
  import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
75
79
  import {createBoundingVolume} from '@loaders.gl/tiles';
76
80
  import {TraversalConversionProps, traverseDatasetWith} from './helpers/tileset-traversal';
77
81
  import {analyzeTileContent, mergePreprocessData} from './helpers/preprocess-3d-tiles';
78
82
 
79
- const ION_DEFAULT_TOKEN =
80
- process.env?.IonToken || // eslint-disable-line
81
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlYWMxMzcyYy0zZjJkLTQwODctODNlNi01MDRkZmMzMjIxOWIiLCJpZCI6OTYyMCwic2NvcGVzIjpbImFzbCIsImFzciIsImdjIl0sImlhdCI6MTU2Mjg2NjI3M30.1FNiClUyk00YH_nWfSGpiQAjR5V2OvREDq1PJ5QMjWQ'; // eslint-disable-line
83
+ const ION_DEFAULT_TOKEN = process.env?.IonToken;
82
84
  const HARDCODED_NODES_PER_PAGE = 64;
83
85
  const _3D_TILES = '3DTILES';
84
86
  const _3D_OBJECT_LAYER_TYPE = '3DObject';
@@ -112,6 +114,7 @@ export default class I3SConverter {
112
114
  loadOptions: Tiles3DLoaderOptions = {
113
115
  _nodeWorkers: true,
114
116
  reuseWorkers: true,
117
+ useLocalLibraries: true,
115
118
  basis: {
116
119
  format: 'rgba32',
117
120
  // We need to load local fs workers because nodejs can't load workers from the Internet
@@ -119,7 +122,8 @@ export default class I3SConverter {
119
122
  },
120
123
  // We need to load local fs workers because nodejs can't load workers from the Internet
121
124
  draco: {workerUrl: './modules/draco/dist/draco-worker-node.js'},
122
- fetch: {}
125
+ fetch: {},
126
+ modules: {}
123
127
  };
124
128
  geoidHeightModel: Geoid | null = null;
125
129
  Loader: LoaderWithParser = Tiles3DLoader;
@@ -130,7 +134,8 @@ export default class I3SConverter {
130
134
  writeQueue: WriteQueue<WriteQueueItem> = new WriteQueue();
131
135
  compressList: string[] | null = null;
132
136
  preprocessData: PreprocessData = {
133
- meshTopologyTypes: new Set()
137
+ meshTopologyTypes: new Set(),
138
+ metadataClasses: new Set()
134
139
  };
135
140
 
136
141
  constructor() {
@@ -187,6 +192,8 @@ export default class I3SConverter {
187
192
  generateTextures?: boolean;
188
193
  generateBoundingVolumes?: boolean;
189
194
  instantNodeWriting?: boolean;
195
+ inquirer?: Promise<unknown>;
196
+ metadataClass?: string;
190
197
  }): Promise<string> {
191
198
  if (isBrowser) {
192
199
  console.log(BROWSER_ERROR_MESSAGE);
@@ -207,7 +214,9 @@ export default class I3SConverter {
207
214
  generateTextures,
208
215
  generateBoundingVolumes,
209
216
  instantNodeWriting = false,
210
- mergeMaterials = true
217
+ mergeMaterials = true,
218
+ inquirer,
219
+ metadataClass
211
220
  } = options;
212
221
  this.options = {
213
222
  maxDepth,
@@ -218,7 +227,9 @@ export default class I3SConverter {
218
227
  token,
219
228
  inputUrl,
220
229
  instantNodeWriting,
221
- mergeMaterials
230
+ mergeMaterials,
231
+ inquirer,
232
+ metadataClass
222
233
  };
223
234
  this.compressList = (this.options.instantNodeWriting && []) || null;
224
235
  this.validate = Boolean(validate);
@@ -237,14 +248,16 @@ export default class I3SConverter {
237
248
  this.nodePages.useWriteFunction(writeFileForSlpk);
238
249
  }
239
250
 
240
- await this.loadWorkers();
241
-
242
251
  try {
243
252
  const preloadOptions = await this._fetchPreloadOptions();
253
+ let tilesetUrl = inputUrl;
254
+ if (preloadOptions.url) {
255
+ tilesetUrl = preloadOptions.url;
256
+ }
244
257
  if (preloadOptions.headers) {
245
258
  this.loadOptions.fetch = {headers: preloadOptions.headers};
246
259
  }
247
- this.sourceTileset = await load(inputUrl, this.Loader, this.loadOptions);
260
+ this.sourceTileset = await loadFromArchive(tilesetUrl, this.Loader, this.loadOptions);
248
261
 
249
262
  const preprocessResult = await this.preprocessConversion();
250
263
 
@@ -278,14 +291,24 @@ export default class I3SConverter {
278
291
  undefined,
279
292
  this.options.maxDepth
280
293
  );
281
- const {meshTopologyTypes} = this.preprocessData;
294
+ const {meshTopologyTypes, metadataClasses} = this.preprocessData;
295
+
282
296
  console.log(`------------------------------------------------`);
283
297
  console.log(`Preprocess results:`);
284
298
  console.log(`glTF mesh topology types: ${Array.from(meshTopologyTypes).join(', ')}`);
299
+
300
+ if (metadataClasses.size) {
301
+ console.log(
302
+ `Feature metadata classes have been found: ${Array.from(metadataClasses).join(', ')}`
303
+ );
304
+ } else {
305
+ console.log('Feature metadata classes have not been found');
306
+ }
307
+
285
308
  console.log(`------------------------------------------------`);
286
309
  if (
287
- !meshTopologyTypes.has(GltfPrimitiveModeString.TRIANGLES) &&
288
- !meshTopologyTypes.has(GltfPrimitiveModeString.TRIANGLE_STRIP)
310
+ !meshTopologyTypes.has(GLTFPrimitiveModeString.TRIANGLES) &&
311
+ !meshTopologyTypes.has(GLTFPrimitiveModeString.TRIANGLE_STRIP)
289
312
  ) {
290
313
  console.log(
291
314
  'The tileset is of unsupported mesh topology types. The conversion will be interrupted.'
@@ -293,6 +316,32 @@ export default class I3SConverter {
293
316
  console.log(`------------------------------------------------`);
294
317
  return false;
295
318
  }
319
+
320
+ if (metadataClasses.size > 1) {
321
+ if (this.options.metadataClass?.length) {
322
+ console.log(`${this.options.metadataClass} has been selected`);
323
+ } else if (this.options.inquirer) {
324
+ const result = await this.options.inquirer.prompt([
325
+ {
326
+ name: 'metadataClass',
327
+ type: 'list',
328
+ message: 'Select feature metadata data class to convert...',
329
+ choices: Array.from(metadataClasses)
330
+ }
331
+ ]);
332
+ this.options.metadataClass = result.metadataClass;
333
+ console.log(`${result.metadataClass} has been selected`);
334
+ } else {
335
+ console.log(
336
+ `A feature metadata class has not been selected. Start the converter with option "--metadata-class". For example, "npx tile-converter ... --metadata-class ${
337
+ Array.from(metadataClasses)[0]
338
+ }"`
339
+ );
340
+ console.log(`------------------------------------------------`);
341
+ return false;
342
+ }
343
+ }
344
+
296
345
  return true;
297
346
  }
298
347
 
@@ -306,18 +355,27 @@ export default class I3SConverter {
306
355
  sourceTile: Tiles3DTileJSONPostprocessed,
307
356
  traversalProps: null
308
357
  ): Promise<null> {
309
- if (sourceTile.type === 'json') {
358
+ const isTileset = isNestedTileset(sourceTile);
359
+ if (isTileset) {
310
360
  await loadNestedTileset(this.sourceTileset, sourceTile, this.loadOptions);
311
361
  return null;
312
362
  }
313
363
  if (sourceTile.id) {
314
364
  console.log(`[analyze]: ${sourceTile.id}`); // eslint-disable-line
315
365
  }
316
- const tileContent = await loadTile3DContent(this.sourceTileset, sourceTile, {
317
- ...this.loadOptions,
318
- '3d-tiles': {...this.loadOptions['3d-tiles'], loadGLTF: false}
319
- });
320
- const tilePreprocessData = await analyzeTileContent(sourceTile, tileContent);
366
+
367
+ let tileContent: Tiles3DTileContent | null = null;
368
+ try {
369
+ tileContent = await loadTile3DContent(this.sourceTileset, sourceTile, {
370
+ ...this.loadOptions,
371
+ '3d-tiles': {...this.loadOptions['3d-tiles'], loadGLTF: false}
372
+ });
373
+ } catch (error) {
374
+ console.log(
375
+ `[warning]: Failed to load ${sourceTile.contentUrl}. An I3S tile with empty content will be added to the output tileset`
376
+ );
377
+ }
378
+ const tilePreprocessData = await analyzeTileContent(tileContent);
321
379
  mergePreprocessData(this.preprocessData, tilePreprocessData);
322
380
 
323
381
  return null;
@@ -511,8 +569,9 @@ export default class I3SConverter {
511
569
  sourceTile: Tiles3DTileJSONPostprocessed,
512
570
  traversalProps: TraversalConversionProps
513
571
  ): Promise<TraversalConversionProps> {
514
- if (sourceTile.type === 'json' || sourceTile.type === 'empty') {
515
- if (sourceTile.type === 'json') {
572
+ const isTileset = isNestedTileset(sourceTile);
573
+ if (isTileset || sourceTile.type === 'empty') {
574
+ if (isTileset) {
516
575
  if (sourceTile.id) {
517
576
  console.log(`[load]: ${sourceTile.id}`); // eslint-disable-line
518
577
  }
@@ -576,7 +635,12 @@ export default class I3SConverter {
576
635
 
577
636
  await this._updateTilesetOptions();
578
637
 
579
- const tileContent = await loadTile3DContent(this.sourceTileset, sourceTile, this.loadOptions);
638
+ let tileContent: Tiles3DTileContent | null = null;
639
+ try {
640
+ tileContent = await loadTile3DContent(this.sourceTileset, sourceTile, this.loadOptions);
641
+ } catch (error) {
642
+ console.log(`[warning]: Failed to load ${sourceTile.contentUrl}`);
643
+ }
580
644
  const sourceBoundingVolume = createBoundingVolume(
581
645
  sourceTile.boundingVolume,
582
646
  transformationMatrix,
@@ -584,9 +648,15 @@ export default class I3SConverter {
584
648
  );
585
649
  let boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel!);
586
650
 
587
- const propertyTable = getPropertyTable(tileContent);
651
+ const propertyTable = getPropertyTable(tileContent, this.options.metadataClass);
588
652
 
589
- if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
653
+ if (propertyTable) {
654
+ /*
655
+ Call the convertion procedure even if the node attributes have been already created.
656
+ We will append new attributes only in case the property table is updated.
657
+ According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
658
+ "The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
659
+ */
590
660
  this._convertPropertyTableToNodeAttributes(propertyTable);
591
661
  }
592
662
 
@@ -672,7 +742,7 @@ export default class I3SConverter {
672
742
  * @param boundingVolume - initialized bounding volume of the source tile
673
743
  * @param tileContent - content of the source tile
674
744
  * @param parentId - id of parent node in node pages
675
- * @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
745
+ * @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA, EXT_MESH_FEATURES or EXT_STRUCTURAL_METADATA
676
746
  * @returns - converted node resources
677
747
  */
678
748
  private async _convertResources(
@@ -703,7 +773,8 @@ export default class I3SConverter {
703
773
  this.generateBoundingVolumes,
704
774
  this.options.mergeMaterials,
705
775
  this.geoidHeightModel!,
706
- this.workerSource
776
+ this.loadOptions.modules as Record<string, string>,
777
+ this.options.metadataClass
707
778
  );
708
779
  return resourcesData;
709
780
  }
@@ -753,13 +824,17 @@ export default class I3SConverter {
753
824
  }
754
825
 
755
826
  let nodeId = resources.nodeId;
756
- let node;
827
+ let node: NodeInPage;
757
828
  if (!nodeId) {
758
829
  node = await this.nodePages.push(nodeInPage, parentId);
759
830
  } else {
760
831
  node = await this.nodePages.getNodeById(nodeId);
761
832
  }
762
833
 
834
+ if (!nodeInPage.mesh) {
835
+ console.log(`[warning]: node ${node.index} is created with empty content`);
836
+ }
837
+
763
838
  NodePages.updateAll(node, nodeInPage);
764
839
  if (meshMaterial) {
765
840
  NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
@@ -915,9 +990,13 @@ export default class I3SConverter {
915
990
  KTX2BasisWriterWorker,
916
991
  {
917
992
  ...KTX2BasisWriterWorker.options,
918
- source: this.workerSource.ktx2,
993
+ ['ktx2-basis-writer']: {
994
+ // We need to load local fs workers because nodejs can't load workers from the Internet
995
+ workerUrl: './modules/textures/dist/ktx2-basis-writer-worker-node.js'
996
+ },
919
997
  reuseWorkers: true,
920
- _nodeWorkers: true
998
+ _nodeWorkers: true,
999
+ useLocalLibraries: true
921
1000
  }
922
1001
  );
923
1002
 
@@ -996,7 +1075,12 @@ export default class I3SConverter {
996
1075
  slpkChildPath: string
997
1076
  ): Promise<void> {
998
1077
  if (attributes?.length && this.layers0?.attributeStorageInfo?.length) {
999
- for (let index = 0; index < attributes.length; index++) {
1078
+ const minimumLength =
1079
+ attributes.length < this.layers0.attributeStorageInfo.length
1080
+ ? attributes.length
1081
+ : this.layers0.attributeStorageInfo.length;
1082
+
1083
+ for (let index = 0; index < minimumLength; index++) {
1000
1084
  const folderName = this.layers0.attributeStorageInfo[index].key;
1001
1085
  const fileBuffer = new Uint8Array(attributes[index]);
1002
1086
 
@@ -1078,19 +1162,30 @@ export default class I3SConverter {
1078
1162
  };
1079
1163
 
1080
1164
  for (const key in propertyTableWithObjectId) {
1081
- const firstAttribute = propertyTableWithObjectId[key][0];
1082
- const attributeType = getAttributeType(key, firstAttribute);
1083
-
1084
- const storageAttribute = createdStorageAttribute(attributeIndex, key, attributeType);
1085
- const fieldAttributeType = getFieldAttributeType(attributeType);
1086
- const fieldAttribute = createFieldAttribute(key, fieldAttributeType);
1087
- const popupInfo = createPopupInfo(propertyTableWithObjectId);
1088
-
1089
- this.layers0!.attributeStorageInfo!.push(storageAttribute);
1090
- this.layers0!.fields!.push(fieldAttribute);
1091
- this.layers0!.popupInfo = popupInfo;
1092
- this.layers0!.layerType = _3D_OBJECT_LAYER_TYPE;
1093
-
1165
+ /*
1166
+ We will append new attributes only in case the property table is updated.
1167
+ According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
1168
+ "The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
1169
+ */
1170
+ const found = this.layers0!.attributeStorageInfo!.find((element) => element.name === key);
1171
+ if (!found) {
1172
+ const firstAttribute = propertyTableWithObjectId[key][0];
1173
+ const attributeType = getAttributeType(key, firstAttribute);
1174
+
1175
+ const storageAttribute: AttributeStorageInfo = createdStorageAttribute(
1176
+ attributeIndex,
1177
+ key,
1178
+ attributeType
1179
+ );
1180
+ const fieldAttributeType = getFieldAttributeType(attributeType);
1181
+ const fieldAttribute = createFieldAttribute(key, fieldAttributeType);
1182
+ const popupInfo = createPopupInfo(propertyTableWithObjectId);
1183
+
1184
+ this.layers0!.attributeStorageInfo!.push(storageAttribute);
1185
+ this.layers0!.fields!.push(fieldAttribute);
1186
+ this.layers0!.popupInfo = popupInfo;
1187
+ this.layers0!.layerType = _3D_OBJECT_LAYER_TYPE;
1188
+ }
1094
1189
  attributeIndex += 1;
1095
1190
  }
1096
1191
  }
@@ -1177,27 +1272,4 @@ export default class I3SConverter {
1177
1272
  private isContentSupported(sourceTile: Tiles3DTileJSONPostprocessed): boolean {
1178
1273
  return ['b3dm', 'glTF', 'scenegraph'].includes(sourceTile.type || '');
1179
1274
  }
1180
-
1181
- private async loadWorkers(): Promise<void> {
1182
- console.log(`Loading workers source...`); // eslint-disable-line no-undef, no-console
1183
- if (this.options.draco) {
1184
- const url = getWorkerURL(DracoWriterWorker, {...getLoaderOptions()});
1185
- const sourceResponse = await fetchFile(url);
1186
- const source = await sourceResponse.text();
1187
- this.workerSource.draco = source;
1188
- }
1189
-
1190
- if (this.generateTextures) {
1191
- const url = getWorkerURL(KTX2BasisWriterWorker, {...getLoaderOptions()});
1192
- const sourceResponse = await fetchFile(url);
1193
- const source = await sourceResponse.text();
1194
- this.workerSource.ktx2 = source;
1195
- }
1196
-
1197
- const i3sAttributesWorkerUrl = getWorkerURL(I3SAttributesWorker, {...getLoaderOptions()});
1198
- const sourceResponse = await fetchFile(i3sAttributesWorkerUrl);
1199
- const source = await sourceResponse.text();
1200
- this.workerSource.I3SAttributes = source;
1201
- console.log(`Loading workers source completed!`); // eslint-disable-line no-undef, no-console
1202
- }
1203
1275
  }