Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- `Cesium3DTilesetSelection::Tileset::getRootTileAvailableEvent` will now resolve even when a `Tileset` is constructed with invalid source parameters, instead of hanging indefinitely.
- Fixed compilation error with MSVC when using custom `CesiumITwinClient::PagedList` types.
- Fixed a "maybe uninitialized" error in `GeoJsonDocumentRasterOverlay` signaled by gcc 15.2.
- Fixed crashes in `GeoJsonDocumentRasterOverlay` caused by the `GeoJsonDocumentRasterOverlayTileProvider` being freed before actions on the worker thread completed.

### v0.58.0 - 2026-03-02

Expand Down
49 changes: 24 additions & 25 deletions CesiumRasterOverlays/src/GeoJsonDocumentRasterOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ struct QuadtreeNode {
struct Quadtree {
GlobeRectangle rectangle = GlobeRectangle::EMPTY;
uint32_t rootId = 0;
VectorStyle defaultStyle;
std::vector<QuadtreeNode> nodes;
std::vector<QuadtreeGeometryData> data;
/**
Expand Down Expand Up @@ -555,28 +556,24 @@ uint32_t buildQuadtreeNode(
return resultId;
}

Quadtree buildQuadtree(
void buildQuadtree(
Quadtree& tree,
const std::shared_ptr<GeoJsonDocument>& document,
const VectorStyle& defaultStyle,
const Ellipsoid& ellipsoid) {
tree.defaultStyle = defaultStyle;

BoundingRegionBuilder builder;
std::vector<QuadtreeGeometryData> data;
const std::optional<VectorStyle>& rootObjectStyle =
document->rootObject.getStyle();
addPrimitivesToData(
&document->rootObject,
data,
tree.data,
builder,
rootObjectStyle ? *rootObjectStyle : defaultStyle,
rootObjectStyle ? *rootObjectStyle : tree.defaultStyle,
ellipsoid);

Quadtree tree{
builder.toGlobeRectangle(),
0,
std::vector<QuadtreeNode>(),
std::move(data),
std::vector<uint32_t>(),
std::vector<uint32_t>()};
tree.rectangle = builder.toGlobeRectangle();

std::vector<uint32_t> dataIndices;
dataIndices.reserve(tree.data.size());
Expand All @@ -598,8 +595,6 @@ Quadtree buildQuadtree(
QuadtreeTileID(0, 0, 0));
// Add last entry so [i + 1] is always valid
tree.dataNodeIndicesBegin.emplace_back((uint32_t)tree.dataIndices.size());

return tree;
}

void rasterizeQuadtreeNode(
Expand Down Expand Up @@ -684,8 +679,7 @@ class CESIUMRASTEROVERLAYS_API GeoJsonDocumentRasterOverlayTileProvider final

private:
std::shared_ptr<GeoJsonDocument> _pDocument;
VectorStyle _defaultStyle;
Quadtree _tree;
std::shared_ptr<Quadtree> _pTree;
Ellipsoid _ellipsoid;
uint32_t _mipLevels;

Expand All @@ -703,14 +697,15 @@ class CESIUMRASTEROVERLAYS_API GeoJsonDocumentRasterOverlayTileProvider final
GeographicProjection(geoJsonOptions.ellipsoid),
GlobeRectangle::MAXIMUM)),
_pDocument(std::move(pDocument)),
_defaultStyle(geoJsonOptions.defaultStyle),
_tree(),
_pTree(),
_ellipsoid(geoJsonOptions.ellipsoid),
_mipLevels(geoJsonOptions.mipLevels) {
CESIUM_ASSERT(this->_pDocument);
this->_tree = buildQuadtree(
this->_pTree = std::make_shared<Quadtree>();
buildQuadtree(
*this->_pTree,
this->_pDocument,
this->_defaultStyle,
geoJsonOptions.defaultStyle,
geoJsonOptions.ellipsoid);
}

Expand All @@ -719,19 +714,23 @@ class CESIUMRASTEROVERLAYS_API GeoJsonDocumentRasterOverlayTileProvider final
// Choose the texture size according to the geometry screen size and raster
// SSE, but no larger than the maximum texture size.
const RasterOverlayOptions& options = this->getOwner().getOptions();
glm::ivec2 textureSize = glm::min(
glm::ivec2(
overlayTile.getTargetScreenPixels() /
options.maximumScreenSpaceError),
glm::ivec2(options.maximumTextureSize));
glm::ivec2 textureSize = glm::max(
glm::min(
glm::ivec2(
overlayTile.getTargetScreenPixels() /
options.maximumScreenSpaceError),
glm::ivec2(options.maximumTextureSize)),
glm::ivec2(1));

return this->getAsyncSystem().runInWorkerThread(
[&tree = this->_tree,
[pTree = this->_pTree,
pDocument = this->_pDocument,
ellipsoid = this->_ellipsoid,
projection = this->getProjection(),
rectangle = overlayTile.getRectangle(),
textureSize,
mipLevels = this->_mipLevels]() -> LoadedRasterOverlayImage {
const Quadtree& tree = *pTree;
const CesiumGeospatial::GlobeRectangle tileRectangle =
CesiumGeospatial::unprojectRectangleSimple(projection, rectangle);

Expand Down