From 4a26fe0c03e6dbdc36ba53dfe02e2f6559a94ffb Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Mon, 31 Mar 2025 17:34:48 -0400 Subject: [PATCH 1/6] Blueprint async action for Cesium ion geocoder --- .../CesiumGeocoderServiceBlueprintLibrary.cpp | 143 ++++++++++++ .../CesiumGeocoderServiceBlueprintLibrary.h | 212 ++++++++++++++++++ 2 files changed, 355 insertions(+) create mode 100644 Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp create mode 100644 Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h diff --git a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp new file mode 100644 index 000000000..3e9da4051 --- /dev/null +++ b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp @@ -0,0 +1,143 @@ +#include "CesiumGeocoderServiceBlueprintLibrary.h" +#include "CesiumRuntime.h" + +FCesiumGeocoderServiceAttribution::FCesiumGeocoderServiceAttribution( + const CesiumIonClient::GeocoderAttribution& attribution) + : Html(UTF8_TO_TCHAR(attribution.html.c_str())), + bShowOnScreen(attribution.showOnScreen) {} + +UCesiumGeocoderServiceFeature::UCesiumGeocoderServiceFeature() : _feature() {} + +FVector UCesiumGeocoderServiceFeature::GetCartographic() const { + if (!this->_feature) { + return FVector::Zero(); + } + + const CesiumGeospatial::Cartographic cartographic = + this->_feature->getCartographic(); + return FVector( + CesiumUtility::Math::radiansToDegrees(cartographic.longitude), + CesiumUtility::Math::radiansToDegrees(cartographic.latitude), + cartographic.height); +} + +FBox UCesiumGeocoderServiceFeature::GetGlobeRectangle() const { + if (!this->_feature) { + return FBox(); + } + + const CesiumGeospatial::GlobeRectangle rect = + this->_feature->getGlobeRectangle(); + const CesiumGeospatial::Cartographic southWest = rect.getSouthwest(); + const CesiumGeospatial::Cartographic northEast = rect.getNortheast(); + return FBox( + FVector( + CesiumUtility::Math::radiansToDegrees(southWest.longitude), + CesiumUtility::Math::radiansToDegrees(southWest.latitude), + southWest.height), + FVector( + CesiumUtility::Math::radiansToDegrees(northEast.longitude), + CesiumUtility::Math::radiansToDegrees(northEast.latitude), + northEast.height)); +} + +FString UCesiumGeocoderServiceFeature::GetDisplayName() const { + if (!this->_feature) { + return FString(); + } + + return UTF8_TO_TCHAR(this->_feature->displayName.c_str()); +} + +void UCesiumGeocoderServiceFeature::SetFeature( + CesiumIonClient::GeocoderFeature&& feature) { + this->_feature = std::move(feature); +} + +UCesiumGeocoderServiceIonGeocoderAsyncAction* +UCesiumGeocoderServiceIonGeocoderAsyncAction::Geocode( + const FString& IonAccessToken, + const UCesiumIonServer* CesiumIonServer, + ECesiumIonGeocoderProviderType ProviderType, + ECesiumIonGeocoderRequestType RequestType, + const FString& Query) { + UCesiumGeocoderServiceIonGeocoderAsyncAction* pAction = + NewObject(); + pAction->_ionAccessToken = IonAccessToken; + pAction->_cesiumIonServer = CesiumIonServer; + pAction->_providerType = ProviderType; + pAction->_requestType = RequestType; + pAction->_query = Query; + return pAction; +} + +void UCesiumGeocoderServiceIonGeocoderAsyncAction::Activate() { + CesiumIonClient::Connection::appData( + getAsyncSystem(), + getAssetAccessor(), + TCHAR_TO_UTF8(*this->_cesiumIonServer->ApiUrl)) + .thenInMainThread([this](CesiumIonClient::Response< + CesiumIonClient::ApplicationData>&& response) { + if (!response.value) { + this->OnGeocodeRequestComplete.Broadcast( + false, + nullptr, + FString::Printf( + TEXT("App data request failed, error code %s, message %s"), + UTF8_TO_TCHAR(response.errorCode.c_str()), + UTF8_TO_TCHAR(response.errorMessage.c_str()))); + return; + } + + CesiumIonClient::Connection connection( + getAsyncSystem(), + getAssetAccessor(), + TCHAR_TO_UTF8(*this->_ionAccessToken), + *response.value, + TCHAR_TO_UTF8(*this->_cesiumIonServer->ApiUrl)); + connection + .geocode( + (CesiumIonClient::GeocoderProviderType)this->_providerType, + (CesiumIonClient::GeocoderRequestType)this->_requestType, + TCHAR_TO_UTF8(*this->_query)) + .thenInMainThread([this](CesiumIonClient::Response< + CesiumIonClient::GeocoderResult>&& + response) { + if (!response.value) { + this->OnGeocodeRequestComplete.Broadcast( + false, + nullptr, + FString::Printf( + TEXT( + "Geocode request failed, error code %s, message %s"), + UTF8_TO_TCHAR(response.errorCode.c_str()), + UTF8_TO_TCHAR(response.errorMessage.c_str()))); + return; + } + + UCesiumGeocoderServiceResult* pResult = + NewObject(); + + pResult->Attributions.Reserve( + response.value->attributions.size()); + for (const CesiumIonClient::GeocoderAttribution& attr : + response.value->attributions) { + pResult->Attributions.Emplace(attr); + } + + pResult->Features.Reserve(response.value->features.size()); + for (CesiumIonClient::GeocoderFeature& feature : + response.value->features) { + UCesiumGeocoderServiceFeature* pFeature = + NewObject(); + pFeature->SetFeature(std::move(feature)); + pResult->Features.Emplace(pFeature); + } + + this->OnGeocodeRequestComplete.Broadcast( + true, + pResult, + FString()); + }); + }); +} diff --git a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h new file mode 100644 index 000000000..5a8fde1fb --- /dev/null +++ b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h @@ -0,0 +1,212 @@ +// Copyright 2020-2025 CesiumGS, Inc. and Contributors + +#pragma once + +#include "Cesium3DTileset.h" +#include "CesiumGeoreference.h" +#include "Kismet/BlueprintAsyncActionBase.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Math/MathFwd.h" +#include "Misc/Optional.h" +#include "Templates/SharedPointer.h" +#include "UObject/Object.h" +#include "UObject/ObjectMacros.h" + +THIRD_PARTY_INCLUDES_START +#include +THIRD_PARTY_INCLUDES_END + +#include +#include +#include +#include + +#include + +#include "CesiumGeocoderServiceBlueprintLibrary.generated.h" + +/** + * @brief The supported providers that can be accessed through ion's geocoder + * API. + */ +UENUM(BlueprintType) +enum class ECesiumIonGeocoderProviderType : uint8 { + /** + * @brief Google geocoder, for use with Google data. + */ + Google = CesiumIonClient::GeocoderProviderType::Google, + /** + * @brief Bing geocoder, for use with Bing data. + */ + Bing = CesiumIonClient::GeocoderProviderType::Bing, + /** + * @brief Use the default geocoder as set on the server. Used when neither + * Bing or Google data is used. + */ + Default = CesiumIonClient::GeocoderProviderType::Default +}; + +/** + * @brief The supported types of requests to geocoding API. + */ +UENUM(BlueprintType) +enum class ECesiumIonGeocoderRequestType : uint8 { + /** + * @brief Perform a full search from a complete query. + */ + Search = CesiumIonClient::GeocoderRequestType::Search, + /** + * @brief Perform a quick search based on partial input, such as while a user + * is typing. + * + * The search results may be less accurate or exhaustive than using + * `ECesiumIonGeocoderRequestType::Search`. + */ + Autocomplete = CesiumIonClient::GeocoderRequestType::Autocomplete +}; + +/** + * @brief Attribution information for a query to a geocoder service. + */ +USTRUCT(BlueprintType) +struct FCesiumGeocoderServiceAttribution { + GENERATED_BODY() +public: + FCesiumGeocoderServiceAttribution() {} + FCesiumGeocoderServiceAttribution( + const CesiumIonClient::GeocoderAttribution& attribution); + + /** + * @brief An HTML string containing the necessary attribution information. + */ + UPROPERTY(BlueprintReadOnly) + FString Html; + + /** + * @brief If true, the credit should be visible in the main credit container. + * Otherwise, it can appear in a popover. + */ + UPROPERTY(BlueprintReadOnly) + bool bShowOnScreen; +}; + +/** + * @brief A single feature (a location or region) obtained from a geocoder + * service. + */ +UCLASS(BlueprintType) +class UCesiumGeocoderServiceFeature : public UObject { + GENERATED_BODY() +public: + UCesiumGeocoderServiceFeature(); + + /** + * @brief Returns a position in Longitude, Latitude, and Height representing + * this feature. + * + * If the geocoder service returned a bounding box for this result, this will + * return the center of the bounding box. If the geocoder service returned a + * coordinate for this result, this will return the coordinate. + */ + UFUNCTION(BlueprintPure) + FVector GetCartographic() const; + + /** + * @brief Returns an FBox representing this feature. `FBox::Min` will hold the + * southwest corner while `FBox::Max` will hold the northwest corner. + * + * If the geocoder service returned a bounding box for this result, this will + * return the bounding box. If the geocoder service returned a coordinate for + * this result, this will return a zero-width rectangle at that coordinate. + */ + UFUNCTION(BlueprintPure) + FBox GetGlobeRectangle() const; + + /** + * @brief The user-friendly display name of this feature. + */ + UFUNCTION(BlueprintPure) + FString GetDisplayName() const; + + void SetFeature(CesiumIonClient::GeocoderFeature&& feature); + +private: + std::optional _feature; +}; + +/** + * @brief The result of making a request to a geocoder service. + */ +UCLASS(BlueprintType) +class UCesiumGeocoderServiceResult : public UObject { + GENERATED_BODY() +public: + UCesiumGeocoderServiceResult() {} + + /** + * @brief Any necessary attributions for this geocoder result. + */ + UPROPERTY(BlueprintReadOnly) + TArray Attributions; + + /** + * @brief The features obtained from this geocoder service, if any. + */ + UPROPERTY(BlueprintReadOnly) + TArray Features; +}; + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams( + FCesiumGeocoderServiceDelegate, + bool, + Success, + UCesiumGeocoderServiceResult*, + Result, + FString, + Error); + +UCLASS() +class CESIUMRUNTIME_API UCesiumGeocoderServiceIonGeocoderAsyncAction + : public UBlueprintAsyncActionBase { + GENERATED_BODY() + +public: + /** + * @brief Queries the Cesium ion Geocoder service. + * + * @param IonAccessToken The access token to use for Cesium ion. This token + * must have the `geocode` scope. + * @param CesiumIonServer Information on the Cesium ion server to perform this + * request against. + * @param ProviderType The provider to obtain a geocoding result from. + * @param RequestType The type of geocoding request to make. + * @param Query The query string. + */ + UFUNCTION( + BlueprintCallable, + Category = "Cesium", + meta = + (BlueprintInternalUseOnly = true, + DisplayName = "Query Cesium ion Geocoder")) + static UCesiumGeocoderServiceIonGeocoderAsyncAction* Geocode( + const FString& IonAccessToken, + const UCesiumIonServer* CesiumIonServer, + ECesiumIonGeocoderProviderType ProviderType, + ECesiumIonGeocoderRequestType RequestType, + const FString& Query); + + UPROPERTY(BlueprintAssignable) + FCesiumGeocoderServiceDelegate OnGeocodeRequestComplete; + + virtual void Activate() override; + +private: + FString _ionAccessToken; + + UPROPERTY() + const UCesiumIonServer* _cesiumIonServer; + + ECesiumIonGeocoderProviderType _providerType; + ECesiumIonGeocoderRequestType _requestType; + FString _query; +}; From 7bcdc55b7c72b32cb0b368c22e6c6f7b32eb9dde Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Thu, 10 Apr 2025 09:39:27 -0400 Subject: [PATCH 2/6] Add Category to fix build issues --- .../CesiumGeocoderServiceBlueprintLibrary.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h index 5a8fde1fb..327ccc6e4 100644 --- a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h +++ b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h @@ -79,14 +79,14 @@ struct FCesiumGeocoderServiceAttribution { /** * @brief An HTML string containing the necessary attribution information. */ - UPROPERTY(BlueprintReadOnly) + UPROPERTY(BlueprintReadOnly, Category = "Cesium|Geocoder") FString Html; /** * @brief If true, the credit should be visible in the main credit container. * Otherwise, it can appear in a popover. */ - UPROPERTY(BlueprintReadOnly) + UPROPERTY(BlueprintReadOnly, Category = "Cesium|Geocoder") bool bShowOnScreen; }; @@ -108,7 +108,7 @@ class UCesiumGeocoderServiceFeature : public UObject { * return the center of the bounding box. If the geocoder service returned a * coordinate for this result, this will return the coordinate. */ - UFUNCTION(BlueprintPure) + UFUNCTION(BlueprintPure, Category = "Cesium|Geocoder") FVector GetCartographic() const; /** @@ -119,13 +119,13 @@ class UCesiumGeocoderServiceFeature : public UObject { * return the bounding box. If the geocoder service returned a coordinate for * this result, this will return a zero-width rectangle at that coordinate. */ - UFUNCTION(BlueprintPure) + UFUNCTION(BlueprintPure, Category = "Cesium|Geocoder") FBox GetGlobeRectangle() const; /** * @brief The user-friendly display name of this feature. */ - UFUNCTION(BlueprintPure) + UFUNCTION(BlueprintPure, Category = "Cesium|Geocoder") FString GetDisplayName() const; void SetFeature(CesiumIonClient::GeocoderFeature&& feature); @@ -146,13 +146,13 @@ class UCesiumGeocoderServiceResult : public UObject { /** * @brief Any necessary attributions for this geocoder result. */ - UPROPERTY(BlueprintReadOnly) + UPROPERTY(BlueprintReadOnly, Category = "Cesium|Geocoder") TArray Attributions; /** * @brief The features obtained from this geocoder service, if any. */ - UPROPERTY(BlueprintReadOnly) + UPROPERTY(BlueprintReadOnly, Category = "Cesium|Geocoder") TArray Features; }; @@ -184,7 +184,7 @@ class CESIUMRUNTIME_API UCesiumGeocoderServiceIonGeocoderAsyncAction */ UFUNCTION( BlueprintCallable, - Category = "Cesium", + Category = "Cesium|Geocoder", meta = (BlueprintInternalUseOnly = true, DisplayName = "Query Cesium ion Geocoder")) From 9de063e97488e304e8c9208fc63852fea556ca49 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Tue, 29 Apr 2025 16:56:38 -0400 Subject: [PATCH 3/6] Remove unnecessary constructor --- .../Private/CesiumGeocoderServiceBlueprintLibrary.cpp | 2 -- .../Public/CesiumGeocoderServiceBlueprintLibrary.h | 2 -- extern/cesium-native | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp index 3e9da4051..f09ec2724 100644 --- a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp +++ b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp @@ -6,8 +6,6 @@ FCesiumGeocoderServiceAttribution::FCesiumGeocoderServiceAttribution( : Html(UTF8_TO_TCHAR(attribution.html.c_str())), bShowOnScreen(attribution.showOnScreen) {} -UCesiumGeocoderServiceFeature::UCesiumGeocoderServiceFeature() : _feature() {} - FVector UCesiumGeocoderServiceFeature::GetCartographic() const { if (!this->_feature) { return FVector::Zero(); diff --git a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h index 327ccc6e4..94ea8d58a 100644 --- a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h +++ b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h @@ -98,8 +98,6 @@ UCLASS(BlueprintType) class UCesiumGeocoderServiceFeature : public UObject { GENERATED_BODY() public: - UCesiumGeocoderServiceFeature(); - /** * @brief Returns a position in Longitude, Latitude, and Height representing * this feature. diff --git a/extern/cesium-native b/extern/cesium-native index 70b97bb61..e9d767cf0 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit 70b97bb6148528d266f1bd9cac8bd7c3468942a5 +Subproject commit e9d767cf0097d72667bce22a4bf678dd1865bd59 From 4f43c61124b1a1a176bfd5f2253efbf10d425f96 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Wed, 30 Apr 2025 10:07:41 -0400 Subject: [PATCH 4/6] Changes from review --- .../CesiumGeocoderServiceBlueprintLibrary.cpp | 65 ++++++++----------- .../CesiumGeocoderServiceBlueprintLibrary.h | 40 +++++++----- 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp index f09ec2724..81dad623a 100644 --- a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp +++ b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp @@ -1,4 +1,5 @@ #include "CesiumGeocoderServiceBlueprintLibrary.h" +#include "CesiumIonServer.h" #include "CesiumRuntime.h" FCesiumGeocoderServiceAttribution::FCesiumGeocoderServiceAttribution( @@ -6,29 +7,14 @@ FCesiumGeocoderServiceAttribution::FCesiumGeocoderServiceAttribution( : Html(UTF8_TO_TCHAR(attribution.html.c_str())), bShowOnScreen(attribution.showOnScreen) {} -FVector UCesiumGeocoderServiceFeature::GetCartographic() const { - if (!this->_feature) { - return FVector::Zero(); - } +FCesiumGeocoderServiceFeature::FCesiumGeocoderServiceFeature( + const CesiumIonClient::GeocoderFeature& feature) { + this->DisplayName = UTF8_TO_TCHAR(feature.displayName.c_str()); - const CesiumGeospatial::Cartographic cartographic = - this->_feature->getCartographic(); - return FVector( - CesiumUtility::Math::radiansToDegrees(cartographic.longitude), - CesiumUtility::Math::radiansToDegrees(cartographic.latitude), - cartographic.height); -} - -FBox UCesiumGeocoderServiceFeature::GetGlobeRectangle() const { - if (!this->_feature) { - return FBox(); - } - - const CesiumGeospatial::GlobeRectangle rect = - this->_feature->getGlobeRectangle(); + const CesiumGeospatial::GlobeRectangle rect = feature.getGlobeRectangle(); const CesiumGeospatial::Cartographic southWest = rect.getSouthwest(); const CesiumGeospatial::Cartographic northEast = rect.getNortheast(); - return FBox( + this->GlobeRectangle = FBox( FVector( CesiumUtility::Math::radiansToDegrees(southWest.longitude), CesiumUtility::Math::radiansToDegrees(southWest.latitude), @@ -37,19 +23,12 @@ FBox UCesiumGeocoderServiceFeature::GetGlobeRectangle() const { CesiumUtility::Math::radiansToDegrees(northEast.longitude), CesiumUtility::Math::radiansToDegrees(northEast.latitude), northEast.height)); -} -FString UCesiumGeocoderServiceFeature::GetDisplayName() const { - if (!this->_feature) { - return FString(); - } - - return UTF8_TO_TCHAR(this->_feature->displayName.c_str()); -} - -void UCesiumGeocoderServiceFeature::SetFeature( - CesiumIonClient::GeocoderFeature&& feature) { - this->_feature = std::move(feature); + const CesiumGeospatial::Cartographic cartographic = feature.getCartographic(); + this->Cartographic = FVector( + CesiumUtility::Math::radiansToDegrees(cartographic.longitude), + CesiumUtility::Math::radiansToDegrees(cartographic.latitude), + cartographic.height); } UCesiumGeocoderServiceIonGeocoderAsyncAction* @@ -59,10 +38,16 @@ UCesiumGeocoderServiceIonGeocoderAsyncAction::Geocode( ECesiumIonGeocoderProviderType ProviderType, ECesiumIonGeocoderRequestType RequestType, const FString& Query) { + UCesiumIonServer* pServer = UCesiumIonServer::GetDefaultServer(); + UCesiumGeocoderServiceIonGeocoderAsyncAction* pAction = NewObject(); - pAction->_ionAccessToken = IonAccessToken; - pAction->_cesiumIonServer = CesiumIonServer; + pAction->_cesiumIonServer = + IsValid(CesiumIonServer) ? CesiumIonServer : pServer; + pAction->_ionAccessToken = + IonAccessToken.IsEmpty() + ? pAction->_cesiumIonServer->DefaultIonAccessToken + : IonAccessToken; pAction->_providerType = ProviderType; pAction->_requestType = RequestType; pAction->_query = Query; @@ -70,6 +55,13 @@ UCesiumGeocoderServiceIonGeocoderAsyncAction::Geocode( } void UCesiumGeocoderServiceIonGeocoderAsyncAction::Activate() { + if (!IsValid(this->_cesiumIonServer)) { + this->OnGeocodeRequestComplete.Broadcast( + false, + nullptr, + TEXT("Could not find valid Cesium ion server object to use.")); + return; + } CesiumIonClient::Connection::appData( getAsyncSystem(), getAssetAccessor(), @@ -126,10 +118,7 @@ void UCesiumGeocoderServiceIonGeocoderAsyncAction::Activate() { pResult->Features.Reserve(response.value->features.size()); for (CesiumIonClient::GeocoderFeature& feature : response.value->features) { - UCesiumGeocoderServiceFeature* pFeature = - NewObject(); - pFeature->SetFeature(std::move(feature)); - pResult->Features.Emplace(pFeature); + pResult->Features.Emplace(feature); } this->OnGeocodeRequestComplete.Broadcast( diff --git a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h index 94ea8d58a..ba3bb63d0 100644 --- a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h +++ b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h @@ -72,7 +72,7 @@ USTRUCT(BlueprintType) struct FCesiumGeocoderServiceAttribution { GENERATED_BODY() public: - FCesiumGeocoderServiceAttribution() {} + FCesiumGeocoderServiceAttribution() = default; FCesiumGeocoderServiceAttribution( const CesiumIonClient::GeocoderAttribution& attribution); @@ -94,10 +94,14 @@ struct FCesiumGeocoderServiceAttribution { * @brief A single feature (a location or region) obtained from a geocoder * service. */ -UCLASS(BlueprintType) -class UCesiumGeocoderServiceFeature : public UObject { +USTRUCT(BlueprintType) +struct FCesiumGeocoderServiceFeature { GENERATED_BODY() public: + FCesiumGeocoderServiceFeature() = default; + FCesiumGeocoderServiceFeature( + const CesiumIonClient::GeocoderFeature& feature); + /** * @brief Returns a position in Longitude, Latitude, and Height representing * this feature. @@ -106,8 +110,11 @@ class UCesiumGeocoderServiceFeature : public UObject { * return the center of the bounding box. If the geocoder service returned a * coordinate for this result, this will return the coordinate. */ - UFUNCTION(BlueprintPure, Category = "Cesium|Geocoder") - FVector GetCartographic() const; + UPROPERTY( + BlueprintReadOnly, + Category = "Cesium|Geocoder", + meta = (AllowPrivateAccess)) + FVector Cartographic; /** * @brief Returns an FBox representing this feature. `FBox::Min` will hold the @@ -117,19 +124,20 @@ class UCesiumGeocoderServiceFeature : public UObject { * return the bounding box. If the geocoder service returned a coordinate for * this result, this will return a zero-width rectangle at that coordinate. */ - UFUNCTION(BlueprintPure, Category = "Cesium|Geocoder") - FBox GetGlobeRectangle() const; + UPROPERTY( + BlueprintReadOnly, + Category = "Cesium|Geocoder", + meta = (AllowPrivateAccess)) + FBox GlobeRectangle; /** * @brief The user-friendly display name of this feature. */ - UFUNCTION(BlueprintPure, Category = "Cesium|Geocoder") - FString GetDisplayName() const; - - void SetFeature(CesiumIonClient::GeocoderFeature&& feature); - -private: - std::optional _feature; + UPROPERTY( + BlueprintReadOnly, + Category = "Cesium|Geocoder", + meta = (AllowPrivateAccess)) + FString DisplayName; }; /** @@ -139,7 +147,7 @@ UCLASS(BlueprintType) class UCesiumGeocoderServiceResult : public UObject { GENERATED_BODY() public: - UCesiumGeocoderServiceResult() {} + UCesiumGeocoderServiceResult() = default; /** * @brief Any necessary attributions for this geocoder result. @@ -151,7 +159,7 @@ class UCesiumGeocoderServiceResult : public UObject { * @brief The features obtained from this geocoder service, if any. */ UPROPERTY(BlueprintReadOnly, Category = "Cesium|Geocoder") - TArray Features; + TArray Features; }; DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams( From ecd2068d522bbc893b9b749f79118a4abad50956 Mon Sep 17 00:00:00 2001 From: Ashley Rogers Date: Wed, 30 Apr 2025 10:18:04 -0400 Subject: [PATCH 5/6] Update cesium-native --- extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/cesium-native b/extern/cesium-native index e9d767cf0..0ac6ced84 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit e9d767cf0097d72667bce22a4bf678dd1865bd59 +Subproject commit 0ac6ced8456d008f9e865272b30c4137a3ea209a From e628786dcd112c196550b6dc21da699cfea3b20c Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 1 May 2025 08:44:50 +1000 Subject: [PATCH 6/6] Rename Cartographic -> LongitudeLatitudeHeight and tweak doc. --- .../CesiumGeocoderServiceBlueprintLibrary.cpp | 2 +- .../CesiumGeocoderServiceBlueprintLibrary.h | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp index 81dad623a..30a6dbee5 100644 --- a/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp +++ b/Source/CesiumRuntime/Private/CesiumGeocoderServiceBlueprintLibrary.cpp @@ -25,7 +25,7 @@ FCesiumGeocoderServiceFeature::FCesiumGeocoderServiceFeature( northEast.height)); const CesiumGeospatial::Cartographic cartographic = feature.getCartographic(); - this->Cartographic = FVector( + this->LongitudeLatitudeHeight = FVector( CesiumUtility::Math::radiansToDegrees(cartographic.longitude), CesiumUtility::Math::radiansToDegrees(cartographic.latitude), cartographic.height); diff --git a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h index ba3bb63d0..f0b422ead 100644 --- a/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h +++ b/Source/CesiumRuntime/Public/CesiumGeocoderServiceBlueprintLibrary.h @@ -103,8 +103,15 @@ struct FCesiumGeocoderServiceFeature { const CesiumIonClient::GeocoderFeature& feature); /** - * @brief Returns a position in Longitude, Latitude, and Height representing - * this feature. + * @brief The position of the feature expressed as longitude in degrees (X), + * latitude in degrees (Y), and height in meters above the ellipsoid (Z). + * + * Do not confuse the ellipsoid height with a geoid height or height above + * mean sea level, which can be tens of meters higher or lower depending on + * where in the world the object is located. + * + * The height may be 0.0, indicating that the geocoder did not provide a + * height for the feature. * * If the geocoder service returned a bounding box for this result, this will * return the center of the bounding box. If the geocoder service returned a @@ -114,11 +121,13 @@ struct FCesiumGeocoderServiceFeature { BlueprintReadOnly, Category = "Cesium|Geocoder", meta = (AllowPrivateAccess)) - FVector Cartographic; + FVector LongitudeLatitudeHeight; /** - * @brief Returns an FBox representing this feature. `FBox::Min` will hold the - * southwest corner while `FBox::Max` will hold the northwest corner. + * @brief The globe rectangle that bounds the feature. The box's `Min.X` is + * the Westernmost longitude in degrees, `Min.Y` is the Southernmost latitude + * in degrees, `Max.X` is the Easternmost longitude in degrees, and `Max.Y` is + * the Northernmost latitude in degrees. * * If the geocoder service returned a bounding box for this result, this will * return the bounding box. If the geocoder service returned a coordinate for