@loaders.gl/tile-converter 3.2.12 → 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 +43 -8
- 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 +58405 -61237
- 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 +50 -60
- 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 +124 -0
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/coordinate-converter.js +2 -19
- 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 +516 -356
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js +57 -43
- 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 +462 -208
- package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +722 -1153
- 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 +41 -82
- 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 +46 -40
- 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 +113 -0
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/coordinate-converter.js +5 -6
- 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 +295 -196
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js +59 -34
- 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 +216 -491
- 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 +27 -38
- 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 +11 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +141 -0
- package/dist/i3s-converter/helpers/coordinate-converter.d.ts +2 -2
- package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
- 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 +349 -99
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/gltf-attributes.js +53 -21
- 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 +218 -403
- 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 +38 -8
- 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 -3
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +21 -16
- 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 +54 -8
- 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 +206 -0
- package/src/i3s-converter/helpers/coordinate-converter.ts +2 -2
- 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 +423 -111
- package/src/i3s-converter/helpers/gltf-attributes.ts +59 -24
- 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 +264 -487
- 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 +33 -2
- package/src/lib/utils/file-utils.ts +62 -7
- package/src/lib/utils/write-queue.ts +42 -19
- 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
|
}
|
|
@@ -242,19 +273,24 @@ export default class I3SConverter {
|
|
|
242
273
|
|
|
243
274
|
const sourceRootTile: TileHeader = this.sourceTileset!.root!;
|
|
244
275
|
const boundingVolumes = createBoundingVolumes(sourceRootTile, this.geoidHeightModel!);
|
|
245
|
-
|
|
276
|
+
await this.nodePages.push({
|
|
246
277
|
index: 0,
|
|
247
278
|
lodThreshold: 0,
|
|
248
279
|
obb: boundingVolumes.obb,
|
|
249
280
|
children: []
|
|
250
281
|
});
|
|
251
282
|
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
await this._convertNodesTree(root0, sourceRootTile, parentId, boundingVolumes);
|
|
283
|
+
const rootNode = await NodeIndexDocument.createRootNode(boundingVolumes, this);
|
|
284
|
+
await this._convertNodesTree(rootNode, sourceRootTile);
|
|
256
285
|
|
|
257
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
|
+
);
|
|
258
294
|
|
|
259
295
|
if (this.layersHasTexture === false) {
|
|
260
296
|
this.layers0!.store.defaultGeometrySchema.ordering =
|
|
@@ -265,8 +301,11 @@ export default class I3SConverter {
|
|
|
265
301
|
|
|
266
302
|
await this._writeLayers0();
|
|
267
303
|
createSceneServerPath(tilesetName, this.layers0!, tilesetPath);
|
|
268
|
-
|
|
269
|
-
|
|
304
|
+
for (const filePath of this.compressList || []) {
|
|
305
|
+
await compressFileWithGzip(filePath);
|
|
306
|
+
await removeFile(filePath);
|
|
307
|
+
}
|
|
308
|
+
await this.nodePages.save();
|
|
270
309
|
await this.writeQueue.finalize();
|
|
271
310
|
await this._createSlpk(tilesetPath);
|
|
272
311
|
}
|
|
@@ -302,77 +341,31 @@ export default class I3SConverter {
|
|
|
302
341
|
this.layers0 = transform(layers0data, layersTemplate());
|
|
303
342
|
}
|
|
304
343
|
|
|
305
|
-
/**
|
|
306
|
-
* Convert and save the layer and embedded tiles
|
|
307
|
-
* @param boundingVolumes - mbs and obb data about node's bounding volume
|
|
308
|
-
* @return 3DNodeIndexDocument data https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
|
|
309
|
-
*/
|
|
310
|
-
private _formRootNodeIndexDocument(boundingVolumes: BoundingVolumes): Node3DIndexDocument {
|
|
311
|
-
const root0data = {
|
|
312
|
-
version: `{${uuidv4().toUpperCase()}}`,
|
|
313
|
-
id: 'root',
|
|
314
|
-
level: 0,
|
|
315
|
-
lodSelection: [
|
|
316
|
-
{
|
|
317
|
-
metricType: 'maxScreenThresholdSQ',
|
|
318
|
-
maxError: 0
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
metricType: 'maxScreenThreshold',
|
|
322
|
-
maxError: 0
|
|
323
|
-
}
|
|
324
|
-
],
|
|
325
|
-
...boundingVolumes,
|
|
326
|
-
children: []
|
|
327
|
-
};
|
|
328
|
-
return transform(root0data, nodeTemplate());
|
|
329
|
-
}
|
|
330
|
-
|
|
331
344
|
/**
|
|
332
345
|
* Form object of 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
|
|
333
|
-
* @param
|
|
346
|
+
* @param rootNode - 3DNodeIndexDocument of root node https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
|
|
334
347
|
* @param sourceRootTile - Source (3DTile) tile data
|
|
335
|
-
* @param parentId - node id in node pages
|
|
336
|
-
* @param boundingVolumes - mbs and obb data about node's bounding volume
|
|
337
348
|
*/
|
|
338
349
|
private async _convertNodesTree(
|
|
339
|
-
|
|
340
|
-
sourceRootTile: TileHeader
|
|
341
|
-
parentId: number,
|
|
342
|
-
boundingVolumes: BoundingVolumes
|
|
350
|
+
rootNode: NodeIndexDocument,
|
|
351
|
+
sourceRootTile: TileHeader
|
|
343
352
|
): Promise<void> {
|
|
344
353
|
await this.sourceTileset!._loadTile(sourceRootTile);
|
|
345
354
|
if (this.isContentSupported(sourceRootTile)) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
href: './1',
|
|
350
|
-
...boundingVolumes
|
|
351
|
-
});
|
|
352
|
-
const [child] = await this._createNode(root0, sourceRootTile, parentId, 0);
|
|
353
|
-
const childPath = join(this.layers0Path, 'nodes', child.path!);
|
|
354
|
-
|
|
355
|
-
if (this.options.slpk) {
|
|
356
|
-
await this.writeQueue.enqueue({
|
|
357
|
-
archiveKey: 'nodes/1/3dNodeIndexDocument.json.gz',
|
|
358
|
-
writePromise: writeFileForSlpk(
|
|
359
|
-
childPath,
|
|
360
|
-
JSON.stringify(child),
|
|
361
|
-
'3dNodeIndexDocument.json'
|
|
362
|
-
)
|
|
363
|
-
});
|
|
364
|
-
} else {
|
|
365
|
-
await 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();
|
|
366
358
|
}
|
|
359
|
+
await rootNode.addChildren(childNodes);
|
|
367
360
|
} else {
|
|
368
361
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
369
|
-
parentNode:
|
|
362
|
+
parentNode: rootNode,
|
|
370
363
|
sourceTiles: sourceRootTile.children,
|
|
371
|
-
parentId,
|
|
372
364
|
level: 1
|
|
373
365
|
});
|
|
374
366
|
}
|
|
375
367
|
await sourceRootTile.unloadContent();
|
|
368
|
+
await rootNode.save();
|
|
376
369
|
}
|
|
377
370
|
|
|
378
371
|
/**
|
|
@@ -382,37 +375,16 @@ export default class I3SConverter {
|
|
|
382
375
|
if (this.options.slpk) {
|
|
383
376
|
await this.writeQueue.enqueue({
|
|
384
377
|
archiveKey: '3dSceneLayer.json.gz',
|
|
385
|
-
writePromise:
|
|
386
|
-
this.layers0Path,
|
|
387
|
-
JSON.stringify(this.layers0),
|
|
388
|
-
'3dSceneLayer.json'
|
|
389
|
-
)
|
|
378
|
+
writePromise: () =>
|
|
379
|
+
writeFileForSlpk(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
|
|
390
380
|
});
|
|
391
381
|
} else {
|
|
392
382
|
await this.writeQueue.enqueue({
|
|
393
|
-
writePromise: writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
383
|
+
writePromise: () => writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
394
384
|
});
|
|
395
385
|
}
|
|
396
386
|
}
|
|
397
387
|
|
|
398
|
-
/**
|
|
399
|
-
* Write 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md in file
|
|
400
|
-
*/
|
|
401
|
-
private async _writeNodeIndexDocument(
|
|
402
|
-
root0: Node3DIndexDocument,
|
|
403
|
-
nodePath: string,
|
|
404
|
-
rootPath: string
|
|
405
|
-
): Promise<void> {
|
|
406
|
-
if (this.options.slpk) {
|
|
407
|
-
await this.writeQueue.enqueue({
|
|
408
|
-
archiveKey: `nodes/${nodePath}/3dNodeIndexDocument.json.gz`,
|
|
409
|
-
writePromise: writeFileForSlpk(rootPath, JSON.stringify(root0), '3dNodeIndexDocument.json')
|
|
410
|
-
});
|
|
411
|
-
} else {
|
|
412
|
-
await this.writeQueue.enqueue({writePromise: writeFile(rootPath, JSON.stringify(root0))});
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
388
|
/**
|
|
417
389
|
* Pack files into *.slpk archive
|
|
418
390
|
* @param tilesetPath - Path to save file
|
|
@@ -458,123 +430,114 @@ export default class I3SConverter {
|
|
|
458
430
|
/**
|
|
459
431
|
* Add child nodes recursively and write them to files
|
|
460
432
|
* @param data - arguments
|
|
433
|
+
* @param data.parentNode - 3DNodeIndexDocument of parent node
|
|
461
434
|
* @param data.sourceTiles - array of source child nodes
|
|
462
|
-
* @param data.parentNode - 3DNodeIndexDocument of parent node for processing child nodes
|
|
463
|
-
* @param data.parentId - id of parent node in node pages
|
|
464
435
|
* @param data.level - level of node (distanse to root node in the tree)
|
|
465
436
|
*/
|
|
466
437
|
private async _addChildrenWithNeighborsAndWriteFile(data: {
|
|
467
|
-
parentNode:
|
|
438
|
+
parentNode: NodeIndexDocument;
|
|
468
439
|
sourceTiles: TileHeader[];
|
|
469
|
-
parentId: number;
|
|
470
440
|
level: number;
|
|
471
441
|
}): Promise<void> {
|
|
472
|
-
|
|
473
|
-
await
|
|
474
|
-
|
|
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);
|
|
475
489
|
}
|
|
476
490
|
|
|
477
491
|
/**
|
|
478
492
|
* Add child nodes recursively and write them to files
|
|
479
|
-
* @param
|
|
480
|
-
* @param
|
|
481
|
-
* @param
|
|
482
|
-
* @param
|
|
483
|
-
* @param data.parentId - id of parent node in node pages
|
|
484
|
-
* @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
|
|
485
497
|
*/
|
|
486
498
|
private async _addChildren(data: {
|
|
487
|
-
|
|
499
|
+
parentNode: NodeIndexDocument;
|
|
488
500
|
sourceTiles: TileHeader[];
|
|
489
|
-
parentNode: Node3DIndexDocument;
|
|
490
|
-
parentId: number;
|
|
491
501
|
level: number;
|
|
492
502
|
}): Promise<void> {
|
|
493
|
-
const {
|
|
503
|
+
const {sourceTiles, parentNode, level} = data;
|
|
494
504
|
if (this.options.maxDepth && level > this.options.maxDepth) {
|
|
495
505
|
return;
|
|
496
506
|
}
|
|
507
|
+
|
|
508
|
+
const promises: Promise<void>[] = [];
|
|
497
509
|
for (const sourceTile of sourceTiles) {
|
|
498
510
|
if (sourceTile.type === 'json') {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
parentId,
|
|
505
|
-
level: level + 1
|
|
506
|
-
});
|
|
507
|
-
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
|
+
}
|
|
508
516
|
} else {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
id: child.id,
|
|
514
|
-
href: `../${child.path}`,
|
|
515
|
-
obb: child.obb,
|
|
516
|
-
mbs: child.mbs
|
|
517
|
-
});
|
|
518
|
-
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}));
|
|
519
521
|
}
|
|
520
522
|
}
|
|
521
523
|
if (sourceTile.id) {
|
|
522
524
|
console.log(sourceTile.id); // eslint-disable-line
|
|
523
525
|
}
|
|
524
526
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
/**
|
|
528
|
-
* Add neightbors to 3DNodeIndexDocument and write it in a file
|
|
529
|
-
* @param parentNode - arguments
|
|
530
|
-
* @param childNodes - array of target child nodes
|
|
531
|
-
*/
|
|
532
|
-
private async _addNeighborsAndWriteFile(
|
|
533
|
-
parentNode: Node3DIndexDocument,
|
|
534
|
-
childNodes: Node3DIndexDocument[]
|
|
535
|
-
): Promise<void> {
|
|
536
|
-
for (const node of childNodes) {
|
|
537
|
-
const childPath = join(this.layers0Path, 'nodes', node.path!);
|
|
538
|
-
const nodePath = node.path;
|
|
539
|
-
delete node.path;
|
|
540
|
-
|
|
541
|
-
// Don't do large amount of "neightbors" to avoid big memory consumption
|
|
542
|
-
if (Number(parentNode?.children?.length) < 1000) {
|
|
543
|
-
for (const neighbor of parentNode.children || []) {
|
|
544
|
-
// eslint-disable-next-line max-depth
|
|
545
|
-
if (node.id === neighbor.id) {
|
|
546
|
-
continue; // eslint-disable-line
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
if (node.neighbors) {
|
|
550
|
-
node.neighbors.push({...neighbor});
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
} else {
|
|
554
|
-
// eslint-disable-next-line no-console, no-undef
|
|
555
|
-
console.warn(
|
|
556
|
-
`Node ${node.id}: neighbors attribute is omited because of large number of neigbors`
|
|
557
|
-
);
|
|
558
|
-
delete node.neighbors;
|
|
559
|
-
}
|
|
560
|
-
await this._writeNodeIndexDocument(node, nodePath!, childPath);
|
|
561
|
-
node.neighbors = [];
|
|
562
|
-
}
|
|
527
|
+
await Promise.all(promises);
|
|
563
528
|
}
|
|
564
529
|
|
|
565
530
|
/**
|
|
566
531
|
* Convert tile to one or more I3S nodes
|
|
567
|
-
* @param
|
|
568
|
-
* @param sourceTile - source
|
|
569
|
-
* @param
|
|
570
|
-
* @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
|
|
571
535
|
*/
|
|
572
536
|
private async _createNode(
|
|
573
|
-
|
|
537
|
+
parentNode: NodeIndexDocument,
|
|
574
538
|
sourceTile: TileHeader,
|
|
575
|
-
parentId: number,
|
|
576
539
|
level: number
|
|
577
|
-
): Promise<
|
|
540
|
+
): Promise<NodeIndexDocument[]> {
|
|
578
541
|
this._checkAddRefinementTypeForTile(sourceTile);
|
|
579
542
|
|
|
580
543
|
await this._updateTilesetOptions();
|
|
@@ -582,20 +545,26 @@ export default class I3SConverter {
|
|
|
582
545
|
|
|
583
546
|
let boundingVolumes = createBoundingVolumes(sourceTile, this.geoidHeightModel!);
|
|
584
547
|
|
|
585
|
-
const
|
|
548
|
+
const propertyTable = getPropertyTable(sourceTile.content);
|
|
586
549
|
|
|
587
|
-
if (
|
|
588
|
-
this.
|
|
550
|
+
if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
|
|
551
|
+
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
589
552
|
}
|
|
590
553
|
|
|
591
|
-
const resourcesData = await this._convertResources(
|
|
554
|
+
const resourcesData = await this._convertResources(
|
|
555
|
+
sourceTile,
|
|
556
|
+
parentNode.inPageId,
|
|
557
|
+
propertyTable
|
|
558
|
+
);
|
|
592
559
|
|
|
593
|
-
const nodes:
|
|
560
|
+
const nodes: NodeIndexDocument[] = [];
|
|
561
|
+
const nodeIds: number[] = [];
|
|
594
562
|
const nodesInPage: NodeInPage[] = [];
|
|
595
563
|
const emptyResources = {
|
|
596
564
|
geometry: null,
|
|
597
565
|
compressedGeometry: null,
|
|
598
566
|
texture: null,
|
|
567
|
+
hasUvRegions: false,
|
|
599
568
|
sharedResources: null,
|
|
600
569
|
meshMaterial: null,
|
|
601
570
|
vertexCount: null,
|
|
@@ -616,34 +585,37 @@ export default class I3SConverter {
|
|
|
616
585
|
(val) => val.metricType === 'maxScreenThresholdSQ'
|
|
617
586
|
) || {maxError: 0};
|
|
618
587
|
|
|
619
|
-
const nodeInPage = this.
|
|
588
|
+
const nodeInPage = await this._updateNodeInNodePages(
|
|
620
589
|
maxScreenThresholdSQ,
|
|
621
590
|
boundingVolumes,
|
|
622
591
|
sourceTile,
|
|
623
|
-
|
|
592
|
+
parentNode.inPageId,
|
|
624
593
|
resources
|
|
625
594
|
);
|
|
626
|
-
|
|
627
|
-
|
|
595
|
+
|
|
596
|
+
const nodeData = await NodeIndexDocument.createNodeIndexDocument(
|
|
597
|
+
parentNode,
|
|
628
598
|
boundingVolumes,
|
|
629
599
|
lodSelection,
|
|
630
600
|
nodeInPage,
|
|
631
601
|
resources
|
|
632
602
|
);
|
|
603
|
+
const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
|
|
604
|
+
nodes.push(node);
|
|
633
605
|
|
|
634
606
|
if (nodeInPage.mesh) {
|
|
635
|
-
await this._writeResources(resources, node.
|
|
607
|
+
await this._writeResources(resources, node.id);
|
|
636
608
|
}
|
|
637
609
|
|
|
638
610
|
if (this.validate) {
|
|
639
|
-
this.boundingVolumeWarnings = validateNodeBoundingVolumes(
|
|
611
|
+
this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
|
|
640
612
|
|
|
641
613
|
if (this.boundingVolumeWarnings && this.boundingVolumeWarnings.length) {
|
|
642
614
|
console.warn('Bounding Volume Warnings: ', ...this.boundingVolumeWarnings); //eslint-disable-line
|
|
643
615
|
}
|
|
644
616
|
}
|
|
645
617
|
|
|
646
|
-
|
|
618
|
+
nodeIds.push(nodeInPage.index);
|
|
647
619
|
nodesInPage.push(nodeInPage);
|
|
648
620
|
}
|
|
649
621
|
|
|
@@ -652,49 +624,40 @@ export default class I3SConverter {
|
|
|
652
624
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
653
625
|
parentNode: nodes[0],
|
|
654
626
|
sourceTiles: sourceTile.children,
|
|
655
|
-
parentId: nodesInPage[0].index!,
|
|
656
627
|
level: level + 1
|
|
657
628
|
});
|
|
658
629
|
return nodes;
|
|
659
630
|
}
|
|
660
631
|
|
|
661
|
-
/**
|
|
662
|
-
* Convert attributesStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
|
|
663
|
-
* from B3DM batch table
|
|
664
|
-
* @param sourceTileContent - tile content of 3DTile
|
|
665
|
-
* @return {void}
|
|
666
|
-
*/
|
|
667
|
-
private _convertAttributeStorageInfo(sourceTileContent: B3DMContent): void {
|
|
668
|
-
// In legacy b3dm files sometimes sourceTileContent is null.
|
|
669
|
-
const batchTable = sourceTileContent && sourceTileContent.batchTableJson;
|
|
670
|
-
if (batchTable && !this.layers0?.attributeStorageInfo?.length) {
|
|
671
|
-
this._convertBatchTableInfoToNodeAttributes(batchTable);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
632
|
/**
|
|
676
633
|
* Convert tile to one or more I3S nodes
|
|
677
634
|
* @param sourceTile - source tile (3DTile)
|
|
678
|
-
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
* result.sharedResources - shared resource data object
|
|
682
|
-
* result.meshMaterial - PBR-like material object
|
|
683
|
-
* result.vertexCount - number of vertices in geometry
|
|
684
|
-
* result.attributes - feature attributes
|
|
685
|
-
* 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
|
|
686
638
|
*/
|
|
687
|
-
private async _convertResources(
|
|
639
|
+
private async _convertResources(
|
|
640
|
+
sourceTile: TileHeader,
|
|
641
|
+
parentId: number,
|
|
642
|
+
propertyTable: FeatureTableJson | null
|
|
643
|
+
): Promise<I3SConvertedResources[] | null> {
|
|
688
644
|
if (!this.isContentSupported(sourceTile)) {
|
|
689
645
|
return null;
|
|
690
646
|
}
|
|
647
|
+
const draftObb = {
|
|
648
|
+
center: [],
|
|
649
|
+
halfSize: [],
|
|
650
|
+
quaternion: []
|
|
651
|
+
};
|
|
691
652
|
const resourcesData = await convertB3dmToI3sGeometry(
|
|
692
653
|
sourceTile.content,
|
|
693
|
-
|
|
654
|
+
async () => (await this.nodePages.push({index: 0, obb: draftObb}, parentId)).index,
|
|
655
|
+
propertyTable,
|
|
694
656
|
this.featuresHashArray,
|
|
695
657
|
this.layers0?.attributeStorageInfo,
|
|
696
658
|
this.options.draco,
|
|
697
659
|
this.generateBoundingVolumes,
|
|
660
|
+
this.options.mergeMaterials,
|
|
698
661
|
this.geoidHeightModel!,
|
|
699
662
|
this.workerSource
|
|
700
663
|
);
|
|
@@ -702,7 +665,7 @@ export default class I3SConverter {
|
|
|
702
665
|
}
|
|
703
666
|
|
|
704
667
|
/**
|
|
705
|
-
*
|
|
668
|
+
* Update node object (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md)
|
|
706
669
|
* in node pages (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodePage.cmn.md)
|
|
707
670
|
* @param maxScreenThresholdSQ - Level of Details (LOD) metric
|
|
708
671
|
* @param boundingVolumes - Bounding volumes
|
|
@@ -713,16 +676,17 @@ export default class I3SConverter {
|
|
|
713
676
|
* @param resources.texture - texture image
|
|
714
677
|
* @param resources.vertexCount - number of vertices in geometry
|
|
715
678
|
* @param resources.featureCount - number of features
|
|
679
|
+
* @param resources.geometry - Uint8Array with geometry attributes
|
|
716
680
|
* @return the node object in node pages
|
|
717
681
|
*/
|
|
718
|
-
private
|
|
682
|
+
private async _updateNodeInNodePages(
|
|
719
683
|
maxScreenThresholdSQ: MaxScreenThresholdSQ,
|
|
720
684
|
boundingVolumes: BoundingVolumes,
|
|
721
685
|
sourceTile: TileHeader,
|
|
722
686
|
parentId: number,
|
|
723
687
|
resources: I3SConvertedResources
|
|
724
|
-
): NodeInPage {
|
|
725
|
-
const {meshMaterial, texture, vertexCount, featureCount, geometry} = resources;
|
|
688
|
+
): Promise<NodeInPage> {
|
|
689
|
+
const {meshMaterial, texture, vertexCount, featureCount, geometry, hasUvRegions} = resources;
|
|
726
690
|
const nodeInPage: NodeInPage = {
|
|
727
691
|
index: 0,
|
|
728
692
|
lodThreshold: maxScreenThresholdSQ.maxError,
|
|
@@ -732,7 +696,7 @@ export default class I3SConverter {
|
|
|
732
696
|
if (geometry && this.isContentSupported(sourceTile)) {
|
|
733
697
|
nodeInPage.mesh = {
|
|
734
698
|
geometry: {
|
|
735
|
-
definition: texture
|
|
699
|
+
definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
|
|
736
700
|
resource: 0
|
|
737
701
|
},
|
|
738
702
|
attribute: {
|
|
@@ -743,83 +707,33 @@ export default class I3SConverter {
|
|
|
743
707
|
}
|
|
744
708
|
};
|
|
745
709
|
}
|
|
746
|
-
const nodeId = this.nodePages.push(nodeInPage, parentId);
|
|
747
710
|
|
|
748
|
-
|
|
749
|
-
|
|
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);
|
|
750
717
|
}
|
|
751
718
|
|
|
719
|
+
NodePages.updateAll(node, nodeInPage);
|
|
720
|
+
if (meshMaterial) {
|
|
721
|
+
NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
|
|
722
|
+
}
|
|
752
723
|
if (texture) {
|
|
753
724
|
const texelCountHint = texture.image.height * texture.image.width;
|
|
754
|
-
|
|
725
|
+
NodePages.updateTexelCountHintByNodeId(node, texelCountHint);
|
|
755
726
|
}
|
|
756
|
-
|
|
757
727
|
if (vertexCount) {
|
|
758
728
|
this.vertexCounter += vertexCount;
|
|
759
|
-
|
|
729
|
+
NodePages.updateVertexCountByNodeId(node, vertexCount);
|
|
760
730
|
}
|
|
761
|
-
|
|
731
|
+
NodePages.updateNodeAttributeByNodeId(node);
|
|
762
732
|
if (featureCount) {
|
|
763
|
-
|
|
733
|
+
NodePages.updateFeatureCountByNodeId(node, featureCount);
|
|
764
734
|
}
|
|
765
735
|
|
|
766
|
-
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
/**
|
|
770
|
-
* Create a new node page object in node pages
|
|
771
|
-
* @param parentNode - 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object of the parent node
|
|
772
|
-
* @param boundingVolumes - Bounding volumes
|
|
773
|
-
* @param lodSelection - Level of Details (LOD) metrics
|
|
774
|
-
* @param nodeInPage - corresponding node object in a node page
|
|
775
|
-
* @param resources - the node resources data
|
|
776
|
-
* @param resources.texture - texture image
|
|
777
|
-
* @param resources.attributes - feature attributes
|
|
778
|
-
* @return 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object
|
|
779
|
-
*/
|
|
780
|
-
private _createNodeIndexDocument(
|
|
781
|
-
parentNode: Node3DIndexDocument,
|
|
782
|
-
boundingVolumes: BoundingVolumes,
|
|
783
|
-
lodSelection: LodSelection[],
|
|
784
|
-
nodeInPage: NodeInPage,
|
|
785
|
-
resources: I3SConvertedResources
|
|
786
|
-
): Node3DIndexDocument {
|
|
787
|
-
const {texture, attributes} = resources;
|
|
788
|
-
const nodeId = nodeInPage.index!;
|
|
789
|
-
const nodeData = {
|
|
790
|
-
version: parentNode.version,
|
|
791
|
-
id: nodeId.toString(),
|
|
792
|
-
path: nodeId.toString(),
|
|
793
|
-
level: parentNode.level! + 1,
|
|
794
|
-
...boundingVolumes,
|
|
795
|
-
lodSelection,
|
|
796
|
-
parentNode: {
|
|
797
|
-
id: parentNode.id,
|
|
798
|
-
href: `../${parentNode.id}`,
|
|
799
|
-
mbs: parentNode.mbs,
|
|
800
|
-
obb: parentNode.obb
|
|
801
|
-
},
|
|
802
|
-
children: [],
|
|
803
|
-
neighbors: []
|
|
804
|
-
};
|
|
805
|
-
const node = transform(nodeData, nodeTemplate());
|
|
806
|
-
|
|
807
|
-
if (nodeInPage.mesh) {
|
|
808
|
-
node.geometryData = [{href: './geometries/0'}];
|
|
809
|
-
node.sharedResource = {href: './shared'};
|
|
810
|
-
|
|
811
|
-
if (texture) {
|
|
812
|
-
node.textureData = [{href: './textures/0'}, {href: './textures/1'}];
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
if (attributes && attributes.length && this.layers0?.attributeStorageInfo?.length) {
|
|
816
|
-
node.attributeData = [];
|
|
817
|
-
for (let index = 0; index < attributes.length; index++) {
|
|
818
|
-
const folderName = this.layers0.attributeStorageInfo[index].key;
|
|
819
|
-
node.attributeData.push({href: `./attributes/${folderName}/0`});
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
}
|
|
736
|
+
this.nodePages.saveNode(node);
|
|
823
737
|
|
|
824
738
|
return node;
|
|
825
739
|
}
|
|
@@ -868,12 +782,12 @@ export default class I3SConverter {
|
|
|
868
782
|
const slpkGeometryPath = join(childPath, 'geometries');
|
|
869
783
|
await this.writeQueue.enqueue({
|
|
870
784
|
archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
|
|
871
|
-
writePromise: writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
785
|
+
writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
872
786
|
});
|
|
873
787
|
} else {
|
|
874
788
|
const geometryPath = join(childPath, 'geometries/0/');
|
|
875
789
|
await this.writeQueue.enqueue({
|
|
876
|
-
writePromise: writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
790
|
+
writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
877
791
|
});
|
|
878
792
|
}
|
|
879
793
|
|
|
@@ -882,12 +796,13 @@ export default class I3SConverter {
|
|
|
882
796
|
const slpkCompressedGeometryPath = join(childPath, 'geometries');
|
|
883
797
|
await this.writeQueue.enqueue({
|
|
884
798
|
archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
|
|
885
|
-
writePromise:
|
|
799
|
+
writePromise: () =>
|
|
800
|
+
writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
|
|
886
801
|
});
|
|
887
802
|
} else {
|
|
888
803
|
const compressedGeometryPath = join(childPath, 'geometries/1/');
|
|
889
804
|
await this.writeQueue.enqueue({
|
|
890
|
-
writePromise: writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
805
|
+
writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
891
806
|
});
|
|
892
807
|
}
|
|
893
808
|
}
|
|
@@ -916,11 +831,11 @@ export default class I3SConverter {
|
|
|
916
831
|
const slpkSharedPath = join(childPath, 'shared');
|
|
917
832
|
await this.writeQueue.enqueue({
|
|
918
833
|
archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
|
|
919
|
-
writePromise: writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
834
|
+
writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
920
835
|
});
|
|
921
836
|
} else {
|
|
922
837
|
const sharedPath = join(childPath, 'shared/');
|
|
923
|
-
await this.writeQueue.enqueue({writePromise: writeFile(sharedPath, sharedDataStr)});
|
|
838
|
+
await this.writeQueue.enqueue({writePromise: () => writeFile(sharedPath, sharedDataStr)});
|
|
924
839
|
}
|
|
925
840
|
}
|
|
926
841
|
|
|
@@ -948,12 +863,19 @@ export default class I3SConverter {
|
|
|
948
863
|
|
|
949
864
|
if (this.generateTextures) {
|
|
950
865
|
formats.push({name: '1', format: 'ktx2'});
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
866
|
+
// For Node.js texture.image.data is type of Buffer
|
|
867
|
+
const copyArrayBuffer = texture.image.data.subarray();
|
|
868
|
+
const arrayToEncode = new Uint8Array(copyArrayBuffer);
|
|
869
|
+
const ktx2TextureData = encode(
|
|
870
|
+
{...texture.image, data: arrayToEncode},
|
|
871
|
+
KTX2BasisWriterWorker,
|
|
872
|
+
{
|
|
873
|
+
...KTX2BasisWriterWorker.options,
|
|
874
|
+
source: this.workerSource.ktx2,
|
|
875
|
+
reuseWorkers: true,
|
|
876
|
+
_nodeWorkers: true
|
|
877
|
+
}
|
|
878
|
+
);
|
|
957
879
|
|
|
958
880
|
await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath);
|
|
959
881
|
}
|
|
@@ -981,6 +903,7 @@ export default class I3SConverter {
|
|
|
981
903
|
|
|
982
904
|
if (!this.layers0!.textureSetDefinitions!.length) {
|
|
983
905
|
this.layers0!.textureSetDefinitions!.push({formats});
|
|
906
|
+
this.layers0!.textureSetDefinitions!.push({formats, atlas: true});
|
|
984
907
|
}
|
|
985
908
|
}
|
|
986
909
|
}
|
|
@@ -1006,12 +929,13 @@ export default class I3SConverter {
|
|
|
1006
929
|
|
|
1007
930
|
await this.writeQueue.enqueue({
|
|
1008
931
|
archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
|
|
1009
|
-
writePromise:
|
|
932
|
+
writePromise: () =>
|
|
933
|
+
writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
|
|
1010
934
|
});
|
|
1011
935
|
} else {
|
|
1012
936
|
const texturePath = join(childPath, `textures/${name}/`);
|
|
1013
937
|
await this.writeQueue.enqueue({
|
|
1014
|
-
writePromise: writeFile(texturePath, textureData, `index.${format}`)
|
|
938
|
+
writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
|
|
1015
939
|
});
|
|
1016
940
|
}
|
|
1017
941
|
}
|
|
@@ -1036,12 +960,12 @@ export default class I3SConverter {
|
|
|
1036
960
|
const slpkAttributesPath = join(childPath, 'attributes', folderName);
|
|
1037
961
|
await this.writeQueue.enqueue({
|
|
1038
962
|
archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
|
|
1039
|
-
writePromise: writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
963
|
+
writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
1040
964
|
});
|
|
1041
965
|
} else {
|
|
1042
966
|
const attributesPath = join(childPath, `attributes/${folderName}/0`);
|
|
1043
967
|
await this.writeQueue.enqueue({
|
|
1044
|
-
writePromise: writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
968
|
+
writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
1045
969
|
});
|
|
1046
970
|
}
|
|
1047
971
|
}
|
|
@@ -1073,7 +997,7 @@ export default class I3SConverter {
|
|
|
1073
997
|
private _findOrCreateMaterial(material: I3SMaterialDefinition): number {
|
|
1074
998
|
const hash = md5(JSON.stringify(material));
|
|
1075
999
|
if (this.materialMap.has(hash)) {
|
|
1076
|
-
return this.materialMap.get(hash);
|
|
1000
|
+
return this.materialMap.get(hash) || 0;
|
|
1077
1001
|
}
|
|
1078
1002
|
const newMaterialId = this.materialDefinitions.push(material) - 1;
|
|
1079
1003
|
this.materialMap.set(hash, newMaterialId);
|
|
@@ -1081,133 +1005,42 @@ export default class I3SConverter {
|
|
|
1081
1005
|
}
|
|
1082
1006
|
|
|
1083
1007
|
/**
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1086
|
-
* @param
|
|
1087
|
-
* @param
|
|
1088
|
-
* @
|
|
1089
|
-
*/
|
|
1090
|
-
private _createdStorageAttribute(
|
|
1091
|
-
attributeIndex: number,
|
|
1092
|
-
key: string,
|
|
1093
|
-
attributeType: Attribute
|
|
1094
|
-
): AttributeStorageInfo {
|
|
1095
|
-
const storageAttribute = {
|
|
1096
|
-
key: `f_${attributeIndex}`,
|
|
1097
|
-
name: key,
|
|
1098
|
-
ordering: ['attributeValues'],
|
|
1099
|
-
header: [{property: 'count', valueType: 'UInt32'}],
|
|
1100
|
-
attributeValues: {valueType: 'Int32', valuesPerElement: 1}
|
|
1101
|
-
};
|
|
1102
|
-
|
|
1103
|
-
switch (attributeType) {
|
|
1104
|
-
case OBJECT_ID_TYPE:
|
|
1105
|
-
this._setupIdAttribute(storageAttribute);
|
|
1106
|
-
break;
|
|
1107
|
-
case STRING_TYPE:
|
|
1108
|
-
this._setupStringAttribute(storageAttribute);
|
|
1109
|
-
break;
|
|
1110
|
-
case DOUBLE_TYPE:
|
|
1111
|
-
this._setupDoubleAttribute(storageAttribute);
|
|
1112
|
-
break;
|
|
1113
|
-
case SHORT_INT_TYPE:
|
|
1114
|
-
break;
|
|
1115
|
-
default:
|
|
1116
|
-
this._setupStringAttribute(storageAttribute);
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
return storageAttribute;
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
/**
|
|
1123
|
-
* Get the attribute type for attributeStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
|
|
1124
|
-
* @param key - attribute's key
|
|
1125
|
-
* @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
|
|
1126
1013
|
*/
|
|
1127
|
-
private
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
return STRING_TYPE;
|
|
1133
|
-
} else if (typeof attribute === 'number') {
|
|
1134
|
-
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;
|
|
1135
1019
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
/**
|
|
1140
|
-
* Setup storage attribute as string.
|
|
1141
|
-
* @param storageAttribute - attribute for map segmentation.
|
|
1142
|
-
*/
|
|
1143
|
-
private _setupStringAttribute(storageAttribute: AttributeStorageInfo): void {
|
|
1144
|
-
storageAttribute.ordering!.unshift('attributeByteCounts');
|
|
1145
|
-
storageAttribute.header.push({property: 'attributeValuesByteCount', valueType: 'UInt32'});
|
|
1146
|
-
storageAttribute.attributeValues = {
|
|
1147
|
-
valueType: 'String',
|
|
1148
|
-
encoding: 'UTF-8',
|
|
1149
|
-
valuesPerElement: 1
|
|
1150
|
-
};
|
|
1151
|
-
storageAttribute.attributeByteCounts = {
|
|
1152
|
-
valueType: 'UInt32',
|
|
1153
|
-
valuesPerElement: 1
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
/**
|
|
1158
|
-
* Setup Id attribute for map segmentation.
|
|
1159
|
-
* @param storageAttribute - attribute for map segmentation .
|
|
1160
|
-
*/
|
|
1161
|
-
private _setupIdAttribute(storageAttribute: AttributeStorageInfo): void {
|
|
1162
|
-
storageAttribute.attributeValues = {
|
|
1163
|
-
valueType: 'Oid32',
|
|
1164
|
-
valuesPerElement: 1
|
|
1165
|
-
};
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
/**
|
|
1169
|
-
* Setup double attribute for map segmentation.
|
|
1170
|
-
* @param storageAttribute - attribute for map segmentation .
|
|
1171
|
-
*/
|
|
1172
|
-
private _setupDoubleAttribute(storageAttribute: AttributeStorageInfo): void {
|
|
1173
|
-
storageAttribute.attributeValues = {
|
|
1174
|
-
valueType: 'Float64',
|
|
1175
|
-
valuesPerElement: 1
|
|
1176
|
-
};
|
|
1020
|
+
const newGeometryId = this.geometryConfigs.push(geometryConfig) - 1;
|
|
1021
|
+
this.geometryMap.set(hash, newGeometryId);
|
|
1022
|
+
return newGeometryId;
|
|
1177
1023
|
}
|
|
1178
1024
|
|
|
1179
1025
|
/**
|
|
1180
|
-
*
|
|
1181
|
-
* @param
|
|
1182
|
-
* @param fieldAttributeType - esri attribute type ('esriFieldTypeString' or 'esriFieldTypeOID').
|
|
1026
|
+
* Do conversion of 3DTiles property table to I3s node attributes.
|
|
1027
|
+
* @param propertyTable - Table with layer meta data.
|
|
1183
1028
|
*/
|
|
1184
|
-
private
|
|
1185
|
-
return {
|
|
1186
|
-
name: key,
|
|
1187
|
-
type: fieldAttributeType,
|
|
1188
|
-
alias: key
|
|
1189
|
-
};
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
/**
|
|
1193
|
-
* Do conversion of 3DTiles batch table to I3s node attributes.
|
|
1194
|
-
* @param batchTable - Table with layer meta data.
|
|
1195
|
-
*/
|
|
1196
|
-
private _convertBatchTableInfoToNodeAttributes(batchTable: BatchTableJson): void {
|
|
1029
|
+
private _convertPropertyTableToNodeAttributes(propertyTable: FeatureTableJson): void {
|
|
1197
1030
|
let attributeIndex = 0;
|
|
1198
|
-
const
|
|
1031
|
+
const propertyTableWithObjectId = {
|
|
1199
1032
|
OBJECTID: [0],
|
|
1200
|
-
...
|
|
1033
|
+
...propertyTable
|
|
1201
1034
|
};
|
|
1202
1035
|
|
|
1203
|
-
for (const key in
|
|
1204
|
-
const firstAttribute =
|
|
1205
|
-
const attributeType =
|
|
1036
|
+
for (const key in propertyTableWithObjectId) {
|
|
1037
|
+
const firstAttribute = propertyTableWithObjectId[key][0];
|
|
1038
|
+
const attributeType = getAttributeType(key, firstAttribute);
|
|
1206
1039
|
|
|
1207
|
-
const storageAttribute =
|
|
1208
|
-
const fieldAttributeType =
|
|
1209
|
-
const fieldAttribute =
|
|
1210
|
-
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);
|
|
1211
1044
|
|
|
1212
1045
|
this.layers0!.attributeStorageInfo!.push(storageAttribute);
|
|
1213
1046
|
this.layers0!.fields!.push(fieldAttribute);
|
|
@@ -1218,62 +1051,6 @@ export default class I3SConverter {
|
|
|
1218
1051
|
}
|
|
1219
1052
|
}
|
|
1220
1053
|
|
|
1221
|
-
/**
|
|
1222
|
-
* Find and return attribute type based on key form Batch table.
|
|
1223
|
-
* @param attributeType
|
|
1224
|
-
*/
|
|
1225
|
-
private _getFieldAttributeType(attributeType: Attribute): ESRIField {
|
|
1226
|
-
switch (attributeType) {
|
|
1227
|
-
case OBJECT_ID_TYPE:
|
|
1228
|
-
return 'esriFieldTypeOID';
|
|
1229
|
-
case STRING_TYPE:
|
|
1230
|
-
return 'esriFieldTypeString';
|
|
1231
|
-
case SHORT_INT_TYPE:
|
|
1232
|
-
return 'esriFieldTypeInteger';
|
|
1233
|
-
case DOUBLE_TYPE:
|
|
1234
|
-
return 'esriFieldTypeDouble';
|
|
1235
|
-
default:
|
|
1236
|
-
return 'esriFieldTypeString';
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
/**
|
|
1241
|
-
* Generate popup info to show metadata on the map.
|
|
1242
|
-
* @param batchTable - Batch table data with OBJECTID.
|
|
1243
|
-
* @return data for correct rendering of popup.
|
|
1244
|
-
*/
|
|
1245
|
-
private _createPopupInfo(batchTable: BatchTableJson): PopupInfo {
|
|
1246
|
-
const title = '{OBJECTID}';
|
|
1247
|
-
const mediaInfos = [];
|
|
1248
|
-
const fieldInfos: FieldInfo[] = [];
|
|
1249
|
-
const popupElements: {
|
|
1250
|
-
fieldInfos: FieldInfo[];
|
|
1251
|
-
type: string;
|
|
1252
|
-
}[] = [];
|
|
1253
|
-
const expressionInfos = [];
|
|
1254
|
-
|
|
1255
|
-
for (const key in batchTable) {
|
|
1256
|
-
fieldInfos.push({
|
|
1257
|
-
fieldName: key,
|
|
1258
|
-
visible: true,
|
|
1259
|
-
isEditable: false,
|
|
1260
|
-
label: key
|
|
1261
|
-
});
|
|
1262
|
-
}
|
|
1263
|
-
popupElements.push({
|
|
1264
|
-
fieldInfos,
|
|
1265
|
-
type: 'fields'
|
|
1266
|
-
});
|
|
1267
|
-
|
|
1268
|
-
return {
|
|
1269
|
-
title,
|
|
1270
|
-
mediaInfos,
|
|
1271
|
-
popupElements,
|
|
1272
|
-
fieldInfos,
|
|
1273
|
-
expressionInfos
|
|
1274
|
-
};
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
1054
|
/**
|
|
1278
1055
|
* Print statistics in the end of conversion
|
|
1279
1056
|
* @param params - output files data
|