@loaders.gl/tile-converter 4.0.0-alpha.22 → 4.0.0-alpha.24
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-converter/helpers/load-i3s.d.ts.map +1 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/converter.min.js +106 -106
- package/dist/dist.min.js +1883 -1241
- package/dist/es5/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
- package/dist/es5/constants.js +1 -5
- package/dist/es5/constants.js.map +1 -1
- package/dist/es5/deps-installer/deps-installer.js +1 -1
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js +26 -11
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/feature-attributes.js +7 -17
- package/dist/es5/i3s-converter/helpers/feature-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +83 -44
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +70 -17
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/node-index-document.js +3 -2
- package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js +1 -2
- package/dist/es5/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +36 -26
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/i3s-converter/types.js.map +1 -1
- package/dist/es5/i3s-server/controllers/slpk-controller.js +2 -2
- package/dist/es5/i3s-server/controllers/slpk-controller.js.map +1 -1
- package/dist/es5/pgm-loader.js +11 -3
- package/dist/es5/pgm-loader.js.map +1 -1
- package/dist/es5/slpk-extractor/slpk-extractor.js +1 -1
- package/dist/es5/slpk-extractor/slpk-extractor.js.map +1 -1
- package/dist/esm/3d-tiles-converter/helpers/load-i3s.js.map +1 -1
- package/dist/esm/constants.js +0 -2
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/deps-installer/deps-installer.js +1 -1
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js +21 -6
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/feature-attributes.js +9 -7
- package/dist/esm/i3s-converter/helpers/feature-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +76 -34
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +66 -13
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/node-index-document.js +2 -1
- package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js +1 -1
- package/dist/esm/i3s-converter/helpers/preprocess-3d-tiles.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +20 -17
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-converter/types.js.map +1 -1
- package/dist/esm/i3s-server/bin/i3s-server.min.js +71 -71
- package/dist/esm/i3s-server/controllers/slpk-controller.js +1 -1
- package/dist/esm/i3s-server/controllers/slpk-controller.js.map +1 -1
- package/dist/esm/pgm-loader.js +7 -4
- package/dist/esm/pgm-loader.js.map +1 -1
- package/dist/esm/slpk-extractor/slpk-extractor.js +2 -1
- package/dist/esm/slpk-extractor/slpk-extractor.js.map +1 -1
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/feature-attributes.d.ts +6 -6
- package/dist/i3s-converter/helpers/feature-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +2 -2
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.d.ts +1 -1
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/types.d.ts +7 -4
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/pgm-loader.d.ts +9 -2
- package/dist/pgm-loader.d.ts.map +1 -1
- package/dist/slpk-extractor/slpk-extractor.d.ts.map +1 -1
- package/dist/slpk-extractor.min.js +38 -38
- package/package.json +14 -14
- package/src/3d-tiles-converter/helpers/load-i3s.ts +1 -0
- package/src/constants.ts +0 -3
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +53 -14
- package/src/i3s-converter/helpers/feature-attributes.ts +20 -15
- package/src/i3s-converter/helpers/geometry-attributes.ts +80 -50
- package/src/i3s-converter/helpers/geometry-converter.ts +153 -21
- package/src/i3s-converter/helpers/node-index-document.ts +5 -1
- package/src/i3s-converter/helpers/preprocess-3d-tiles.ts +1 -1
- package/src/i3s-converter/i3s-converter.ts +42 -17
- package/src/i3s-converter/types.ts +8 -4
- package/src/i3s-server/controllers/slpk-controller.ts +1 -1
- package/src/pgm-loader.ts +15 -7
- package/src/slpk-extractor/slpk-extractor.ts +2 -1
- package/dist/3d-tiles-converter/3d-tiles-converter.js +0 -279
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js +0 -271
- package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +0 -23
- package/dist/3d-tiles-converter/helpers/load-i3s.js +0 -42
- package/dist/3d-tiles-converter/helpers/texture-atlas.js +0 -54
- package/dist/3d-tiles-converter/json-templates/tileset.js +0 -43
- package/dist/bundle.js +0 -5
- package/dist/constants.js +0 -6
- package/dist/converter-cli.js +0 -222
- package/dist/deps-installer/deps-installer.js +0 -89
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +0 -158
- package/dist/i3s-converter/helpers/coordinate-converter.js +0 -122
- package/dist/i3s-converter/helpers/create-scene-server-path.js +0 -28
- package/dist/i3s-converter/helpers/feature-attributes.js +0 -216
- package/dist/i3s-converter/helpers/geometry-attributes.js +0 -203
- package/dist/i3s-converter/helpers/geometry-converter.js +0 -1240
- package/dist/i3s-converter/helpers/gltf-attributes.js +0 -129
- package/dist/i3s-converter/helpers/load-3d-tiles.js +0 -99
- package/dist/i3s-converter/helpers/node-debug.js +0 -120
- package/dist/i3s-converter/helpers/node-index-document.js +0 -268
- package/dist/i3s-converter/helpers/node-pages.js +0 -316
- package/dist/i3s-converter/helpers/preprocess-3d-tiles.js +0 -100
- package/dist/i3s-converter/helpers/tileset-traversal.js +0 -29
- package/dist/i3s-converter/i3s-converter.js +0 -945
- package/dist/i3s-converter/json-templates/geometry-definitions.js +0 -87
- package/dist/i3s-converter/json-templates/layers.js +0 -139
- package/dist/i3s-converter/json-templates/metadata.js +0 -25
- package/dist/i3s-converter/json-templates/node.js +0 -89
- package/dist/i3s-converter/json-templates/scene-server.js +0 -31
- package/dist/i3s-converter/json-templates/shared-resources.js +0 -129
- package/dist/i3s-converter/json-templates/store.js +0 -103
- package/dist/i3s-converter/types.js +0 -17
- package/dist/i3s-server/app.js +0 -29
- package/dist/i3s-server/bin/www.js +0 -37
- package/dist/i3s-server/controllers/index-controller.js +0 -31
- package/dist/i3s-server/controllers/slpk-controller.js +0 -33
- package/dist/i3s-server/routes/index.js +0 -20
- package/dist/i3s-server/routes/slpk-router.js +0 -34
- package/dist/i3s-server/utils/create-scene-server.js +0 -22
- package/dist/i3s-server/utils/server-utils.js +0 -66
- package/dist/index.js +0 -10
- package/dist/lib/utils/cli-utils.js +0 -82
- package/dist/lib/utils/compress-util.js +0 -257
- package/dist/lib/utils/file-utils.js +0 -139
- package/dist/lib/utils/geometry-utils.js +0 -18
- package/dist/lib/utils/lod-conversion-utils.js +0 -76
- package/dist/lib/utils/queue.js +0 -18
- package/dist/lib/utils/statistic-utills.js +0 -64
- package/dist/lib/utils/write-queue.js +0 -80
- package/dist/pgm-loader.js +0 -24
- package/dist/slpk-extractor/slpk-extractor.js +0 -74
- package/dist/slpk-extractor-cli.js +0 -102
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type {FeatureTableJson, Tiles3DTileContent} from '@loaders.gl/3d-tiles';
|
|
2
2
|
import type {
|
|
3
|
+
GLTF_EXT_mesh_features,
|
|
4
|
+
GLTF_EXT_structural_metadata,
|
|
3
5
|
GLTFAccessorPostprocessed,
|
|
4
6
|
GLTFMaterialPostprocessed,
|
|
5
7
|
GLTFNodePostprocessed,
|
|
@@ -47,7 +49,8 @@ import {GL} from '@loaders.gl/math';
|
|
|
47
49
|
import type {GLTFAttributesData, TextureImageProperties, TypedArrayConstructor} from '../types';
|
|
48
50
|
import {generateSyntheticIndices} from '../../lib/utils/geometry-utils';
|
|
49
51
|
import {BoundingSphere, OrientedBoundingBox} from '@math.gl/culling';
|
|
50
|
-
|
|
52
|
+
|
|
53
|
+
import {EXT_MESH_FEATURES, EXT_FEATURE_METADATA, EXT_STRUCTURAL_METADATA} from '@loaders.gl/gltf';
|
|
51
54
|
|
|
52
55
|
// Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
|
|
53
56
|
const DEFAULT_ROUGHNESS_FACTOR = 1;
|
|
@@ -241,12 +244,18 @@ async function _makeNodeResources({
|
|
|
241
244
|
const {faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount} =
|
|
242
245
|
generateAttributes(convertedAttributes);
|
|
243
246
|
|
|
244
|
-
|
|
245
|
-
|
|
247
|
+
let featureIdsMap: Record<string, number> = {};
|
|
248
|
+
if (propertyTable) {
|
|
249
|
+
/**
|
|
250
|
+
* 3DTiles has featureIndices unique only for one tile.
|
|
251
|
+
* In I3S featureIds are unique layer-wide. We create featureIds from all feature properties.
|
|
252
|
+
* If 3DTiles features has equal set of properties they are considered as same feature in I3S.
|
|
253
|
+
*/
|
|
254
|
+
featureIdsMap = makeFeatureIdsUnique(
|
|
246
255
|
featureIds,
|
|
247
256
|
convertedAttributes.featureIndices,
|
|
248
257
|
featuresHashArray,
|
|
249
|
-
|
|
258
|
+
propertyTable
|
|
250
259
|
);
|
|
251
260
|
}
|
|
252
261
|
|
|
@@ -288,6 +297,7 @@ async function _makeNodeResources({
|
|
|
288
297
|
if (attributeStorageInfo && propertyTable) {
|
|
289
298
|
attributes = convertPropertyTableToAttributeBuffers(
|
|
290
299
|
featureIds,
|
|
300
|
+
featureIdsMap,
|
|
291
301
|
propertyTable,
|
|
292
302
|
attributeStorageInfo
|
|
293
303
|
);
|
|
@@ -1249,17 +1259,18 @@ function generateImageId(texture: GLTFTexturePostprocessed, nodeId: number) {
|
|
|
1249
1259
|
* @param featureIndices
|
|
1250
1260
|
* @param featuresHashArray
|
|
1251
1261
|
* @param batchTable
|
|
1252
|
-
* @returns
|
|
1262
|
+
* @returns propertyTable indices to map featureIds
|
|
1253
1263
|
*/
|
|
1254
1264
|
function makeFeatureIdsUnique(
|
|
1255
1265
|
featureIds: number[],
|
|
1256
1266
|
featureIndices: number[],
|
|
1257
1267
|
featuresHashArray: string[],
|
|
1258
1268
|
batchTable: {[key: string]: any}
|
|
1259
|
-
) {
|
|
1269
|
+
): Record<string, number> {
|
|
1260
1270
|
const replaceMap = getFeaturesReplaceMap(featureIds, batchTable, featuresHashArray);
|
|
1261
1271
|
replaceIndicesByUnique(featureIndices, replaceMap);
|
|
1262
1272
|
replaceIndicesByUnique(featureIds, replaceMap);
|
|
1273
|
+
return replaceMap;
|
|
1263
1274
|
}
|
|
1264
1275
|
|
|
1265
1276
|
/**
|
|
@@ -1273,8 +1284,8 @@ function getFeaturesReplaceMap(
|
|
|
1273
1284
|
featureIds: any[],
|
|
1274
1285
|
batchTable: object,
|
|
1275
1286
|
featuresHashArray: any[]
|
|
1276
|
-
): Record<string,
|
|
1277
|
-
const featureMap: Record<string,
|
|
1287
|
+
): Record<string, number> {
|
|
1288
|
+
const featureMap: Record<string, number> = {};
|
|
1278
1289
|
|
|
1279
1290
|
for (let index = 0; index < featureIds.length; index++) {
|
|
1280
1291
|
const oldFeatureId = featureIds[index];
|
|
@@ -1326,7 +1337,7 @@ function getOrCreateUniqueFeatureId(
|
|
|
1326
1337
|
* @param featureMap
|
|
1327
1338
|
* @returns
|
|
1328
1339
|
*/
|
|
1329
|
-
function replaceIndicesByUnique(indicesArray:
|
|
1340
|
+
function replaceIndicesByUnique(indicesArray: number[], featureMap: Record<string, number>) {
|
|
1330
1341
|
for (let index = 0; index < indicesArray.length; index++) {
|
|
1331
1342
|
indicesArray[index] = featureMap[indicesArray[index]];
|
|
1332
1343
|
}
|
|
@@ -1341,6 +1352,7 @@ function replaceIndicesByUnique(indicesArray: any[], featureMap: Record<string,
|
|
|
1341
1352
|
*/
|
|
1342
1353
|
function convertPropertyTableToAttributeBuffers(
|
|
1343
1354
|
featureIds: number[],
|
|
1355
|
+
featureIdsMap: Record<string, number>,
|
|
1344
1356
|
propertyTable: FeatureTableJson,
|
|
1345
1357
|
attributeStorageInfo: AttributeStorageInfo[]
|
|
1346
1358
|
): any[] {
|
|
@@ -1348,7 +1360,7 @@ function convertPropertyTableToAttributeBuffers(
|
|
|
1348
1360
|
|
|
1349
1361
|
const needFlattenPropertyTable = checkPropertiesLength(featureIds, propertyTable);
|
|
1350
1362
|
const properties = needFlattenPropertyTable
|
|
1351
|
-
? flattenPropertyTableByFeatureIds(
|
|
1363
|
+
? flattenPropertyTableByFeatureIds(featureIdsMap, propertyTable)
|
|
1352
1364
|
: propertyTable;
|
|
1353
1365
|
|
|
1354
1366
|
const propertyTableWithObjectIds = {
|
|
@@ -1358,10 +1370,12 @@ function convertPropertyTableToAttributeBuffers(
|
|
|
1358
1370
|
|
|
1359
1371
|
for (const propertyName in propertyTableWithObjectIds) {
|
|
1360
1372
|
const type = getAttributeType(propertyName, attributeStorageInfo);
|
|
1361
|
-
|
|
1362
|
-
|
|
1373
|
+
if (type) {
|
|
1374
|
+
const value = propertyTableWithObjectIds[propertyName];
|
|
1375
|
+
const attributeBuffer = generateAttributeBuffer(type, value);
|
|
1363
1376
|
|
|
1364
|
-
|
|
1377
|
+
attributeBuffers.push(attributeBuffer);
|
|
1378
|
+
}
|
|
1365
1379
|
}
|
|
1366
1380
|
|
|
1367
1381
|
return attributeBuffers;
|
|
@@ -1401,6 +1415,20 @@ function generateAttributeBuffer(type: string, value: any): ArrayBuffer {
|
|
|
1401
1415
|
*/
|
|
1402
1416
|
function getAttributeType(key: string, attributeStorageInfo: any[]): string {
|
|
1403
1417
|
const attribute = attributeStorageInfo.find((attr) => attr.name === key);
|
|
1418
|
+
if (!attribute) {
|
|
1419
|
+
console.error(
|
|
1420
|
+
`attribute is null, key=${key}, attributeStorageInfo=${JSON.stringify(
|
|
1421
|
+
attributeStorageInfo,
|
|
1422
|
+
null,
|
|
1423
|
+
2
|
|
1424
|
+
)}`
|
|
1425
|
+
);
|
|
1426
|
+
return '';
|
|
1427
|
+
}
|
|
1428
|
+
if (!attribute.attributeValues) {
|
|
1429
|
+
console.error(`attributeValues is null, attribute=${attribute}`);
|
|
1430
|
+
return '';
|
|
1431
|
+
}
|
|
1404
1432
|
return attribute.attributeValues.valueType;
|
|
1405
1433
|
}
|
|
1406
1434
|
|
|
@@ -1577,8 +1605,8 @@ function generateFeatureIndexAttribute(
|
|
|
1577
1605
|
* Find property table in tile
|
|
1578
1606
|
* For example it can be batchTable for b3dm files or property table in gLTF extension.
|
|
1579
1607
|
* @param tileContent - 3DTiles tile content
|
|
1580
|
-
* @param metadataClass -
|
|
1581
|
-
* @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
1608
|
+
* @param metadataClass - user selected feature metadata class name
|
|
1609
|
+
* @return batch table from b3dm / feature properties from EXT_FEATURE_METADATA, EXT_MESH_FEATURES or EXT_STRUCTURAL_METADATA
|
|
1582
1610
|
*/
|
|
1583
1611
|
export function getPropertyTable(
|
|
1584
1612
|
tileContent: Tiles3DTileContent | null,
|
|
@@ -1587,7 +1615,7 @@ export function getPropertyTable(
|
|
|
1587
1615
|
if (!tileContent) {
|
|
1588
1616
|
return null;
|
|
1589
1617
|
}
|
|
1590
|
-
|
|
1618
|
+
let propertyTable: FeatureTableJson | null;
|
|
1591
1619
|
const batchTableJson = tileContent?.batchTableJson;
|
|
1592
1620
|
|
|
1593
1621
|
if (batchTableJson) {
|
|
@@ -1598,14 +1626,25 @@ export function getPropertyTable(
|
|
|
1598
1626
|
|
|
1599
1627
|
switch (extensionName) {
|
|
1600
1628
|
case EXT_MESH_FEATURES: {
|
|
1601
|
-
|
|
1602
|
-
|
|
1629
|
+
propertyTable = getPropertyTableFromExtMeshFeatures(
|
|
1630
|
+
extension as GLTF_EXT_mesh_features,
|
|
1631
|
+
metadataClass
|
|
1632
|
+
);
|
|
1633
|
+
return propertyTable;
|
|
1634
|
+
}
|
|
1635
|
+
case EXT_STRUCTURAL_METADATA: {
|
|
1636
|
+
propertyTable = getPropertyTableFromExtStructuralMetadata(
|
|
1637
|
+
extension as GLTF_EXT_structural_metadata,
|
|
1638
|
+
metadataClass
|
|
1639
|
+
);
|
|
1640
|
+
return propertyTable;
|
|
1603
1641
|
}
|
|
1604
1642
|
case EXT_FEATURE_METADATA: {
|
|
1605
|
-
|
|
1643
|
+
propertyTable = getPropertyTableFromExtFeatureMetadata(
|
|
1606
1644
|
extension as GLTF_EXT_feature_metadata_GLTF,
|
|
1607
1645
|
metadataClass
|
|
1608
1646
|
);
|
|
1647
|
+
return propertyTable;
|
|
1609
1648
|
}
|
|
1610
1649
|
default:
|
|
1611
1650
|
return null;
|
|
@@ -1618,9 +1657,18 @@ export function getPropertyTable(
|
|
|
1618
1657
|
*/
|
|
1619
1658
|
function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
|
|
1620
1659
|
extensionName: null | string;
|
|
1621
|
-
extension:
|
|
1660
|
+
extension:
|
|
1661
|
+
| string
|
|
1662
|
+
| GLTF_EXT_feature_metadata_GLTF
|
|
1663
|
+
| GLTF_EXT_structural_metadata
|
|
1664
|
+
| GLTF_EXT_mesh_features
|
|
1665
|
+
| null;
|
|
1622
1666
|
} {
|
|
1623
|
-
const extensionsWithPropertyTables = [
|
|
1667
|
+
const extensionsWithPropertyTables = [
|
|
1668
|
+
EXT_FEATURE_METADATA,
|
|
1669
|
+
EXT_STRUCTURAL_METADATA,
|
|
1670
|
+
EXT_MESH_FEATURES
|
|
1671
|
+
];
|
|
1624
1672
|
const extensionsUsed = tileContent?.gltf?.extensionsUsed;
|
|
1625
1673
|
|
|
1626
1674
|
if (!extensionsUsed) {
|
|
@@ -1649,6 +1697,8 @@ function getPropertyTableExtension(tileContent: Tiles3DTileContent): {
|
|
|
1649
1697
|
/**
|
|
1650
1698
|
* Handle EXT_feature_metadata to get property table
|
|
1651
1699
|
* @param extension - global level of EXT_FEATURE_METADATA extension
|
|
1700
|
+
* @param metadataClass - user selected feature metadata class name
|
|
1701
|
+
* @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
|
|
1652
1702
|
*/
|
|
1653
1703
|
function getPropertyTableFromExtFeatureMetadata(
|
|
1654
1704
|
extension: GLTF_EXT_feature_metadata_GLTF,
|
|
@@ -1701,3 +1751,85 @@ function getPropertyTableFromExtFeatureMetadata(
|
|
|
1701
1751
|
);
|
|
1702
1752
|
return null;
|
|
1703
1753
|
}
|
|
1754
|
+
|
|
1755
|
+
/**
|
|
1756
|
+
* Handle EXT_structural_metadata to get property table
|
|
1757
|
+
* @param extension - global level of EXT_STRUCTURAL_METADATA extension
|
|
1758
|
+
* @param metadataClass - user selected feature metadata class name
|
|
1759
|
+
* @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
|
|
1760
|
+
*/
|
|
1761
|
+
function getPropertyTableFromExtStructuralMetadata(
|
|
1762
|
+
extension: GLTF_EXT_structural_metadata,
|
|
1763
|
+
metadataClass?: string
|
|
1764
|
+
): FeatureTableJson | null {
|
|
1765
|
+
if (extension?.propertyTables) {
|
|
1766
|
+
/**
|
|
1767
|
+
* Take only first feature table to generate attributes storage info object.
|
|
1768
|
+
* TODO: Think about getting data from all feature tables?
|
|
1769
|
+
* It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
|
|
1770
|
+
* In I3S we should decide which featureIds attribute will be passed to geometry data.
|
|
1771
|
+
*/
|
|
1772
|
+
const firstPropertyTable = extension?.propertyTables[0];
|
|
1773
|
+
const propertyTableWithData = {};
|
|
1774
|
+
|
|
1775
|
+
for (const propertyName in firstPropertyTable.properties) {
|
|
1776
|
+
propertyTableWithData[propertyName] = firstPropertyTable.properties[propertyName].data;
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
return propertyTableWithData;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
if (extension?.propertyTextures) {
|
|
1783
|
+
/**
|
|
1784
|
+
* Take only first feature table to generate attributes storage info object.
|
|
1785
|
+
* TODO: Think about getting data from all feature tables?
|
|
1786
|
+
* It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
|
|
1787
|
+
* In I3S we should decide which featureIds attribute will be passed to geometry data.
|
|
1788
|
+
*/
|
|
1789
|
+
if (extension?.propertyTextures) {
|
|
1790
|
+
const firstPropertyTexture = extension?.propertyTextures[0];
|
|
1791
|
+
const propertyTableWithData = {};
|
|
1792
|
+
|
|
1793
|
+
for (const propertyName in firstPropertyTexture.properties) {
|
|
1794
|
+
propertyTableWithData[propertyName] = firstPropertyTexture.properties[propertyName].data;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
return propertyTableWithData;
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
console.warn(
|
|
1802
|
+
"The I3S converter couldn't handle EXT_structural_metadata extension: There is neither propertyTables, no propertyTextures in the extension."
|
|
1803
|
+
);
|
|
1804
|
+
return null;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
/**
|
|
1808
|
+
* Handle EXT_mesh_features to get property table
|
|
1809
|
+
* @param extension - global level of EXT_MESH_FEATURES extension
|
|
1810
|
+
* @param metadataClass - user selected feature metadata class name
|
|
1811
|
+
* @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
|
|
1812
|
+
*/
|
|
1813
|
+
function getPropertyTableFromExtMeshFeatures(
|
|
1814
|
+
extension: GLTF_EXT_mesh_features,
|
|
1815
|
+
metadataClass?: string
|
|
1816
|
+
): FeatureTableJson | null {
|
|
1817
|
+
if (extension?.featureIds) {
|
|
1818
|
+
const firstFeatureId = extension?.featureIds[0];
|
|
1819
|
+
const propertyTableWithData = {};
|
|
1820
|
+
|
|
1821
|
+
// When firstFeatureId.propertyTable is defined, the property data will be taken from EXT_structural_metadata extension
|
|
1822
|
+
if (!firstFeatureId.propertyTable) {
|
|
1823
|
+
console.warn(
|
|
1824
|
+
'Should be implemented as we have the tileset with Ext_mesh_features not linked with EXT_structural_metadata extension'
|
|
1825
|
+
);
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
return propertyTableWithData;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
console.warn(
|
|
1832
|
+
"The I3S converter couldn't handle EXT_mesh_features extension: There is no featureIds in the extension."
|
|
1833
|
+
);
|
|
1834
|
+
return null;
|
|
1835
|
+
}
|
|
@@ -323,7 +323,11 @@ export class NodeIndexDocument {
|
|
|
323
323
|
parentNode.converter.layers0?.attributeStorageInfo?.length
|
|
324
324
|
) {
|
|
325
325
|
node.attributeData = [];
|
|
326
|
-
|
|
326
|
+
const minimumLength =
|
|
327
|
+
attributes.length < parentNode.converter.layers0.attributeStorageInfo.length
|
|
328
|
+
? attributes.length
|
|
329
|
+
: parentNode.converter.layers0.attributeStorageInfo.length;
|
|
330
|
+
for (let index = 0; index < minimumLength; index++) {
|
|
327
331
|
const folderName = parentNode.converter.layers0.attributeStorageInfo[index].key;
|
|
328
332
|
node.attributeData.push({href: `./attributes/${folderName}/0`});
|
|
329
333
|
}
|
|
@@ -2,7 +2,7 @@ import {Tiles3DTileContent} from '@loaders.gl/3d-tiles';
|
|
|
2
2
|
import {GLTFPrimitiveModeString, PreprocessData} from '../types';
|
|
3
3
|
import {GLTF, GLTFLoader, GLTF_EXT_feature_metadata_GLTF} from '@loaders.gl/gltf';
|
|
4
4
|
import {parse} from '@loaders.gl/core';
|
|
5
|
-
import {EXT_FEATURE_METADATA} from '
|
|
5
|
+
import {EXT_FEATURE_METADATA} from '@loaders.gl/gltf';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* glTF primitive modes
|
|
@@ -12,7 +12,8 @@ import type {
|
|
|
12
12
|
SceneLayer3D,
|
|
13
13
|
BoundingVolumes,
|
|
14
14
|
MaxScreenThresholdSQ,
|
|
15
|
-
NodeInPage
|
|
15
|
+
NodeInPage,
|
|
16
|
+
AttributeStorageInfo
|
|
16
17
|
} from '@loaders.gl/i3s';
|
|
17
18
|
import {load, encode, isBrowser} from '@loaders.gl/core';
|
|
18
19
|
import {CesiumIonLoader, Tiles3DLoader} from '@loaders.gl/3d-tiles';
|
|
@@ -649,7 +650,14 @@ export default class I3SConverter {
|
|
|
649
650
|
|
|
650
651
|
const propertyTable = getPropertyTable(tileContent, this.options.metadataClass);
|
|
651
652
|
|
|
652
|
-
if (propertyTable
|
|
653
|
+
if (propertyTable) {
|
|
654
|
+
/*
|
|
655
|
+
Call the convertion procedure even if the node attributes have been already created.
|
|
656
|
+
We will append new attributes only in case the property table is updated.
|
|
657
|
+
According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
|
|
658
|
+
"The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
|
|
659
|
+
But the specification of ver 2.1 doesn't have such a requirement ("...the same for every node...")
|
|
660
|
+
*/
|
|
653
661
|
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
654
662
|
}
|
|
655
663
|
|
|
@@ -735,7 +743,7 @@ export default class I3SConverter {
|
|
|
735
743
|
* @param boundingVolume - initialized bounding volume of the source tile
|
|
736
744
|
* @param tileContent - content of the source tile
|
|
737
745
|
* @param parentId - id of parent node in node pages
|
|
738
|
-
* @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
746
|
+
* @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA, EXT_MESH_FEATURES or EXT_STRUCTURAL_METADATA
|
|
739
747
|
* @returns - converted node resources
|
|
740
748
|
*/
|
|
741
749
|
private async _convertResources(
|
|
@@ -1068,7 +1076,12 @@ export default class I3SConverter {
|
|
|
1068
1076
|
slpkChildPath: string
|
|
1069
1077
|
): Promise<void> {
|
|
1070
1078
|
if (attributes?.length && this.layers0?.attributeStorageInfo?.length) {
|
|
1071
|
-
|
|
1079
|
+
const minimumLength =
|
|
1080
|
+
attributes.length < this.layers0.attributeStorageInfo.length
|
|
1081
|
+
? attributes.length
|
|
1082
|
+
: this.layers0.attributeStorageInfo.length;
|
|
1083
|
+
|
|
1084
|
+
for (let index = 0; index < minimumLength; index++) {
|
|
1072
1085
|
const folderName = this.layers0.attributeStorageInfo[index].key;
|
|
1073
1086
|
const fileBuffer = new Uint8Array(attributes[index]);
|
|
1074
1087
|
|
|
@@ -1150,19 +1163,31 @@ export default class I3SConverter {
|
|
|
1150
1163
|
};
|
|
1151
1164
|
|
|
1152
1165
|
for (const key in propertyTableWithObjectId) {
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
+
/*
|
|
1167
|
+
We will append new attributes only in case the property table is updated.
|
|
1168
|
+
According to ver 1.9 (see https://github.com/Esri/i3s-spec/blob/master/docs/1.9/attributeStorageInfo.cmn.md):
|
|
1169
|
+
"The attributeStorageInfo object describes the structure of the binary attribute data resource of a layer, which is the same for every node in the layer."
|
|
1170
|
+
But the specification of ver 2.1 doesn't have such a requirement ("...the same for every node...")
|
|
1171
|
+
*/
|
|
1172
|
+
const found = this.layers0!.attributeStorageInfo!.find((element) => element.name === key);
|
|
1173
|
+
if (!found) {
|
|
1174
|
+
const firstAttribute = propertyTableWithObjectId[key][0];
|
|
1175
|
+
const attributeType = getAttributeType(key, firstAttribute);
|
|
1176
|
+
|
|
1177
|
+
const storageAttribute: AttributeStorageInfo = createdStorageAttribute(
|
|
1178
|
+
attributeIndex,
|
|
1179
|
+
key,
|
|
1180
|
+
attributeType
|
|
1181
|
+
);
|
|
1182
|
+
const fieldAttributeType = getFieldAttributeType(attributeType);
|
|
1183
|
+
const fieldAttribute = createFieldAttribute(key, fieldAttributeType);
|
|
1184
|
+
const popupInfo = createPopupInfo(propertyTableWithObjectId);
|
|
1185
|
+
|
|
1186
|
+
this.layers0!.attributeStorageInfo!.push(storageAttribute);
|
|
1187
|
+
this.layers0!.fields!.push(fieldAttribute);
|
|
1188
|
+
this.layers0!.popupInfo = popupInfo;
|
|
1189
|
+
this.layers0!.layerType = _3D_OBJECT_LAYER_TYPE;
|
|
1190
|
+
}
|
|
1166
1191
|
attributeIndex += 1;
|
|
1167
1192
|
}
|
|
1168
1193
|
}
|
|
@@ -106,10 +106,8 @@ export type GeometryAttributes = {
|
|
|
106
106
|
featureCount: number;
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
/** Geometry attributes
|
|
110
|
-
export type
|
|
111
|
-
/** Feature Id */
|
|
112
|
-
featureId: number;
|
|
109
|
+
/** Geometry attributes applicable for reordering by featureId */
|
|
110
|
+
export type GroupedAttributes = {
|
|
113
111
|
/** POSITION attribute value */
|
|
114
112
|
positions: Float32Array;
|
|
115
113
|
/** NORMAL attribute value */
|
|
@@ -122,6 +120,12 @@ export type GroupedByFeatureIdAttributes = {
|
|
|
122
120
|
texCoords: Float32Array;
|
|
123
121
|
};
|
|
124
122
|
|
|
123
|
+
/** Geometry attributes specific for the particular feature */
|
|
124
|
+
export type GroupedByFeatureIdAttributes = GroupedAttributes & {
|
|
125
|
+
/** Feature Id */
|
|
126
|
+
featureId: number;
|
|
127
|
+
};
|
|
128
|
+
|
|
125
129
|
/** Shared resources made from GLTF material */
|
|
126
130
|
export type SharedResourcesArrays = {
|
|
127
131
|
/** material definitions list https://github.com/Esri/i3s-spec/blob/master/docs/1.8/materialDefinitionInfo.cmn.md */
|
package/src/pgm-loader.ts
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
import type {LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
2
|
-
import {parsePGM} from '@math.gl/geoid';
|
|
1
|
+
import type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
2
|
+
import {Geoid, parsePGM} from '@math.gl/geoid';
|
|
3
3
|
|
|
4
4
|
// __VERSION__ is injected by babel-plugin-version-inline
|
|
5
5
|
// @ts-ignore TS2304: Cannot find name '__VERSION__'.
|
|
6
6
|
const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
|
|
7
7
|
|
|
8
|
+
export {Geoid};
|
|
9
|
+
|
|
10
|
+
export type PGMLoaderOptions = LoaderOptions & {
|
|
11
|
+
pgm?: {
|
|
12
|
+
cubic?: boolean;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
8
16
|
/**
|
|
9
17
|
* Loader for PGM - Netpbm grayscale image format
|
|
10
18
|
*/
|
|
11
|
-
export const PGMLoader: LoaderWithParser = {
|
|
19
|
+
export const PGMLoader: LoaderWithParser<Geoid, never, PGMLoaderOptions> = {
|
|
12
20
|
name: 'PGM - Netpbm grayscale image format',
|
|
13
21
|
id: 'pgm',
|
|
14
22
|
module: 'tile-converter',
|
|
15
23
|
version: VERSION,
|
|
16
24
|
mimeTypes: ['image/x-portable-graymap'],
|
|
17
|
-
|
|
18
|
-
parse: async (arrayBuffer, options) => parsePGM(new Uint8Array(arrayBuffer), options),
|
|
25
|
+
parse: async (arrayBuffer, options) => parsePGM(new Uint8Array(arrayBuffer), options?.pgm || {}),
|
|
19
26
|
extensions: ['pgm'],
|
|
20
27
|
options: {
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
pgm: {
|
|
29
|
+
cubic: false
|
|
30
|
+
}
|
|
23
31
|
}
|
|
24
32
|
};
|
|
@@ -2,7 +2,8 @@ import {isBrowser} from '@loaders.gl/core';
|
|
|
2
2
|
|
|
3
3
|
import {BROWSER_ERROR_MESSAGE} from '../constants';
|
|
4
4
|
import {path} from '@loaders.gl/loader-utils';
|
|
5
|
-
import {FileHandleFile
|
|
5
|
+
import {FileHandleFile} from '@loaders.gl/loader-utils';
|
|
6
|
+
import {parseZipLocalFileHeader} from '@loaders.gl/zip';
|
|
6
7
|
import {GZipCompression} from '@loaders.gl/compression';
|
|
7
8
|
import {writeFile} from '../lib/utils/file-utils';
|
|
8
9
|
|