@loaders.gl/tile-converter 3.3.0-alpha.1 → 3.3.0-alpha.10
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 +61034 -64112
- 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 +507 -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 +794 -1125
- 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 +197 -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 +235 -508
- 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 +91 -0
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/node-index-document.js +242 -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 +200 -92
- 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 +234 -420
- 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 +306 -0
- package/src/i3s-converter/helpers/node-pages.ts +222 -109
- package/src/i3s-converter/i3s-converter.ts +279 -499
- 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,36 +373,15 @@ 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
|
-
});
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
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')
|
|
382
|
+
await this.writeQueue.enqueue({
|
|
383
|
+
writePromise: () => writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
398
384
|
});
|
|
399
|
-
} else {
|
|
400
|
-
this.writeQueue.enqueue({writePromise: writeFile(rootPath, JSON.stringify(root0))});
|
|
401
385
|
}
|
|
402
386
|
}
|
|
403
387
|
|
|
@@ -446,146 +430,141 @@ 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
|
}
|
|
507
|
+
|
|
508
|
+
const promises: Promise<void>[] = [];
|
|
485
509
|
for (const sourceTile of sourceTiles) {
|
|
486
510
|
if (sourceTile.type === 'json') {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
parentId,
|
|
493
|
-
level: level + 1
|
|
494
|
-
});
|
|
495
|
-
await sourceTile.unloadContent();
|
|
511
|
+
if (this.options.instantNodeWriting) {
|
|
512
|
+
await this.convertNestedTileset({parentNode, sourceTile, level});
|
|
513
|
+
} else {
|
|
514
|
+
promises.push(this.convertNestedTileset({parentNode, sourceTile, level}));
|
|
515
|
+
}
|
|
496
516
|
} else {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
id: child.id,
|
|
502
|
-
href: `../${child.path}`,
|
|
503
|
-
obb: child.obb,
|
|
504
|
-
mbs: child.mbs
|
|
505
|
-
});
|
|
506
|
-
childNodes.push(child);
|
|
517
|
+
if (this.options.instantNodeWriting) {
|
|
518
|
+
await this.convertNode({parentNode, sourceTile, level});
|
|
519
|
+
} else {
|
|
520
|
+
promises.push(this.convertNode({parentNode, sourceTile, level}));
|
|
507
521
|
}
|
|
508
522
|
}
|
|
509
523
|
if (sourceTile.id) {
|
|
510
524
|
console.log(sourceTile.id); // eslint-disable-line
|
|
511
525
|
}
|
|
512
526
|
}
|
|
513
|
-
|
|
514
|
-
|
|
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
|
-
}
|
|
527
|
+
await Promise.all(promises);
|
|
551
528
|
}
|
|
552
529
|
|
|
553
530
|
/**
|
|
554
531
|
* 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)
|
|
532
|
+
* @param parentNode - 3DNodeIndexDocument of parent node
|
|
533
|
+
* @param sourceTile - source 3DTile data
|
|
534
|
+
* @param level - tree level
|
|
559
535
|
*/
|
|
560
536
|
private async _createNode(
|
|
561
|
-
|
|
537
|
+
parentNode: NodeIndexDocument,
|
|
562
538
|
sourceTile: TileHeader,
|
|
563
|
-
parentId: number,
|
|
564
539
|
level: number
|
|
565
|
-
): Promise<
|
|
566
|
-
|
|
567
|
-
this._checkAddRefinementTypeForTile(sourceTile);
|
|
568
|
-
}
|
|
540
|
+
): Promise<NodeIndexDocument[]> {
|
|
541
|
+
this._checkAddRefinementTypeForTile(sourceTile);
|
|
569
542
|
|
|
570
543
|
await this._updateTilesetOptions();
|
|
571
544
|
await this.sourceTileset!._loadTile(sourceTile);
|
|
572
545
|
|
|
573
546
|
let boundingVolumes = createBoundingVolumes(sourceTile, this.geoidHeightModel!);
|
|
574
547
|
|
|
575
|
-
const
|
|
548
|
+
const propertyTable = getPropertyTable(sourceTile.content);
|
|
576
549
|
|
|
577
|
-
if (
|
|
578
|
-
this.
|
|
550
|
+
if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
|
|
551
|
+
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
579
552
|
}
|
|
580
553
|
|
|
581
|
-
const resourcesData = await this._convertResources(
|
|
554
|
+
const resourcesData = await this._convertResources(
|
|
555
|
+
sourceTile,
|
|
556
|
+
parentNode.inPageId,
|
|
557
|
+
propertyTable
|
|
558
|
+
);
|
|
582
559
|
|
|
583
|
-
const nodes:
|
|
560
|
+
const nodes: NodeIndexDocument[] = [];
|
|
561
|
+
const nodeIds: number[] = [];
|
|
584
562
|
const nodesInPage: NodeInPage[] = [];
|
|
585
563
|
const emptyResources = {
|
|
586
564
|
geometry: null,
|
|
587
565
|
compressedGeometry: null,
|
|
588
566
|
texture: null,
|
|
567
|
+
hasUvRegions: false,
|
|
589
568
|
sharedResources: null,
|
|
590
569
|
meshMaterial: null,
|
|
591
570
|
vertexCount: null,
|
|
@@ -606,34 +585,37 @@ export default class I3SConverter {
|
|
|
606
585
|
(val) => val.metricType === 'maxScreenThresholdSQ'
|
|
607
586
|
) || {maxError: 0};
|
|
608
587
|
|
|
609
|
-
const nodeInPage = this.
|
|
588
|
+
const nodeInPage = await this._updateNodeInNodePages(
|
|
610
589
|
maxScreenThresholdSQ,
|
|
611
590
|
boundingVolumes,
|
|
612
591
|
sourceTile,
|
|
613
|
-
|
|
592
|
+
parentNode.inPageId,
|
|
614
593
|
resources
|
|
615
594
|
);
|
|
616
|
-
|
|
617
|
-
|
|
595
|
+
|
|
596
|
+
const nodeData = await NodeIndexDocument.createNodeIndexDocument(
|
|
597
|
+
parentNode,
|
|
618
598
|
boundingVolumes,
|
|
619
599
|
lodSelection,
|
|
620
600
|
nodeInPage,
|
|
621
601
|
resources
|
|
622
602
|
);
|
|
603
|
+
const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
|
|
604
|
+
nodes.push(node);
|
|
623
605
|
|
|
624
606
|
if (nodeInPage.mesh) {
|
|
625
|
-
await this._writeResources(resources, node.
|
|
607
|
+
await this._writeResources(resources, node.id);
|
|
626
608
|
}
|
|
627
609
|
|
|
628
610
|
if (this.validate) {
|
|
629
|
-
this.boundingVolumeWarnings = validateNodeBoundingVolumes(
|
|
611
|
+
this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
|
|
630
612
|
|
|
631
613
|
if (this.boundingVolumeWarnings && this.boundingVolumeWarnings.length) {
|
|
632
614
|
console.warn('Bounding Volume Warnings: ', ...this.boundingVolumeWarnings); //eslint-disable-line
|
|
633
615
|
}
|
|
634
616
|
}
|
|
635
617
|
|
|
636
|
-
|
|
618
|
+
nodeIds.push(nodeInPage.index);
|
|
637
619
|
nodesInPage.push(nodeInPage);
|
|
638
620
|
}
|
|
639
621
|
|
|
@@ -642,49 +624,40 @@ export default class I3SConverter {
|
|
|
642
624
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
643
625
|
parentNode: nodes[0],
|
|
644
626
|
sourceTiles: sourceTile.children,
|
|
645
|
-
parentId: nodesInPage[0].index!,
|
|
646
627
|
level: level + 1
|
|
647
628
|
});
|
|
648
629
|
return nodes;
|
|
649
630
|
}
|
|
650
631
|
|
|
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
632
|
/**
|
|
666
633
|
* Convert tile to one or more I3S nodes
|
|
667
634
|
* @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
|
|
635
|
+
* @param parentId - id of parent node in node pages
|
|
636
|
+
* @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
637
|
+
* @returns - converted node resources
|
|
676
638
|
*/
|
|
677
|
-
private async _convertResources(
|
|
639
|
+
private async _convertResources(
|
|
640
|
+
sourceTile: TileHeader,
|
|
641
|
+
parentId: number,
|
|
642
|
+
propertyTable: FeatureTableJson | null
|
|
643
|
+
): Promise<I3SConvertedResources[] | null> {
|
|
678
644
|
if (!this.isContentSupported(sourceTile)) {
|
|
679
645
|
return null;
|
|
680
646
|
}
|
|
647
|
+
const draftObb = {
|
|
648
|
+
center: [],
|
|
649
|
+
halfSize: [],
|
|
650
|
+
quaternion: []
|
|
651
|
+
};
|
|
681
652
|
const resourcesData = await convertB3dmToI3sGeometry(
|
|
682
653
|
sourceTile.content,
|
|
683
|
-
|
|
654
|
+
async () => (await this.nodePages.push({index: 0, obb: draftObb}, parentId)).index,
|
|
655
|
+
propertyTable,
|
|
684
656
|
this.featuresHashArray,
|
|
685
657
|
this.layers0?.attributeStorageInfo,
|
|
686
658
|
this.options.draco,
|
|
687
659
|
this.generateBoundingVolumes,
|
|
660
|
+
this.options.mergeMaterials,
|
|
688
661
|
this.geoidHeightModel!,
|
|
689
662
|
this.workerSource
|
|
690
663
|
);
|
|
@@ -692,7 +665,7 @@ export default class I3SConverter {
|
|
|
692
665
|
}
|
|
693
666
|
|
|
694
667
|
/**
|
|
695
|
-
*
|
|
668
|
+
* Update node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
|
|
696
669
|
* in node pages (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodePage.cmn.md)
|
|
697
670
|
* @param maxScreenThresholdSQ - Level of Details (LOD) metric
|
|
698
671
|
* @param boundingVolumes - Bounding volumes
|
|
@@ -703,16 +676,17 @@ export default class I3SConverter {
|
|
|
703
676
|
* @param resources.texture - texture image
|
|
704
677
|
* @param resources.vertexCount - number of vertices in geometry
|
|
705
678
|
* @param resources.featureCount - number of features
|
|
679
|
+
* @param resources.geometry - Uint8Array with geometry attributes
|
|
706
680
|
* @return the node object in node pages
|
|
707
681
|
*/
|
|
708
|
-
private
|
|
682
|
+
private async _updateNodeInNodePages(
|
|
709
683
|
maxScreenThresholdSQ: MaxScreenThresholdSQ,
|
|
710
684
|
boundingVolumes: BoundingVolumes,
|
|
711
685
|
sourceTile: TileHeader,
|
|
712
686
|
parentId: number,
|
|
713
687
|
resources: I3SConvertedResources
|
|
714
|
-
): NodeInPage {
|
|
715
|
-
const {meshMaterial, texture, vertexCount, featureCount, geometry} = resources;
|
|
688
|
+
): Promise<NodeInPage> {
|
|
689
|
+
const {meshMaterial, texture, vertexCount, featureCount, geometry, hasUvRegions} = resources;
|
|
716
690
|
const nodeInPage: NodeInPage = {
|
|
717
691
|
index: 0,
|
|
718
692
|
lodThreshold: maxScreenThresholdSQ.maxError,
|
|
@@ -722,7 +696,7 @@ export default class I3SConverter {
|
|
|
722
696
|
if (geometry && this.isContentSupported(sourceTile)) {
|
|
723
697
|
nodeInPage.mesh = {
|
|
724
698
|
geometry: {
|
|
725
|
-
definition: texture
|
|
699
|
+
definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
|
|
726
700
|
resource: 0
|
|
727
701
|
},
|
|
728
702
|
attribute: {
|
|
@@ -733,83 +707,33 @@ export default class I3SConverter {
|
|
|
733
707
|
}
|
|
734
708
|
};
|
|
735
709
|
}
|
|
736
|
-
const nodeId = this.nodePages.push(nodeInPage, parentId);
|
|
737
710
|
|
|
738
|
-
|
|
739
|
-
|
|
711
|
+
let nodeId = resources.nodeId;
|
|
712
|
+
let node;
|
|
713
|
+
if (!nodeId) {
|
|
714
|
+
node = await this.nodePages.push(nodeInPage, parentId);
|
|
715
|
+
} else {
|
|
716
|
+
node = await this.nodePages.getNodeById(nodeId);
|
|
740
717
|
}
|
|
741
718
|
|
|
719
|
+
NodePages.updateAll(node, nodeInPage);
|
|
720
|
+
if (meshMaterial) {
|
|
721
|
+
NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
|
|
722
|
+
}
|
|
742
723
|
if (texture) {
|
|
743
724
|
const texelCountHint = texture.image.height * texture.image.width;
|
|
744
|
-
|
|
725
|
+
NodePages.updateTexelCountHintByNodeId(node, texelCountHint);
|
|
745
726
|
}
|
|
746
|
-
|
|
747
727
|
if (vertexCount) {
|
|
748
728
|
this.vertexCounter += vertexCount;
|
|
749
|
-
|
|
729
|
+
NodePages.updateVertexCountByNodeId(node, vertexCount);
|
|
750
730
|
}
|
|
751
|
-
|
|
731
|
+
NodePages.updateNodeAttributeByNodeId(node);
|
|
752
732
|
if (featureCount) {
|
|
753
|
-
|
|
733
|
+
NodePages.updateFeatureCountByNodeId(node, featureCount);
|
|
754
734
|
}
|
|
755
735
|
|
|
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
|
-
}
|
|
736
|
+
this.nodePages.saveNode(node);
|
|
813
737
|
|
|
814
738
|
return node;
|
|
815
739
|
}
|
|
@@ -856,28 +780,29 @@ export default class I3SConverter {
|
|
|
856
780
|
): Promise<void> {
|
|
857
781
|
if (this.options.slpk) {
|
|
858
782
|
const slpkGeometryPath = join(childPath, 'geometries');
|
|
859
|
-
this.writeQueue.enqueue({
|
|
783
|
+
await this.writeQueue.enqueue({
|
|
860
784
|
archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
|
|
861
|
-
writePromise: writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
785
|
+
writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
862
786
|
});
|
|
863
787
|
} else {
|
|
864
788
|
const geometryPath = join(childPath, 'geometries/0/');
|
|
865
|
-
this.writeQueue.enqueue({
|
|
866
|
-
writePromise: writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
789
|
+
await this.writeQueue.enqueue({
|
|
790
|
+
writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
867
791
|
});
|
|
868
792
|
}
|
|
869
793
|
|
|
870
794
|
if (this.options.draco) {
|
|
871
795
|
if (this.options.slpk) {
|
|
872
796
|
const slpkCompressedGeometryPath = join(childPath, 'geometries');
|
|
873
|
-
this.writeQueue.enqueue({
|
|
797
|
+
await this.writeQueue.enqueue({
|
|
874
798
|
archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
|
|
875
|
-
writePromise:
|
|
799
|
+
writePromise: () =>
|
|
800
|
+
writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
|
|
876
801
|
});
|
|
877
802
|
} else {
|
|
878
803
|
const compressedGeometryPath = join(childPath, 'geometries/1/');
|
|
879
|
-
this.writeQueue.enqueue({
|
|
880
|
-
writePromise: writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
804
|
+
await this.writeQueue.enqueue({
|
|
805
|
+
writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
881
806
|
});
|
|
882
807
|
}
|
|
883
808
|
}
|
|
@@ -904,13 +829,13 @@ export default class I3SConverter {
|
|
|
904
829
|
const sharedDataStr = JSON.stringify(sharedData);
|
|
905
830
|
if (this.options.slpk) {
|
|
906
831
|
const slpkSharedPath = join(childPath, 'shared');
|
|
907
|
-
this.writeQueue.enqueue({
|
|
832
|
+
await this.writeQueue.enqueue({
|
|
908
833
|
archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
|
|
909
|
-
writePromise: writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
834
|
+
writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
910
835
|
});
|
|
911
836
|
} else {
|
|
912
837
|
const sharedPath = join(childPath, 'shared/');
|
|
913
|
-
this.writeQueue.enqueue({writePromise: writeFile(sharedPath, sharedDataStr)});
|
|
838
|
+
await this.writeQueue.enqueue({writePromise: () => writeFile(sharedPath, sharedDataStr)});
|
|
914
839
|
}
|
|
915
840
|
}
|
|
916
841
|
|
|
@@ -978,6 +903,7 @@ export default class I3SConverter {
|
|
|
978
903
|
|
|
979
904
|
if (!this.layers0!.textureSetDefinitions!.length) {
|
|
980
905
|
this.layers0!.textureSetDefinitions!.push({formats});
|
|
906
|
+
this.layers0!.textureSetDefinitions!.push({formats, atlas: true});
|
|
981
907
|
}
|
|
982
908
|
}
|
|
983
909
|
}
|
|
@@ -1001,14 +927,15 @@ export default class I3SConverter {
|
|
|
1001
927
|
const slpkTexturePath = join(childPath, 'textures');
|
|
1002
928
|
const compress = false;
|
|
1003
929
|
|
|
1004
|
-
this.writeQueue.enqueue({
|
|
930
|
+
await this.writeQueue.enqueue({
|
|
1005
931
|
archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
|
|
1006
|
-
writePromise:
|
|
932
|
+
writePromise: () =>
|
|
933
|
+
writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
|
|
1007
934
|
});
|
|
1008
935
|
} else {
|
|
1009
936
|
const texturePath = join(childPath, `textures/${name}/`);
|
|
1010
|
-
this.writeQueue.enqueue({
|
|
1011
|
-
writePromise: writeFile(texturePath, textureData, `index.${format}`)
|
|
937
|
+
await this.writeQueue.enqueue({
|
|
938
|
+
writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
|
|
1012
939
|
});
|
|
1013
940
|
}
|
|
1014
941
|
}
|
|
@@ -1031,14 +958,14 @@ export default class I3SConverter {
|
|
|
1031
958
|
|
|
1032
959
|
if (this.options.slpk) {
|
|
1033
960
|
const slpkAttributesPath = join(childPath, 'attributes', folderName);
|
|
1034
|
-
this.writeQueue.enqueue({
|
|
961
|
+
await this.writeQueue.enqueue({
|
|
1035
962
|
archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
|
|
1036
|
-
writePromise: writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
963
|
+
writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
1037
964
|
});
|
|
1038
965
|
} else {
|
|
1039
966
|
const attributesPath = join(childPath, `attributes/${folderName}/0`);
|
|
1040
|
-
this.writeQueue.enqueue({
|
|
1041
|
-
writePromise: writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
967
|
+
await this.writeQueue.enqueue({
|
|
968
|
+
writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
1042
969
|
});
|
|
1043
970
|
}
|
|
1044
971
|
}
|
|
@@ -1070,7 +997,7 @@ export default class I3SConverter {
|
|
|
1070
997
|
private _findOrCreateMaterial(material: I3SMaterialDefinition): number {
|
|
1071
998
|
const hash = md5(JSON.stringify(material));
|
|
1072
999
|
if (this.materialMap.has(hash)) {
|
|
1073
|
-
return this.materialMap.get(hash);
|
|
1000
|
+
return this.materialMap.get(hash) || 0;
|
|
1074
1001
|
}
|
|
1075
1002
|
const newMaterialId = this.materialDefinitions.push(material) - 1;
|
|
1076
1003
|
this.materialMap.set(hash, newMaterialId);
|
|
@@ -1078,133 +1005,42 @@ export default class I3SConverter {
|
|
|
1078
1005
|
}
|
|
1079
1006
|
|
|
1080
1007
|
/**
|
|
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
|
|
1008
|
+
* Get unique geometry configuration index
|
|
1009
|
+
* In the end of conversion configurations will be transformed to geometryDefinitions array
|
|
1010
|
+
* @param hasTexture
|
|
1011
|
+
* @param hasUvRegions
|
|
1012
|
+
* @returns
|
|
1123
1013
|
*/
|
|
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;
|
|
1014
|
+
private findOrCreateGeometryDefinition(hasTexture: boolean, hasUvRegions: boolean): number {
|
|
1015
|
+
const geometryConfig = {hasTexture, hasUvRegions};
|
|
1016
|
+
const hash = md5(JSON.stringify(geometryConfig));
|
|
1017
|
+
if (this.geometryMap.has(hash)) {
|
|
1018
|
+
return this.geometryMap.get(hash) || 0;
|
|
1132
1019
|
}
|
|
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
|
-
};
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
/**
|
|
1177
|
-
* Setup field attribute for map segmentation.
|
|
1178
|
-
* @param key - attribute for map segmentation.
|
|
1179
|
-
* @param fieldAttributeType - esri attribute type ('esriFieldTypeString' or 'esriFieldTypeOID').
|
|
1180
|
-
*/
|
|
1181
|
-
private _createFieldAttribute(key: string, fieldAttributeType: ESRIField): Field {
|
|
1182
|
-
return {
|
|
1183
|
-
name: key,
|
|
1184
|
-
type: fieldAttributeType,
|
|
1185
|
-
alias: key
|
|
1186
|
-
};
|
|
1020
|
+
const newGeometryId = this.geometryConfigs.push(geometryConfig) - 1;
|
|
1021
|
+
this.geometryMap.set(hash, newGeometryId);
|
|
1022
|
+
return newGeometryId;
|
|
1187
1023
|
}
|
|
1188
1024
|
|
|
1189
1025
|
/**
|
|
1190
|
-
* Do conversion of 3DTiles
|
|
1191
|
-
* @param
|
|
1026
|
+
* Do conversion of 3DTiles property table to I3s node attributes.
|
|
1027
|
+
* @param propertyTable - Table with layer meta data.
|
|
1192
1028
|
*/
|
|
1193
|
-
private
|
|
1029
|
+
private _convertPropertyTableToNodeAttributes(propertyTable: FeatureTableJson): void {
|
|
1194
1030
|
let attributeIndex = 0;
|
|
1195
|
-
const
|
|
1031
|
+
const propertyTableWithObjectId = {
|
|
1196
1032
|
OBJECTID: [0],
|
|
1197
|
-
...
|
|
1033
|
+
...propertyTable
|
|
1198
1034
|
};
|
|
1199
1035
|
|
|
1200
|
-
for (const key in
|
|
1201
|
-
const firstAttribute =
|
|
1202
|
-
const attributeType =
|
|
1036
|
+
for (const key in propertyTableWithObjectId) {
|
|
1037
|
+
const firstAttribute = propertyTableWithObjectId[key][0];
|
|
1038
|
+
const attributeType = getAttributeType(key, firstAttribute);
|
|
1203
1039
|
|
|
1204
|
-
const storageAttribute =
|
|
1205
|
-
const fieldAttributeType =
|
|
1206
|
-
const fieldAttribute =
|
|
1207
|
-
const popupInfo =
|
|
1040
|
+
const storageAttribute = createdStorageAttribute(attributeIndex, key, attributeType);
|
|
1041
|
+
const fieldAttributeType = getFieldAttributeType(attributeType);
|
|
1042
|
+
const fieldAttribute = createFieldAttribute(key, fieldAttributeType);
|
|
1043
|
+
const popupInfo = createPopupInfo(propertyTableWithObjectId);
|
|
1208
1044
|
|
|
1209
1045
|
this.layers0!.attributeStorageInfo!.push(storageAttribute);
|
|
1210
1046
|
this.layers0!.fields!.push(fieldAttribute);
|
|
@@ -1215,62 +1051,6 @@ export default class I3SConverter {
|
|
|
1215
1051
|
}
|
|
1216
1052
|
}
|
|
1217
1053
|
|
|
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
1054
|
/**
|
|
1275
1055
|
* Print statistics in the end of conversion
|
|
1276
1056
|
* @param params - output files data
|