@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.
Files changed (67) hide show
  1. package/dist/3d-tiles-attributes-worker.js +3 -3
  2. package/dist/3d-tiles-attributes-worker.js.map +1 -1
  3. package/dist/converter.min.js +10 -10
  4. package/dist/dist.min.js +791 -554
  5. package/dist/es5/3d-tiles-attributes-worker.js +1 -1
  6. package/dist/es5/i3s-attributes-worker.js +1 -1
  7. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +15 -4
  8. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  9. package/dist/es5/i3s-converter/helpers/feature-attributes.js +60 -0
  10. package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -0
  11. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +39 -7
  12. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  13. package/dist/es5/i3s-converter/helpers/geometry-converter.js +161 -49
  14. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  15. package/dist/es5/i3s-converter/helpers/node-pages.js +102 -46
  16. package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
  17. package/dist/es5/i3s-converter/i3s-converter.js +235 -141
  18. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  19. package/dist/es5/lib/utils/write-queue.js +66 -28
  20. package/dist/es5/lib/utils/write-queue.js.map +1 -1
  21. package/dist/es5/pgm-loader.js +1 -1
  22. package/dist/esm/3d-tiles-attributes-worker.js +1 -1
  23. package/dist/esm/i3s-attributes-worker.js +1 -1
  24. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +15 -4
  25. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  26. package/dist/esm/i3s-converter/helpers/feature-attributes.js +34 -0
  27. package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -0
  28. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +23 -7
  29. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  30. package/dist/esm/i3s-converter/helpers/geometry-converter.js +132 -30
  31. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  32. package/dist/esm/i3s-converter/helpers/node-pages.js +3 -3
  33. package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
  34. package/dist/esm/i3s-converter/i3s-converter.js +32 -42
  35. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  36. package/dist/esm/lib/utils/write-queue.js +10 -0
  37. package/dist/esm/lib/utils/write-queue.js.map +1 -1
  38. package/dist/esm/pgm-loader.js +1 -1
  39. package/dist/i3s-attributes-worker.js +3 -3
  40. package/dist/i3s-attributes-worker.js.map +2 -2
  41. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
  42. package/dist/i3s-converter/helpers/batch-ids-extensions.js +12 -1
  43. package/dist/i3s-converter/helpers/feature-attributes.d.ts +24 -0
  44. package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -0
  45. package/dist/i3s-converter/helpers/feature-attributes.js +55 -0
  46. package/dist/i3s-converter/helpers/geometry-attributes.js +26 -7
  47. package/dist/i3s-converter/helpers/geometry-converter.d.ts +9 -2
  48. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  49. package/dist/i3s-converter/helpers/geometry-converter.js +124 -33
  50. package/dist/i3s-converter/helpers/node-pages.js +3 -3
  51. package/dist/i3s-converter/i3s-converter.d.ts +7 -14
  52. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  53. package/dist/i3s-converter/i3s-converter.js +56 -50
  54. package/dist/i3s-converter/types.d.ts +0 -48
  55. package/dist/i3s-converter/types.d.ts.map +1 -1
  56. package/dist/lib/utils/write-queue.d.ts +1 -0
  57. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  58. package/dist/lib/utils/write-queue.js +13 -0
  59. package/package.json +15 -15
  60. package/src/i3s-converter/helpers/batch-ids-extensions.ts +22 -5
  61. package/src/i3s-converter/helpers/feature-attributes.ts +65 -0
  62. package/src/i3s-converter/helpers/geometry-attributes.ts +30 -7
  63. package/src/i3s-converter/helpers/geometry-converter.ts +161 -37
  64. package/src/i3s-converter/helpers/node-pages.ts +3 -3
  65. package/src/i3s-converter/i3s-converter.ts +41 -51
  66. package/src/i3s-converter/types.ts +0 -51
  67. package/src/lib/utils/write-queue.ts +12 -0
