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