Skip to content

Commit 8f17045

Browse files
authored
Merge pull request #1222 from CesiumGS/more-tileset-parsing
Make more properties from tileset.json available on `TilesetMetadata`
2 parents bc32305 + a4c2890 commit 8f17045

File tree

5 files changed

+102
-42
lines changed

5 files changed

+102
-42
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
- Added `element_type` to `IntrusivePointer`, allowing it to be used with `std::pointer_types`.
1515
- Added implicit conversion of `IntrusivePointer<T>` to `T*`.
16+
- All properties and extensions from `tileset.json`, except `"root"`, are now parsed into `TilesetMetadata` when a tileset is loaded by `Cesium3DTilesSelection::Tileset`.
1617

1718
##### Fixes :wrench:
1819

Cesium3DTilesSelection/include/Cesium3DTilesSelection/TilesetMetadata.h

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#pragma once
22

3+
#include <Cesium3DTiles/Asset.h>
34
#include <Cesium3DTiles/GroupMetadata.h>
5+
#include <Cesium3DTiles/Properties.h>
46
#include <Cesium3DTiles/Schema.h>
7+
#include <Cesium3DTiles/Statistics.h>
58
#include <Cesium3DTilesSelection/Library.h>
69
#include <CesiumAsync/SharedFuture.h>
10+
#include <CesiumUtility/ExtensibleObject.h>
711

812
#include <optional>
913
#include <string>
14+
#include <unordered_map>
1015
#include <vector>
1116

