Skip to content

Commit 7d410b7

Browse files
authored
Merge pull request #1677 from CesiumGS/vector-overlay
Implement `CesiumRasterOverlays::VectorDocumentRasterOverlay` in Unreal
2 parents 8e3afd3 + 761bf28 commit 7d410b7

14 files changed

+700
-2
lines changed

CHANGES.md

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

1010
##### Additions :tada:
1111

12+
- Added `CesiumGeoJsonDocumentRasterOverlay`, allowing stylized GeoJSON to be rasterized and draped over terrain and other 3D Tiles.
1213
- Added `FCesiumPropertyAttributeProperty` to represent glTF property attribute properties and `UCesiumPropertyAttributePropertyBlueprintLibrary` to retrieve their values.
1314
- Added `FCesiumPropertyAttribute` to represent glTF property attributes and `UCesiumPropertyAttributeBlueprintLibrary` to act upon them with Blueprints.
1415
- Added `UCesiumPrimitiveMetadataBlueprintLibrary::GetPropertyAttributes` to retrieve the property attributes from a `FCesiumPrimitiveMetadata`.

Source/CesiumRuntime/Private/CesiumGeoJsonDocument.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ FCesiumGeoJsonDocument::FCesiumGeoJsonDocument(
1313
std::shared_ptr<CesiumVectorData::GeoJsonDocument>&& document)
1414
: _pDocument(std::move(document)) {}
1515

