diff --git a/CHANGES.md b/CHANGES.md index 25b7037a8..daa3a8a20 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,10 +4,12 @@ ##### Additions :tada: +- Added `CesiumAzureMapsRasterOverlay`. - Added the interface `ICesium3DTilesetLifecycleEventReceiver`: when an implementation is registered on a tileset (with `ACesium3DTileset::SetLifecycleEventReceiver`), its functions will be called at various points in a tile's lifecycle, like when a mesh component is created, when a material is instanced, when the tile changes visibility, when it is unloaded, etc. ##### Fixes :wrench: +- Fixed a bug where `CesiumCreditSystem` would not filter out empty credits, resulting in duplicate on-screen delimiters. - Fixed a problem where multi-selecting `UCesiumGlobeAnchorComponent` could cause the selected components to teleport to 0 degrees longitude and 0 degrees latitude. Now, the geospatial position and orientation fields are hidden while multi-selecting. ### v2.20.0 - 2025-10-01 diff --git a/Source/CesiumRuntime/Private/CesiumAzureMapsRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumAzureMapsRasterOverlay.cpp new file mode 100644 index 000000000..6928208a0 --- /dev/null +++ b/Source/CesiumRuntime/Private/CesiumAzureMapsRasterOverlay.cpp @@ -0,0 +1,65 @@ +// Copyright 2020-2025 CesiumGS, Inc. and Contributors + +#include "CesiumAzureMapsRasterOverlay.h" +#include +#include + +using namespace CesiumRasterOverlays; + +namespace { +std::string getTilesetId(EAzureMapsTilesetId tilesetId) { + switch (tilesetId) { + case EAzureMapsTilesetId::BaseDarkGrey: + return AzureMapsTilesetId::baseDarkGrey; + case EAzureMapsTilesetId::BaseLabelsRoad: + return AzureMapsTilesetId::baseLabelsRoad; + case EAzureMapsTilesetId::BaseLabelsDarkGrey: + return AzureMapsTilesetId::baseLabelsDarkGrey; + case EAzureMapsTilesetId::BaseHybridRoad: + return AzureMapsTilesetId::baseHybridRoad; + case EAzureMapsTilesetId::BaseHybridDarkGrey: + return AzureMapsTilesetId::baseHybridDarkGrey; + case EAzureMapsTilesetId::Imagery: + return AzureMapsTilesetId::imagery; + case EAzureMapsTilesetId::Terra: + return AzureMapsTilesetId::terra; + case EAzureMapsTilesetId::WeatherRadar: + return AzureMapsTilesetId::weatherRadar; + case EAzureMapsTilesetId::WeatherInfrared: + return AzureMapsTilesetId::weatherInfrared; + case EAzureMapsTilesetId::TrafficAbsolute: + return AzureMapsTilesetId::trafficAbsolute; + case EAzureMapsTilesetId::TrafficRelativeMain: + return AzureMapsTilesetId::trafficRelativeMain; + case EAzureMapsTilesetId::TrafficRelativeDark: + return AzureMapsTilesetId::trafficRelativeDark; + case EAzureMapsTilesetId::TrafficDelay: + return AzureMapsTilesetId::trafficDelay; + case EAzureMapsTilesetId::TrafficReduced: + return AzureMapsTilesetId::trafficReduced; + case EAzureMapsTilesetId::BaseRoad: + default: + return AzureMapsTilesetId::baseRoad; + } +} +} // namespace + +std::unique_ptr +UCesiumAzureMapsRasterOverlay::CreateOverlay( + const CesiumRasterOverlays::RasterOverlayOptions& options) { + if (this->Key.IsEmpty()) { + // We must have a key to create this overlay. + return nullptr; + } + + return std::make_unique( + TCHAR_TO_UTF8(*this->MaterialLayerKey), + AzureMapsSessionParameters{ + .key = TCHAR_TO_UTF8(*this->Key), + .apiVersion = TCHAR_TO_UTF8(*this->ApiVersion), + .tilesetId = getTilesetId(this->TilesetId), + .language = TCHAR_TO_UTF8(*this->Language), + .view = TCHAR_TO_UTF8(*this->View), + }, + options); +} diff --git a/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp b/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp index 88797f280..bbb747b42 100644 --- a/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp +++ b/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp @@ -340,15 +340,19 @@ void ACesiumCreditSystem::Tick(float DeltaTime) { for (int i = 0; i < creditsToShowThisFrame.size(); i++) { const CesiumUtility::Credit& credit = creditsToShowThisFrame[i]; - FString CreditRtf; + FString creditRtf; const std::string& html = _pCreditSystem->getHtml(credit); auto htmlFind = _htmlToRtf.find(html); if (htmlFind != _htmlToRtf.end()) { - CreditRtf = htmlFind->second; + creditRtf = htmlFind->second; } else { - CreditRtf = ConvertHtmlToRtf(html); - _htmlToRtf.insert({html, CreditRtf}); + creditRtf = ConvertHtmlToRtf(html); + _htmlToRtf.insert({html, creditRtf}); + } + + if (creditRtf.IsEmpty()) { + continue; } if (_pCreditSystem->shouldBeShownOnScreen(credit)) { @@ -358,13 +362,13 @@ void ACesiumCreditSystem::Tick(float DeltaTime) { OnScreenCredits += TEXT(" \u2022 "); } - OnScreenCredits += CreditRtf; + OnScreenCredits += creditRtf; } else { if (i != 0) { Credits += "\n"; } - Credits += CreditRtf; + Credits += creditRtf; } } diff --git a/Source/CesiumRuntime/Private/CesiumGoogleMapTilesRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumGoogleMapTilesRasterOverlay.cpp index 3d60293b8..3a690f565 100644 --- a/Source/CesiumRuntime/Private/CesiumGoogleMapTilesRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumGoogleMapTilesRasterOverlay.cpp @@ -1,10 +1,10 @@ // Copyright 2020-2025 CesiumGS, Inc. and Contributors #include "CesiumGoogleMapTilesRasterOverlay.h" -#include "Cesium3DTilesSelection/Tileset.h" -#include "CesiumJsonReader/JsonObjectJsonHandler.h" -#include "CesiumJsonReader/JsonReader.h" -#include "CesiumRasterOverlays/GoogleMapTilesRasterOverlay.h" +#include +#include +#include +#include using namespace CesiumJsonReader; using namespace CesiumRasterOverlays; diff --git a/Source/CesiumRuntime/Public/CesiumAzureMapsRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumAzureMapsRasterOverlay.h new file mode 100644 index 000000000..c95be41ca --- /dev/null +++ b/Source/CesiumRuntime/Public/CesiumAzureMapsRasterOverlay.h @@ -0,0 +1,146 @@ +// Copyright 2020-2025 CesiumGS, Inc. and Contributors + +#pragma once + +#include "CesiumRasterOverlay.h" +#include "CoreMinimal.h" +#include "CesiumAzureMapsRasterOverlay.generated.h" + +/** + * Supported values for the `TilesetId` property. + */ +UENUM(BlueprintType) +enum class EAzureMapsTilesetId : uint8 { + /** + * All roadmap layers with Azure Maps' main style. + */ + BaseRoad UMETA(DisplayName = "Base"), + /** + * All roadmap layers with Azure Maps' dark grey style. + */ + BaseDarkGrey UMETA(DisplayName = "Base (Dark Grey)"), + /** + * Label data in Azure Maps' main style. + */ + BaseLabelsRoad UMETA(DisplayName = "Labels"), + /** + * Label data in Azure Maps' dark grey style. + */ + BaseLabelsDarkGrey UMETA(DisplayName = "Labels (Dark Grey)"), + /** + * Road, boundary, and label data in Azure Maps' main style. + */ + BaseHybridRoad UMETA(DisplayName = "Hybrid"), + /** + * Road, boundary, and label data in Azure Maps' dark grey style. + */ + BaseHybridDarkGrey UMETA(DisplayName = "Hybrid (Dark Grey)"), + /** + * A combination of satellite or aerial imagery. Only available for accounts + * under S1 and G2 pricing SKU. + */ + Imagery, + /** + * Shaded relief and terra layers. + */ + Terra, + /** + * Weather radar tiles. Latest weather radar images including areas of rain, + * snow, ice and mixed conditions. + */ + WeatherRadar UMETA(DisplayName = "Weather (Radar)"), + /** + * Weather infrared tiles. Latest infrared satellite images showing clouds by + * their temperature. + */ + WeatherInfrared UMETA(DisplayName = "Weather (Infrared)"), + /** + * Absolute traffic tiles in Azure Maps' main style. + */ + TrafficAbsolute UMETA(DisplayName = "Traffic (Absolute)"), + /** + * Relative traffic tiles in Azure Maps' main style. This filters out traffic + * data from smaller streets that are otherwise included in TrafficAbsolute. + */ + TrafficRelativeMain UMETA(DisplayName = "Traffic (Relative)"), + /** + * Relative traffic tiles in Azure Maps' dark style. This filters out traffic + * data from smaller streets that are otherwise included in TrafficAbsolute. + */ + TrafficRelativeDark UMETA(DisplayName = "Traffic (Relative, Dark)"), + /** + * Delay traffic tiles in Azure Maps' dark style. This only shows the points + * of delay along traffic routes that are otherwise included in + * TrafficAbsolute. + */ + TrafficDelay UMETA(DisplayName = "Traffic (Delay)"), + /** + * Reduced traffic tiles in Azure Maps' dark style. This shows the traffic + * routes and major delay points, but filters out some data that is otherwise + * included in TrafficAbsolute. + */ + TrafficReduced UMETA(DisplayName = "Traffic (Reduced)"), +}; + +/** + * A raster overlay that directly accesses Azure Maps. If you're using Azure + * Maps via Cesium ion, use the "Cesium ion Raster Overlay" component instead. + */ +UCLASS(ClassGroup = Cesium, meta = (BlueprintSpawnableComponent)) +class CESIUMRUNTIME_API UCesiumAzureMapsRasterOverlay + : public UCesiumRasterOverlay { + GENERATED_BODY() + +public: + /** + * The Azure Maps subscription key to use. + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") + FString Key; + + /** + * The version number of Azure Maps API. + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") + FString ApiVersion = "2024-04-01"; + + /** + * The tileset ID to use. + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") + EAzureMapsTilesetId TilesetId = EAzureMapsTilesetId::BaseRoad; + + /** + * The language in which search results should be returned. This should be one + * of the supported IETF language tags, case insensitive. When data in the + * specified language is not available for a specific field, default language + * is used. + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") + FString Language = "en-US"; + + /** + * The View parameter (also called the "user region" parameter) allows + * you to show the correct maps for a certain country/region for + * geopolitically disputed regions. + * + * Different countries/regions have different views of such regions, and the + * View parameter allows your application to comply with the view required by + * the country/region your application will be serving. By default, the View + * parameter is set to "Unified" even if you haven't defined it in the + * request. It is your responsibility to determine the location of your users, + * and then set the View parameter correctly for that location. Alternatively, + * you have the option to set 'View=Auto', which will return the map data + * based on the IP address of the request. The View parameter in Azure Maps + * must be used in compliance with applicable laws, including those regarding + * mapping, of the country/region where maps, images and other data and third + * party content that you are authorized to access via Azure Maps is made + * available. Example: view=IN. + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") + FString View = "US"; + +protected: + virtual std::unique_ptr CreateOverlay( + const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; +}; diff --git a/Source/CesiumRuntime/Public/CesiumRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumRasterOverlay.h index 8cd5f7544..601c273c9 100644 --- a/Source/CesiumRuntime/Public/CesiumRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumRasterOverlay.h @@ -111,7 +111,7 @@ class CESIUMRUNTIME_API UCesiumRasterOverlay : public UActorComponent { * overlay will be removed from the Cesium3DTileset if already present but not * re-added. */ - UFUNCTION(BlueprintCallable, Category = "Cesium") + UFUNCTION(CallInEditor, BlueprintCallable, Category = "Cesium") void Refresh(); UFUNCTION(BlueprintCallable, Category = "Cesium") diff --git a/extern/cesium-native b/extern/cesium-native index 126a412a7..aa5646dbf 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit 126a412a791dd596c5ed81c05ef2443339c64ff8 +Subproject commit aa5646dbf58d6cf8164b2e7a5e09c120184beba1