1217
namespace CesiumAsync {
@@ -18,12 +23,24 @@ namespace Cesium3DTilesSelection {
1823

1924
/**
2025
* @brief Holds the metadata associated with a {@link Tileset} or an external
21-
* tileset.
26+
* tileset. This holds all of the fields of {@link Cesium3DTiles::Tileset}
27+
* except for the root tile.
2228
*/
23-
class CESIUM3DTILESSELECTION_API TilesetMetadata {
29+
class CESIUM3DTILESSELECTION_API TilesetMetadata
30+
: public CesiumUtility::ExtensibleObject {
2431
public:
2532
~TilesetMetadata() noexcept;
2633

34+
/**
35+
* @brief Metadata about the entire tileset.
36+
*/
37+
Cesium3DTiles::Asset asset;
38+
39+
/**
40+
* @brief A dictionary object of metadata about per-feature properties.
41+
*/
42+
std::unordered_map<std::string, Cesium3DTiles::Properties> properties;
43+
2744
/**
2845
* @brief An object defining the structure of metadata classes and enums. When
2946
* this is defined, then `schemaUri` shall be undefined.
@@ -36,6 +53,11 @@ class CESIUM3DTILESSELECTION_API TilesetMetadata {
3653
*/
3754
std::optional<std::string> schemaUri;
3855

56+
/**
57+
* @brief An object containing statistics about metadata entities.
58+
*/
59+
std::optional<Cesium3DTiles::Statistics> statistics;
60+
3961
/**
4062
* @brief An array of groups that tile content may belong to. Each element of
4163
* this array is a metadata entity that describes the group. The tile content
@@ -48,6 +70,24 @@ class CESIUM3DTILESSELECTION_API TilesetMetadata {
4870
*/
4971
std::optional<Cesium3DTiles::MetadataEntity> metadata;
5072

73+
/**
74+
* @brief The error, in meters, introduced if this tileset is not rendered. At
75+
* runtime, the geometric error is used to compute screen space error (SSE),
76+
* i.e., the error measured in pixels.
77+
*/
78+
std::optional<double> geometricError;
79+
80+
/**
81+
* @brief Names of 3D Tiles extensions used somewhere in this tileset.
82+
*/
83+
std::vector<std::string> extensionsUsed;
84+
85+
/**
86+
* @brief Names of 3D Tiles extensions required to properly load this tileset.
87+
* Each element of this array shall also be contained in `extensionsUsed`.
88+
*/
89+
std::vector<std::string> extensionsRequired;
90+
5191
/**
5292
* @brief Asynchronously loads the {@link schema} from the {@link schemaUri}.
5393
* If the {@link schemaUri} does not contain a value, this method does

Cesium3DTilesSelection/src/TilesetContentManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ TilesetContentManager::TilesetContentManager(
847847
pLogger,
848848
url,
849849
pCompletedRequest->headers(),
850-
tilesetJson,
850+
std::move(tilesetJson),
851851
ellipsoid)
852852
.thenImmediately(
853853
[](TilesetContentLoaderResult<TilesetContentLoader>&&

Cesium3DTilesSelection/src/TilesetJsonLoader.cpp

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
#include <Cesium3DTilesReader/BoundingVolumeReader.h>
1313
#include <Cesium3DTilesReader/ContentReader.h>
1414
#include <Cesium3DTilesReader/ExtensionContent3dTilesContentVoxelsReader.h>
15-
#include <Cesium3DTilesReader/GroupMetadataReader.h>
16-
#include <Cesium3DTilesReader/MetadataEntityReader.h>
17-
#include <Cesium3DTilesReader/SchemaReader.h>
15+
#include <Cesium3DTilesReader/TilesetReader.h>
1816
#include <Cesium3DTilesSelection/BoundingVolume.h>
1917
#include <Cesium3DTilesSelection/Tile.h>
2018
#include <Cesium3DTilesSelection/TileContent.h>
@@ -24,6 +22,7 @@
2422
#include <Cesium3DTilesSelection/TilesetContentLoader.h>
2523
#include <Cesium3DTilesSelection/TilesetContentLoaderResult.h>
2624
#include <Cesium3DTilesSelection/TilesetExternals.h>
25+
#include <Cesium3DTilesSelection/TilesetMetadata.h>
2726
#include <CesiumAsync/AsyncSystem.h>
2827
#include <CesiumAsync/HttpHeaders.h>
2928
#include <CesiumAsync/IAssetAccessor.h>
@@ -60,6 +59,7 @@
6059
#include <cstddef>
6160
#include <cstdint>
6261
#include <cstring>
62+
#include <iterator>
6363
#include <memory>
6464
#include <optional>
6565
#include <span>
@@ -710,41 +710,55 @@ TilesetContentLoaderResult<TilesetJsonLoader> parseTilesetJson(
710710
ErrorList{}};
711711
}
712712

713-
void parseTilesetMetadata(
713+
void removeRootPropertyAndParseTilesetMetadata(
714+
const std::shared_ptr<spdlog::logger>& pLogger,
714715
const std::string& baseUrl,
715-
const rapidjson::Document& tilesetJson,
716+
rapidjson::Document&& tilesetJson,
716717
TileExternalContent& externalContent) {
717-
auto schemaIt = tilesetJson.FindMember("schema");
718-
if (schemaIt != tilesetJson.MemberEnd()) {
719-
Cesium3DTilesReader::SchemaReader schemaReader;
720-
auto schemaResult = schemaReader.readFromJson(schemaIt->value);
721-
if (schemaResult.value) {
722-
externalContent.metadata.schema = std::move(*schemaResult.value);
723-
}
724-
}
725-
726-
auto schemaUriIt = tilesetJson.FindMember("schemaUri");
727-
if (schemaUriIt != tilesetJson.MemberEnd() && schemaUriIt->value.IsString()) {
728-
externalContent.metadata.schemaUri =
729-
CesiumUtility::Uri::resolve(baseUrl, schemaUriIt->value.GetString());
730-
}
731-
732-
const auto metadataIt = tilesetJson.FindMember("metadata");
733-
if (metadataIt != tilesetJson.MemberEnd()) {
734-
Cesium3DTilesReader::MetadataEntityReader metadataReader;
735-
auto metadataResult = metadataReader.readFromJson(metadataIt->value);
736-
if (metadataResult.value) {
737-
externalContent.metadata.metadata = std::move(*metadataResult.value);
738-
}
718+
// Remove the root tile from the RapidJSON document. Parsing the complete tile
719+
// tree will take too long, and we don't need it.
720+
tilesetJson.RemoveMember("root");
721+
722+
Cesium3DTilesReader::TilesetReader tilesetReader;
723+
auto tilesetResult = tilesetReader.readFromJson(tilesetJson);
724+
725+
if (!tilesetResult.errors.empty() || !tilesetResult.warnings.empty()) {
726+
ErrorList errorList;
727+
errorList.warnings.resize(
728+
tilesetResult.errors.size() + tilesetResult.warnings.size());
729+
std::copy(
730+
std::make_move_iterator(tilesetResult.errors.begin()),
731+
std::make_move_iterator(tilesetResult.errors.end()),
732+
errorList.warnings.begin());
733+
std::copy(
734+
std::make_move_iterator(tilesetResult.warnings.begin()),
735+
std::make_move_iterator(tilesetResult.warnings.end()),
736+
errorList.warnings.begin() + std::vector<std::string>::difference_type(
737+
tilesetResult.errors.size()));
738+
errorList.logWarning(pLogger, "Could not parse metadata from tileset.json");
739739
}
740740

741-
const auto groupsIt = tilesetJson.FindMember("groups");
742-
if (groupsIt != tilesetJson.MemberEnd()) {
743-
Cesium3DTilesReader::GroupMetadataReader groupMetadataReader;
744-
auto groupsResult = groupMetadataReader.readArrayFromJson(groupsIt->value);
745-
if (groupsResult.value) {
746-
externalContent.metadata.groups = std::move(*groupsResult.value);
741+
if (tilesetResult.value) {
742+
Cesium3DTiles::Tileset& tileset = *tilesetResult.value;
743+
Cesium3DTilesSelection::TilesetMetadata& metadata =
744+
externalContent.metadata;
745+
746+
metadata.asset = std::move(tileset.asset);
747+
metadata.extensions = std::move(tileset.extensions);
748+
metadata.extensionsRequired = std::move(tileset.extensionsRequired);
749+
metadata.extensionsUsed = std::move(tileset.extensionsUsed);
750+
metadata.extras = std::move(tileset.extras);
751+
metadata.geometricError = tileset.geometricError;
752+
metadata.groups = std::move(tileset.groups);
753+
metadata.metadata = std::move(tileset.metadata);
754+
metadata.properties = std::move(tileset.properties);
755+
metadata.schema = std::move(tileset.schema);
756+
if (tileset.schemaUri) {
757+
metadata.schemaUri =
758+
CesiumUtility::Uri::resolve(baseUrl, *tileset.schemaUri);
747759
}
760+
metadata.statistics = std::move(tileset.statistics);
761+
metadata.unknownProperties = std::move(tileset.unknownProperties);
748762
}
749763
}
750764

@@ -792,9 +806,10 @@ TileLoadResult parseExternalTilesetInWorkerThread(
792806
ellipsoid);
793807

794808
// Populate the root tile with metadata
795-
parseTilesetMetadata(
809+
removeRootPropertyAndParseTilesetMetadata(
810+
pLogger,
796811
tileUrl,
797-
tilesetJson,
812+
std::move(tilesetJson),
798813
externalContentInitializer.externalContent);
799814

800815
// check and log any errors
@@ -893,7 +908,7 @@ TilesetJsonLoader::createLoader(
893908
pLogger,
894909
pCompletedRequest->url(),
895910
pCompletedRequest->headers(),
896-
tilesetJson,
911+
std::move(tilesetJson),
897912
ellipsoid);
898913
});
899914
}
@@ -905,7 +920,7 @@ TilesetJsonLoader::createLoader(
905920
const std::shared_ptr<spdlog::logger>& pLogger,
906921
const std::string& tilesetJsonUrl,
907922
const CesiumAsync::HttpHeaders& requestHeaders,
908-
const rapidjson::Document& tilesetJson,
923+
rapidjson::Document&& tilesetJson,
909924
const CesiumGeospatial::Ellipsoid& ellipsoid) {
910925
TilesetContentLoaderResult<TilesetJsonLoader> result = parseTilesetJson(
911926
pLogger,
@@ -963,7 +978,11 @@ TilesetJsonLoader::createLoader(
963978
result.pRootTile->getContent().getExternalContent();
964979
CESIUM_ASSERT(pExternal);
965980
if (pExternal) {
966-
parseTilesetMetadata(tilesetJsonUrl, tilesetJson, *pExternal);
981+
removeRootPropertyAndParseTilesetMetadata(
982+
pLogger,
983+
tilesetJsonUrl,
984+
std::move(tilesetJson),
985+
*pExternal);
967986
}
968987

969988
return asyncSystem.createResolvedFuture(std::move(result))

Cesium3DTilesSelection/src/TilesetJsonLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class TilesetJsonLoader : public TilesetContentLoader {
4949
const std::shared_ptr<spdlog::logger>& pLogger,
5050
const std::string& tilesetJsonUrl,
5151
const CesiumAsync::HttpHeaders& requestHeaders,
52-
const rapidjson::Document& tilesetJson,
52+
rapidjson::Document&& tilesetJson,
5353
const CesiumGeospatial::Ellipsoid& ellipsoid CESIUM_DEFAULT_ELLIPSOID);
5454

5555
protected:

0 commit comments

Comments
 (0)