16+
bool FCesiumGeoJsonDocument::IsValid() const {
17+
return this->_pDocument != nullptr;
18+
}
19+
20+
const std::shared_ptr<CesiumVectorData::GeoJsonDocument>&
21+
FCesiumGeoJsonDocument::GetDocument() const {
22+
return this->_pDocument;
23+
}
24+
1625
bool UCesiumGeoJsonDocumentBlueprintLibrary::LoadGeoJsonFromString(
1726
const FString& InString,
1827
FCesiumGeoJsonDocument& OutGeoJsonDocument) {
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
2+
3+
#include "CesiumGeoJsonDocumentRasterOverlay.h"
4+
5+
#include "CesiumCustomVersion.h"
6+
#include "CesiumGeometry/QuadtreeTilingScheme.h"
7+
#include "CesiumGeospatial/GlobeRectangle.h"
8+
#include "CesiumGeospatial/Projection.h"
9+
#include "CesiumRasterOverlays/GeoJsonDocumentRasterOverlay.h"
10+
#include "CesiumVectorData/VectorStyle.h"
11+
12+
#include "CesiumRuntime.h"
13+
14+
namespace {
15+
CesiumAsync::Future<std::shared_ptr<CesiumVectorData::GeoJsonDocument>>
16+
wrapLoaderFuture(
17+
UCesiumGeoJsonDocumentRasterOverlay* pThis,
18+
CesiumAsync::Future<
19+
CesiumUtility::Result<CesiumVectorData::GeoJsonDocument>>&& future) {
20+
return std::move(future).thenInMainThread(
21+
[pThis](CesiumUtility::Result<CesiumVectorData::GeoJsonDocument>&&
22+
documentResult)
23+
-> std::shared_ptr<CesiumVectorData::GeoJsonDocument> {
24+
if (documentResult.errors) {
25+
documentResult.errors.logError(
26+
spdlog::default_logger(),
27+
"Errors loading GeoJSON document: ");
28+
return nullptr;
29+
}
30+
31+
std::shared_ptr<CesiumVectorData::GeoJsonDocument> pGeoJsonDocument =
32+
std::make_shared<CesiumVectorData::GeoJsonDocument>(
33+
std::move(*documentResult.value));
34+
35+
if (pThis->OnDocumentLoaded.IsBound()) {
36+
pThis->OnDocumentLoaded.Execute(FCesiumGeoJsonDocument(
37+
std::shared_ptr<CesiumVectorData::GeoJsonDocument>(
38+
pGeoJsonDocument)));
39+
}
40+
41+
return pGeoJsonDocument;
42+
});
43+
}
44+
} // namespace
45+
46+
std::unique_ptr<CesiumRasterOverlays::RasterOverlay>
47+
UCesiumGeoJsonDocumentRasterOverlay::CreateOverlay(
48+
const CesiumRasterOverlays::RasterOverlayOptions& options) {
49+
if (this->Source == ECesiumGeoJsonDocumentRasterOverlaySource::FromDocument &&
50+
!this->GeoJsonDocument.IsValid()) {
51+
// Don't create an overlay with an invalid document.
52+
return nullptr;
53+
}
54+
55+
CesiumRasterOverlays::GeoJsonDocumentRasterOverlayOptions vectorOptions{
56+
this->DefaultStyle.toNative(),
57+
options.ellipsoid,
58+
this->MipLevels};
59+
60+
if (this->Source ==
61+
ECesiumGeoJsonDocumentRasterOverlaySource::FromCesiumIon) {
62+
if (!IsValid(this->CesiumIonServer)) {
63+
this->CesiumIonServer = UCesiumIonServer::GetServerForNewObjects();
64+
}
65+
66+
return std::make_unique<CesiumRasterOverlays::GeoJsonDocumentRasterOverlay>(
67+
TCHAR_TO_UTF8(*this->MaterialLayerKey),
68+
wrapLoaderFuture(
69+
this,
70+
CesiumVectorData::GeoJsonDocument::fromCesiumIonAsset(
71+
getAsyncSystem(),
72+
getAssetAccessor(),
73+
this->IonAssetID,
74+
TCHAR_TO_UTF8(*this->CesiumIonServer->DefaultIonAccessToken),
75+
std::string(TCHAR_TO_UTF8(*this->CesiumIonServer->ApiUrl)) +
76+
"/")),
77+
vectorOptions,
78+
options);
79+
} else if (
80+
this->Source == ECesiumGeoJsonDocumentRasterOverlaySource::FromUrl) {
81+
std::vector<CesiumAsync::IAssetAccessor::THeader> headers;
82+
headers.reserve(this->RequestHeaders.Num());
83+
84+
for (auto& [k, v] : this->RequestHeaders) {
85+
headers.push_back({TCHAR_TO_UTF8(*k), TCHAR_TO_UTF8(*v)});
86+
}
87+
88+
return std::make_unique<CesiumRasterOverlays::GeoJsonDocumentRasterOverlay>(
89+
TCHAR_TO_UTF8(*this->MaterialLayerKey),
90+
wrapLoaderFuture(
91+
this,
92+
CesiumVectorData::GeoJsonDocument::fromUrl(
93+
getAsyncSystem(),
94+
getAssetAccessor(),
95+
TCHAR_TO_UTF8(*this->Url),
96+
std::move(headers))),
97+
vectorOptions,
98+
options);
99+
}
100+
101+
if (this->OnDocumentLoaded.IsBound()) {
102+
this->OnDocumentLoaded.Execute(this->GeoJsonDocument);
103+
}
104+
105+
return std::make_unique<CesiumRasterOverlays::GeoJsonDocumentRasterOverlay>(
106+
getAsyncSystem(),
107+
TCHAR_TO_UTF8(*this->MaterialLayerKey),
108+
this->GeoJsonDocument.GetDocument(),
109+
vectorOptions,
110+
options);
111+
}

Source/CesiumRuntime/Private/CesiumGeoJsonObject.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,41 @@ UCesiumGeoJsonObjectBlueprintLibrary::GetObjectAsFeatureCollection(
451451
return Features;
452452
}
453453

454+
FCesiumVectorStyle UCesiumGeoJsonObjectBlueprintLibrary::GetStyle(
455+
const FCesiumGeoJsonObject& InObject,
456+
EHasValue& Branches) {
457+
if (!InObject._pDocument || !InObject._pObject) {
458+
Branches = EHasValue::NoValue;
459+
return FCesiumVectorStyle();
460+
}
461+
462+
const std::optional<CesiumVectorData::VectorStyle> style =
463+
InObject._pObject->getStyle();
464+
Branches = style ? EHasValue::HasValue : EHasValue::NoValue;
465+
return style ? FCesiumVectorStyle::fromNative(*style) : FCesiumVectorStyle();
466+
}
467+
468+
void UCesiumGeoJsonObjectBlueprintLibrary::SetStyle(
469+
UPARAM(Ref) FCesiumGeoJsonObject& InObject,
470+
const FCesiumVectorStyle& InStyle) {
471+
if (!InObject._pDocument || !InObject._pObject) {
472+
return;
473+
}
474+
475+
const_cast<CesiumVectorData::GeoJsonObject*>(InObject._pObject)->getStyle() =
476+
InStyle.toNative();
477+
}
478+
479+
void UCesiumGeoJsonObjectBlueprintLibrary::ClearStyle(
480+
UPARAM(Ref) FCesiumGeoJsonObject& InObject) {
481+
if (!InObject._pDocument || !InObject._pObject) {
482+
return;
483+
}
484+
485+
const_cast<CesiumVectorData::GeoJsonObject*>(InObject._pObject)->getStyle() =
486+
std::nullopt;
487+
}
488+
454489
FCesiumGeoJsonLineString::FCesiumGeoJsonLineString(TArray<FVector>&& InPoints)
455490
: Points(MoveTemp(InPoints)) {}
456491

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include "CesiumVectorStyle.h"
2+
3+
#include "CesiumUtility/Color.h"
4+
5+
namespace {
6+
CesiumVectorData::LineStyle
7+
lineStyleToNative(const FCesiumVectorLineStyle& InLineStyle) {
8+
return CesiumVectorData::LineStyle{
9+
{CesiumUtility::Color{
10+
InLineStyle.Color.R,
11+
InLineStyle.Color.G,
12+
InLineStyle.Color.B,
13+
InLineStyle.Color.A},
14+
(CesiumVectorData::ColorMode)InLineStyle.ColorMode},
15+
InLineStyle.Width,
16+
(CesiumVectorData::LineWidthMode)InLineStyle.WidthMode};
17+
}
18+
} // namespace
19+
20+
CesiumVectorData::VectorStyle FCesiumVectorStyle::toNative() const {
21+
// Assert that enums are equivalent to catch any issues.
22+
static_assert(
23+
(uint8)CesiumVectorData::ColorMode::Normal ==
24+
(uint8)ECesiumVectorColorMode::Normal);
25+
static_assert(
26+
(uint8)CesiumVectorData::ColorMode::Random ==
27+
(uint8)ECesiumVectorColorMode::Random);
28+
static_assert(
29+
(uint8)CesiumVectorData::LineWidthMode::Meters ==
30+
(uint8)ECesiumVectorLineWidthMode::Meters);
31+
static_assert(
32+
(uint8)CesiumVectorData::LineWidthMode::Pixels ==
33+
(uint8)ECesiumVectorLineWidthMode::Pixels);
34+
35+
std::optional<CesiumVectorData::ColorStyle> fillStyle;
36+
if (this->PolygonStyle.Fill) {
37+
fillStyle = CesiumVectorData::ColorStyle{
38+
CesiumUtility::Color{
39+
this->PolygonStyle.FillStyle.Color.R,
40+
this->PolygonStyle.FillStyle.Color.G,
41+
this->PolygonStyle.FillStyle.Color.B,
42+
this->PolygonStyle.FillStyle.Color.A},
43+
(CesiumVectorData::ColorMode)this->LineStyle.ColorMode};
44+
}
45+
46+
return CesiumVectorData::VectorStyle{
47+
lineStyleToNative(this->LineStyle),
48+
CesiumVectorData::PolygonStyle{
49+
fillStyle,
50+
this->PolygonStyle.Outline
51+
? std::optional<CesiumVectorData::LineStyle>(
52+
lineStyleToNative(this->PolygonStyle.OutlineStyle))
53+
: std::nullopt}};
54+
}
55+
56+
FCesiumVectorStyle
57+
FCesiumVectorStyle::fromNative(const CesiumVectorData::VectorStyle& style) {
58+
FCesiumVectorLineStyle OutlineStyle;
59+
if (style.polygon.outline) {
60+
OutlineStyle = FCesiumVectorLineStyle{
61+
FColor(
62+
(uint8)style.polygon.outline->color.r,
63+
(uint8)style.polygon.outline->color.g,
64+
(uint8)style.polygon.outline->color.b,
65+
(uint8)style.polygon.outline->color.a),
66+
(ECesiumVectorColorMode)style.polygon.outline->colorMode,
67+
style.polygon.outline->width,
68+
(ECesiumVectorLineWidthMode)style.polygon.outline->widthMode};
69+
}
70+
71+
FCesiumVectorPolygonFillStyle FillStyle;
72+
if (style.polygon.fill) {
73+
FillStyle = FCesiumVectorPolygonFillStyle{
74+
FColor(
75+
(uint8)style.polygon.fill->color.r,
76+
(uint8)style.polygon.fill->color.g,
77+
(uint8)style.polygon.fill->color.b,
78+
(uint8)style.polygon.fill->color.a),
79+
(ECesiumVectorColorMode)style.polygon.fill->colorMode};
80+
}
81+
82+
return FCesiumVectorStyle{
83+
FCesiumVectorLineStyle{
84+
FColor(
85+
(uint8)style.line.color.r,
86+
(uint8)style.line.color.g,
87+
(uint8)style.line.color.b,
88+
(uint8)style.line.color.a),
89+
(ECesiumVectorColorMode)style.line.colorMode,
90+
style.line.width,
91+
(ECesiumVectorLineWidthMode)style.line.widthMode},
92+
FCesiumVectorPolygonStyle{
93+
style.polygon.fill.has_value(),
94+
FillStyle,
95+
style.polygon.outline.has_value(),
96+
OutlineStyle}};
97+
}

Source/CesiumRuntime/Public/CesiumGeoJsonDocument.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ struct FCesiumGeoJsonDocument {
3434
FCesiumGeoJsonDocument(
3535
std::shared_ptr<CesiumVectorData::GeoJsonDocument>&& document);
3636

37+
/**
38+
* @brief Checks if this FCesiumGeoJsonDocument is valid (document is not
39+
* nullptr).
40+
*/
41+
bool IsValid() const;
42+
43+
/**
44+
* @brief Returns the `CesiumVectorData::GeoJsonDocument` this wraps.
45+
*/
46+
const std::shared_ptr<CesiumVectorData::GeoJsonDocument>& GetDocument() const;
47+
3748
private:
3849
std::shared_ptr<CesiumVectorData::GeoJsonDocument> _pDocument;
3950

0 commit comments

Comments
 (0)