@loaders.gl/tile-converter 3.3.0-alpha.1 → 3.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/3d-tiles-attributes-worker.js +3 -3
- package/dist/3d-tiles-attributes-worker.js.map +1 -1
- package/dist/converter.min.js +10 -10
- package/dist/dist.min.js +791 -554
- package/dist/es5/3d-tiles-attributes-worker.js +1 -1
- package/dist/es5/i3s-attributes-worker.js +1 -1
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +15 -4
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/feature-attributes.js +60 -0
- package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +39 -7
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +161 -49
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/node-pages.js +102 -46
- package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +235 -141
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/lib/utils/write-queue.js +66 -28
- package/dist/es5/lib/utils/write-queue.js.map +1 -1
- package/dist/es5/pgm-loader.js +1 -1
- package/dist/esm/3d-tiles-attributes-worker.js +1 -1
- package/dist/esm/i3s-attributes-worker.js +1 -1
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +15 -4
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/feature-attributes.js +34 -0
- package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +23 -7
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +132 -30
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/node-pages.js +3 -3
- package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +32 -42
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/lib/utils/write-queue.js +10 -0
- package/dist/esm/lib/utils/write-queue.js.map +1 -1
- package/dist/esm/pgm-loader.js +1 -1
- package/dist/i3s-attributes-worker.js +3 -3
- package/dist/i3s-attributes-worker.js.map +2 -2
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +12 -1
- package/dist/i3s-converter/helpers/feature-attributes.d.ts +24 -0
- package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/feature-attributes.js +55 -0
- package/dist/i3s-converter/helpers/geometry-attributes.js +26 -7
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +9 -2
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +124 -33
- package/dist/i3s-converter/helpers/node-pages.js +3 -3
- package/dist/i3s-converter/i3s-converter.d.ts +7 -14
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +56 -50
- package/dist/i3s-converter/types.d.ts +0 -48
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.d.ts +1 -0
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +13 -0
- package/package.json +15 -15
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +22 -5
- package/src/i3s-converter/helpers/feature-attributes.ts +65 -0
- package/src/i3s-converter/helpers/geometry-attributes.ts +30 -7
- package/src/i3s-converter/helpers/geometry-converter.ts +161 -37
- package/src/i3s-converter/helpers/node-pages.ts +3 -3
- package/src/i3s-converter/i3s-converter.ts +41 -51
- package/src/i3s-converter/types.ts +0 -51
- package/src/lib/utils/write-queue.ts +12 -0
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
2
21
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
23
|
};
|
|
@@ -15,7 +34,7 @@ const node_pages_1 = __importDefault(require("./helpers/node-pages"));
|
|
|
15
34
|
const file_utils_1 = require("../lib/utils/file-utils");
|
|
16
35
|
const compress_util_1 = require("../lib/utils/compress-util");
|
|
17
36
|
const statistic_utills_1 = require("../lib/utils/statistic-utills");
|
|
18
|
-
const geometry_converter_1 =
|
|
37
|
+
const geometry_converter_1 = __importStar(require("./helpers/geometry-converter"));
|
|
19
38
|
const coordinate_converter_1 = require("./helpers/coordinate-converter");
|
|
20
39
|
const create_scene_server_path_1 = require("./helpers/create-scene-server-path");
|
|
21
40
|
const lod_conversion_utils_1 = require("../lib/utils/lod-conversion-utils");
|
|
@@ -240,13 +259,13 @@ class I3SConverter {
|
|
|
240
259
|
const [child] = await this._createNode(root0, sourceRootTile, parentId, 0);
|
|
241
260
|
const childPath = (0, path_1.join)(this.layers0Path, 'nodes', child.path);
|
|
242
261
|
if (this.options.slpk) {
|
|
243
|
-
this.writeQueue.enqueue({
|
|
262
|
+
await this.writeQueue.enqueue({
|
|
244
263
|
archiveKey: 'nodes/1/3dNodeIndexDocument.json.gz',
|
|
245
264
|
writePromise: (0, file_utils_1.writeFileForSlpk)(childPath, JSON.stringify(child), '3dNodeIndexDocument.json')
|
|
246
265
|
});
|
|
247
266
|
}
|
|
248
267
|
else {
|
|
249
|
-
this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(childPath, JSON.stringify(child)) });
|
|
268
|
+
await this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(childPath, JSON.stringify(child)) });
|
|
250
269
|
}
|
|
251
270
|
}
|
|
252
271
|
else {
|
|
@@ -264,13 +283,13 @@ class I3SConverter {
|
|
|
264
283
|
*/
|
|
265
284
|
async _writeLayers0() {
|
|
266
285
|
if (this.options.slpk) {
|
|
267
|
-
this.writeQueue.enqueue({
|
|
286
|
+
await this.writeQueue.enqueue({
|
|
268
287
|
archiveKey: '3dSceneLayer.json.gz',
|
|
269
288
|
writePromise: (0, file_utils_1.writeFileForSlpk)(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
|
|
270
289
|
});
|
|
271
290
|
}
|
|
272
291
|
else {
|
|
273
|
-
this.writeQueue.enqueue({
|
|
292
|
+
await this.writeQueue.enqueue({
|
|
274
293
|
writePromise: (0, file_utils_1.writeFile)(this.layers0Path, JSON.stringify(this.layers0))
|
|
275
294
|
});
|
|
276
295
|
}
|
|
@@ -280,13 +299,13 @@ class I3SConverter {
|
|
|
280
299
|
*/
|
|
281
300
|
async _writeNodeIndexDocument(root0, nodePath, rootPath) {
|
|
282
301
|
if (this.options.slpk) {
|
|
283
|
-
this.writeQueue.enqueue({
|
|
302
|
+
await this.writeQueue.enqueue({
|
|
284
303
|
archiveKey: `nodes/${nodePath}/3dNodeIndexDocument.json.gz`,
|
|
285
304
|
writePromise: (0, file_utils_1.writeFileForSlpk)(rootPath, JSON.stringify(root0), '3dNodeIndexDocument.json')
|
|
286
305
|
});
|
|
287
306
|
}
|
|
288
307
|
else {
|
|
289
|
-
this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(rootPath, JSON.stringify(root0)) });
|
|
308
|
+
await this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(rootPath, JSON.stringify(root0)) });
|
|
290
309
|
}
|
|
291
310
|
}
|
|
292
311
|
/**
|
|
@@ -426,11 +445,11 @@ class I3SConverter {
|
|
|
426
445
|
await this._updateTilesetOptions();
|
|
427
446
|
await this.sourceTileset._loadTile(sourceTile);
|
|
428
447
|
let boundingVolumes = (0, coordinate_converter_1.createBoundingVolumes)(sourceTile, this.geoidHeightModel);
|
|
429
|
-
const
|
|
430
|
-
if (
|
|
431
|
-
this.
|
|
448
|
+
const propertyTable = (0, geometry_converter_1.getPropertyTable)(sourceTile);
|
|
449
|
+
if (propertyTable && !this.layers0?.attributeStorageInfo?.length) {
|
|
450
|
+
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
432
451
|
}
|
|
433
|
-
const resourcesData = await this._convertResources(sourceTile);
|
|
452
|
+
const resourcesData = await this._convertResources(sourceTile, propertyTable);
|
|
434
453
|
const nodes = [];
|
|
435
454
|
const nodesInPage = [];
|
|
436
455
|
const emptyResources = {
|
|
@@ -474,19 +493,6 @@ class I3SConverter {
|
|
|
474
493
|
});
|
|
475
494
|
return nodes;
|
|
476
495
|
}
|
|
477
|
-
/**
|
|
478
|
-
* Convert attributesStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
|
|
479
|
-
* from B3DM batch table
|
|
480
|
-
* @param sourceTileContent - tile content of 3DTile
|
|
481
|
-
* @return {void}
|
|
482
|
-
*/
|
|
483
|
-
_convertAttributeStorageInfo(sourceTileContent) {
|
|
484
|
-
// In legacy b3dm files sometimes sourceTileContent is null.
|
|
485
|
-
const batchTable = sourceTileContent && sourceTileContent.batchTableJson;
|
|
486
|
-
if (batchTable && !this.layers0?.attributeStorageInfo?.length) {
|
|
487
|
-
this._convertBatchTableInfoToNodeAttributes(batchTable);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
496
|
/**
|
|
491
497
|
* Convert tile to one or more I3S nodes
|
|
492
498
|
* @param sourceTile - source tile (3DTile)
|
|
@@ -499,11 +505,11 @@ class I3SConverter {
|
|
|
499
505
|
* result.attributes - feature attributes
|
|
500
506
|
* result.featureCount - number of features
|
|
501
507
|
*/
|
|
502
|
-
async _convertResources(sourceTile) {
|
|
508
|
+
async _convertResources(sourceTile, propertyTable) {
|
|
503
509
|
if (!this.isContentSupported(sourceTile)) {
|
|
504
510
|
return null;
|
|
505
511
|
}
|
|
506
|
-
const resourcesData = await (0, geometry_converter_1.default)(sourceTile.content, Number(this.nodePages.nodesCounter), this.featuresHashArray, this.layers0?.attributeStorageInfo, this.options.draco, this.generateBoundingVolumes, this.geoidHeightModel, this.workerSource);
|
|
512
|
+
const resourcesData = await (0, geometry_converter_1.default)(sourceTile.content, Number(this.nodePages.nodesCounter), propertyTable, this.featuresHashArray, this.layers0?.attributeStorageInfo, this.options.draco, this.generateBoundingVolumes, this.geoidHeightModel, this.workerSource);
|
|
507
513
|
return resourcesData;
|
|
508
514
|
}
|
|
509
515
|
/**
|
|
@@ -636,28 +642,28 @@ class I3SConverter {
|
|
|
636
642
|
async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath) {
|
|
637
643
|
if (this.options.slpk) {
|
|
638
644
|
const slpkGeometryPath = (0, path_1.join)(childPath, 'geometries');
|
|
639
|
-
this.writeQueue.enqueue({
|
|
645
|
+
await this.writeQueue.enqueue({
|
|
640
646
|
archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
|
|
641
647
|
writePromise: (0, file_utils_1.writeFileForSlpk)(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
642
648
|
});
|
|
643
649
|
}
|
|
644
650
|
else {
|
|
645
651
|
const geometryPath = (0, path_1.join)(childPath, 'geometries/0/');
|
|
646
|
-
this.writeQueue.enqueue({
|
|
652
|
+
await this.writeQueue.enqueue({
|
|
647
653
|
writePromise: (0, file_utils_1.writeFile)(geometryPath, geometryBuffer, 'index.bin')
|
|
648
654
|
});
|
|
649
655
|
}
|
|
650
656
|
if (this.options.draco) {
|
|
651
657
|
if (this.options.slpk) {
|
|
652
658
|
const slpkCompressedGeometryPath = (0, path_1.join)(childPath, 'geometries');
|
|
653
|
-
this.writeQueue.enqueue({
|
|
659
|
+
await this.writeQueue.enqueue({
|
|
654
660
|
archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
|
|
655
661
|
writePromise: (0, file_utils_1.writeFileForSlpk)(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
|
|
656
662
|
});
|
|
657
663
|
}
|
|
658
664
|
else {
|
|
659
665
|
const compressedGeometryPath = (0, path_1.join)(childPath, 'geometries/1/');
|
|
660
|
-
this.writeQueue.enqueue({
|
|
666
|
+
await this.writeQueue.enqueue({
|
|
661
667
|
writePromise: (0, file_utils_1.writeFile)(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
662
668
|
});
|
|
663
669
|
}
|
|
@@ -679,14 +685,14 @@ class I3SConverter {
|
|
|
679
685
|
const sharedDataStr = JSON.stringify(sharedData);
|
|
680
686
|
if (this.options.slpk) {
|
|
681
687
|
const slpkSharedPath = (0, path_1.join)(childPath, 'shared');
|
|
682
|
-
this.writeQueue.enqueue({
|
|
688
|
+
await this.writeQueue.enqueue({
|
|
683
689
|
archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
|
|
684
690
|
writePromise: (0, file_utils_1.writeFileForSlpk)(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
685
691
|
});
|
|
686
692
|
}
|
|
687
693
|
else {
|
|
688
694
|
const sharedPath = (0, path_1.join)(childPath, 'shared/');
|
|
689
|
-
this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(sharedPath, sharedDataStr) });
|
|
695
|
+
await this.writeQueue.enqueue({ writePromise: (0, file_utils_1.writeFile)(sharedPath, sharedDataStr) });
|
|
690
696
|
}
|
|
691
697
|
}
|
|
692
698
|
/**
|
|
@@ -747,14 +753,14 @@ class I3SConverter {
|
|
|
747
753
|
if (this.options.slpk) {
|
|
748
754
|
const slpkTexturePath = (0, path_1.join)(childPath, 'textures');
|
|
749
755
|
const compress = false;
|
|
750
|
-
this.writeQueue.enqueue({
|
|
756
|
+
await this.writeQueue.enqueue({
|
|
751
757
|
archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
|
|
752
758
|
writePromise: (0, file_utils_1.writeFileForSlpk)(slpkTexturePath, textureData, `${name}.${format}`, compress)
|
|
753
759
|
});
|
|
754
760
|
}
|
|
755
761
|
else {
|
|
756
762
|
const texturePath = (0, path_1.join)(childPath, `textures/${name}/`);
|
|
757
|
-
this.writeQueue.enqueue({
|
|
763
|
+
await this.writeQueue.enqueue({
|
|
758
764
|
writePromise: (0, file_utils_1.writeFile)(texturePath, textureData, `index.${format}`)
|
|
759
765
|
});
|
|
760
766
|
}
|
|
@@ -772,14 +778,14 @@ class I3SConverter {
|
|
|
772
778
|
const fileBuffer = new Uint8Array(attributes[index]);
|
|
773
779
|
if (this.options.slpk) {
|
|
774
780
|
const slpkAttributesPath = (0, path_1.join)(childPath, 'attributes', folderName);
|
|
775
|
-
this.writeQueue.enqueue({
|
|
781
|
+
await this.writeQueue.enqueue({
|
|
776
782
|
archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
|
|
777
783
|
writePromise: (0, file_utils_1.writeFileForSlpk)(slpkAttributesPath, fileBuffer, '0.bin')
|
|
778
784
|
});
|
|
779
785
|
}
|
|
780
786
|
else {
|
|
781
787
|
const attributesPath = (0, path_1.join)(childPath, `attributes/${folderName}/0`);
|
|
782
|
-
this.writeQueue.enqueue({
|
|
788
|
+
await this.writeQueue.enqueue({
|
|
783
789
|
writePromise: (0, file_utils_1.writeFile)(attributesPath, fileBuffer, 'index.bin')
|
|
784
790
|
});
|
|
785
791
|
}
|
|
@@ -819,7 +825,7 @@ class I3SConverter {
|
|
|
819
825
|
/**
|
|
820
826
|
* Generate storage attribute for map segmentation.
|
|
821
827
|
* @param attributeIndex - order index of attribute (f_0, f_1 ...).
|
|
822
|
-
* @param key - attribute key from
|
|
828
|
+
* @param key - attribute key from propertyTable.
|
|
823
829
|
* @param attributeType - attribute type.
|
|
824
830
|
* @return Updated storageAttribute.
|
|
825
831
|
*/
|
|
@@ -851,7 +857,7 @@ class I3SConverter {
|
|
|
851
857
|
/**
|
|
852
858
|
* Get the attribute type for attributeStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
|
|
853
859
|
* @param key - attribute's key
|
|
854
|
-
* @param attribute - attribute's type in
|
|
860
|
+
* @param attribute - attribute's type in propertyTable
|
|
855
861
|
*/
|
|
856
862
|
getAttributeType(key, attribute) {
|
|
857
863
|
if (key === OBJECT_ID_TYPE) {
|
|
@@ -915,22 +921,22 @@ class I3SConverter {
|
|
|
915
921
|
};
|
|
916
922
|
}
|
|
917
923
|
/**
|
|
918
|
-
* Do conversion of 3DTiles
|
|
919
|
-
* @param
|
|
924
|
+
* Do conversion of 3DTiles property table to I3s node attributes.
|
|
925
|
+
* @param propertyTable - Table with layer meta data.
|
|
920
926
|
*/
|
|
921
|
-
|
|
927
|
+
_convertPropertyTableToNodeAttributes(propertyTable) {
|
|
922
928
|
let attributeIndex = 0;
|
|
923
|
-
const
|
|
929
|
+
const propertyTableWithObjectId = {
|
|
924
930
|
OBJECTID: [0],
|
|
925
|
-
...
|
|
931
|
+
...propertyTable
|
|
926
932
|
};
|
|
927
|
-
for (const key in
|
|
928
|
-
const firstAttribute =
|
|
933
|
+
for (const key in propertyTableWithObjectId) {
|
|
934
|
+
const firstAttribute = propertyTableWithObjectId[key][0];
|
|
929
935
|
const attributeType = this.getAttributeType(key, firstAttribute);
|
|
930
936
|
const storageAttribute = this._createdStorageAttribute(attributeIndex, key, attributeType);
|
|
931
937
|
const fieldAttributeType = this._getFieldAttributeType(attributeType);
|
|
932
938
|
const fieldAttribute = this._createFieldAttribute(key, fieldAttributeType);
|
|
933
|
-
const popupInfo = this._createPopupInfo(
|
|
939
|
+
const popupInfo = this._createPopupInfo(propertyTableWithObjectId);
|
|
934
940
|
this.layers0.attributeStorageInfo.push(storageAttribute);
|
|
935
941
|
this.layers0.fields.push(fieldAttribute);
|
|
936
942
|
this.layers0.popupInfo = popupInfo;
|
|
@@ -939,7 +945,7 @@ class I3SConverter {
|
|
|
939
945
|
}
|
|
940
946
|
}
|
|
941
947
|
/**
|
|
942
|
-
* Find and return attribute type based on key form
|
|
948
|
+
* Find and return attribute type based on key form propertyTable.
|
|
943
949
|
* @param attributeType
|
|
944
950
|
*/
|
|
945
951
|
_getFieldAttributeType(attributeType) {
|
|
@@ -958,16 +964,16 @@ class I3SConverter {
|
|
|
958
964
|
}
|
|
959
965
|
/**
|
|
960
966
|
* Generate popup info to show metadata on the map.
|
|
961
|
-
* @param
|
|
967
|
+
* @param propertyTable - table data with OBJECTID.
|
|
962
968
|
* @return data for correct rendering of popup.
|
|
963
969
|
*/
|
|
964
|
-
_createPopupInfo(
|
|
970
|
+
_createPopupInfo(propertyTable) {
|
|
965
971
|
const title = '{OBJECTID}';
|
|
966
972
|
const mediaInfos = [];
|
|
967
973
|
const fieldInfos = [];
|
|
968
974
|
const popupElements = [];
|
|
969
975
|
const expressionInfos = [];
|
|
970
|
-
for (const key in
|
|
976
|
+
for (const key in propertyTable) {
|
|
971
977
|
fieldInfos.push({
|
|
972
978
|
fieldName: key,
|
|
973
979
|
visible: true,
|
|
@@ -111,52 +111,4 @@ export declare type I3SMaterialWithTexture = {
|
|
|
111
111
|
/** Texture content (image) */
|
|
112
112
|
texture?: ImageDataType;
|
|
113
113
|
};
|
|
114
|
-
/**
|
|
115
|
-
* 3DTilesNext EXT_feature_metadata extension
|
|
116
|
-
* Spec - https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata
|
|
117
|
-
*/
|
|
118
|
-
export declare type ExtFeatureMetadata = {
|
|
119
|
-
/** Feature ids definition in attributes */
|
|
120
|
-
featureIdAttributes?: ExtFeatureMetadataAttribute[];
|
|
121
|
-
/** Feature ids definition in textures */
|
|
122
|
-
featureIdTextures?: ExtFeatureMetadataAttribute[];
|
|
123
|
-
};
|
|
124
|
-
/**
|
|
125
|
-
* Attribute which described featureIds definition.
|
|
126
|
-
*/
|
|
127
|
-
export declare type ExtFeatureMetadataAttribute = {
|
|
128
|
-
/** Name of feature table */
|
|
129
|
-
featureTable: string;
|
|
130
|
-
/** Described how feature ids are defined */
|
|
131
|
-
featureIds: ExtFeatureMetadataFeatureIds;
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* Defining featureIds by attributes or implicitly.
|
|
135
|
-
*/
|
|
136
|
-
declare type ExtFeatureMetadataFeatureIds = {
|
|
137
|
-
/** Name of attribute where featureIds are defined */
|
|
138
|
-
attribute?: string;
|
|
139
|
-
/** Sets a constant feature ID for each vertex. The default is 0. */
|
|
140
|
-
constant?: number;
|
|
141
|
-
/** Sets the rate at which feature IDs increment.
|
|
142
|
-
* If divisor is zero then constant is used.
|
|
143
|
-
* If divisor is greater than zero the feature ID increments once per divisor sets of vertices, starting at constant.
|
|
144
|
-
* The default is 0
|
|
145
|
-
*/
|
|
146
|
-
divisor?: number;
|
|
147
|
-
/** gLTF textureInfo object - https://github.com/CesiumGS/glTF/blob/3d-tiles-next/specification/2.0/schema/textureInfo.schema.json */
|
|
148
|
-
texture?: ExtFeatureMetadataTexture;
|
|
149
|
-
/** Must be a single channel ("r", "g", "b", or "a") */
|
|
150
|
-
channels?: 'r' | 'g' | 'b' | 'a';
|
|
151
|
-
};
|
|
152
|
-
/**
|
|
153
|
-
* Reference to a texture.
|
|
154
|
-
*/
|
|
155
|
-
declare type ExtFeatureMetadataTexture = {
|
|
156
|
-
/** The set index of texture's TEXCOORD attribute used for texture coordinate mapping.*/
|
|
157
|
-
texCoord: number;
|
|
158
|
-
/** The index of the texture. */
|
|
159
|
-
index: number;
|
|
160
|
-
};
|
|
161
|
-
export {};
|
|
162
114
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/i3s-converter/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEjD,4CAA4C;AAC5C,oBAAY,qBAAqB,GAAG;IAClC;;;OAGG;IACH,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACjD;;OAEG;IACH,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;IACpB;;OAEG;IACH,eAAe,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC9C;;OAEG;IACH,YAAY,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC5C;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;OAEG;IACH,UAAU,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACjC;;OAEG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,oBAAY,mBAAmB,GAAG;IAChC,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,iCAAiC;IACjC,SAAS,EAAE,YAAY,CAAC;IACxB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAClC,iDAAiD;IACjD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;OAEG;IACH,eAAe,EAAE,IAAI,GAAG,eAAe,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,oBAAY,kBAAkB,GAAG;IAC/B,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,iCAAiC;IACjC,SAAS,EAAE,YAAY,CAAC;IACxB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,WAAW,CAAC;IACvB,kCAAkC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,8DAA8D;AAC9D,oBAAY,4BAA4B,GAAG;IACzC,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,iCAAiC;IACjC,SAAS,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF,+CAA+C;AAC/C,oBAAY,qBAAqB,GAAG;IAClC,oHAAoH;IACpH,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACnD,kHAAkH;IAClH,sBAAsB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACjD,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,2EAA2E;AAC3E,oBAAY,sBAAsB,GAAG;IACnC,2GAA2G;IAC3G,QAAQ,EAAE,qBAAqB,CAAC;IAChC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/i3s-converter/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEjD,4CAA4C;AAC5C,oBAAY,qBAAqB,GAAG;IAClC;;;OAGG;IACH,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACjD;;OAEG;IACH,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;IACpB;;OAEG;IACH,eAAe,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC9C;;OAEG;IACH,YAAY,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC5C;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;OAEG;IACH,UAAU,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACjC;;OAEG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,oBAAY,mBAAmB,GAAG;IAChC,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,iCAAiC;IACjC,SAAS,EAAE,YAAY,CAAC;IACxB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAClC,iDAAiD;IACjD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;OAEG;IACH,eAAe,EAAE,IAAI,GAAG,eAAe,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,oBAAY,kBAAkB,GAAG;IAC/B,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,iCAAiC;IACjC,SAAS,EAAE,YAAY,CAAC;IACxB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,WAAW,CAAC;IACvB,kCAAkC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,8DAA8D;AAC9D,oBAAY,4BAA4B,GAAG;IACzC,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,iCAAiC;IACjC,SAAS,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF,+CAA+C;AAC/C,oBAAY,qBAAqB,GAAG;IAClC,oHAAoH;IACpH,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACnD,kHAAkH;IAClH,sBAAsB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACjD,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,2EAA2E;AAC3E,oBAAY,sBAAsB,GAAG;IACnC,2GAA2G;IAC3G,QAAQ,EAAE,qBAAqB,CAAC;IAChC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC"}
|
|
@@ -12,6 +12,7 @@ export default class WriteQueue<T extends WriteQueueItem> extends Queue<T> {
|
|
|
12
12
|
listeningInterval: number;
|
|
13
13
|
writeConcurrency: number;
|
|
14
14
|
constructor(listeningInterval?: number, writeConcurrency?: number);
|
|
15
|
+
enqueue(val: T): Promise<void>;
|
|
15
16
|
startListening(): void;
|
|
16
17
|
stopListening(): void;
|
|
17
18
|
startWrite(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-queue.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/write-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"write-queue.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/write-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAM9B,oBAAY,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,KAAK,CAAC,CAAC,CAAC;IACxE,OAAO,CAAC,UAAU,CAAC,CAAiB;IAC7B,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAQ;IAC1C,OAAO,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAM;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;gBAEpB,iBAAiB,GAAE,MAAa,EAAE,gBAAgB,GAAE,MAAY;IAMtE,OAAO,CAAC,GAAG,EAAE,CAAC;IAQpB,cAAc;IAId,aAAa;IAMP,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAKjB,OAAO;IAmBrB,OAAO,CAAC,aAAa;CAWtB"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const queue_1 = require("./queue");
|
|
7
|
+
const process_1 = __importDefault(require("process"));
|
|
8
|
+
/** Memory limit size is based on testing */
|
|
9
|
+
const MEMORY_LIMIT = 4 * 1024 * 1024 * 1024; // 4GB
|
|
4
10
|
class WriteQueue extends queue_1.Queue {
|
|
5
11
|
constructor(listeningInterval = 2000, writeConcurrency = 400) {
|
|
6
12
|
super();
|
|
@@ -9,6 +15,13 @@ class WriteQueue extends queue_1.Queue {
|
|
|
9
15
|
this.listeningInterval = listeningInterval;
|
|
10
16
|
this.writeConcurrency = writeConcurrency;
|
|
11
17
|
}
|
|
18
|
+
async enqueue(val) {
|
|
19
|
+
super.enqueue(val);
|
|
20
|
+
/** https://nodejs.org/docs/latest-v14.x/api/process.html#process_process_memoryusage */
|
|
21
|
+
if (process_1.default.memoryUsage().rss > MEMORY_LIMIT) {
|
|
22
|
+
await this.startWrite();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
12
25
|
startListening() {
|
|
13
26
|
this.intervalId = setInterval(this.startWrite.bind(this), this.listeningInterval);
|
|
14
27
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/tile-converter",
|
|
3
|
-
"version": "3.3.0-alpha.
|
|
3
|
+
"version": "3.3.0-alpha.2",
|
|
4
4
|
"description": "Converter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -43,19 +43,19 @@
|
|
|
43
43
|
"build-3d-tiles-attributes-worker": "esbuild src/workers/3d-tiles-attributes-worker.ts --outfile=dist/3d-tiles-attributes-worker.js --platform=node --target=esnext,node12 --minify --bundle --sourcemap --define:__VERSION__=\\\"$npm_package_version\\\""
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@loaders.gl/3d-tiles": "3.3.0-alpha.
|
|
47
|
-
"@loaders.gl/crypto": "3.3.0-alpha.
|
|
48
|
-
"@loaders.gl/draco": "3.3.0-alpha.
|
|
49
|
-
"@loaders.gl/gltf": "3.3.0-alpha.
|
|
50
|
-
"@loaders.gl/i3s": "3.3.0-alpha.
|
|
51
|
-
"@loaders.gl/images": "3.3.0-alpha.
|
|
52
|
-
"@loaders.gl/loader-utils": "3.3.0-alpha.
|
|
53
|
-
"@loaders.gl/polyfills": "3.3.0-alpha.
|
|
54
|
-
"@loaders.gl/schema": "3.3.0-alpha.
|
|
55
|
-
"@loaders.gl/textures": "3.3.0-alpha.
|
|
56
|
-
"@loaders.gl/tiles": "3.3.0-alpha.
|
|
57
|
-
"@loaders.gl/worker-utils": "3.3.0-alpha.
|
|
58
|
-
"@loaders.gl/zip": "3.3.0-alpha.
|
|
46
|
+
"@loaders.gl/3d-tiles": "3.3.0-alpha.2",
|
|
47
|
+
"@loaders.gl/crypto": "3.3.0-alpha.2",
|
|
48
|
+
"@loaders.gl/draco": "3.3.0-alpha.2",
|
|
49
|
+
"@loaders.gl/gltf": "3.3.0-alpha.2",
|
|
50
|
+
"@loaders.gl/i3s": "3.3.0-alpha.2",
|
|
51
|
+
"@loaders.gl/images": "3.3.0-alpha.2",
|
|
52
|
+
"@loaders.gl/loader-utils": "3.3.0-alpha.2",
|
|
53
|
+
"@loaders.gl/polyfills": "3.3.0-alpha.2",
|
|
54
|
+
"@loaders.gl/schema": "3.3.0-alpha.2",
|
|
55
|
+
"@loaders.gl/textures": "3.3.0-alpha.2",
|
|
56
|
+
"@loaders.gl/tiles": "3.3.0-alpha.2",
|
|
57
|
+
"@loaders.gl/worker-utils": "3.3.0-alpha.2",
|
|
58
|
+
"@loaders.gl/zip": "3.3.0-alpha.2",
|
|
59
59
|
"@luma.gl/engine": "^8.5.4",
|
|
60
60
|
"@math.gl/core": "^3.5.1",
|
|
61
61
|
"@math.gl/culling": "^3.5.1",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"@loaders.gl/core": "^3.2.0"
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "628f1f0eed0f14b50ccff4c561023acf6e0657e6"
|
|
79
79
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type {GLTFAccessorPostprocessed} from 'modules/gltf/src/lib/types/gltf-types';
|
|
2
2
|
import type {Image, MeshPrimitive} from 'modules/gltf/src/lib/types/gltf-postprocessed-schema';
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
GLTF_EXT_feature_metadata_attribute,
|
|
5
|
+
GLTF_EXT_feature_metadata_primitive
|
|
6
|
+
} from 'modules/gltf/src/lib/types/gltf-json-schema';
|
|
4
7
|
|
|
5
8
|
const EXT_MESH_FEATURES = 'EXT_mesh_features';
|
|
6
9
|
const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
|
|
@@ -29,7 +32,7 @@ export function handleBatchIdsExtensions(
|
|
|
29
32
|
case EXT_FEATURE_METADATA:
|
|
30
33
|
return handleExtFeatureMetadataExtension(
|
|
31
34
|
attributes,
|
|
32
|
-
extensionData as
|
|
35
|
+
extensionData as GLTF_EXT_feature_metadata_primitive,
|
|
33
36
|
images
|
|
34
37
|
);
|
|
35
38
|
case EXT_MESH_FEATURES:
|
|
@@ -54,7 +57,7 @@ function handleExtFeatureMetadataExtension(
|
|
|
54
57
|
attributes: {
|
|
55
58
|
[key: string]: GLTFAccessorPostprocessed;
|
|
56
59
|
},
|
|
57
|
-
extFeatureMetadata:
|
|
60
|
+
extFeatureMetadata: GLTF_EXT_feature_metadata_primitive,
|
|
58
61
|
images: Image[]
|
|
59
62
|
): number[] {
|
|
60
63
|
// Take only first extension object to get batchIds attribute name.
|
|
@@ -82,10 +85,24 @@ function handleExtFeatureMetadataExtension(
|
|
|
82
85
|
extFeatureMetadata?.featureIdTextures && extFeatureMetadata?.featureIdTextures[0];
|
|
83
86
|
|
|
84
87
|
if (featureIdTexture) {
|
|
85
|
-
const
|
|
88
|
+
const textureAttributeIndex = featureIdTexture?.featureIds?.texture?.texCoord || 0;
|
|
89
|
+
const textCoordAttribute = `TEXCOORD_${textureAttributeIndex}`;
|
|
90
|
+
const textureCoordinates = attributes[textCoordAttribute].value;
|
|
86
91
|
return generateBatchIdsFromTexture(featureIdTexture, textureCoordinates, images);
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
// Take only first extension texture to get batchIds from the root EXT_feature_metadata object.
|
|
95
|
+
const featureTexture =
|
|
96
|
+
extFeatureMetadata?.featureTextures && extFeatureMetadata?.featureTextures[0];
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* TODO need to get batchIds from root extension
|
|
100
|
+
*/
|
|
101
|
+
if (featureTexture) {
|
|
102
|
+
console.warn("EXT_feature_metadata doesn't yet support featureTextures in primitive");
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
return [];
|
|
90
107
|
}
|
|
91
108
|
|
|
@@ -130,7 +147,7 @@ function generateImplicitFeatureIds(
|
|
|
130
147
|
* @param featureIdTextures
|
|
131
148
|
*/
|
|
132
149
|
function generateBatchIdsFromTexture(
|
|
133
|
-
featureIdTexture:
|
|
150
|
+
featureIdTexture: GLTF_EXT_feature_metadata_attribute,
|
|
134
151
|
textureCoordinates: Float32Array,
|
|
135
152
|
images: Image[]
|
|
136
153
|
) {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type {FeatureTableJson} from '@loaders.gl/3d-tiles';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Takes attributes from property table based on featureIds.
|
|
5
|
+
* If there is no property value for particular featureId (index) the property will be null.
|
|
6
|
+
* Example:
|
|
7
|
+
* Initial data:
|
|
8
|
+
* OBJECTID: [0, 1, 5]
|
|
9
|
+
* component: ['Windows', 'Frames', 'Wall', 'Roof', 'Skylight']
|
|
10
|
+
* Result:
|
|
11
|
+
* OBJECTID: [0, 1, 5]
|
|
12
|
+
* component: ['Windows', 'Frames', 'null']
|
|
13
|
+
* @param featureIds
|
|
14
|
+
* @param propertyTable
|
|
15
|
+
*/
|
|
16
|
+
export function flattenPropertyTableByFeatureIds(
|
|
17
|
+
featureIds: number[],
|
|
18
|
+
propertyTable: FeatureTableJson
|
|
19
|
+
): FeatureTableJson {
|
|
20
|
+
const resultPropertyTable: FeatureTableJson = {};
|
|
21
|
+
for (const propertyName in propertyTable) {
|
|
22
|
+
const properties = propertyTable[propertyName];
|
|
23
|
+
resultPropertyTable[propertyName] = getPropertiesByFeatureIds(properties, featureIds);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return resultPropertyTable;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Getting properties by featureId index
|
|
31
|
+
* @param properties
|
|
32
|
+
* @param featureIds
|
|
33
|
+
*/
|
|
34
|
+
function getPropertiesByFeatureIds(properties: any[], featureIds: number[]): any[] {
|
|
35
|
+
const resultProperties: any = [];
|
|
36
|
+
|
|
37
|
+
for (const featureId of featureIds) {
|
|
38
|
+
const property = properties[featureId] || null;
|
|
39
|
+
resultProperties.push(property);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return resultProperties;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check that all attributes in propertyTable have the same length as FeatureIds.
|
|
47
|
+
* If there are differencies between lengths we should flatten property table based on exiesting featureIds.
|
|
48
|
+
* @param featureIds
|
|
49
|
+
* @param propertyTable
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
export function checkPropertiesLength(
|
|
53
|
+
featureIds: number[],
|
|
54
|
+
propertyTable: FeatureTableJson
|
|
55
|
+
): boolean {
|
|
56
|
+
let needFlatten = false;
|
|
57
|
+
|
|
58
|
+
for (const attribute of Object.values(propertyTable)) {
|
|
59
|
+
if (featureIds.length !== attribute.length) {
|
|
60
|
+
needFlatten = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return needFlatten;
|
|
65
|
+
}
|
|
@@ -47,7 +47,7 @@ function calculateFaceRangesAndFeaturesCount(featureIndices: number[]): {
|
|
|
47
47
|
} {
|
|
48
48
|
let rangeIndex = 1;
|
|
49
49
|
let featureIndex = 1;
|
|
50
|
-
let currentFeatureId = featureIndices
|
|
50
|
+
let currentFeatureId = getFrequentValue(featureIndices.slice(0, VALUES_PER_VERTEX));
|
|
51
51
|
const faceRangeList: any[] = [];
|
|
52
52
|
const featureIds: any[] = [];
|
|
53
53
|
const uniqueFeatureIds = [currentFeatureId];
|
|
@@ -55,20 +55,21 @@ function calculateFaceRangesAndFeaturesCount(featureIndices: number[]): {
|
|
|
55
55
|
faceRangeList[0] = 0;
|
|
56
56
|
featureIds[0] = currentFeatureId;
|
|
57
57
|
|
|
58
|
-
for (let index =
|
|
59
|
-
|
|
58
|
+
for (let index = VALUES_PER_VERTEX; index < featureIndices.length; index += VALUES_PER_VERTEX) {
|
|
59
|
+
const newFeatureId = getFrequentValue(featureIndices.slice(index, index + VALUES_PER_VERTEX));
|
|
60
|
+
if (currentFeatureId !== newFeatureId) {
|
|
60
61
|
faceRangeList[rangeIndex] = index / VALUES_PER_VERTEX - 1;
|
|
61
62
|
faceRangeList[rangeIndex + 1] = index / VALUES_PER_VERTEX;
|
|
62
|
-
featureIds[featureIndex] =
|
|
63
|
+
featureIds[featureIndex] = newFeatureId;
|
|
63
64
|
|
|
64
|
-
if (!uniqueFeatureIds.includes(
|
|
65
|
-
uniqueFeatureIds.push(
|
|
65
|
+
if (!uniqueFeatureIds.includes(newFeatureId)) {
|
|
66
|
+
uniqueFeatureIds.push(newFeatureId);
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
rangeIndex += 2;
|
|
69
70
|
featureIndex += 1;
|
|
70
71
|
}
|
|
71
|
-
currentFeatureId =
|
|
72
|
+
currentFeatureId = newFeatureId;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
faceRangeList[rangeIndex] = featureIndices.length / VALUES_PER_VERTEX - 1;
|
|
@@ -79,6 +80,28 @@ function calculateFaceRangesAndFeaturesCount(featureIndices: number[]): {
|
|
|
79
80
|
return {faceRange, featureCount, featureIds};
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Find most frequent value to avoid situation where one vertex can be part of multiple features (objects).
|
|
85
|
+
* @param values
|
|
86
|
+
*/
|
|
87
|
+
function getFrequentValue(values: number[]): number {
|
|
88
|
+
const map: {[key: number]: number} = {};
|
|
89
|
+
|
|
90
|
+
let mostFrequentValue = values[0];
|
|
91
|
+
let maxCount = 1;
|
|
92
|
+
|
|
93
|
+
for (const value of values) {
|
|
94
|
+
// Save item and it's frequency count to the map.
|
|
95
|
+
map[value] = (map[value] || 0) + 1;
|
|
96
|
+
// Find max count of frequency.
|
|
97
|
+
maxCount = maxCount > map[value] ? maxCount : map[value];
|
|
98
|
+
// Find the most frequent value.
|
|
99
|
+
mostFrequentValue = maxCount > map[value] ? mostFrequentValue : value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return mostFrequentValue;
|
|
103
|
+
}
|
|
104
|
+
|
|
82
105
|
/**
|
|
83
106
|
* Generate list of attribute object grouped by feature ids.
|
|
84
107
|
* @param attributes
|