Skip to content
Open
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3bead27
Support MAXAR_content_geojson in tilesets
timoore Aug 25, 2025
adb705f
Call prepareInLoadThread() for tiles with feature content
timoore Aug 27, 2025
4806a06
Add test for loading GeoJson
timoore Aug 28, 2025
eadf0cb
Add include files for clang-tidy's benefit
timoore Aug 28, 2025
9c6a8fc
Documentation fixes
timoore Aug 28, 2025
c88bd5f
More documentation fixes
timoore Aug 28, 2025
e0c1e1c
Merge branch 'main' into tileset-geojson
timoore Mar 20, 2026
d4873ba
Early work on GeoJson tilesets with glTF translation
timoore Mar 27, 2026
c3d39d8
Get it to compile
timoore Mar 27, 2026
b230b40
process GeoJson line strings
timoore Mar 31, 2026
72027d0
Add conversion of GeoJson Polygon and MultiPolygon features
timoore Apr 1, 2026
2c809dd
Early work on GeoJson tilesets with glTF translation
timoore Mar 27, 2026
e29b691
Get it to compile
timoore Mar 27, 2026
16ba9fd
process GeoJson line strings
timoore Mar 31, 2026
fc6271c
Add conversion of GeoJson Polygon and MultiPolygon features
timoore Apr 1, 2026
4d8a2c8
Merge branch 'tileset-geojson2' into geojsontogltf
timoore Apr 2, 2026
c618027
Fixup from merge
timoore Apr 2, 2026
b0e5e52
Make root tile of EllipsoidTileset have a bounding box
timoore Apr 7, 2026
208ad09
Fix error in translateGltf option logic
timoore Apr 7, 2026
7042520
fixup for clang-format
timoore Apr 7, 2026
2084113
Make clang-tidy happy
timoore Apr 7, 2026
172fee0
Set accessor min and max, assuage clang-tidy
timoore Apr 7, 2026
a772d41
more clang-tidy
timoore Apr 7, 2026
1b50ce3
Gather GeoJson point data
timoore Apr 7, 2026
0f6e40d
clang-format
timoore Apr 7, 2026
2aa9c92
Documentation
timoore Apr 7, 2026
fa36156
format the documentation
timoore Apr 8, 2026
beb403d
Clean up iteration
timoore Apr 8, 2026
c6e8e9c
Clean up glTF construction and fix bugs
timoore Apr 8, 2026
df2caed
include Mesh.h for clang-tidy
timoore Apr 8, 2026
b3dafc2
Add an obnoxious color to the feature material, for debugging
timoore Apr 17, 2026
deabec6
more while loop -> for loop cleanup
timoore Apr 17, 2026
5155010
Change to using a local class for doing the conversion
timoore Apr 17, 2026
26bb57a
Change from operator() method to convert()
timoore Apr 17, 2026
d0f71f1
Use helper functions to remove redundant code
timoore Apr 17, 2026
f2d7c69
Fix clang-tidy complaints
timoore Apr 17, 2026
3790b84
Don't use static_cast for integer casts
timoore Apr 17, 2026
6bc96e1
Use BoundingRegionBuilder to find coordinate "centroid"
timoore Apr 20, 2026
ffbd51e
clang-format and clang-tidy strike again
timoore Apr 20, 2026
7f68b73
Remove translateVectorFeaturesOptions
timoore Apr 20, 2026
b009a33
more cleanup from PR review
timoore Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cesium3DTilesSelection/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ target_link_libraries(Cesium3DTilesSelection
CesiumQuantizedMeshTerrain
CesiumRasterOverlays
CesiumUtility
CesiumVectorData
spdlog::spdlog
# PRIVATE
libmorton::libmorton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ struct CESIUM3DTILESSELECTION_API TilesetContentOptions {
* shader.
*/
bool applyTextureTransform = true;

/**
* @brief Whether to translate vector feature data, e.g. GeoJSON content, to
* glTF, or leave it in its native format.
*/
bool translateVectorFeatures = true;
Comment thread
timoore marked this conversation as resolved.
Outdated
};

/**
Expand Down
5 changes: 5 additions & 0 deletions Cesium3DTilesSelection/src/EllipsoidTilesetLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ EllipsoidTilesetLoader::EllipsoidTilesetLoader(const Ellipsoid& ellipsoid)

pRootTile->setRefine(TileRefine::Replace);
pRootTile->setUnconditionallyRefine();
pRootTile->setBoundingVolume(BoundingRegion(
pCustomLoader->_projection.MAXIMUM_GLOBE_RECTANGLE,
0.0,
0.0,
pCustomLoader->_projection.getEllipsoid()));

std::vector<Tile> children;
uint32_t rootTilesX = pCustomLoader->_tilingScheme.getRootTilesX();
Expand Down
98 changes: 78 additions & 20 deletions Cesium3DTilesSelection/src/TilesetJsonLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <CesiumUtility/ErrorList.h>
#include <CesiumUtility/JsonHelpers.h>
#include <CesiumUtility/Uri.h>
#include <CesiumVectorData/GeoJsonDocument.h>
#include <CesiumVectorData/GltfConverter.h>

#include <fmt/format.h>
#include <glm/common.hpp>
Expand Down Expand Up @@ -770,27 +772,11 @@ TileLoadResult parseExternalTilesetInWorkerThread(
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
std::shared_ptr<CesiumAsync::IAssetRequest>&& pCompletedRequest,
ExternalContentInitializer&& externalContentInitializer,
const CesiumGeospatial::Ellipsoid& ellipsoid) {
const CesiumGeospatial::Ellipsoid& ellipsoid,
rapidjson::Document& tilesetJson) {
Comment thread
timoore marked this conversation as resolved.
Outdated
// create external tileset
Comment thread
timoore marked this conversation as resolved.
Outdated
const CesiumAsync::IAssetResponse* pResponse = pCompletedRequest->response();
const auto& responseData = pResponse->data();
const auto& tileUrl = pCompletedRequest->url();

rapidjson::Document tilesetJson;
tilesetJson.Parse(
reinterpret_cast<const char*>(responseData.data()),
responseData.size());
if (tilesetJson.HasParseError()) {
SPDLOG_LOGGER_ERROR(
pLogger,
"Error when parsing tileset JSON, error code {} at byte offset {}",
tilesetJson.GetParseError(),
tilesetJson.GetErrorOffset());
return TileLoadResult::createFailedResult(
pAssetAccessor,
std::move(pCompletedRequest));
}

// Save the parsed external tileset into custom data.
// We will propagate it back to tile later in the main
// thread
Expand Down Expand Up @@ -841,6 +827,77 @@ TileLoadResult parseExternalTilesetInWorkerThread(
ellipsoid};
}

TileLoadResult parseJsonContentInWorkerThread(
const glm::dmat4& tileTransform,
CesiumGeometry::Axis upAxis,
TileRefine tileRefine,
const std::shared_ptr<spdlog::logger>& pLogger,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
std::shared_ptr<CesiumAsync::IAssetRequest>&& pCompletedRequest,
ExternalContentInitializer&& externalContentInitializer,
const CesiumGeospatial::Ellipsoid& ellipsoid,
bool translateToGltf) {
const CesiumAsync::IAssetResponse* pResponse = pCompletedRequest->response();
const auto& responseData = pResponse->data();

rapidjson::Document tilesetJson;
Comment thread
timoore marked this conversation as resolved.
Outdated
tilesetJson.Parse(
reinterpret_cast<const char*>(responseData.data()),
responseData.size());
if (tilesetJson.HasParseError()) {
SPDLOG_LOGGER_ERROR(
pLogger,
"Error when parsing tileset JSON, error code {} at byte offset {}",
Comment thread
timoore marked this conversation as resolved.
Outdated
tilesetJson.GetParseError(),
tilesetJson.GetErrorOffset());
return TileLoadResult::createFailedResult(
pAssetAccessor,
std::move(pCompletedRequest));
}
if (const auto typeIt = tilesetJson.FindMember("type");
typeIt != tilesetJson.MemberEnd()) {
auto geoJson = CesiumVectorData::GeoJsonDocument::fromGeoJson(tilesetJson);
if (!(geoJson.value.has_value() && !geoJson.errors.hasErrors() &&
translateToGltf)) {
return TileLoadResult::createFailedResult(
pAssetAccessor,
std::move(pCompletedRequest));
Comment thread
timoore marked this conversation as resolved.
Outdated
} else {

Comment thread
timoore marked this conversation as resolved.
Outdated
CesiumVectorData::ConverterResult converterResult =
CesiumVectorData::GltfConverter::convert(*geoJson.value);
if (converterResult.model.has_value() &&
!converterResult.errors.hasErrors()) {
return TileLoadResult{
std::move(*converterResult.model),
CesiumGeometry::Axis::Z,
std::nullopt,
std::nullopt,
std::nullopt,
pAssetAccessor,
std::move(pCompletedRequest),
{},
TileLoadResultState::Success,
ellipsoid};
} else {
return TileLoadResult::createFailedResult(
pAssetAccessor,
std::move(pCompletedRequest));
Comment thread
timoore marked this conversation as resolved.
}
}
} else {
return parseExternalTilesetInWorkerThread(
tileTransform,
upAxis,
tileRefine,
pLogger,
pAssetAccessor,
std::move(pCompletedRequest),
std::move(externalContentInitializer),
ellipsoid,
tilesetJson);
}
}
} // namespace

TilesetJsonLoader::TilesetJsonLoader(
Expand Down Expand Up @@ -1155,15 +1212,16 @@ TilesetJsonLoader::loadTileContent(const TileLoadInput& loadInput) {
} else {
// not a renderable content, then it must be external tileset
Comment thread
timoore marked this conversation as resolved.
Outdated
return asyncSystem.createResolvedFuture(
parseExternalTilesetInWorkerThread(
parseJsonContentInWorkerThread(
tileTransform,
upAxis,
tileRefine,
pLogger,
pAssetAccessor,
std::move(pCompletedRequest),
std::move(externalContentInitializer),
ellipsoid));
ellipsoid,
contentOptions.translateVectorFeatures));
}
});
}
Expand Down
2 changes: 2 additions & 0 deletions CesiumVectorData/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ target_link_libraries(CesiumVectorData
CesiumGeospatial
CesiumAsync
CesiumGltf
CesiumGltfContent
PRIVATE
blend2d::blend2d
$<BUILD_INTERFACE:earcut>
${CESIUM_VECTOR_DATA_ASMJIT_DEPENDENCY}
)
39 changes: 39 additions & 0 deletions CesiumVectorData/include/CesiumVectorData/GltfConverter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <CesiumGltf/Model.h>
#include <CesiumVectorData/GeoJsonDocument.h>

namespace CesiumVectorData {

/**
* @brief The result of converting a GeoJSON file to a glTF model.
*/
struct CESIUMVECTORDATA_API ConverterResult {
Comment thread
timoore marked this conversation as resolved.
Outdated
/**
* @brief The gltf model converted from GeoJSON. This is empty if
* there are errors during the conversion
*/
std::optional<CesiumGltf::Model> model;

/**
* @brief The error and warning list when converting to a gltf
* model. This is empty if there are no errors during the conversion
*/
CesiumUtility::ErrorList errors;
};

/**
* @brief Functional for converting GeoJSON documents to glTF.
*/
class CESIUMVECTORDATA_API GltfConverter {
public:
/**
* @brief Convert geoJSON document to a result which includes a glTF Model
* object.
*
* @param geoJson The GeoJSON document.
* @returns A result object that includes the glTF Model and any errors.
*/
static ConverterResult convert(const GeoJsonDocument& geoJson);
};
} // namespace CesiumVectorData
Loading
Loading