@loaders.gl/tile-converter 4.0.0-alpha.4 → 4.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/3d-tiles-attributes-worker.d.ts +28 -0
- package/dist/3d-tiles-attributes-worker.d.ts.map +1 -0
- package/dist/3d-tiles-attributes-worker.js +3 -0
- package/dist/3d-tiles-attributes-worker.js.map +7 -0
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +90 -0
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -0
- package/dist/3d-tiles-converter/3d-tiles-converter.js +273 -231
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +79 -18
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -0
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js +269 -236
- package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts +4 -7
- package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts.map +1 -0
- package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +22 -9
- package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts +9 -0
- package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts.map +1 -0
- package/dist/3d-tiles-converter/helpers/texture-atlas.js +47 -28
- package/dist/3d-tiles-converter/json-templates/tileset.d.ts +15 -0
- package/dist/3d-tiles-converter/json-templates/tileset.d.ts.map +1 -0
- package/dist/3d-tiles-converter/json-templates/tileset.js +42 -36
- package/dist/bundle.d.ts +2 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +2 -2
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +4 -0
- package/dist/converter-cli.d.ts +2 -0
- package/dist/converter-cli.d.ts.map +1 -0
- package/dist/converter-cli.js +280 -0
- package/dist/converter.min.js +186 -190
- package/dist/deps-installer/deps-installer.d.ts +11 -3
- package/dist/deps-installer/deps-installer.d.ts.map +1 -0
- package/dist/deps-installer/deps-installer.js +60 -23
- package/dist/dist.min.js +63496 -0
- package/dist/es5/3d-tiles-attributes-worker.js +25 -0
- package/dist/es5/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +470 -0
- package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -0
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +301 -0
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -0
- package/dist/es5/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +18 -0
- package/dist/es5/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +1 -0
- package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js +33 -0
- package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js.map +1 -0
- package/dist/es5/3d-tiles-converter/json-templates/tileset.js +61 -0
- package/dist/es5/3d-tiles-converter/json-templates/tileset.js.map +1 -0
- package/dist/es5/bundle.js +6 -0
- package/dist/es5/bundle.js.map +1 -0
- package/dist/es5/constants.js +9 -0
- package/dist/es5/constants.js.map +1 -0
- package/dist/es5/converter-cli.js +289 -0
- package/dist/es5/converter-cli.js.map +1 -0
- package/dist/es5/deps-installer/deps-installer.js +123 -0
- package/dist/es5/deps-installer/deps-installer.js.map +1 -0
- package/dist/es5/i3s-attributes-worker.js +25 -0
- package/dist/es5/i3s-attributes-worker.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +116 -0
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/coordinate-converter.js +90 -0
- package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/create-scene-server-path.js +41 -0
- package/dist/es5/i3s-converter/helpers/create-scene-server-path.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/feature-attributes.js +174 -0
- package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +213 -0
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +1173 -0
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js +83 -0
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/node-debug.js +76 -0
- package/dist/es5/i3s-converter/helpers/node-debug.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/node-index-document.js +492 -0
- package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/node-pages.js +519 -0
- package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -0
- package/dist/es5/i3s-converter/i3s-converter.js +1519 -0
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/geometry-definitions.js +107 -0
- package/dist/es5/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/layers.js +163 -0
- package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/metadata.js +31 -0
- package/dist/es5/i3s-converter/json-templates/metadata.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/node.js +99 -0
- package/dist/es5/i3s-converter/json-templates/node.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/scene-server.js +39 -0
- package/dist/es5/i3s-converter/json-templates/scene-server.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/shared-resources.js +173 -0
- package/dist/es5/i3s-converter/json-templates/shared-resources.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/store.js +107 -0
- package/dist/es5/i3s-converter/json-templates/store.js.map +1 -0
- package/dist/es5/i3s-converter/types.js +2 -0
- package/dist/es5/i3s-converter/types.js.map +1 -0
- package/dist/es5/i3s-server/app.js +18 -0
- package/dist/es5/i3s-server/app.js.map +1 -0
- package/dist/es5/i3s-server/controllers/index-controller.js +55 -0
- package/dist/es5/i3s-server/controllers/index-controller.js.map +1 -0
- package/dist/es5/i3s-server/routes/index.js +37 -0
- package/dist/es5/i3s-server/routes/index.js.map +1 -0
- package/dist/es5/index.js +21 -0
- package/dist/es5/index.js.map +1 -0
- package/dist/es5/lib/utils/compress-util.js +346 -0
- package/dist/es5/lib/utils/compress-util.js.map +1 -0
- package/dist/es5/lib/utils/file-utils.js +208 -0
- package/dist/es5/lib/utils/file-utils.js.map +1 -0
- package/dist/es5/lib/utils/lod-conversion-utils.js +44 -0
- package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -0
- package/dist/es5/lib/utils/queue.js +47 -0
- package/dist/es5/lib/utils/queue.js.map +1 -0
- package/dist/es5/lib/utils/statistic-utills.d.ts +25 -0
- package/dist/es5/lib/utils/statistic-utills.js +147 -0
- package/dist/es5/lib/utils/statistic-utills.js.map +1 -0
- package/dist/es5/lib/utils/write-queue.js +214 -0
- package/dist/es5/lib/utils/write-queue.js.map +1 -0
- package/dist/es5/pgm-loader.js +41 -0
- package/dist/es5/pgm-loader.js.map +1 -0
- package/dist/es5/workers/3d-tiles-attributes-worker.js +28 -0
- package/dist/es5/workers/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/es5/workers/i3s-attributes-worker.js +30 -0
- package/dist/es5/workers/i3s-attributes-worker.js.map +1 -0
- package/dist/esm/3d-tiles-attributes-worker.js +16 -0
- package/dist/esm/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +248 -0
- package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -0
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +224 -0
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -0
- package/dist/esm/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +10 -0
- package/dist/esm/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +1 -0
- package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js +27 -0
- package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js.map +1 -0
- package/dist/esm/3d-tiles-converter/json-templates/tileset.js +37 -0
- package/dist/esm/3d-tiles-converter/json-templates/tileset.js.map +1 -0
- package/dist/esm/bundle.js +4 -0
- package/dist/esm/bundle.js.map +1 -0
- package/dist/esm/constants.js +2 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/converter-cli.js +232 -0
- package/dist/esm/converter-cli.js.map +1 -0
- package/dist/esm/deps-installer/deps-installer.js +44 -0
- package/dist/esm/deps-installer/deps-installer.js.map +1 -0
- package/dist/esm/i3s-attributes-worker.js +16 -0
- package/dist/esm/i3s-attributes-worker.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +105 -0
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/coordinate-converter.js +80 -0
- package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/create-scene-server-path.js +16 -0
- package/dist/esm/i3s-converter/helpers/create-scene-server-path.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/feature-attributes.js +147 -0
- package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -0
- package/{src → dist/esm}/i3s-converter/helpers/geometry-attributes.js +80 -106
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +887 -0
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js +76 -0
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -0
- package/{src → dist/esm}/i3s-converter/helpers/node-debug.js +20 -41
- package/dist/esm/i3s-converter/helpers/node-debug.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/node-index-document.js +188 -0
- package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/node-pages.js +206 -0
- package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -0
- package/dist/esm/i3s-converter/i3s-converter.js +771 -0
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/geometry-definitions.js +89 -0
- package/dist/esm/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/layers.js +133 -0
- package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/metadata.js +22 -0
- package/dist/esm/i3s-converter/json-templates/metadata.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/node.js +80 -0
- package/dist/esm/i3s-converter/json-templates/node.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/scene-server.js +28 -0
- package/dist/esm/i3s-converter/json-templates/scene-server.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/shared-resources.js +123 -0
- package/dist/esm/i3s-converter/json-templates/shared-resources.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/store.js +98 -0
- package/dist/esm/i3s-converter/json-templates/store.js.map +1 -0
- package/dist/esm/i3s-converter/types.js +2 -0
- package/dist/esm/i3s-converter/types.js.map +1 -0
- package/dist/esm/i3s-server/app.js +16 -0
- package/dist/esm/i3s-server/app.js.map +1 -0
- package/dist/esm/i3s-server/bin/www +102 -0
- package/dist/esm/i3s-server/certs/cert.pem +19 -0
- package/dist/esm/i3s-server/certs/key.pem +27 -0
- package/dist/esm/i3s-server/controllers/index-controller.js +24 -0
- package/dist/esm/i3s-server/controllers/index-controller.js.map +1 -0
- package/dist/esm/i3s-server/routes/index.js +16 -0
- package/dist/esm/i3s-server/routes/index.js.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/utils/compress-util.js +168 -0
- package/dist/esm/lib/utils/compress-util.js.map +1 -0
- package/dist/esm/lib/utils/file-utils.js +87 -0
- package/dist/esm/lib/utils/file-utils.js.map +1 -0
- package/dist/esm/lib/utils/lod-conversion-utils.js +37 -0
- package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -0
- package/dist/esm/lib/utils/queue.js +15 -0
- package/dist/esm/lib/utils/queue.js.map +1 -0
- package/dist/esm/lib/utils/statistic-utills.d.ts +25 -0
- package/dist/esm/lib/utils/statistic-utills.js +62 -0
- package/dist/esm/lib/utils/statistic-utills.js.map +1 -0
- package/dist/esm/lib/utils/write-queue.js +85 -0
- package/dist/esm/lib/utils/write-queue.js.map +1 -0
- package/dist/esm/pgm-loader.js +15 -0
- package/dist/esm/pgm-loader.js.map +1 -0
- package/dist/esm/workers/3d-tiles-attributes-worker.js +8 -0
- package/dist/esm/workers/3d-tiles-attributes-worker.js.map +1 -0
- package/dist/esm/workers/i3s-attributes-worker.js +7 -0
- package/dist/esm/workers/i3s-attributes-worker.js.map +1 -0
- package/dist/i3s-attributes-worker.d.ts +37 -0
- package/dist/i3s-attributes-worker.d.ts.map +1 -0
- package/dist/i3s-attributes-worker.js +9 -0
- package/dist/i3s-attributes-worker.js.map +7 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +11 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +141 -0
- package/dist/i3s-converter/helpers/coordinate-converter.d.ts +41 -0
- package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/coordinate-converter.js +120 -42
- package/dist/i3s-converter/helpers/create-scene-server-path.d.ts +9 -0
- package/dist/i3s-converter/helpers/create-scene-server-path.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/create-scene-server-path.js +27 -15
- package/dist/i3s-converter/helpers/feature-attributes.d.ts +56 -0
- package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/feature-attributes.js +216 -0
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts +8 -0
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/geometry-attributes.js +188 -185
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +36 -35
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/geometry-converter.js +1149 -650
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts +9 -0
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/gltf-attributes.js +88 -0
- package/dist/i3s-converter/helpers/node-debug.d.ts +8 -0
- package/dist/i3s-converter/helpers/node-debug.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/node-debug.js +106 -74
- package/dist/i3s-converter/helpers/node-index-document.d.ts +95 -0
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/node-index-document.js +250 -0
- package/dist/i3s-converter/helpers/node-pages.d.ts +125 -113
- package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/node-pages.js +313 -133
- package/dist/i3s-converter/i3s-converter.d.ts +267 -0
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -0
- package/dist/i3s-converter/i3s-converter.js +860 -861
- package/dist/i3s-converter/json-templates/geometry-definitions.d.ts +7 -0
- package/dist/i3s-converter/json-templates/geometry-definitions.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/geometry-definitions.js +87 -0
- package/dist/i3s-converter/json-templates/layers.d.ts +70 -0
- package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/layers.js +138 -190
- package/dist/i3s-converter/json-templates/metadata.d.ts +22 -0
- package/dist/i3s-converter/json-templates/metadata.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/metadata.js +25 -22
- package/dist/i3s-converter/json-templates/node.d.ts +61 -0
- package/dist/i3s-converter/json-templates/node.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/node.js +88 -79
- package/dist/i3s-converter/json-templates/scene-server.d.ts +28 -0
- package/dist/i3s-converter/json-templates/scene-server.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/scene-server.js +31 -28
- package/dist/i3s-converter/json-templates/shared-resources.d.ts +14 -0
- package/dist/i3s-converter/json-templates/shared-resources.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/shared-resources.js +124 -125
- package/dist/i3s-converter/json-templates/store.d.ts +95 -0
- package/dist/i3s-converter/json-templates/store.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/store.js +100 -95
- package/dist/i3s-converter/types.d.ts +145 -0
- package/dist/i3s-converter/types.d.ts.map +1 -0
- package/dist/i3s-converter/types.js +2 -0
- package/dist/i3s-server/app.d.ts +3 -0
- package/dist/i3s-server/app.d.ts.map +1 -0
- package/dist/i3s-server/app.js +2 -9
- package/dist/i3s-server/controllers/index-controller.d.ts +2 -0
- package/dist/i3s-server/controllers/index-controller.d.ts.map +1 -0
- package/dist/i3s-server/controllers/index-controller.js +16 -24
- package/dist/i3s-server/routes/index.d.ts +3 -0
- package/dist/i3s-server/routes/index.d.ts.map +1 -0
- package/dist/i3s-server/routes/index.js +11 -15
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -5
- package/dist/lib/utils/compress-util.d.ts +45 -0
- package/dist/lib/utils/compress-util.d.ts.map +1 -0
- package/dist/lib/utils/compress-util.js +238 -160
- package/dist/lib/utils/file-utils.d.ts +22 -14
- package/dist/lib/utils/file-utils.d.ts.map +1 -0
- package/dist/lib/utils/file-utils.js +133 -36
- package/dist/lib/utils/lod-conversion-utils.d.ts +21 -12
- package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -0
- package/dist/lib/utils/lod-conversion-utils.js +72 -39
- package/dist/lib/utils/queue.d.ts +7 -0
- package/dist/lib/utils/queue.d.ts.map +1 -0
- package/dist/lib/utils/queue.js +18 -0
- package/dist/lib/utils/statistic-utills.d.ts +3 -25
- package/dist/lib/utils/statistic-utills.d.ts.map +1 -0
- package/dist/lib/utils/statistic-utills.js +58 -67
- package/dist/lib/utils/write-queue.d.ts +39 -0
- package/dist/lib/utils/write-queue.d.ts.map +1 -0
- package/dist/lib/utils/write-queue.js +80 -0
- package/dist/pgm-loader.d.ts +6 -0
- package/dist/pgm-loader.d.ts.map +1 -0
- package/dist/pgm-loader.js +23 -14
- package/dist/workers/3d-tiles-attributes-worker.d.ts +2 -0
- package/dist/workers/3d-tiles-attributes-worker.d.ts.map +1 -0
- package/dist/workers/3d-tiles-attributes-worker.js +9 -0
- package/dist/workers/i3s-attributes-worker.d.ts +2 -0
- package/dist/workers/i3s-attributes-worker.d.ts.map +1 -0
- package/dist/workers/i3s-attributes-worker.js +5 -0
- package/package.json +35 -24
- package/src/3d-tiles-attributes-worker.ts +43 -0
- package/src/3d-tiles-converter/3d-tiles-converter.ts +124 -59
- package/src/3d-tiles-converter/helpers/{b3dm-converter.js → b3dm-converter.ts} +71 -38
- package/src/3d-tiles-converter/helpers/{i3s-obb-to-3d-tiles-obb.js → i3s-obb-to-3d-tiles-obb.ts} +16 -1
- package/src/3d-tiles-converter/helpers/texture-atlas.ts +4 -4
- package/src/3d-tiles-converter/json-templates/{tileset.js → tileset.ts} +9 -9
- package/src/constants.ts +2 -0
- package/src/converter-cli.ts +370 -0
- package/src/deps-installer/deps-installer.ts +71 -0
- package/src/i3s-attributes-worker.ts +50 -0
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +206 -0
- package/src/i3s-converter/helpers/coordinate-converter.ts +87 -27
- package/src/i3s-converter/helpers/create-scene-server-path.ts +29 -0
- package/src/i3s-converter/helpers/feature-attributes.ts +247 -0
- package/src/i3s-converter/helpers/geometry-attributes.ts +267 -0
- package/src/i3s-converter/helpers/geometry-converter.ts +1608 -0
- package/src/i3s-converter/helpers/gltf-attributes.ts +103 -0
- package/src/i3s-converter/helpers/node-debug.ts +146 -0
- package/src/i3s-converter/helpers/node-index-document.ts +315 -0
- package/src/i3s-converter/helpers/node-pages.ts +344 -0
- package/src/i3s-converter/i3s-converter.ts +557 -627
- package/src/i3s-converter/json-templates/geometry-definitions.ts +83 -0
- package/src/i3s-converter/json-templates/layers.ts +137 -0
- package/src/i3s-converter/json-templates/{metadata.js → metadata.ts} +2 -2
- package/src/i3s-converter/json-templates/{node.js → node.ts} +12 -12
- package/src/i3s-converter/json-templates/{scene-server.js → scene-server.ts} +2 -2
- package/src/i3s-converter/json-templates/{shared-resources.js → shared-resources.ts} +17 -17
- package/src/i3s-converter/types.ts +165 -0
- package/src/index.ts +0 -4
- package/src/lib/utils/{compress-util.js → compress-util.ts} +105 -18
- package/src/lib/utils/file-utils.ts +139 -0
- package/src/lib/utils/{lod-conversion-utils.js → lod-conversion-utils.ts} +27 -5
- package/src/lib/utils/queue.ts +17 -0
- package/src/lib/utils/write-queue.ts +110 -0
- package/src/pgm-loader.ts +3 -3
- package/src/workers/3d-tiles-attributes-worker.ts +6 -0
- package/src/workers/i3s-attributes-worker.ts +7 -0
- package/dist/3d-tiles-converter/3d-tiles-converter.js.map +0 -1
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +0 -1
- package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +0 -1
- package/dist/3d-tiles-converter/helpers/texture-atlas.js.map +0 -1
- package/dist/3d-tiles-converter/json-templates/tileset.js.map +0 -1
- package/dist/bundle.js.map +0 -1
- package/dist/deps-installer/deps-installer.js.map +0 -1
- package/dist/i3s-converter/helpers/coordinate-converter.js.map +0 -1
- package/dist/i3s-converter/helpers/create-scene-server-path.js.map +0 -1
- package/dist/i3s-converter/helpers/geometry-attributes.js.map +0 -1
- package/dist/i3s-converter/helpers/geometry-converter.js.map +0 -1
- package/dist/i3s-converter/helpers/node-debug.js.map +0 -1
- package/dist/i3s-converter/helpers/node-pages.js.map +0 -1
- package/dist/i3s-converter/i3s-converter.js.map +0 -1
- package/dist/i3s-converter/json-templates/layers.js.map +0 -1
- package/dist/i3s-converter/json-templates/metadata.js.map +0 -1
- package/dist/i3s-converter/json-templates/node.js.map +0 -1
- package/dist/i3s-converter/json-templates/scene-server.js.map +0 -1
- package/dist/i3s-converter/json-templates/shared-resources.js.map +0 -1
- package/dist/i3s-converter/json-templates/store.js.map +0 -1
- package/dist/i3s-server/app.js.map +0 -1
- package/dist/i3s-server/controllers/index-controller.js.map +0 -1
- package/dist/i3s-server/routes/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/geoid-height-model.d.ts +0 -41
- package/dist/lib/geoid-height-model.js +0 -140
- package/dist/lib/geoid-height-model.js.map +0 -1
- package/dist/lib/pgm-parser.d.ts +0 -14
- package/dist/lib/pgm-parser.js +0 -183
- package/dist/lib/pgm-parser.js.map +0 -1
- package/dist/lib/utils/compress-util.js.map +0 -1
- package/dist/lib/utils/compress-utils.d.ts +0 -53
- package/dist/lib/utils/file-utils.js.map +0 -1
- package/dist/lib/utils/lod-conversion-utils.js.map +0 -1
- package/dist/lib/utils/statistic-utills.js.map +0 -1
- package/dist/pgm-loader.js.map +0 -1
- package/src/3d-tiles-converter/helpers/b3dm-converter.d.ts +0 -23
- package/src/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts +0 -16
- package/src/deps-installer/deps-installer.d.ts +0 -10
- package/src/deps-installer/deps-installer.js +0 -22
- package/src/i3s-converter/helpers/create-scene-server-path.js +0 -25
- package/src/i3s-converter/helpers/geometry-converter.d.ts +0 -40
- package/src/i3s-converter/helpers/geometry-converter.js +0 -915
- package/src/i3s-converter/helpers/node-pages.d.ts +0 -144
- package/src/i3s-converter/helpers/node-pages.js +0 -208
- package/src/i3s-converter/json-templates/layers.js +0 -199
- package/src/lib/geoid-height-model.d.ts +0 -41
- package/src/lib/geoid-height-model.js +0 -239
- package/src/lib/pgm-parser.d.ts +0 -14
- package/src/lib/pgm-parser.js +0 -179
- package/src/lib/utils/compress-utils.d.ts +0 -53
- package/src/lib/utils/file-utils.d.ts +0 -43
- package/src/lib/utils/file-utils.js +0 -38
- package/src/lib/utils/lod-conversion-utils.d.ts +0 -32
- /package/dist/{i3s-server → es5/i3s-server}/bin/www +0 -0
- /package/dist/{i3s-server → es5/i3s-server}/certs/cert.pem +0 -0
- /package/dist/{i3s-server → es5/i3s-server}/certs/key.pem +0 -0
- /package/src/i3s-converter/json-templates/{store.js → store.ts} +0 -0
- /package/src/lib/utils/{statistic-utills.js → statistic-utills.ts} +0 -0
|
@@ -1,27 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import type {GLTFMaterial} from '@loaders.gl/gltf';
|
|
3
|
-
import type {BatchTableJson, B3DMContent} from '@loaders.gl/3d-tiles';
|
|
1
|
+
// loaders.gl, MIT license
|
|
4
2
|
|
|
3
|
+
import type {Tileset3DProps} from '@loaders.gl/tiles';
|
|
4
|
+
import type {FeatureTableJson} from '@loaders.gl/3d-tiles';
|
|
5
|
+
import type {WriteQueueItem} from '../lib/utils/write-queue';
|
|
5
6
|
import type {
|
|
6
|
-
AttributeStorageInfo,
|
|
7
7
|
SceneLayer3D,
|
|
8
8
|
BoundingVolumes,
|
|
9
|
-
Node3DIndexDocument,
|
|
10
|
-
NodeReference,
|
|
11
|
-
I3SGeometry,
|
|
12
9
|
MaxScreenThresholdSQ,
|
|
13
|
-
NodeInPage
|
|
14
|
-
LodSelection,
|
|
15
|
-
SharedResources,
|
|
16
|
-
TextureImage,
|
|
17
|
-
Attribute,
|
|
18
|
-
ESRIField,
|
|
19
|
-
Field,
|
|
20
|
-
PopupInfo
|
|
10
|
+
NodeInPage
|
|
21
11
|
} from '@loaders.gl/i3s';
|
|
22
|
-
import {load, encode} from '@loaders.gl/core';
|
|
12
|
+
import {load, encode, fetchFile, getLoaderOptions, isBrowser} from '@loaders.gl/core';
|
|
23
13
|
import {Tileset3D} from '@loaders.gl/tiles';
|
|
24
|
-
import {CesiumIonLoader} from '@loaders.gl/3d-tiles';
|
|
14
|
+
import {CesiumIonLoader, Tiles3DLoader} from '@loaders.gl/3d-tiles';
|
|
15
|
+
import {Geoid} from '@math.gl/geoid';
|
|
25
16
|
import {join} from 'path';
|
|
26
17
|
import {v4 as uuidv4} from 'uuid';
|
|
27
18
|
import process from 'process';
|
|
@@ -29,41 +20,58 @@ import transform from 'json-map-transform';
|
|
|
29
20
|
import md5 from 'md5';
|
|
30
21
|
|
|
31
22
|
import NodePages from './helpers/node-pages';
|
|
32
|
-
import {writeFile, removeDir, writeFileForSlpk} from '../lib/utils/file-utils';
|
|
23
|
+
import {writeFile, removeDir, writeFileForSlpk, removeFile} from '../lib/utils/file-utils';
|
|
33
24
|
import {
|
|
25
|
+
compressFileWithGzip,
|
|
34
26
|
compressWithChildProcess
|
|
35
27
|
// generateHash128FromZip,
|
|
36
28
|
// addFileToZip
|
|
37
29
|
} from '../lib/utils/compress-util';
|
|
38
30
|
import {calculateFilesSize, timeConverter} from '../lib/utils/statistic-utills';
|
|
39
|
-
import convertB3dmToI3sGeometry from './helpers/geometry-converter';
|
|
31
|
+
import convertB3dmToI3sGeometry, {getPropertyTable} from './helpers/geometry-converter';
|
|
40
32
|
import {
|
|
41
33
|
createBoundingVolumes,
|
|
42
|
-
|
|
34
|
+
convertBoundingVolumeToI3SFullExtent
|
|
43
35
|
} from './helpers/coordinate-converter';
|
|
44
36
|
import {createSceneServerPath} from './helpers/create-scene-server-path';
|
|
45
37
|
import {convertGeometricErrorToScreenThreshold} from '../lib/utils/lod-conversion-utils';
|
|
46
38
|
import {PGMLoader} from '../pgm-loader';
|
|
47
39
|
|
|
48
40
|
import {LAYERS as layersTemplate} from './json-templates/layers';
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
41
|
+
import {GEOMETRY_DEFINITION as geometryDefinitionTemlate} from './json-templates/geometry-definitions';
|
|
42
|
+
import {SHARED_RESOURCES as sharedResourcesTemplate} from './json-templates/shared-resources';
|
|
51
43
|
import {validateNodeBoundingVolumes} from './helpers/node-debug';
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
import {
|
|
44
|
+
// loaders.gl, MIT license
|
|
45
|
+
|
|
46
|
+
import {Tile3D} from '@loaders.gl/tiles';
|
|
47
|
+
import {KTX2BasisWriterWorker} from '@loaders.gl/textures';
|
|
48
|
+
import {LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
49
|
+
import {I3SMaterialDefinition, TextureSetDefinitionFormats} from '@loaders.gl/i3s/src/types';
|
|
50
|
+
import {ImageWriter} from '@loaders.gl/images';
|
|
51
|
+
import {GLTFImagePostprocessed} from '@loaders.gl/gltf';
|
|
52
|
+
import {I3SConvertedResources, SharedResourcesArrays} from './types';
|
|
53
|
+
import {getWorkerURL, WorkerFarm} from '@loaders.gl/worker-utils';
|
|
54
|
+
import {DracoWriterWorker} from '@loaders.gl/draco';
|
|
55
|
+
import WriteQueue from '../lib/utils/write-queue';
|
|
56
|
+
import {I3SAttributesWorker} from '../i3s-attributes-worker';
|
|
57
|
+
import {BROWSER_ERROR_MESSAGE} from '../constants';
|
|
58
|
+
import {
|
|
59
|
+
createdStorageAttribute,
|
|
60
|
+
createFieldAttribute,
|
|
61
|
+
createPopupInfo,
|
|
62
|
+
getAttributeType,
|
|
63
|
+
getFieldAttributeType
|
|
64
|
+
} from './helpers/feature-attributes';
|
|
65
|
+
import {NodeIndexDocument} from './helpers/node-index-document';
|
|
55
66
|
|
|
56
67
|
const ION_DEFAULT_TOKEN =
|
|
57
|
-
process.env
|
|
68
|
+
process.env?.IonToken || // eslint-disable-line
|
|
58
69
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlYWMxMzcyYy0zZjJkLTQwODctODNlNi01MDRkZmMzMjIxOWIiLCJpZCI6OTYyMCwic2NvcGVzIjpbImFzbCIsImFzciIsImdjIl0sImlhdCI6MTU2Mjg2NjI3M30.1FNiClUyk00YH_nWfSGpiQAjR5V2OvREDq1PJ5QMjWQ'; // eslint-disable-line
|
|
59
70
|
const HARDCODED_NODES_PER_PAGE = 64;
|
|
60
71
|
const _3D_TILES = '3DTILES';
|
|
61
72
|
const _3D_OBJECT_LAYER_TYPE = '3DObject';
|
|
62
|
-
const STRING_TYPE = 'string';
|
|
63
|
-
const SHORT_INT_TYPE = 'Int32';
|
|
64
|
-
const DOUBLE_TYPE = 'double';
|
|
65
|
-
const OBJECT_ID_TYPE = 'OBJECTID';
|
|
66
73
|
const REFRESH_TOKEN_TIMEOUT = 1800; // 30 minutes in seconds
|
|
74
|
+
const CESIUM_DATASET_PREFIX = 'https://';
|
|
67
75
|
// const FS_FILE_TOO_LARGE = 'ERR_FS_FILE_TOO_LARGE';
|
|
68
76
|
|
|
69
77
|
/**
|
|
@@ -71,32 +79,41 @@ const REFRESH_TOKEN_TIMEOUT = 1800; // 30 minutes in seconds
|
|
|
71
79
|
*/
|
|
72
80
|
export default class I3SConverter {
|
|
73
81
|
nodePages: NodePages;
|
|
74
|
-
fileMap: {[key: string]: string};
|
|
75
82
|
options: any;
|
|
76
83
|
layers0Path: string;
|
|
77
|
-
materialMap: Map<
|
|
78
|
-
materialDefinitions:
|
|
84
|
+
materialMap: Map<string, number>;
|
|
85
|
+
materialDefinitions: I3SMaterialDefinition[];
|
|
86
|
+
geometryMap: Map<string, number>;
|
|
87
|
+
geometryConfigs: {hasTexture: boolean; hasUvRegions: boolean}[];
|
|
79
88
|
vertexCounter: number;
|
|
80
|
-
layers0: SceneLayer3D;
|
|
89
|
+
layers0: SceneLayer3D | null;
|
|
81
90
|
featuresHashArray: string[];
|
|
82
91
|
refinementCounter: {
|
|
83
92
|
tilesCount: number;
|
|
84
93
|
tilesWithAddRefineCount: number;
|
|
85
94
|
};
|
|
86
95
|
validate: boolean;
|
|
87
|
-
boundingVolumeWarnings?: string[];
|
|
88
|
-
conversionStartTime: [number, number];
|
|
89
|
-
refreshTokenTime: [number, number];
|
|
90
|
-
sourceTileset: Tileset3D | null;
|
|
91
|
-
geoidHeightModel:
|
|
96
|
+
boundingVolumeWarnings?: string[] = [];
|
|
97
|
+
conversionStartTime: [number, number] = [0, 0];
|
|
98
|
+
refreshTokenTime: [number, number] = [0, 0];
|
|
99
|
+
sourceTileset: Tileset3D | null = null;
|
|
100
|
+
geoidHeightModel: Geoid | null = null;
|
|
101
|
+
Loader: LoaderWithParser = Tiles3DLoader;
|
|
102
|
+
generateTextures: boolean;
|
|
103
|
+
generateBoundingVolumes: boolean;
|
|
104
|
+
layersHasTexture: boolean;
|
|
105
|
+
workerSource: {[key: string]: string} = {};
|
|
106
|
+
writeQueue: WriteQueue<WriteQueueItem> = new WriteQueue();
|
|
107
|
+
compressList: string[] | null = null;
|
|
92
108
|
|
|
93
109
|
constructor() {
|
|
94
|
-
this.nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE);
|
|
95
|
-
this.fileMap = {};
|
|
110
|
+
this.nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE, this);
|
|
96
111
|
this.options = {};
|
|
97
112
|
this.layers0Path = '';
|
|
98
113
|
this.materialMap = new Map();
|
|
99
114
|
this.materialDefinitions = [];
|
|
115
|
+
this.geometryMap = new Map();
|
|
116
|
+
this.geometryConfigs = [];
|
|
100
117
|
this.vertexCounter = 0;
|
|
101
118
|
this.layers0 = null;
|
|
102
119
|
this.featuresHashArray = [];
|
|
@@ -105,7 +122,10 @@ export default class I3SConverter {
|
|
|
105
122
|
tilesWithAddRefineCount: 0
|
|
106
123
|
};
|
|
107
124
|
this.validate = false;
|
|
108
|
-
this.
|
|
125
|
+
this.generateTextures = false;
|
|
126
|
+
this.generateBoundingVolumes = false;
|
|
127
|
+
this.layersHasTexture = false;
|
|
128
|
+
this.compressList = null;
|
|
109
129
|
}
|
|
110
130
|
|
|
111
131
|
/**
|
|
@@ -121,19 +141,30 @@ export default class I3SConverter {
|
|
|
121
141
|
* @param options.token Token for Cesium ION tilesets authentication
|
|
122
142
|
* @param options.draco Generate I3S 1.7 draco compressed geometries
|
|
123
143
|
* @param options.validate -enable validation
|
|
144
|
+
* @param options.generateTextures - generate alternative type of textures (to have non-compressed jpeg/png and compressed ktx2)
|
|
145
|
+
* @param options.generateBoundingVolumes - generate bounding volumes from vertices coordinates instead of source tiles bounding volumes
|
|
146
|
+
* @param options.instantNodeWriting - Keep created 3DNodeIndexDocument files on disk instead of memory. This option reduce memory usage but decelerates conversion speed
|
|
124
147
|
*/
|
|
125
148
|
async convert(options: {
|
|
126
149
|
inputUrl: string;
|
|
127
150
|
outputPath: string;
|
|
128
151
|
tilesetName: string;
|
|
129
152
|
sevenZipExe: string;
|
|
130
|
-
egmFilePath
|
|
153
|
+
egmFilePath: string;
|
|
131
154
|
maxDepth?: number;
|
|
132
155
|
slpk?: boolean;
|
|
133
156
|
token?: string;
|
|
134
157
|
draco?: boolean;
|
|
158
|
+
mergeMaterials?: boolean;
|
|
135
159
|
validate?: boolean;
|
|
160
|
+
generateTextures?: boolean;
|
|
161
|
+
generateBoundingVolumes?: boolean;
|
|
162
|
+
instantNodeWriting?: boolean;
|
|
136
163
|
}): Promise<any> {
|
|
164
|
+
if (isBrowser) {
|
|
165
|
+
console.log(BROWSER_ERROR_MESSAGE);
|
|
166
|
+
return BROWSER_ERROR_MESSAGE;
|
|
167
|
+
}
|
|
137
168
|
this.conversionStartTime = process.hrtime();
|
|
138
169
|
const {
|
|
139
170
|
tilesetName,
|
|
@@ -142,13 +173,34 @@ export default class I3SConverter {
|
|
|
142
173
|
inputUrl,
|
|
143
174
|
validate,
|
|
144
175
|
outputPath,
|
|
145
|
-
draco,
|
|
176
|
+
draco = true,
|
|
146
177
|
sevenZipExe,
|
|
147
178
|
maxDepth,
|
|
148
|
-
token
|
|
179
|
+
token,
|
|
180
|
+
generateTextures,
|
|
181
|
+
generateBoundingVolumes,
|
|
182
|
+
instantNodeWriting = false,
|
|
183
|
+
mergeMaterials = true
|
|
149
184
|
} = options;
|
|
150
|
-
this.options = {
|
|
151
|
-
|
|
185
|
+
this.options = {
|
|
186
|
+
maxDepth,
|
|
187
|
+
slpk,
|
|
188
|
+
sevenZipExe,
|
|
189
|
+
egmFilePath,
|
|
190
|
+
draco,
|
|
191
|
+
token,
|
|
192
|
+
inputUrl,
|
|
193
|
+
instantNodeWriting,
|
|
194
|
+
mergeMaterials
|
|
195
|
+
};
|
|
196
|
+
this.compressList = (this.options.instantNodeWriting && []) || null;
|
|
197
|
+
this.validate = Boolean(validate);
|
|
198
|
+
this.Loader = inputUrl.indexOf(CESIUM_DATASET_PREFIX) !== -1 ? CesiumIonLoader : Tiles3DLoader;
|
|
199
|
+
this.generateTextures = Boolean(generateTextures);
|
|
200
|
+
this.generateBoundingVolumes = Boolean(generateBoundingVolumes);
|
|
201
|
+
|
|
202
|
+
this.writeQueue = new WriteQueue();
|
|
203
|
+
this.writeQueue.startListening();
|
|
152
204
|
|
|
153
205
|
console.log('Loading egm file...'); // eslint-disable-line
|
|
154
206
|
this.geoidHeightModel = await load(egmFilePath, PGMLoader);
|
|
@@ -158,19 +210,44 @@ export default class I3SConverter {
|
|
|
158
210
|
this.nodePages.useWriteFunction(writeFileForSlpk);
|
|
159
211
|
}
|
|
160
212
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
213
|
+
await this.loadWorkers();
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
const preloadOptions = await this._fetchPreloadOptions();
|
|
217
|
+
const tilesetOptions: Tileset3DProps = {
|
|
218
|
+
loadOptions: {
|
|
219
|
+
_nodeWorkers: true,
|
|
220
|
+
reuseWorkers: true,
|
|
221
|
+
basis: {format: 'rgba32'},
|
|
222
|
+
'basis-nodejs': {
|
|
223
|
+
format: 'rgba32',
|
|
224
|
+
workerUrl: './modules/textures/dist/basis-nodejs-worker.js'
|
|
225
|
+
},
|
|
226
|
+
'draco-nodejs': {workerUrl: './modules/draco/dist/draco-nodejs-worker.js'}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
if (preloadOptions.headers) {
|
|
230
|
+
tilesetOptions.loadOptions!.fetch = {headers: preloadOptions.headers};
|
|
231
|
+
}
|
|
232
|
+
Object.assign(tilesetOptions, preloadOptions);
|
|
233
|
+
const sourceTilesetJson = await load(inputUrl, this.Loader, tilesetOptions.loadOptions);
|
|
234
|
+
// console.log(tilesetJson); // eslint-disable-line
|
|
235
|
+
this.sourceTileset = new Tileset3D(sourceTilesetJson, tilesetOptions);
|
|
236
|
+
|
|
237
|
+
await this._createAndSaveTileset(
|
|
238
|
+
outputPath,
|
|
239
|
+
tilesetName,
|
|
240
|
+
sourceTilesetJson?.root?.boundingVolume?.region
|
|
241
|
+
);
|
|
242
|
+
await this._finishConversion({slpk: Boolean(slpk), outputPath, tilesetName});
|
|
243
|
+
return sourceTilesetJson;
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw error;
|
|
246
|
+
} finally {
|
|
247
|
+
// Clean up worker pools
|
|
248
|
+
const workerFarm = WorkerFarm.getWorkerFarm({});
|
|
249
|
+
workerFarm.destroy();
|
|
165
250
|
}
|
|
166
|
-
Object.assign(tilesetOptions, preloadOptions);
|
|
167
|
-
const sourceTilesetJson = await load(inputUrl, CesiumIonLoader, tilesetOptions.loadOptions);
|
|
168
|
-
// console.log(tilesetJson); // eslint-disable-line
|
|
169
|
-
this.sourceTileset = new Tileset3D(sourceTilesetJson, tilesetOptions);
|
|
170
|
-
|
|
171
|
-
await this._createAndSaveTileset(outputPath, tilesetName);
|
|
172
|
-
await this._finishConversion({slpk, outputPath, tilesetName});
|
|
173
|
-
return sourceTilesetJson;
|
|
174
251
|
}
|
|
175
252
|
|
|
176
253
|
/**
|
|
@@ -178,7 +255,11 @@ export default class I3SConverter {
|
|
|
178
255
|
* @param outputPath - path to save output data
|
|
179
256
|
* @param tilesetName - new tileset path
|
|
180
257
|
*/
|
|
181
|
-
private async _createAndSaveTileset(
|
|
258
|
+
private async _createAndSaveTileset(
|
|
259
|
+
outputPath: string,
|
|
260
|
+
tilesetName: string,
|
|
261
|
+
boundingVolumeRegion?: number[]
|
|
262
|
+
): Promise<void> {
|
|
182
263
|
const tilesetPath = join(`${outputPath}`, `${tilesetName}`);
|
|
183
264
|
// Removing the tilesetPath needed to exclude erroneous files after conversion
|
|
184
265
|
try {
|
|
@@ -189,29 +270,47 @@ export default class I3SConverter {
|
|
|
189
270
|
|
|
190
271
|
this.layers0Path = join(tilesetPath, 'SceneServer', 'layers', '0');
|
|
191
272
|
|
|
192
|
-
this._formLayers0(tilesetName);
|
|
273
|
+
this._formLayers0(tilesetName, boundingVolumeRegion);
|
|
193
274
|
|
|
194
275
|
this.materialDefinitions = [];
|
|
195
276
|
this.materialMap = new Map();
|
|
196
277
|
|
|
197
|
-
const sourceRootTile = this.sourceTileset
|
|
198
|
-
const boundingVolumes = createBoundingVolumes(sourceRootTile, this.geoidHeightModel);
|
|
199
|
-
|
|
278
|
+
const sourceRootTile: Tile3D = this.sourceTileset!.root!;
|
|
279
|
+
const boundingVolumes = createBoundingVolumes(sourceRootTile, this.geoidHeightModel!);
|
|
280
|
+
await this.nodePages.push({
|
|
281
|
+
index: 0,
|
|
200
282
|
lodThreshold: 0,
|
|
201
283
|
obb: boundingVolumes.obb,
|
|
202
284
|
children: []
|
|
203
285
|
});
|
|
204
286
|
|
|
205
|
-
const
|
|
206
|
-
|
|
287
|
+
const rootNode = await NodeIndexDocument.createRootNode(boundingVolumes, this);
|
|
288
|
+
await this._convertNodesTree(rootNode, sourceRootTile);
|
|
207
289
|
|
|
208
|
-
|
|
290
|
+
this.layers0!.materialDefinitions = this.materialDefinitions;
|
|
291
|
+
// @ts-ignore
|
|
292
|
+
this.layers0.geometryDefinitions = transform(
|
|
293
|
+
this.geometryConfigs.map((config) => ({
|
|
294
|
+
geometryConfig: {...config, draco: this.options.draco}
|
|
295
|
+
})),
|
|
296
|
+
geometryDefinitionTemlate()
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
if (this.layersHasTexture === false) {
|
|
300
|
+
this.layers0!.store.defaultGeometrySchema.ordering =
|
|
301
|
+
this.layers0!.store.defaultGeometrySchema.ordering.filter(
|
|
302
|
+
(attribute) => attribute !== 'uv0'
|
|
303
|
+
);
|
|
304
|
+
}
|
|
209
305
|
|
|
210
|
-
this.layers0.materialDefinitions = this.materialDefinitions;
|
|
211
306
|
await this._writeLayers0();
|
|
212
|
-
createSceneServerPath(tilesetName, this.layers0
|
|
213
|
-
|
|
214
|
-
|
|
307
|
+
createSceneServerPath(tilesetName, this.layers0!, tilesetPath);
|
|
308
|
+
for (const filePath of this.compressList || []) {
|
|
309
|
+
await compressFileWithGzip(filePath);
|
|
310
|
+
await removeFile(filePath);
|
|
311
|
+
}
|
|
312
|
+
await this.nodePages.save();
|
|
313
|
+
await this.writeQueue.finalize();
|
|
215
314
|
await this._createSlpk(tilesetPath);
|
|
216
315
|
}
|
|
217
316
|
|
|
@@ -219,8 +318,15 @@ export default class I3SConverter {
|
|
|
219
318
|
* Form object of 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
|
|
220
319
|
* @param tilesetName - Name of layer
|
|
221
320
|
*/
|
|
222
|
-
private _formLayers0(tilesetName: string): void {
|
|
223
|
-
const
|
|
321
|
+
private _formLayers0(tilesetName: string, boundingVolumeRegion?: number[]): void {
|
|
322
|
+
const fullExtent = convertBoundingVolumeToI3SFullExtent(
|
|
323
|
+
this.sourceTileset?.boundingVolume || this.sourceTileset?.root?.boundingVolume
|
|
324
|
+
);
|
|
325
|
+
if (boundingVolumeRegion) {
|
|
326
|
+
fullExtent.zmin = boundingVolumeRegion[4];
|
|
327
|
+
fullExtent.zmax = boundingVolumeRegion[5];
|
|
328
|
+
}
|
|
329
|
+
const extent = [fullExtent.xmin, fullExtent.ymin, fullExtent.xmax, fullExtent.ymax];
|
|
224
330
|
const layers0data = {
|
|
225
331
|
version: `{${uuidv4().toUpperCase()}}`,
|
|
226
332
|
id: 0,
|
|
@@ -233,79 +339,37 @@ export default class I3SConverter {
|
|
|
233
339
|
nodePages: {
|
|
234
340
|
nodesPerPage: HARDCODED_NODES_PER_PAGE
|
|
235
341
|
},
|
|
236
|
-
compressGeometry: this.options.draco
|
|
342
|
+
compressGeometry: this.options.draco,
|
|
343
|
+
fullExtent
|
|
237
344
|
};
|
|
238
|
-
|
|
239
|
-
this.layers0 = transform(layers0data, layersTemplate);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Convert and save the layer and embedded tiles
|
|
244
|
-
* @param boundingVolumes - mbs and obb data about node's bounding volume
|
|
245
|
-
* @return 3DNodeIndexDocument data https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
|
|
246
|
-
*/
|
|
247
|
-
private _formRootNodeIndexDocument(boundingVolumes: BoundingVolumes): Node3DIndexDocument {
|
|
248
|
-
const root0data = {
|
|
249
|
-
version: `{${uuidv4().toUpperCase()}}`,
|
|
250
|
-
id: 'root',
|
|
251
|
-
level: 0,
|
|
252
|
-
lodSelection: [
|
|
253
|
-
{
|
|
254
|
-
metricType: 'maxScreenThresholdSQ',
|
|
255
|
-
maxError: 0
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
metricType: 'maxScreenThreshold',
|
|
259
|
-
maxError: 0
|
|
260
|
-
}
|
|
261
|
-
],
|
|
262
|
-
...boundingVolumes,
|
|
263
|
-
children: []
|
|
264
|
-
};
|
|
265
|
-
return transform(root0data, nodeTemplate);
|
|
345
|
+
this.layers0 = transform(layers0data, layersTemplate());
|
|
266
346
|
}
|
|
267
347
|
|
|
268
348
|
/**
|
|
269
349
|
* Form object of 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
|
|
270
|
-
* @param
|
|
350
|
+
* @param rootNode - 3DNodeIndexDocument of root node https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
|
|
271
351
|
* @param sourceRootTile - Source (3DTile) tile data
|
|
272
|
-
* @param parentId - node id in node pages
|
|
273
|
-
* @param boundingVolumes - mbs and obb data about node's bounding volume
|
|
274
352
|
*/
|
|
275
353
|
private async _convertNodesTree(
|
|
276
|
-
|
|
277
|
-
sourceRootTile:
|
|
278
|
-
parentId: number,
|
|
279
|
-
boundingVolumes: BoundingVolumes
|
|
354
|
+
rootNode: NodeIndexDocument,
|
|
355
|
+
sourceRootTile: Tile3D
|
|
280
356
|
): Promise<void> {
|
|
281
|
-
await this.sourceTileset
|
|
282
|
-
if (
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
...boundingVolumes
|
|
287
|
-
});
|
|
288
|
-
const [child] = await this._createNode(root0, sourceRootTile, parentId, 0);
|
|
289
|
-
const childPath = join(this.layers0Path, 'nodes', child.path);
|
|
290
|
-
|
|
291
|
-
if (this.options.slpk) {
|
|
292
|
-
this.fileMap['nodes/1/3dNodeIndexDocument.json.gz'] = await writeFileForSlpk(
|
|
293
|
-
childPath,
|
|
294
|
-
JSON.stringify(child),
|
|
295
|
-
'3dNodeIndexDocument.json'
|
|
296
|
-
);
|
|
297
|
-
} else {
|
|
298
|
-
await writeFile(childPath, JSON.stringify(child));
|
|
357
|
+
await this.sourceTileset!._loadTile(sourceRootTile);
|
|
358
|
+
if (this.isContentSupported(sourceRootTile)) {
|
|
359
|
+
const childNodes = await this._createNode(rootNode, sourceRootTile, 0);
|
|
360
|
+
for (const childNode of childNodes) {
|
|
361
|
+
await childNode.save();
|
|
299
362
|
}
|
|
363
|
+
await rootNode.addChildren(childNodes);
|
|
300
364
|
} else {
|
|
301
365
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
302
|
-
parentNode:
|
|
366
|
+
parentNode: rootNode,
|
|
303
367
|
sourceTiles: sourceRootTile.children,
|
|
304
|
-
parentId,
|
|
305
368
|
level: 1
|
|
306
369
|
});
|
|
307
370
|
}
|
|
308
371
|
await sourceRootTile.unloadContent();
|
|
372
|
+
await rootNode.save();
|
|
309
373
|
}
|
|
310
374
|
|
|
311
375
|
/**
|
|
@@ -313,32 +377,15 @@ export default class I3SConverter {
|
|
|
313
377
|
*/
|
|
314
378
|
private async _writeLayers0(): Promise<void> {
|
|
315
379
|
if (this.options.slpk) {
|
|
316
|
-
this.
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
);
|
|
321
|
-
} else {
|
|
322
|
-
await writeFile(this.layers0Path, JSON.stringify(this.layers0));
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Write 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md in file
|
|
328
|
-
*/
|
|
329
|
-
private async _writeNodeIndexDocument(
|
|
330
|
-
root0: Node3DIndexDocument,
|
|
331
|
-
nodePath: string,
|
|
332
|
-
rootPath: string
|
|
333
|
-
): Promise<void> {
|
|
334
|
-
if (this.options.slpk) {
|
|
335
|
-
this.fileMap[`nodes/${nodePath}/3dNodeIndexDocument.json.gz`] = await writeFileForSlpk(
|
|
336
|
-
rootPath,
|
|
337
|
-
JSON.stringify(root0),
|
|
338
|
-
'3dNodeIndexDocument.json'
|
|
339
|
-
);
|
|
380
|
+
await this.writeQueue.enqueue({
|
|
381
|
+
archiveKey: '3dSceneLayer.json.gz',
|
|
382
|
+
writePromise: () =>
|
|
383
|
+
writeFileForSlpk(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
|
|
384
|
+
});
|
|
340
385
|
} else {
|
|
341
|
-
await
|
|
386
|
+
await this.writeQueue.enqueue({
|
|
387
|
+
writePromise: () => writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
388
|
+
});
|
|
342
389
|
}
|
|
343
390
|
}
|
|
344
391
|
|
|
@@ -387,64 +434,85 @@ export default class I3SConverter {
|
|
|
387
434
|
/**
|
|
388
435
|
* Add child nodes recursively and write them to files
|
|
389
436
|
* @param data - arguments
|
|
437
|
+
* @param data.parentNode - 3DNodeIndexDocument of parent node
|
|
390
438
|
* @param data.sourceTiles - array of source child nodes
|
|
391
|
-
* @param data.parentNode - 3DNodeIndexDocument of parent node for processing child nodes
|
|
392
|
-
* @param data.parentId - id of parent node in node pages
|
|
393
439
|
* @param data.level - level of node (distanse to root node in the tree)
|
|
394
440
|
*/
|
|
395
441
|
private async _addChildrenWithNeighborsAndWriteFile(data: {
|
|
396
|
-
parentNode:
|
|
397
|
-
sourceTiles:
|
|
398
|
-
parentId: number;
|
|
442
|
+
parentNode: NodeIndexDocument;
|
|
443
|
+
sourceTiles: Tile3D[];
|
|
399
444
|
level: number;
|
|
400
445
|
}): Promise<void> {
|
|
401
|
-
|
|
402
|
-
await
|
|
403
|
-
|
|
446
|
+
await this._addChildren(data);
|
|
447
|
+
await data.parentNode.addNeighbors();
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Convert nested subtree of 3DTiles dataset
|
|
452
|
+
* @param param0
|
|
453
|
+
* @param data.parentNode - 3DNodeIndexDocument of parent node
|
|
454
|
+
* @param param0.sourceTile - source 3DTile data
|
|
455
|
+
* @param param0.level - tree level
|
|
456
|
+
*/
|
|
457
|
+
private async convertNestedTileset({
|
|
458
|
+
parentNode,
|
|
459
|
+
sourceTile,
|
|
460
|
+
level
|
|
461
|
+
}: {
|
|
462
|
+
parentNode: NodeIndexDocument;
|
|
463
|
+
sourceTile: Tile3D;
|
|
464
|
+
level: number;
|
|
465
|
+
}) {
|
|
466
|
+
await this.sourceTileset!._loadTile(sourceTile);
|
|
467
|
+
await this._addChildren({
|
|
468
|
+
parentNode,
|
|
469
|
+
sourceTiles: sourceTile.children,
|
|
470
|
+
level: level + 1
|
|
471
|
+
});
|
|
472
|
+
await sourceTile.unloadContent();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Convert 3DTiles tile to I3S node
|
|
477
|
+
* @param param0
|
|
478
|
+
* @param param0.parentNode - 3DNodeIndexDocument of parent node
|
|
479
|
+
* @param param0.sourceTile - source 3DTile data
|
|
480
|
+
* @param param0.level - tree level
|
|
481
|
+
*/
|
|
482
|
+
private async convertNode({
|
|
483
|
+
parentNode,
|
|
484
|
+
sourceTile,
|
|
485
|
+
level
|
|
486
|
+
}: {
|
|
487
|
+
parentNode: NodeIndexDocument;
|
|
488
|
+
sourceTile: Tile3D;
|
|
489
|
+
level: number;
|
|
490
|
+
}) {
|
|
491
|
+
const childNodes = await this._createNode(parentNode, sourceTile, level);
|
|
492
|
+
await parentNode.addChildren(childNodes);
|
|
404
493
|
}
|
|
405
494
|
|
|
406
495
|
/**
|
|
407
496
|
* Add child nodes recursively and write them to files
|
|
408
|
-
* @param
|
|
409
|
-
* @param
|
|
410
|
-
* @param
|
|
411
|
-
* @param
|
|
412
|
-
* @param data.parentId - id of parent node in node pages
|
|
413
|
-
* @param data.level - level of node (distanse to root node in the tree)
|
|
497
|
+
* @param param0 - arguments
|
|
498
|
+
* @param param0.parentNode - 3DNodeIndexDocument of parent node
|
|
499
|
+
* @param param0.sourceTile - source 3DTile data
|
|
500
|
+
* @param param0.level - tree level
|
|
414
501
|
*/
|
|
415
502
|
private async _addChildren(data: {
|
|
416
|
-
|
|
417
|
-
sourceTiles:
|
|
418
|
-
parentNode: Node3DIndexDocument;
|
|
419
|
-
parentId: number;
|
|
503
|
+
parentNode: NodeIndexDocument;
|
|
504
|
+
sourceTiles: Tile3D[];
|
|
420
505
|
level: number;
|
|
421
506
|
}): Promise<void> {
|
|
422
|
-
const {
|
|
507
|
+
const {sourceTiles, parentNode, level} = data;
|
|
423
508
|
if (this.options.maxDepth && level > this.options.maxDepth) {
|
|
424
509
|
return;
|
|
425
510
|
}
|
|
426
511
|
for (const sourceTile of sourceTiles) {
|
|
427
512
|
if (sourceTile.type === 'json') {
|
|
428
|
-
await this.
|
|
429
|
-
await this._addChildren({
|
|
430
|
-
parentNode,
|
|
431
|
-
sourceTiles: sourceTile.children,
|
|
432
|
-
childNodes,
|
|
433
|
-
parentId,
|
|
434
|
-
level: level + 1
|
|
435
|
-
});
|
|
436
|
-
await sourceTile.unloadContent();
|
|
513
|
+
await this.convertNestedTileset({parentNode, sourceTile, level});
|
|
437
514
|
} else {
|
|
438
|
-
|
|
439
|
-
const children = await this._createNode(parentNode, sourceTile, parentId, level);
|
|
440
|
-
for (const child of children) {
|
|
441
|
-
parentNode.children.push({
|
|
442
|
-
id: child.id,
|
|
443
|
-
href: `../${child.path}`,
|
|
444
|
-
...boundingVolumes
|
|
445
|
-
});
|
|
446
|
-
childNodes.push(child);
|
|
447
|
-
}
|
|
515
|
+
await this.convertNode({parentNode, sourceTile, level});
|
|
448
516
|
}
|
|
449
517
|
if (sourceTile.id) {
|
|
450
518
|
console.log(sourceTile.id); // eslint-disable-line
|
|
@@ -452,172 +520,145 @@ export default class I3SConverter {
|
|
|
452
520
|
}
|
|
453
521
|
}
|
|
454
522
|
|
|
455
|
-
/**
|
|
456
|
-
* Add neightbors to 3DNodeIndexDocument and write it in a file
|
|
457
|
-
* @param parentNode - arguments
|
|
458
|
-
* @param childNodes - array of target child nodes
|
|
459
|
-
*/
|
|
460
|
-
private async _addNeighborsAndWriteFile(
|
|
461
|
-
parentNode: Node3DIndexDocument,
|
|
462
|
-
childNodes: Node3DIndexDocument[]
|
|
463
|
-
): Promise<void> {
|
|
464
|
-
for (const node of childNodes) {
|
|
465
|
-
const childPath = join(this.layers0Path, 'nodes', node.path);
|
|
466
|
-
const nodePath = node.path;
|
|
467
|
-
delete node.path;
|
|
468
|
-
|
|
469
|
-
// Don't do large amount of "neightbors" to avoid big memory consumption
|
|
470
|
-
if (parentNode.children.length < 1000) {
|
|
471
|
-
for (const neighbor of parentNode.children) {
|
|
472
|
-
// eslint-disable-next-line max-depth
|
|
473
|
-
if (node.id === neighbor.id) {
|
|
474
|
-
continue; // eslint-disable-line
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
node.neighbors.push({...neighbor});
|
|
478
|
-
}
|
|
479
|
-
} else {
|
|
480
|
-
// eslint-disable-next-line no-console, no-undef
|
|
481
|
-
console.warn(
|
|
482
|
-
`Node ${node.id}: neighbors attribute is omited because of large number of neigbors`
|
|
483
|
-
);
|
|
484
|
-
delete node.neighbors;
|
|
485
|
-
}
|
|
486
|
-
await this._writeNodeIndexDocument(node, nodePath, childPath);
|
|
487
|
-
node.neighbors = [];
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
523
|
/**
|
|
492
524
|
* Convert tile to one or more I3S nodes
|
|
493
|
-
* @param
|
|
494
|
-
* @param sourceTile - source
|
|
495
|
-
* @param
|
|
496
|
-
* @param level - level of node (distanse to root node in the tree)
|
|
525
|
+
* @param parentNode - 3DNodeIndexDocument of parent node
|
|
526
|
+
* @param sourceTile - source 3DTile data
|
|
527
|
+
* @param level - tree level
|
|
497
528
|
*/
|
|
498
529
|
private async _createNode(
|
|
499
|
-
|
|
500
|
-
sourceTile:
|
|
501
|
-
parentId: number,
|
|
530
|
+
parentNode: NodeIndexDocument,
|
|
531
|
+
sourceTile: Tile3D,
|
|
502
532
|
level: number
|
|
503
|
-
): Promise<
|
|
504
|
-
|
|
505
|
-
this._checkAddRefinementTypeForTile(sourceTile);
|
|
506
|
-
}
|
|
533
|
+
): Promise<NodeIndexDocument[]> {
|
|
534
|
+
this._checkAddRefinementTypeForTile(sourceTile);
|
|
507
535
|
|
|
508
536
|
await this._updateTilesetOptions();
|
|
509
|
-
await this.sourceTileset
|
|
510
|
-
const boundingVolumes = createBoundingVolumes(sourceTile, this.geoidHeightModel);
|
|
537
|
+
await this.sourceTileset!._loadTile(sourceTile);
|
|
511
538
|
|
|
512
|
-
|
|
513
|
-
const maxScreenThresholdSQ = lodSelection.find(
|
|
514
|
-
(val) => val.metricType === 'maxScreenThresholdSQ'
|
|
515
|
-
) || {maxError: 0};
|
|
539
|
+
let boundingVolumes = createBoundingVolumes(sourceTile, this.geoidHeightModel!);
|
|
516
540
|
|
|
517
|
-
const
|
|
541
|
+
const propertyTable = getPropertyTable(sourceTile.content);
|
|
518
542
|
|
|
519
|
-
if (
|
|
520
|
-
this.
|
|
543
|
+
if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
|
|
544
|
+
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
521
545
|
}
|
|
522
546
|
|
|
523
|
-
const resourcesData = await this._convertResources(
|
|
547
|
+
const resourcesData = await this._convertResources(
|
|
548
|
+
sourceTile,
|
|
549
|
+
parentNode.inPageId,
|
|
550
|
+
propertyTable
|
|
551
|
+
);
|
|
524
552
|
|
|
525
|
-
const nodes = [];
|
|
553
|
+
const nodes: NodeIndexDocument[] = [];
|
|
554
|
+
const nodeIds: number[] = [];
|
|
555
|
+
const nodesInPage: NodeInPage[] = [];
|
|
526
556
|
const emptyResources = {
|
|
527
557
|
geometry: null,
|
|
528
558
|
compressedGeometry: null,
|
|
529
559
|
texture: null,
|
|
560
|
+
hasUvRegions: false,
|
|
530
561
|
sharedResources: null,
|
|
531
562
|
meshMaterial: null,
|
|
532
563
|
vertexCount: null,
|
|
533
564
|
attributes: null,
|
|
534
|
-
featureCount: null
|
|
565
|
+
featureCount: null,
|
|
566
|
+
boundingVolumes: null
|
|
535
567
|
};
|
|
568
|
+
|
|
536
569
|
for (const resources of resourcesData || [emptyResources]) {
|
|
537
|
-
|
|
570
|
+
this.layersHasTexture = this.layersHasTexture || Boolean(resources.texture);
|
|
571
|
+
|
|
572
|
+
if (this.generateBoundingVolumes && resources.boundingVolumes) {
|
|
573
|
+
boundingVolumes = resources.boundingVolumes;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const lodSelection = convertGeometricErrorToScreenThreshold(sourceTile, boundingVolumes);
|
|
577
|
+
const maxScreenThresholdSQ = lodSelection.find(
|
|
578
|
+
(val) => val.metricType === 'maxScreenThresholdSQ'
|
|
579
|
+
) || {maxError: 0};
|
|
580
|
+
|
|
581
|
+
const nodeInPage = await this._updateNodeInNodePages(
|
|
538
582
|
maxScreenThresholdSQ,
|
|
539
583
|
boundingVolumes,
|
|
540
584
|
sourceTile,
|
|
541
|
-
|
|
585
|
+
parentNode.inPageId,
|
|
542
586
|
resources
|
|
543
587
|
);
|
|
544
|
-
|
|
545
|
-
|
|
588
|
+
|
|
589
|
+
const nodeData = await NodeIndexDocument.createNodeIndexDocument(
|
|
590
|
+
parentNode,
|
|
546
591
|
boundingVolumes,
|
|
547
592
|
lodSelection,
|
|
548
593
|
nodeInPage,
|
|
549
594
|
resources
|
|
550
595
|
);
|
|
596
|
+
const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
|
|
597
|
+
nodes.push(node);
|
|
551
598
|
|
|
552
599
|
if (nodeInPage.mesh) {
|
|
553
|
-
await this._writeResources(resources, node.
|
|
600
|
+
await this._writeResources(resources, node.id);
|
|
554
601
|
}
|
|
555
602
|
|
|
556
603
|
if (this.validate) {
|
|
557
|
-
this.boundingVolumeWarnings = validateNodeBoundingVolumes(
|
|
604
|
+
this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
|
|
558
605
|
|
|
559
606
|
if (this.boundingVolumeWarnings && this.boundingVolumeWarnings.length) {
|
|
560
607
|
console.warn('Bounding Volume Warnings: ', ...this.boundingVolumeWarnings); //eslint-disable-line
|
|
561
608
|
}
|
|
562
609
|
}
|
|
563
610
|
|
|
564
|
-
|
|
611
|
+
nodeIds.push(nodeInPage.index);
|
|
612
|
+
nodesInPage.push(nodeInPage);
|
|
565
613
|
}
|
|
566
614
|
|
|
567
615
|
sourceTile.unloadContent();
|
|
568
616
|
|
|
569
|
-
const firstNode = nodes[0];
|
|
570
617
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
571
|
-
parentNode:
|
|
618
|
+
parentNode: nodes[0],
|
|
572
619
|
sourceTiles: sourceTile.children,
|
|
573
|
-
parentId: firstNode.id,
|
|
574
620
|
level: level + 1
|
|
575
621
|
});
|
|
576
622
|
return nodes;
|
|
577
623
|
}
|
|
578
624
|
|
|
579
|
-
/**
|
|
580
|
-
* Convert attributesStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
|
|
581
|
-
* from B3DM batch table
|
|
582
|
-
* @param sourceTileContent - tile content of 3DTile
|
|
583
|
-
* @return {void}
|
|
584
|
-
*/
|
|
585
|
-
private _convertAttributeStorageInfo(sourceTileContent: B3DMContent): void {
|
|
586
|
-
// In legacy b3dm files sometimes sourceTileContent is null.
|
|
587
|
-
const batchTable = sourceTileContent && sourceTileContent.batchTableJson;
|
|
588
|
-
if (batchTable && !this.layers0.attributeStorageInfo.length) {
|
|
589
|
-
this._convertBatchTableInfoToNodeAttributes(batchTable);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
625
|
/**
|
|
594
626
|
* Convert tile to one or more I3S nodes
|
|
595
627
|
* @param sourceTile - source tile (3DTile)
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
* result.sharedResources - shared resource data object
|
|
600
|
-
* result.meshMaterial - PBR-like material object
|
|
601
|
-
* result.vertexCount - number of vertices in geometry
|
|
602
|
-
* result.attributes - feature attributes
|
|
603
|
-
* result.featureCount - number of features
|
|
628
|
+
* @param parentId - id of parent node in node pages
|
|
629
|
+
* @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
630
|
+
* @returns - converted node resources
|
|
604
631
|
*/
|
|
605
|
-
private async _convertResources(
|
|
606
|
-
|
|
632
|
+
private async _convertResources(
|
|
633
|
+
sourceTile: Tile3D,
|
|
634
|
+
parentId: number,
|
|
635
|
+
propertyTable: FeatureTableJson | null
|
|
636
|
+
): Promise<I3SConvertedResources[] | null> {
|
|
637
|
+
if (!this.isContentSupported(sourceTile)) {
|
|
607
638
|
return null;
|
|
608
639
|
}
|
|
640
|
+
const draftObb = {
|
|
641
|
+
center: [],
|
|
642
|
+
halfSize: [],
|
|
643
|
+
quaternion: []
|
|
644
|
+
};
|
|
609
645
|
const resourcesData = await convertB3dmToI3sGeometry(
|
|
610
646
|
sourceTile.content,
|
|
611
|
-
|
|
647
|
+
async () => (await this.nodePages.push({index: 0, obb: draftObb}, parentId)).index,
|
|
648
|
+
propertyTable,
|
|
612
649
|
this.featuresHashArray,
|
|
613
|
-
this.layers0
|
|
614
|
-
this.options.draco
|
|
650
|
+
this.layers0?.attributeStorageInfo,
|
|
651
|
+
this.options.draco,
|
|
652
|
+
this.generateBoundingVolumes,
|
|
653
|
+
this.options.mergeMaterials,
|
|
654
|
+
this.geoidHeightModel!,
|
|
655
|
+
this.workerSource
|
|
615
656
|
);
|
|
616
657
|
return resourcesData;
|
|
617
658
|
}
|
|
618
659
|
|
|
619
660
|
/**
|
|
620
|
-
*
|
|
661
|
+
* Update node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
|
|
621
662
|
* in node pages (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodePage.cmn.md)
|
|
622
663
|
* @param maxScreenThresholdSQ - Level of Details (LOD) metric
|
|
623
664
|
* @param boundingVolumes - Bounding volumes
|
|
@@ -628,112 +669,64 @@ export default class I3SConverter {
|
|
|
628
669
|
* @param resources.texture - texture image
|
|
629
670
|
* @param resources.vertexCount - number of vertices in geometry
|
|
630
671
|
* @param resources.featureCount - number of features
|
|
672
|
+
* @param resources.geometry - Uint8Array with geometry attributes
|
|
631
673
|
* @return the node object in node pages
|
|
632
674
|
*/
|
|
633
|
-
private
|
|
675
|
+
private async _updateNodeInNodePages(
|
|
634
676
|
maxScreenThresholdSQ: MaxScreenThresholdSQ,
|
|
635
677
|
boundingVolumes: BoundingVolumes,
|
|
636
|
-
sourceTile:
|
|
678
|
+
sourceTile: Tile3D,
|
|
637
679
|
parentId: number,
|
|
638
|
-
resources:
|
|
639
|
-
): NodeInPage {
|
|
640
|
-
const {meshMaterial, texture, vertexCount, featureCount, geometry} = resources;
|
|
641
|
-
const nodeInPage = {
|
|
680
|
+
resources: I3SConvertedResources
|
|
681
|
+
): Promise<NodeInPage> {
|
|
682
|
+
const {meshMaterial, texture, vertexCount, featureCount, geometry, hasUvRegions} = resources;
|
|
683
|
+
const nodeInPage: NodeInPage = {
|
|
684
|
+
index: 0,
|
|
642
685
|
lodThreshold: maxScreenThresholdSQ.maxError,
|
|
643
686
|
obb: boundingVolumes.obb,
|
|
644
|
-
children: []
|
|
645
|
-
mesh: null
|
|
687
|
+
children: []
|
|
646
688
|
};
|
|
647
|
-
if (geometry &&
|
|
689
|
+
if (geometry && this.isContentSupported(sourceTile)) {
|
|
648
690
|
nodeInPage.mesh = {
|
|
649
691
|
geometry: {
|
|
650
|
-
definition: texture
|
|
692
|
+
definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
|
|
693
|
+
resource: 0
|
|
651
694
|
},
|
|
652
|
-
attribute: {
|
|
695
|
+
attribute: {
|
|
696
|
+
resource: 0
|
|
697
|
+
},
|
|
698
|
+
material: {
|
|
699
|
+
definition: 0
|
|
700
|
+
}
|
|
653
701
|
};
|
|
654
702
|
}
|
|
655
|
-
const nodeId = this.nodePages.push(nodeInPage, parentId);
|
|
656
703
|
|
|
657
|
-
|
|
658
|
-
|
|
704
|
+
let nodeId = resources.nodeId;
|
|
705
|
+
let node;
|
|
706
|
+
if (!nodeId) {
|
|
707
|
+
node = await this.nodePages.push(nodeInPage, parentId);
|
|
708
|
+
} else {
|
|
709
|
+
node = await this.nodePages.getNodeById(nodeId);
|
|
659
710
|
}
|
|
660
711
|
|
|
712
|
+
NodePages.updateAll(node, nodeInPage);
|
|
713
|
+
if (meshMaterial) {
|
|
714
|
+
NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
|
|
715
|
+
}
|
|
661
716
|
if (texture) {
|
|
662
717
|
const texelCountHint = texture.image.height * texture.image.width;
|
|
663
|
-
|
|
718
|
+
NodePages.updateTexelCountHintByNodeId(node, texelCountHint);
|
|
664
719
|
}
|
|
665
|
-
|
|
666
720
|
if (vertexCount) {
|
|
667
721
|
this.vertexCounter += vertexCount;
|
|
668
|
-
|
|
722
|
+
NodePages.updateVertexCountByNodeId(node, vertexCount);
|
|
669
723
|
}
|
|
670
|
-
|
|
724
|
+
NodePages.updateNodeAttributeByNodeId(node);
|
|
671
725
|
if (featureCount) {
|
|
672
|
-
|
|
726
|
+
NodePages.updateFeatureCountByNodeId(node, featureCount);
|
|
673
727
|
}
|
|
674
728
|
|
|
675
|
-
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
/**
|
|
679
|
-
* Create a new node page object in node pages
|
|
680
|
-
* @param parentNode - 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object of the parent node
|
|
681
|
-
* @param boundingVolumes - Bounding volumes
|
|
682
|
-
* @param lodSelection - Level of Details (LOD) metrics
|
|
683
|
-
* @param nodeInPage - corresponding node object in a node page
|
|
684
|
-
* @param resources - the node resources data
|
|
685
|
-
* @param resources.texture - texture image
|
|
686
|
-
* @param resources.attributes - feature attributes
|
|
687
|
-
* @return 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object
|
|
688
|
-
*/
|
|
689
|
-
private _createNodeIndexDocument(
|
|
690
|
-
parentNode: Node3DIndexDocument,
|
|
691
|
-
boundingVolumes: BoundingVolumes,
|
|
692
|
-
lodSelection: LodSelection[],
|
|
693
|
-
nodeInPage: NodeInPage,
|
|
694
|
-
resources: I3SGeometry
|
|
695
|
-
): Node3DIndexDocument {
|
|
696
|
-
const {texture, attributes} = resources;
|
|
697
|
-
const nodeId = nodeInPage.index;
|
|
698
|
-
const nodeData = {
|
|
699
|
-
version: parentNode.version,
|
|
700
|
-
id: nodeId.toString(),
|
|
701
|
-
path: nodeId.toString(),
|
|
702
|
-
level: parentNode.level + 1,
|
|
703
|
-
...boundingVolumes,
|
|
704
|
-
lodSelection,
|
|
705
|
-
parentNode: {
|
|
706
|
-
id: parentNode.id,
|
|
707
|
-
href: `../${parentNode.id}`,
|
|
708
|
-
mbs: parentNode.mbs,
|
|
709
|
-
obb: parentNode.obb
|
|
710
|
-
},
|
|
711
|
-
children: [],
|
|
712
|
-
neighbors: []
|
|
713
|
-
};
|
|
714
|
-
const node = transform(nodeData, nodeTemplate);
|
|
715
|
-
|
|
716
|
-
if (nodeInPage.mesh) {
|
|
717
|
-
node.geometryData = [{href: './geometries/0'}];
|
|
718
|
-
node.sharedResource = {href: './shared'};
|
|
719
|
-
|
|
720
|
-
if (texture) {
|
|
721
|
-
node.textureData = [{href: './textures/0'}, {href: './textures/1'}];
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
if (
|
|
725
|
-
attributes &&
|
|
726
|
-
attributes.length &&
|
|
727
|
-
this.layers0.attributeStorageInfo &&
|
|
728
|
-
this.layers0.attributeStorageInfo.length
|
|
729
|
-
) {
|
|
730
|
-
node.attributeData = [];
|
|
731
|
-
for (let index = 0; index < attributes.length; index++) {
|
|
732
|
-
const folderName = this.layers0.attributeStorageInfo[index].key;
|
|
733
|
-
node.attributeData.push({href: `./attributes/${folderName}/0`});
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
}
|
|
729
|
+
this.nodePages.saveNode(node);
|
|
737
730
|
|
|
738
731
|
return node;
|
|
739
732
|
}
|
|
@@ -748,7 +741,7 @@ export default class I3SConverter {
|
|
|
748
741
|
* @param resources.attributes - feature attributes
|
|
749
742
|
* @return {Promise<void>}
|
|
750
743
|
*/
|
|
751
|
-
private async _writeResources(resources:
|
|
744
|
+
private async _writeResources(resources: I3SConvertedResources, nodePath: string): Promise<void> {
|
|
752
745
|
const {
|
|
753
746
|
geometry: geometryBuffer,
|
|
754
747
|
compressedGeometry,
|
|
@@ -759,7 +752,7 @@ export default class I3SConverter {
|
|
|
759
752
|
const childPath = join(this.layers0Path, 'nodes', nodePath);
|
|
760
753
|
const slpkChildPath = join('nodes', nodePath);
|
|
761
754
|
|
|
762
|
-
await this._writeGeometries(geometryBuffer
|
|
755
|
+
await this._writeGeometries(geometryBuffer!, compressedGeometry!, childPath, slpkChildPath);
|
|
763
756
|
await this._writeShared(sharedResources, childPath, slpkChildPath, nodePath);
|
|
764
757
|
await this._writeTexture(texture, childPath, slpkChildPath);
|
|
765
758
|
await this._writeAttributes(attributes, childPath, slpkChildPath);
|
|
@@ -774,33 +767,36 @@ export default class I3SConverter {
|
|
|
774
767
|
*/
|
|
775
768
|
private async _writeGeometries(
|
|
776
769
|
geometryBuffer: ArrayBuffer,
|
|
777
|
-
compressedGeometry: ArrayBuffer
|
|
770
|
+
compressedGeometry: Promise<ArrayBuffer>,
|
|
778
771
|
childPath: string,
|
|
779
772
|
slpkChildPath: string
|
|
780
773
|
): Promise<void> {
|
|
781
774
|
if (this.options.slpk) {
|
|
782
775
|
const slpkGeometryPath = join(childPath, 'geometries');
|
|
783
|
-
this.
|
|
784
|
-
|
|
785
|
-
geometryBuffer,
|
|
786
|
-
|
|
787
|
-
);
|
|
776
|
+
await this.writeQueue.enqueue({
|
|
777
|
+
archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
|
|
778
|
+
writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
779
|
+
});
|
|
788
780
|
} else {
|
|
789
781
|
const geometryPath = join(childPath, 'geometries/0/');
|
|
790
|
-
await
|
|
782
|
+
await this.writeQueue.enqueue({
|
|
783
|
+
writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
784
|
+
});
|
|
791
785
|
}
|
|
792
786
|
|
|
793
787
|
if (this.options.draco) {
|
|
794
788
|
if (this.options.slpk) {
|
|
795
789
|
const slpkCompressedGeometryPath = join(childPath, 'geometries');
|
|
796
|
-
this.
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
);
|
|
790
|
+
await this.writeQueue.enqueue({
|
|
791
|
+
archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
|
|
792
|
+
writePromise: () =>
|
|
793
|
+
writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
|
|
794
|
+
});
|
|
801
795
|
} else {
|
|
802
796
|
const compressedGeometryPath = join(childPath, 'geometries/1/');
|
|
803
|
-
await
|
|
797
|
+
await this.writeQueue.enqueue({
|
|
798
|
+
writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
799
|
+
});
|
|
804
800
|
}
|
|
805
801
|
}
|
|
806
802
|
}
|
|
@@ -813,85 +809,130 @@ export default class I3SConverter {
|
|
|
813
809
|
* @param nodePath - a node path
|
|
814
810
|
*/
|
|
815
811
|
private async _writeShared(
|
|
816
|
-
sharedResources:
|
|
812
|
+
sharedResources: SharedResourcesArrays | null,
|
|
817
813
|
childPath: string,
|
|
818
814
|
slpkChildPath: string,
|
|
819
815
|
nodePath: string
|
|
820
816
|
): Promise<void> {
|
|
817
|
+
if (!sharedResources) {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
821
820
|
sharedResources.nodePath = nodePath;
|
|
822
|
-
const sharedData = transform(sharedResources,
|
|
821
|
+
const sharedData = transform(sharedResources, sharedResourcesTemplate());
|
|
823
822
|
const sharedDataStr = JSON.stringify(sharedData);
|
|
824
823
|
if (this.options.slpk) {
|
|
825
824
|
const slpkSharedPath = join(childPath, 'shared');
|
|
826
|
-
this.
|
|
827
|
-
|
|
828
|
-
sharedDataStr,
|
|
829
|
-
|
|
830
|
-
);
|
|
825
|
+
await this.writeQueue.enqueue({
|
|
826
|
+
archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
|
|
827
|
+
writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
828
|
+
});
|
|
831
829
|
} else {
|
|
832
830
|
const sharedPath = join(childPath, 'shared/');
|
|
833
|
-
await writeFile(sharedPath, sharedDataStr);
|
|
831
|
+
await this.writeQueue.enqueue({writePromise: () => writeFile(sharedPath, sharedDataStr)});
|
|
834
832
|
}
|
|
835
833
|
}
|
|
836
834
|
|
|
837
835
|
/**
|
|
838
|
-
*
|
|
836
|
+
* Generates textures based on texture mime type and fill in textureSetDefinitions data.
|
|
839
837
|
* @param texture - the texture image
|
|
840
838
|
* @param childPath - a child path to write resources
|
|
841
839
|
* @param slpkChildPath - the resource path inside *slpk file
|
|
842
840
|
*/
|
|
843
841
|
private async _writeTexture(
|
|
844
|
-
texture:
|
|
842
|
+
texture: GLTFImagePostprocessed,
|
|
845
843
|
childPath: string,
|
|
846
844
|
slpkChildPath: string
|
|
847
845
|
): Promise<void> {
|
|
848
846
|
if (texture) {
|
|
849
|
-
const format = this._getFormatByMimeType(texture
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
847
|
+
const format = this._getFormatByMimeType(texture?.mimeType);
|
|
848
|
+
const formats: TextureSetDefinitionFormats = [];
|
|
849
|
+
const textureData = texture.bufferView!.data;
|
|
850
|
+
|
|
851
|
+
switch (format) {
|
|
852
|
+
case 'jpg':
|
|
853
|
+
case 'png': {
|
|
854
|
+
formats.push({name: '0', format});
|
|
855
|
+
await this.writeTextureFile(textureData, '0', format, childPath, slpkChildPath);
|
|
856
|
+
|
|
857
|
+
if (this.generateTextures) {
|
|
858
|
+
formats.push({name: '1', format: 'ktx2'});
|
|
859
|
+
// For Node.js texture.image.data is type of Buffer
|
|
860
|
+
const copyArrayBuffer = texture.image.data.subarray();
|
|
861
|
+
const arrayToEncode = new Uint8Array(copyArrayBuffer);
|
|
862
|
+
const ktx2TextureData = encode(
|
|
863
|
+
{...texture.image, data: arrayToEncode},
|
|
864
|
+
KTX2BasisWriterWorker,
|
|
865
|
+
{
|
|
866
|
+
...KTX2BasisWriterWorker.options,
|
|
867
|
+
source: this.workerSource.ktx2,
|
|
868
|
+
reuseWorkers: true,
|
|
869
|
+
_nodeWorkers: true
|
|
870
|
+
}
|
|
871
|
+
);
|
|
872
|
+
|
|
873
|
+
await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath);
|
|
874
|
+
}
|
|
867
875
|
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
const compress = false;
|
|
871
|
-
|
|
872
|
-
this.fileMap[`${slpkChildPath}/textures/0.${format}`] = await writeFileForSlpk(
|
|
873
|
-
slpkTexturePath,
|
|
874
|
-
textureData,
|
|
875
|
-
`0.${format}`,
|
|
876
|
-
compress
|
|
877
|
-
);
|
|
876
|
+
break;
|
|
877
|
+
}
|
|
878
878
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
879
|
+
case 'ktx2': {
|
|
880
|
+
formats.push({name: '1', format});
|
|
881
|
+
await this.writeTextureFile(textureData, '1', format, childPath, slpkChildPath);
|
|
882
|
+
|
|
883
|
+
if (this.generateTextures) {
|
|
884
|
+
formats.push({name: '0', format: 'jpg'});
|
|
885
|
+
const decodedFromKTX2TextureData = encode(texture.image!.data[0], ImageWriter);
|
|
886
|
+
await this.writeTextureFile(
|
|
887
|
+
decodedFromKTX2TextureData,
|
|
888
|
+
'0',
|
|
889
|
+
'jpg',
|
|
890
|
+
childPath,
|
|
891
|
+
slpkChildPath
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
888
896
|
|
|
889
|
-
|
|
890
|
-
|
|
897
|
+
if (!this.layers0!.textureSetDefinitions!.length) {
|
|
898
|
+
this.layers0!.textureSetDefinitions!.push({formats});
|
|
899
|
+
this.layers0!.textureSetDefinitions!.push({formats, atlas: true});
|
|
891
900
|
}
|
|
892
901
|
}
|
|
893
902
|
}
|
|
894
903
|
|
|
904
|
+
/**
|
|
905
|
+
* Write the texture image in a file
|
|
906
|
+
* @param textureData
|
|
907
|
+
* @param name
|
|
908
|
+
* @param format
|
|
909
|
+
* @param childPath
|
|
910
|
+
* @param slpkChildPath
|
|
911
|
+
*/
|
|
912
|
+
private async writeTextureFile(
|
|
913
|
+
textureData: Promise<ArrayBuffer>,
|
|
914
|
+
name: string,
|
|
915
|
+
format: 'jpg' | 'png' | 'ktx2',
|
|
916
|
+
childPath: string,
|
|
917
|
+
slpkChildPath: string
|
|
918
|
+
): Promise<void> {
|
|
919
|
+
if (this.options.slpk) {
|
|
920
|
+
const slpkTexturePath = join(childPath, 'textures');
|
|
921
|
+
const compress = false;
|
|
922
|
+
|
|
923
|
+
await this.writeQueue.enqueue({
|
|
924
|
+
archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
|
|
925
|
+
writePromise: () =>
|
|
926
|
+
writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
|
|
927
|
+
});
|
|
928
|
+
} else {
|
|
929
|
+
const texturePath = join(childPath, `textures/${name}/`);
|
|
930
|
+
await this.writeQueue.enqueue({
|
|
931
|
+
writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
895
936
|
/**
|
|
896
937
|
* Write feature attributes in files
|
|
897
938
|
* @param attributes - feature attributes
|
|
@@ -899,29 +940,26 @@ export default class I3SConverter {
|
|
|
899
940
|
* @param slpkChildPath - the resource path inside *slpk file
|
|
900
941
|
*/
|
|
901
942
|
private async _writeAttributes(
|
|
902
|
-
attributes: ArrayBuffer[],
|
|
943
|
+
attributes: ArrayBuffer[] | null = [],
|
|
903
944
|
childPath: string,
|
|
904
945
|
slpkChildPath: string
|
|
905
946
|
): Promise<void> {
|
|
906
|
-
if (
|
|
907
|
-
attributes.length &&
|
|
908
|
-
this.layers0.attributeStorageInfo &&
|
|
909
|
-
this.layers0.attributeStorageInfo.length
|
|
910
|
-
) {
|
|
947
|
+
if (attributes?.length && this.layers0?.attributeStorageInfo?.length) {
|
|
911
948
|
for (let index = 0; index < attributes.length; index++) {
|
|
912
949
|
const folderName = this.layers0.attributeStorageInfo[index].key;
|
|
913
950
|
const fileBuffer = new Uint8Array(attributes[index]);
|
|
914
951
|
|
|
915
952
|
if (this.options.slpk) {
|
|
916
953
|
const slpkAttributesPath = join(childPath, 'attributes', folderName);
|
|
917
|
-
this.
|
|
918
|
-
|
|
919
|
-
fileBuffer,
|
|
920
|
-
|
|
921
|
-
);
|
|
954
|
+
await this.writeQueue.enqueue({
|
|
955
|
+
archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
|
|
956
|
+
writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
957
|
+
});
|
|
922
958
|
} else {
|
|
923
959
|
const attributesPath = join(childPath, `attributes/${folderName}/0`);
|
|
924
|
-
await
|
|
960
|
+
await this.writeQueue.enqueue({
|
|
961
|
+
writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
962
|
+
});
|
|
925
963
|
}
|
|
926
964
|
}
|
|
927
965
|
}
|
|
@@ -931,12 +969,14 @@ export default class I3SConverter {
|
|
|
931
969
|
* Return file format by its MIME type
|
|
932
970
|
* @param mimeType - feature attributes
|
|
933
971
|
*/
|
|
934
|
-
private _getFormatByMimeType(mimeType: string):
|
|
972
|
+
private _getFormatByMimeType(mimeType: string | undefined): 'jpg' | 'png' | 'ktx2' {
|
|
935
973
|
switch (mimeType) {
|
|
936
974
|
case 'image/jpeg':
|
|
937
975
|
return 'jpg';
|
|
938
976
|
case 'image/png':
|
|
939
977
|
return 'png';
|
|
978
|
+
case 'image/ktx2':
|
|
979
|
+
return 'ktx2';
|
|
940
980
|
default:
|
|
941
981
|
return 'jpg';
|
|
942
982
|
}
|
|
@@ -947,10 +987,10 @@ export default class I3SConverter {
|
|
|
947
987
|
* @param material - end-to-end index of the node
|
|
948
988
|
* @return material id
|
|
949
989
|
*/
|
|
950
|
-
private _findOrCreateMaterial(material:
|
|
990
|
+
private _findOrCreateMaterial(material: I3SMaterialDefinition): number {
|
|
951
991
|
const hash = md5(JSON.stringify(material));
|
|
952
992
|
if (this.materialMap.has(hash)) {
|
|
953
|
-
return this.materialMap.get(hash);
|
|
993
|
+
return this.materialMap.get(hash) || 0;
|
|
954
994
|
}
|
|
955
995
|
const newMaterialId = this.materialDefinitions.push(material) - 1;
|
|
956
996
|
this.materialMap.set(hash, newMaterialId);
|
|
@@ -958,196 +998,52 @@ export default class I3SConverter {
|
|
|
958
998
|
}
|
|
959
999
|
|
|
960
1000
|
/**
|
|
961
|
-
*
|
|
962
|
-
*
|
|
963
|
-
* @param
|
|
964
|
-
* @param
|
|
965
|
-
* @
|
|
1001
|
+
* Get unique geometry configuration index
|
|
1002
|
+
* In the end of conversion configurations will be transformed to geometryDefinitions array
|
|
1003
|
+
* @param hasTexture
|
|
1004
|
+
* @param hasUvRegions
|
|
1005
|
+
* @returns
|
|
966
1006
|
*/
|
|
967
|
-
private
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
const storageAttribute = {
|
|
973
|
-
key: `f_${attributeIndex}`,
|
|
974
|
-
name: key,
|
|
975
|
-
ordering: ['attributeValues'],
|
|
976
|
-
header: [{property: 'count', valueType: 'UInt32'}],
|
|
977
|
-
attributeValues: {valueType: 'Int32', valuesPerElement: 1}
|
|
978
|
-
};
|
|
979
|
-
|
|
980
|
-
switch (attributeType) {
|
|
981
|
-
case OBJECT_ID_TYPE:
|
|
982
|
-
this._setupIdAttribute(storageAttribute);
|
|
983
|
-
break;
|
|
984
|
-
case STRING_TYPE:
|
|
985
|
-
this._setupStringAttribute(storageAttribute);
|
|
986
|
-
break;
|
|
987
|
-
case DOUBLE_TYPE:
|
|
988
|
-
this._setupDoubleAttribute(storageAttribute);
|
|
989
|
-
break;
|
|
990
|
-
case SHORT_INT_TYPE:
|
|
991
|
-
break;
|
|
992
|
-
default:
|
|
993
|
-
this._setupStringAttribute(storageAttribute);
|
|
1007
|
+
private findOrCreateGeometryDefinition(hasTexture: boolean, hasUvRegions: boolean): number {
|
|
1008
|
+
const geometryConfig = {hasTexture, hasUvRegions};
|
|
1009
|
+
const hash = md5(JSON.stringify(geometryConfig));
|
|
1010
|
+
if (this.geometryMap.has(hash)) {
|
|
1011
|
+
return this.geometryMap.get(hash) || 0;
|
|
994
1012
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
/**
|
|
1000
|
-
* Get the attribute type for attributeStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
|
|
1001
|
-
* @param key - attribute's key
|
|
1002
|
-
* @param attribute - attribute's type in batchTable
|
|
1003
|
-
*/
|
|
1004
|
-
private getAttributeType(key: string, attribute: string): string {
|
|
1005
|
-
if (key === OBJECT_ID_TYPE) {
|
|
1006
|
-
return OBJECT_ID_TYPE;
|
|
1007
|
-
}
|
|
1008
|
-
if (typeof attribute === STRING_TYPE) {
|
|
1009
|
-
return STRING_TYPE;
|
|
1010
|
-
} else if (typeof attribute === 'number') {
|
|
1011
|
-
return Number.isInteger(attribute) ? SHORT_INT_TYPE : DOUBLE_TYPE;
|
|
1012
|
-
}
|
|
1013
|
-
return STRING_TYPE;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
/**
|
|
1017
|
-
* Setup storage attribute as string.
|
|
1018
|
-
* @param storageAttribute - attribute for map segmentation.
|
|
1019
|
-
*/
|
|
1020
|
-
private _setupStringAttribute(storageAttribute: AttributeStorageInfo): void {
|
|
1021
|
-
storageAttribute.ordering.unshift('attributeByteCounts');
|
|
1022
|
-
storageAttribute.header.push({property: 'attributeValuesByteCount', valueType: 'UInt32'});
|
|
1023
|
-
storageAttribute.attributeValues = {
|
|
1024
|
-
valueType: 'String',
|
|
1025
|
-
encoding: 'UTF-8',
|
|
1026
|
-
valuesPerElement: 1
|
|
1027
|
-
};
|
|
1028
|
-
storageAttribute.attributeByteCounts = {
|
|
1029
|
-
valueType: 'UInt32',
|
|
1030
|
-
valuesPerElement: 1
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
/**
|
|
1035
|
-
* Setup Id attribute for map segmentation.
|
|
1036
|
-
* @param storageAttribute - attribute for map segmentation .
|
|
1037
|
-
*/
|
|
1038
|
-
private _setupIdAttribute(storageAttribute: AttributeStorageInfo): void {
|
|
1039
|
-
storageAttribute.attributeValues = {
|
|
1040
|
-
valueType: 'Oid32',
|
|
1041
|
-
valuesPerElement: 1
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
/**
|
|
1046
|
-
* Setup double attribute for map segmentation.
|
|
1047
|
-
* @param storageAttribute - attribute for map segmentation .
|
|
1048
|
-
*/
|
|
1049
|
-
private _setupDoubleAttribute(storageAttribute: AttributeStorageInfo): void {
|
|
1050
|
-
storageAttribute.attributeValues = {
|
|
1051
|
-
valueType: 'Float64',
|
|
1052
|
-
valuesPerElement: 1
|
|
1053
|
-
};
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
/**
|
|
1057
|
-
* Setup field attribute for map segmentation.
|
|
1058
|
-
* @param key - attribute for map segmentation.
|
|
1059
|
-
* @param fieldAttributeType - esri attribute type ('esriFieldTypeString' or 'esriFieldTypeOID').
|
|
1060
|
-
*/
|
|
1061
|
-
private _createFieldAttribute(key: string, fieldAttributeType: ESRIField): Field {
|
|
1062
|
-
return {
|
|
1063
|
-
name: key,
|
|
1064
|
-
type: fieldAttributeType,
|
|
1065
|
-
alias: key
|
|
1066
|
-
};
|
|
1013
|
+
const newGeometryId = this.geometryConfigs.push(geometryConfig) - 1;
|
|
1014
|
+
this.geometryMap.set(hash, newGeometryId);
|
|
1015
|
+
return newGeometryId;
|
|
1067
1016
|
}
|
|
1068
1017
|
|
|
1069
1018
|
/**
|
|
1070
|
-
* Do conversion of 3DTiles
|
|
1071
|
-
* @param
|
|
1019
|
+
* Do conversion of 3DTiles property table to I3s node attributes.
|
|
1020
|
+
* @param propertyTable - Table with layer meta data.
|
|
1072
1021
|
*/
|
|
1073
|
-
private
|
|
1022
|
+
private _convertPropertyTableToNodeAttributes(propertyTable: FeatureTableJson): void {
|
|
1074
1023
|
let attributeIndex = 0;
|
|
1075
|
-
const
|
|
1024
|
+
const propertyTableWithObjectId = {
|
|
1076
1025
|
OBJECTID: [0],
|
|
1077
|
-
...
|
|
1026
|
+
...propertyTable
|
|
1078
1027
|
};
|
|
1079
1028
|
|
|
1080
|
-
for (const key in
|
|
1081
|
-
const firstAttribute =
|
|
1082
|
-
const attributeType =
|
|
1029
|
+
for (const key in propertyTableWithObjectId) {
|
|
1030
|
+
const firstAttribute = propertyTableWithObjectId[key][0];
|
|
1031
|
+
const attributeType = getAttributeType(key, firstAttribute);
|
|
1083
1032
|
|
|
1084
|
-
const storageAttribute =
|
|
1085
|
-
const fieldAttributeType =
|
|
1086
|
-
const fieldAttribute =
|
|
1087
|
-
const popupInfo =
|
|
1033
|
+
const storageAttribute = createdStorageAttribute(attributeIndex, key, attributeType);
|
|
1034
|
+
const fieldAttributeType = getFieldAttributeType(attributeType);
|
|
1035
|
+
const fieldAttribute = createFieldAttribute(key, fieldAttributeType);
|
|
1036
|
+
const popupInfo = createPopupInfo(propertyTableWithObjectId);
|
|
1088
1037
|
|
|
1089
|
-
this.layers0
|
|
1090
|
-
this.layers0
|
|
1091
|
-
this.layers0
|
|
1092
|
-
this.layers0
|
|
1038
|
+
this.layers0!.attributeStorageInfo!.push(storageAttribute);
|
|
1039
|
+
this.layers0!.fields!.push(fieldAttribute);
|
|
1040
|
+
this.layers0!.popupInfo = popupInfo;
|
|
1041
|
+
this.layers0!.layerType = _3D_OBJECT_LAYER_TYPE;
|
|
1093
1042
|
|
|
1094
1043
|
attributeIndex += 1;
|
|
1095
1044
|
}
|
|
1096
1045
|
}
|
|
1097
1046
|
|
|
1098
|
-
/**
|
|
1099
|
-
* Find and return attribute type based on key form Batch table.
|
|
1100
|
-
* @param attributeType
|
|
1101
|
-
*/
|
|
1102
|
-
private _getFieldAttributeType(attributeType: Attribute): ESRIField {
|
|
1103
|
-
switch (attributeType) {
|
|
1104
|
-
case OBJECT_ID_TYPE:
|
|
1105
|
-
return 'esriFieldTypeOID';
|
|
1106
|
-
case STRING_TYPE:
|
|
1107
|
-
return 'esriFieldTypeString';
|
|
1108
|
-
case SHORT_INT_TYPE:
|
|
1109
|
-
return 'esriFieldTypeInteger';
|
|
1110
|
-
case DOUBLE_TYPE:
|
|
1111
|
-
return 'esriFieldTypeDouble';
|
|
1112
|
-
default:
|
|
1113
|
-
return 'esriFieldTypeString';
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
/**
|
|
1118
|
-
* Generate popup info to show metadata on the map.
|
|
1119
|
-
* @param batchTable - Batch table data with OBJECTID.
|
|
1120
|
-
* @return data for correct rendering of popup.
|
|
1121
|
-
*/
|
|
1122
|
-
private _createPopupInfo(batchTable: BatchTableJson): PopupInfo {
|
|
1123
|
-
const title = '{OBJECTID}';
|
|
1124
|
-
const mediaInfos = [];
|
|
1125
|
-
const fieldInfos = [];
|
|
1126
|
-
const popupElements = [];
|
|
1127
|
-
const expressionInfos = [];
|
|
1128
|
-
|
|
1129
|
-
for (const key in batchTable) {
|
|
1130
|
-
fieldInfos.push({
|
|
1131
|
-
fieldName: key,
|
|
1132
|
-
visible: true,
|
|
1133
|
-
isEditable: false,
|
|
1134
|
-
label: key
|
|
1135
|
-
});
|
|
1136
|
-
}
|
|
1137
|
-
popupElements.push({
|
|
1138
|
-
fieldInfos,
|
|
1139
|
-
type: 'fields'
|
|
1140
|
-
});
|
|
1141
|
-
|
|
1142
|
-
return {
|
|
1143
|
-
title,
|
|
1144
|
-
mediaInfos,
|
|
1145
|
-
popupElements,
|
|
1146
|
-
fieldInfos,
|
|
1147
|
-
expressionInfos
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
1047
|
/**
|
|
1152
1048
|
* Print statistics in the end of conversion
|
|
1153
1049
|
* @param params - output files data
|
|
@@ -1177,10 +1073,13 @@ export default class I3SConverter {
|
|
|
1177
1073
|
* Fetch preload options for ION tileset
|
|
1178
1074
|
*/
|
|
1179
1075
|
private async _fetchPreloadOptions(): Promise<any> {
|
|
1076
|
+
if (!this.Loader.preload) {
|
|
1077
|
+
return {};
|
|
1078
|
+
}
|
|
1180
1079
|
const options = {
|
|
1181
1080
|
'cesium-ion': {accessToken: this.options.token || ION_DEFAULT_TOKEN}
|
|
1182
1081
|
};
|
|
1183
|
-
const preloadOptions = await
|
|
1082
|
+
const preloadOptions = await this.Loader.preload(this.options.inputUrl, options);
|
|
1184
1083
|
this.refreshTokenTime = process.hrtime();
|
|
1185
1084
|
return {...options, ...preloadOptions};
|
|
1186
1085
|
}
|
|
@@ -1196,10 +1095,10 @@ export default class I3SConverter {
|
|
|
1196
1095
|
this.refreshTokenTime = process.hrtime();
|
|
1197
1096
|
|
|
1198
1097
|
const preloadOptions = await this._fetchPreloadOptions();
|
|
1199
|
-
this.sourceTileset
|
|
1098
|
+
this.sourceTileset!.options = {...this.sourceTileset!.options, ...preloadOptions};
|
|
1200
1099
|
if (preloadOptions.headers) {
|
|
1201
|
-
this.sourceTileset
|
|
1202
|
-
...this.sourceTileset
|
|
1100
|
+
this.sourceTileset!.loadOptions.fetch = {
|
|
1101
|
+
...this.sourceTileset!.loadOptions.fetch,
|
|
1203
1102
|
headers: preloadOptions.headers
|
|
1204
1103
|
};
|
|
1205
1104
|
console.log('Authorization Bearer token has been updated'); // eslint-disable-line no-undef, no-console
|
|
@@ -1209,7 +1108,7 @@ export default class I3SConverter {
|
|
|
1209
1108
|
/** Do calculations of all tiles and tiles with "ADD" type of refinement.
|
|
1210
1109
|
* @param tile
|
|
1211
1110
|
*/
|
|
1212
|
-
private _checkAddRefinementTypeForTile(tile:
|
|
1111
|
+
private _checkAddRefinementTypeForTile(tile: Tile3D): void {
|
|
1213
1112
|
const ADD_TILE_REFINEMENT = 1;
|
|
1214
1113
|
|
|
1215
1114
|
if (tile.refine === ADD_TILE_REFINEMENT) {
|
|
@@ -1219,4 +1118,35 @@ export default class I3SConverter {
|
|
|
1219
1118
|
|
|
1220
1119
|
this.refinementCounter.tilesCount += 1;
|
|
1221
1120
|
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Check if the tile's content format is supported by the converter
|
|
1123
|
+
* @param sourceRootTile
|
|
1124
|
+
* @returns
|
|
1125
|
+
*/
|
|
1126
|
+
private isContentSupported(sourceRootTile: Tile3D): boolean {
|
|
1127
|
+
return ['b3dm', 'glTF'].includes(sourceRootTile?.content?.type);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
private async loadWorkers(): Promise<void> {
|
|
1131
|
+
console.log(`Loading workers source...`); // eslint-disable-line no-undef, no-console
|
|
1132
|
+
if (this.options.draco) {
|
|
1133
|
+
const url = getWorkerURL(DracoWriterWorker, {...getLoaderOptions()});
|
|
1134
|
+
const sourceResponse = await fetchFile(url);
|
|
1135
|
+
const source = await sourceResponse.text();
|
|
1136
|
+
this.workerSource.draco = source;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
if (this.generateTextures) {
|
|
1140
|
+
const url = getWorkerURL(KTX2BasisWriterWorker, {...getLoaderOptions()});
|
|
1141
|
+
const sourceResponse = await fetchFile(url);
|
|
1142
|
+
const source = await sourceResponse.text();
|
|
1143
|
+
this.workerSource.ktx2 = source;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
const i3sAttributesWorkerUrl = getWorkerURL(I3SAttributesWorker, {...getLoaderOptions()});
|
|
1147
|
+
const sourceResponse = await fetchFile(i3sAttributesWorkerUrl);
|
|
1148
|
+
const source = await sourceResponse.text();
|
|
1149
|
+
this.workerSource.I3SAttributes = source;
|
|
1150
|
+
console.log(`Loading workers source completed!`); // eslint-disable-line no-undef, no-console
|
|
1151
|
+
}
|
|
1222
1152
|
}
|