@@ -1 +1 @@
1
- {"version":3,"file":"batch-ids-extensions.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/batch-ids-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,uCAAuC,CAAC;AACrF,OAAO,KAAK,EAAC,KAAK,EAAE,aAAa,EAAC,MAAM,sDAAsD,CAAC;AAM/F;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAAC;CAC1C,EACD,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,KAAK,EAAE,GACd,MAAM,EAAE,CAwBV"}
1
+ {"version":3,"file":"batch-ids-extensions.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/batch-ids-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,uCAAuC,CAAC;AACrF,OAAO,KAAK,EAAC,KAAK,EAAE,aAAa,EAAC,MAAM,sDAAsD,CAAC;AAS/F;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAAC;CAC1C,EACD,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,KAAK,EAAE,GACd,MAAM,EAAE,CAwBV"}
@@ -50,9 +50,20 @@ function handleExtFeatureMetadataExtension(attributes, extFeatureMetadata, image
50
50
  // Take only first extension object to get batchIds attribute name.
51
51
  const featureIdTexture = extFeatureMetadata?.featureIdTextures && extFeatureMetadata?.featureIdTextures[0];
52
52
  if (featureIdTexture) {
53
- const textureCoordinates = attributes.TEXCOORD_0.value;
53
+ const textureAttributeIndex = featureIdTexture?.featureIds?.texture?.texCoord || 0;
54
+ const textCoordAttribute = `TEXCOORD_${textureAttributeIndex}`;
55
+ const textureCoordinates = attributes[textCoordAttribute].value;
54
56
  return generateBatchIdsFromTexture(featureIdTexture, textureCoordinates, images);
55
57
  }
58
+ // Take only first extension texture to get batchIds from the root EXT_feature_metadata object.
59
+ const featureTexture = extFeatureMetadata?.featureTextures && extFeatureMetadata?.featureTextures[0];
60
+ /**
61
+ * TODO need to get batchIds from root extension
62
+ */
63
+ if (featureTexture) {
64
+ console.warn("EXT_feature_metadata doesn't yet support featureTextures in primitive");
65
+ return [];
66
+ }
56
67
  return [];
57
68
  }
58
69
  /**
@@ -0,0 +1,24 @@
1
+ import type { FeatureTableJson } from '@loaders.gl/3d-tiles';
2
+ /**
3
+ * Takes attributes from property table based on featureIds.
4
+ * If there is no property value for particular featureId (index) the property will be null.
5
+ * Example:
6
+ * Initial data:
7
+ * OBJECTID: [0, 1, 5]
8
+ * component: ['Windows', 'Frames', 'Wall', 'Roof', 'Skylight']
9
+ * Result:
10
+ * OBJECTID: [0, 1, 5]
11
+ * component: ['Windows', 'Frames', 'null']
12
+ * @param featureIds
13
+ * @param propertyTable
14
+ */
15
+ export declare function flattenPropertyTableByFeatureIds(featureIds: number[], propertyTable: FeatureTableJson): FeatureTableJson;
16
+ /**
17
+ * Check that all attributes in propertyTable have the same length as FeatureIds.
18
+ * If there are differencies between lengths we should flatten property table based on exiesting featureIds.
19
+ * @param featureIds
20
+ * @param propertyTable
21
+ * @returns
22
+ */
23
+ export declare function checkPropertiesLength(featureIds: number[], propertyTable: FeatureTableJson): boolean;
24
+ //# sourceMappingURL=feature-attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/feature-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,EAAE,gBAAgB,GAC9B,gBAAgB,CAQlB;AAkBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,EAAE,gBAAgB,GAC9B,OAAO,CAUT"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkPropertiesLength = exports.flattenPropertyTableByFeatureIds = void 0;
4
+ /**
5
+ * Takes attributes from property table based on featureIds.
6
+ * If there is no property value for particular featureId (index) the property will be null.
7
+ * Example:
8
+ * Initial data:
9
+ * OBJECTID: [0, 1, 5]
10
+ * component: ['Windows', 'Frames', 'Wall', 'Roof', 'Skylight']
11
+ * Result:
12
+ * OBJECTID: [0, 1, 5]
13
+ * component: ['Windows', 'Frames', 'null']
14
+ * @param featureIds
15
+ * @param propertyTable
16
+ */
17
+ function flattenPropertyTableByFeatureIds(featureIds, propertyTable) {
18
+ const resultPropertyTable = {};
19
+ for (const propertyName in propertyTable) {
20
+ const properties = propertyTable[propertyName];
21
+ resultPropertyTable[propertyName] = getPropertiesByFeatureIds(properties, featureIds);
22
+ }
23
+ return resultPropertyTable;
24
+ }
25
+ exports.flattenPropertyTableByFeatureIds = flattenPropertyTableByFeatureIds;
26
+ /**
27
+ * Getting properties by featureId index
28
+ * @param properties
29
+ * @param featureIds
30
+ */
31
+ function getPropertiesByFeatureIds(properties, featureIds) {
32
+ const resultProperties = [];
33
+ for (const featureId of featureIds) {
34
+ const property = properties[featureId] || null;
35
+ resultProperties.push(property);
36
+ }
37
+ return resultProperties;
38
+ }
39
+ /**
40
+ * Check that all attributes in propertyTable have the same length as FeatureIds.
41
+ * If there are differencies between lengths we should flatten property table based on exiesting featureIds.
42
+ * @param featureIds
43
+ * @param propertyTable
44
+ * @returns
45
+ */
46
+ function checkPropertiesLength(featureIds, propertyTable) {
47
+ let needFlatten = false;
48
+ for (const attribute of Object.values(propertyTable)) {
49
+ if (featureIds.length !== attribute.length) {
50
+ needFlatten = true;
51
+ }
52
+ }
53
+ return needFlatten;
54
+ }
55
+ exports.checkPropertiesLength = checkPropertiesLength;
@@ -38,30 +38,49 @@ exports.generateAttributes = generateAttributes;
38
38
  function calculateFaceRangesAndFeaturesCount(featureIndices) {
39
39
  let rangeIndex = 1;
40
40
  let featureIndex = 1;
41
- let currentFeatureId = featureIndices[0];
41
+ let currentFeatureId = getFrequentValue(featureIndices.slice(0, VALUES_PER_VERTEX));
42
42
  const faceRangeList = [];
43
43
  const featureIds = [];
44
44
  const uniqueFeatureIds = [currentFeatureId];
45
45
  faceRangeList[0] = 0;
46
46
  featureIds[0] = currentFeatureId;
47
- for (let index = 1; index < featureIndices.length; index++) {
48
- if (currentFeatureId !== featureIndices[index]) {
47
+ for (let index = VALUES_PER_VERTEX; index < featureIndices.length; index += VALUES_PER_VERTEX) {
48
+ const newFeatureId = getFrequentValue(featureIndices.slice(index, index + VALUES_PER_VERTEX));
49
+ if (currentFeatureId !== newFeatureId) {
49
50
  faceRangeList[rangeIndex] = index / VALUES_PER_VERTEX - 1;
50
51
  faceRangeList[rangeIndex + 1] = index / VALUES_PER_VERTEX;
51
- featureIds[featureIndex] = featureIndices[index];
52
- if (!uniqueFeatureIds.includes(featureIndices[index])) {
53
- uniqueFeatureIds.push(featureIndices[index]);
52
+ featureIds[featureIndex] = newFeatureId;
53
+ if (!uniqueFeatureIds.includes(newFeatureId)) {
54
+ uniqueFeatureIds.push(newFeatureId);
54
55
  }
55
56
  rangeIndex += 2;
56
57
  featureIndex += 1;
57
58
  }
58
- currentFeatureId = featureIndices[index];
59
+ currentFeatureId = newFeatureId;
59
60
  }
60
61
  faceRangeList[rangeIndex] = featureIndices.length / VALUES_PER_VERTEX - 1;
61
62
  const faceRange = new Uint32Array(faceRangeList);
62
63
  const featureCount = uniqueFeatureIds.length;
63
64
  return { faceRange, featureCount, featureIds };
64
65
  }
66
+ /**
67
+ * Find most frequent value to avoid situation where one vertex can be part of multiple features (objects).
68
+ * @param values
69
+ */
70
+ function getFrequentValue(values) {
71
+ const map = {};
72
+ let mostFrequentValue = values[0];
73
+ let maxCount = 1;
74
+ for (const value of values) {
75
+ // Save item and it's frequency count to the map.
76
+ map[value] = (map[value] || 0) + 1;
77
+ // Find max count of frequency.
78
+ maxCount = maxCount > map[value] ? maxCount : map[value];
79
+ // Find the most frequent value.
80
+ mostFrequentValue = maxCount > map[value] ? mostFrequentValue : value;
81
+ }
82
+ return mostFrequentValue;
83
+ }
65
84
  /**
66
85
  * Generate list of attribute object grouped by feature ids.
67
86
  * @param attributes
@@ -1,5 +1,6 @@
1
+ import type { B3DMContent, FeatureTableJson } from '@loaders.gl/3d-tiles';
2
+ import { Tile3D } from '@loaders.gl/tiles';
1
3
  import { ConvertedAttributes, I3SConvertedResources } from '../types';
2
- import { B3DMContent } from '@loaders.gl/3d-tiles';
3
4
  import { AttributeStorageInfo } from '@loaders.gl/i3s';
4
5
  import { Geoid } from '@math.gl/geoid';
5
6
  import { B3DMAttributesData } from '../../i3s-attributes-worker';
@@ -15,7 +16,7 @@ import { B3DMAttributesData } from '../../i3s-attributes-worker';
15
16
  * @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
16
17
  * @returns Array of node resources to create one or more i3s nodes
17
18
  */
18
- export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, nodeId: number, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, geoidHeightModel: Geoid, workerSource: {
19
+ export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, nodeId: number, propertyTable: FeatureTableJson | null, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, geoidHeightModel: Geoid, workerSource: {
19
20
  [key: string]: string;
20
21
  }): Promise<I3SConvertedResources[] | null>;
21
22
  /**
@@ -26,4 +27,10 @@ export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, nodeI
26
27
  * @returns map of converted geometry attributes
27
28
  */
28
29
  export declare function convertAttributes(attributesData: B3DMAttributesData, useCartesianPositions: boolean): Promise<Map<string, ConvertedAttributes>>;
30
+ /**
31
+ * Find property table in tile
32
+ * For example it can be batchTable for b3dm files or property table in gLTF extension.
33
+ * @param sourceTile
34
+ */
35
+ export declare function getPropertyTable(sourceTile: Tile3D): FeatureTableJson | null;
29
36
  //# sourceMappingURL=geometry-converter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAGtB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EACL,oBAAoB,EAIrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAMrC,OAAO,EAAC,kBAAkB,EAAqC,MAAM,6BAA6B,CAAC;AAyBnG;;;;;;;;;;;GAWG;AACH,wBAA8B,wBAAwB,CACpD,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EAAE,EAC3B,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,SAAS,EACxD,KAAK,EAAE,OAAO,EACd,uBAAuB,EAAE,OAAO,EAChC,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,2CAoEtC;AAiID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,kBAAkB,EAClC,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CA0C3C"}
1
+ {"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAQxE,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAKzC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAGtB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,oBAAoB,EAIrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAMrC,OAAO,EAAC,kBAAkB,EAAqC,MAAM,6BAA6B,CAAC;AA6BnG;;;;;;;;;;;GAWG;AACH,wBAA8B,wBAAwB,CACpD,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,gBAAgB,GAAG,IAAI,EACtC,iBAAiB,EAAE,MAAM,EAAE,EAC3B,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,SAAS,EACxD,KAAK,EAAE,OAAO,EACd,uBAAuB,EAAE,OAAO,EAChC,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,2CAqEtC;AAuID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,kBAAkB,EAClC,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CA0C3C;AAu7BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAoB5E"}
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.convertAttributes = void 0;
6
+ exports.getPropertyTable = exports.convertAttributes = void 0;
7
7
  const core_1 = require("@math.gl/core");
8
8
  const geospatial_1 = require("@math.gl/geospatial");
9
9
  const draco_1 = require("@loaders.gl/draco");
@@ -14,6 +14,7 @@ const geometry_attributes_1 = require("./geometry-attributes");
14
14
  const coordinate_converter_1 = require("./coordinate-converter");
15
15
  const gltf_attributes_1 = require("./gltf-attributes");
16
16
  const batch_ids_extensions_1 = require("./batch-ids-extensions");
17
+ const feature_attributes_1 = require("./feature-attributes");
17
18
  // Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
18
19
  const DEFAULT_ROUGHNESS_FACTOR = 1;
19
20
  const DEFAULT_METALLIC_FACTOR = 1;
@@ -30,6 +31,8 @@ const OBJECT_ID_TYPE = 'Oid32';
30
31
  * BATCHID - Legacy attribute name which includes batch info.
31
32
  */
32
33
  const BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES = ['CUSTOM_ATTRIBUTE_2', '_BATCHID', 'BATCHID'];
34
+ const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
35
+ const EXT_MESH_FEATURES = 'EXT_mesh_features';
33
36
  let scratchVector = new core_1.Vector3();
34
37
  /**
35
38
  * Convert binary data from b3dm file to i3s resources
@@ -43,7 +46,7 @@ let scratchVector = new core_1.Vector3();
43
46
  * @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
44
47
  * @returns Array of node resources to create one or more i3s nodes
45
48
  */
46
- async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
49
+ async function convertB3dmToI3sGeometry(tileContent, nodeId, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
47
50
  const useCartesianPositions = generateBoundingVolumes;
48
51
  const materialAndTextureList = convertMaterials(tileContent.gltf?.materials);
49
52
  const dataForAttributesConversion = (0, gltf_attributes_1.prepareDataForAttributesConversion)(tileContent);
@@ -87,6 +90,7 @@ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray,
87
90
  tileContent,
88
91
  nodeId: nodesCounter,
89
92
  featuresHashArray,
93
+ propertyTable,
90
94
  attributeStorageInfo,
91
95
  draco,
92
96
  workerSource
@@ -132,7 +136,7 @@ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeigh
132
136
  * @param params.draco - is converter should create draco compressed geometry
133
137
  * @returns Array of I3S node resources
134
138
  */
135
- async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, workerSource }) {
139
+ async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, propertyTable, attributeStorageInfo, draco, workerSource }) {
136
140
  const boundingVolumes = convertedAttributes.boundingVolumes;
137
141
  const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
138
142
  const { faceRange, featureIds, positions, normals, colors, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
@@ -153,7 +157,10 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
153
157
  faceRange
154
158
  }, workerSource.draco)
155
159
  : null;
156
- const attributes = convertBatchTableToAttributeBuffers(tileContent.batchTableJson, featureIds, attributeStorageInfo);
160
+ let attributes = [];
161
+ if (attributeStorageInfo && propertyTable) {
162
+ attributes = convertPropertyTableToAttributeBuffers(featureIds, propertyTable, attributeStorageInfo);
163
+ }
157
164
  return {
158
165
  geometry: fileBuffer,
159
166
  compressedGeometry,
@@ -743,43 +750,53 @@ function replaceIndicesByUnique(indicesArray, featureMap) {
743
750
  }
744
751
  }
745
752
  /**
746
- * Convert batch table data to attribute buffers.
747
- * @param {Object} batchTable - table with metadata for particular feature.
753
+ * Convert property table data to attribute buffers.
754
+ * @param {Object} propertyTable - table with metadata for particular feature.
748
755
  * @param {Array} featureIds
749
756
  * @param {Array} attributeStorageInfo
750
757
  * @returns {Array} - Array of file buffers.
751
758
  */
752
- function convertBatchTableToAttributeBuffers(batchTable, featureIds, attributeStorageInfo) {
759
+ function convertPropertyTableToAttributeBuffers(featureIds, propertyTable, attributeStorageInfo) {
753
760
  const attributeBuffers = [];
754
- if (batchTable) {
755
- const batchTableWithFeatureIds = {
756
- OBJECTID: featureIds,
757
- ...batchTable
758
- };
759
- for (const key in batchTableWithFeatureIds) {
760
- const type = getAttributeType(key, attributeStorageInfo);
761
- let attributeBuffer = null;
762
- switch (type) {
763
- case OBJECT_ID_TYPE:
764
- case SHORT_INT_TYPE:
765
- attributeBuffer = generateShortIntegerAttributeBuffer(batchTableWithFeatureIds[key]);
766
- break;
767
- case DOUBLE_TYPE:
768
- attributeBuffer = generateDoubleAttributeBuffer(batchTableWithFeatureIds[key]);
769
- break;
770
- case STRING_TYPE:
771
- attributeBuffer = generateStringAttributeBuffer(batchTableWithFeatureIds[key]);
772
- break;
773
- default:
774
- attributeBuffer = generateStringAttributeBuffer(batchTableWithFeatureIds[key]);
775
- }
776
- if (attributeBuffer) {
777
- attributeBuffers.push(attributeBuffer);
778
- }
779
- }
761
+ const needFlattenPropertyTable = (0, feature_attributes_1.checkPropertiesLength)(featureIds, propertyTable);
762
+ const properties = needFlattenPropertyTable
763
+ ? (0, feature_attributes_1.flattenPropertyTableByFeatureIds)(featureIds, propertyTable)
764
+ : propertyTable;
765
+ const propertyTableWithObjectIds = {
766
+ OBJECTID: featureIds,
767
+ ...properties
768
+ };
769
+ for (const propertyName in propertyTableWithObjectIds) {
770
+ const type = getAttributeType(propertyName, attributeStorageInfo);
771
+ const value = propertyTableWithObjectIds[propertyName];
772
+ const attributeBuffer = generateAttributeBuffer(type, value);
773
+ attributeBuffers.push(attributeBuffer);
780
774
  }
781
775
  return attributeBuffers;
782
776
  }
777
+ /**
778
+ * Generates attribute buffer based on attribute type
779
+ * @param type
780
+ * @param value
781
+ */
782
+ function generateAttributeBuffer(type, value) {
783
+ let attributeBuffer;
784
+ switch (type) {
785
+ case OBJECT_ID_TYPE:
786
+ case SHORT_INT_TYPE:
787
+ attributeBuffer = generateShortIntegerAttributeBuffer(value);
788
+ break;
789
+ case DOUBLE_TYPE:
790
+ attributeBuffer = generateDoubleAttributeBuffer(value);
791
+ break;
792
+ case STRING_TYPE:
793
+ attributeBuffer = generateStringAttributeBuffer(value);
794
+ break;
795
+ default:
796
+ attributeBuffer = generateStringAttributeBuffer(value);
797
+ }
798
+ return attributeBuffer;
799
+ }
783
800
  /**
784
801
  * Return attribute type.
785
802
  * @param {String} key
@@ -904,3 +921,77 @@ function generateFeatureIndexAttribute(featureIndex, faceRange) {
904
921
  }
905
922
  return orderedFeatureIndices;
906
923
  }
924
+ /**
925
+ * Find property table in tile
926
+ * For example it can be batchTable for b3dm files or property table in gLTF extension.
927
+ * @param sourceTile
928
+ */
929
+ function getPropertyTable(sourceTile) {
930
+ const batchTableJson = sourceTile?.content?.batchTableJson;
931
+ if (batchTableJson) {
932
+ return batchTableJson;
933
+ }
934
+ const { extensionName, extension } = getPropertyTableExtension(sourceTile);
935
+ switch (extensionName) {
936
+ case EXT_MESH_FEATURES: {
937
+ console.warn('The I3S converter does not yet support the EXT_mesh_features extension');
938
+ return null;
939
+ }
940
+ case EXT_FEATURE_METADATA: {
941
+ return getPropertyTableFromExtFeatureMetadata(extension);
942
+ }
943
+ default:
944
+ return null;
945
+ }
946
+ }
947
+ exports.getPropertyTable = getPropertyTable;
948
+ /**
949
+ * Check extensions which can be with property table inside.
950
+ * @param sourceTile
951
+ */
952
+ function getPropertyTableExtension(sourceTile) {
953
+ const extensionsWithPropertyTables = [EXT_FEATURE_METADATA, EXT_MESH_FEATURES];
954
+ const extensionsUsed = sourceTile?.content?.gltf?.extensionsUsed;
955
+ if (!extensionsUsed) {
956
+ return { extensionName: null, extension: null };
957
+ }
958
+ let extensionName = '';
959
+ for (const extensionItem of sourceTile?.content?.gltf?.extensionsUsed) {
960
+ if (extensionsWithPropertyTables.includes(extensionItem)) {
961
+ extensionName = extensionItem;
962
+ break;
963
+ }
964
+ }
965
+ const extension = sourceTile?.content?.gltf?.extensions?.[extensionName];
966
+ return { extensionName, extension };
967
+ }
968
+ /**
969
+ * Handle EXT_feature_metadata to get property table
970
+ * @param extension
971
+ * TODO add EXT_feature_metadata feature textures support.
972
+ */
973
+ function getPropertyTableFromExtFeatureMetadata(extension) {
974
+ if (extension?.featureTextures) {
975
+ console.warn('The I3S converter does not yet support the EXT_feature_metadata feature textures');
976
+ return null;
977
+ }
978
+ if (extension?.featureTables) {
979
+ /**
980
+ * Take only first feature table to generate attributes storage info object.
981
+ * TODO: Think about getting data from all feature tables?
982
+ * It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
983
+ * In I3S we should decide which featureIds attribute will be passed to geometry data.
984
+ */
985
+ const firstFeatureTableName = Object.keys(extension.featureTables)?.[0];
986
+ if (firstFeatureTableName) {
987
+ const featureTable = extension?.featureTables[firstFeatureTableName];
988
+ const propertyTable = {};
989
+ for (const propertyName in featureTable.properties) {
990
+ propertyTable[propertyName] = featureTable.properties[propertyName].data;
991
+ }
992
+ return propertyTable;
993
+ }
994
+ }
995
+ console.warn("The I3S converter couldn't handle EXT_feature_metadata extension");
996
+ return null;
997
+ }
@@ -184,14 +184,14 @@ class NodePages {
184
184
  for (const [index, nodePage] of this.nodePages.entries()) {
185
185
  const nodePageStr = JSON.stringify(nodePage);
186
186
  const slpkPath = (0, path_1.join)(layers0Path, 'nodepages');
187
- writeQueue.enqueue({
187
+ await writeQueue.enqueue({
188
188
  archiveKey: `nodePages/${index.toString()}.json.gz`,
189
189
  writePromise: this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`)
190
190
  });
191
191
  }
192
192
  const metadata = (0, json_map_transform_1.default)({ nodeCount: this.nodesCounter }, (0, metadata_1.METADATA)());
193
193
  const compress = false;
194
- writeQueue.enqueue({
194
+ await writeQueue.enqueue({
195
195
  archiveKey: 'metadata.json',
196
196
  writePromise: this.writeFile(layers0Path, JSON.stringify(metadata), 'metadata.json', compress)
197
197
  });
@@ -200,7 +200,7 @@ class NodePages {
200
200
  for (const [index, nodePage] of this.nodePages.entries()) {
201
201
  const nodePageStr = JSON.stringify(nodePage);
202
202
  const nodePagePath = (0, path_1.join)(layers0Path, 'nodepages', index.toString());
203
- writeQueue.enqueue({ writePromise: this.writeFile(nodePagePath, nodePageStr) });
203
+ await writeQueue.enqueue({ writePromise: this.writeFile(nodePagePath, nodePageStr) });
204
204
  }
205
205
  }
206
206
  }
@@ -136,13 +136,6 @@ export default class I3SConverter {
136
136
  * @param level - level of node (distanse to root node in the tree)
137
137
  */
138
138
  private _createNode;
139
- /**
140
- * Convert attributesStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
141
- * from B3DM batch table
142
- * @param sourceTileContent - tile content of 3DTile
143
- * @return {void}
144
- */
145
- private _convertAttributeStorageInfo;
146
139
  /**
147
140
  * Convert tile to one or more I3S nodes
148
141
  * @param sourceTile - source tile (3DTile)
@@ -247,7 +240,7 @@ export default class I3SConverter {
247
240
  /**
248
241
  * Generate storage attribute for map segmentation.
249
242
  * @param attributeIndex - order index of attribute (f_0, f_1 ...).
250
- * @param key - attribute key from batch table.\
243
+ * @param key - attribute key from propertyTable.
251
244
  * @param attributeType - attribute type.
252
245
  * @return Updated storageAttribute.
253
246
  */
@@ -255,7 +248,7 @@ export default class I3SConverter {
255
248
  /**
256
249
  * Get the attribute type for attributeStorageInfo https://github.com/Esri/i3s-spec/blob/master/docs/1.7/attributeStorageInfo.cmn.md
257
250
  * @param key - attribute's key
258
- * @param attribute - attribute's type in batchTable
251
+ * @param attribute - attribute's type in propertyTable
259
252
  */
260
253
  private getAttributeType;
261
254
  /**
@@ -280,18 +273,18 @@ export default class I3SConverter {
280
273
  */
281
274
  private _createFieldAttribute;
282
275
  /**
283
- * Do conversion of 3DTiles batch table to I3s node attributes.
284
- * @param batchTable - Table with layer meta data.
276
+ * Do conversion of 3DTiles property table to I3s node attributes.
277
+ * @param propertyTable - Table with layer meta data.
285
278
  */
286
- private _convertBatchTableInfoToNodeAttributes;
279
+ private _convertPropertyTableToNodeAttributes;
287
280
  /**
288
- * Find and return attribute type based on key form Batch table.
281
+ * Find and return attribute type based on key form propertyTable.
289
282
  * @param attributeType
290
283
  */
291
284
  private _getFieldAttributeType;
292
285
  /**
293
286
  * Generate popup info to show metadata on the map.
294
- * @param batchTable - Batch table data with OBJECTID.
287
+ * @param propertyTable - table data with OBJECTID.
295
288
  * @return data for correct rendering of popup.
296
289
  */
297
290
  private _createPopupInfo;
@@ -1 +1 @@
1
- {"version":3,"file":"i3s-converter.d.ts","sourceRoot":"","sources":["../../src/i3s-converter/i3s-converter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"i3s-converter.d.ts","sourceRoot":"","sources":["../../src/i3s-converter/i3s-converter.ts"],"names":[],"mappings":"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"}