Skip to content

Commit 8281c3c

Browse files
authored
Merge pull request #1741 from CesiumGS/google-raster-overlay
Add CesiumGoogleMapTilesRasterOverlay
2 parents bc73e13 + 5df4eb8 commit 8281c3c

File tree

6 files changed

+321
-2
lines changed

6 files changed

+321
-2
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
##### Additions :tada:
66

77
- Added support for rendering glTFs with line primitives.
8+
- Added `UCesiumGoogleMapTilesRasterOverlay`.
9+
- Added `AssetOptions` property to `UCesiumIonRasterOverlay`.
810

911
### v2.19.1 - 2025-09-02
1012

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2020-2025 CesiumGS, Inc. and Contributors
2+
3+
#include "CesiumGoogleMapTilesRasterOverlay.h"
4+
#include "Cesium3DTilesSelection/Tileset.h"
5+
#include "CesiumJsonReader/JsonObjectJsonHandler.h"
6+
#include "CesiumJsonReader/JsonReader.h"
7+
#include "CesiumRasterOverlays/GoogleMapTilesRasterOverlay.h"
8+
9+
using namespace CesiumJsonReader;
10+
using namespace CesiumRasterOverlays;
11+
using namespace CesiumUtility;
12+
13+
namespace {
14+
15+
std::string getMapType(EGoogleMapTilesMapType mapType) {
16+
switch (mapType) {
17+
case EGoogleMapTilesMapType::Roadmap:
18+
return GoogleMapTilesMapType::roadmap;
19+
case EGoogleMapTilesMapType::Terrain:
20+
return GoogleMapTilesMapType::terrain;
21+
case EGoogleMapTilesMapType::Satellite:
22+
default:
23+
return GoogleMapTilesMapType::satellite;
24+
}
25+
}
26+
27+
std::string getScale(EGoogleMapTilesScale scale) {
28+
switch (scale) {
29+
case EGoogleMapTilesScale::ScaleFactor4x:
30+
return GoogleMapTilesScale::scaleFactor4x;
31+
case EGoogleMapTilesScale::ScaleFactor2x:
32+
return GoogleMapTilesScale::scaleFactor2x;
33+
case EGoogleMapTilesScale::ScaleFactor1x:
34+
default:
35+
return GoogleMapTilesScale::scaleFactor1x;
36+
}
37+
}
38+
39+
std::optional<std::vector<std::string>> getLayerTypes(
40+
const TArray<EGoogleMapTilesLayerType>& layerTypes,
41+
EGoogleMapTilesMapType mapType) {
42+
std::vector<std::string> result;
43+
44+
bool hasRoadmap = false;
45+
46+
if (!layerTypes.IsEmpty()) {
47+
result.reserve(layerTypes.Num());
48+
49+
for (EGoogleMapTilesLayerType layerType : layerTypes) {
50+
switch (layerType) {
51+
case EGoogleMapTilesLayerType::Roadmap:
52+
hasRoadmap = true;
53+
result.emplace_back(GoogleMapTilesLayerType::layerRoadmap);
54+
break;
55+
case EGoogleMapTilesLayerType::Streetview:
56+
result.emplace_back(GoogleMapTilesLayerType::layerStreetview);
57+
break;
58+
case EGoogleMapTilesLayerType::Traffic:
59+
result.emplace_back(GoogleMapTilesLayerType::layerTraffic);
60+
break;
61+
}
62+
}
63+
}
64+
65+
if (mapType == EGoogleMapTilesMapType::Terrain && !hasRoadmap) {
66+
UE_LOG(
67+
LogCesium,
68+
Warning,
69+
TEXT(
70+
"When the MapType is set to Terrain, LayerTypes must contain Roadmap."));
71+
}
72+
73+
return result;
74+
}
75+
76+
JsonValue::Array getStyles(const TArray<FString>& styles) {
77+
JsonValue::Array result;
78+
result.reserve(styles.Num());
79+
80+
JsonObjectJsonHandler handler{};
81+
82+
for (int32 i = 0; i < styles.Num(); ++i) {
83+
const FString& style = styles[i];
84+
std::string styleUtf8 = TCHAR_TO_UTF8(*style);
85+
ReadJsonResult<JsonValue> response = JsonReader::readJson(
86+
std::span<const std::byte>(
87+
reinterpret_cast<const std::byte*>(styleUtf8.data()),
88+
styleUtf8.size()),
89+
handler);
90+
91+
ErrorList errorList;
92+
errorList.errors = std::move(response.errors);
93+
errorList.warnings = std::move(response.warnings);
94+
errorList.log(
95+
spdlog::default_logger(),
96+
fmt::format("Problems parsing JSON in element {} of Styles:", i));
97+
98+
if (response.value) {
99+
result.emplace_back(std::move(*response.value));
100+
}
101+
}
102+
103+
return result;
104+
}
105+
106+
} // namespace
107+
108+
std::unique_ptr<CesiumRasterOverlays::RasterOverlay>
109+
UCesiumGoogleMapTilesRasterOverlay::CreateOverlay(
110+
const CesiumRasterOverlays::RasterOverlayOptions& options) {
111+
if (this->Key.IsEmpty()) {
112+
// We must have a key to create this overlay.
113+
return nullptr;
114+
}
115+
116+
return std::make_unique<CesiumRasterOverlays::GoogleMapTilesRasterOverlay>(
117+
TCHAR_TO_UTF8(*this->MaterialLayerKey),
118+
CesiumRasterOverlays::GoogleMapTilesNewSessionParameters{
119+
.key = TCHAR_TO_UTF8(*this->Key),
120+
.mapType = getMapType(this->MapType),
121+
.language = TCHAR_TO_UTF8(*this->Language),
122+
.region = TCHAR_TO_UTF8(*this->Region),
123+
.scale = getScale(this->Scale),
124+
.highDpi = this->HighDPI,
125+
.layerTypes = getLayerTypes(this->LayerTypes, this->MapType),
126+
.styles = getStyles(this->Styles),
127+
.overlay = this->Overlay},
128+
options);
129+
}

Source/CesiumRuntime/Private/CesiumIonRasterOverlay.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,18 @@ UCesiumIonRasterOverlay::CreateOverlay(
4646
if (*apiUrl.rbegin() != '/')
4747
apiUrl += '/';
4848

49-
return std::make_unique<CesiumRasterOverlays::IonRasterOverlay>(
49+
auto pOverlay = std::make_unique<CesiumRasterOverlays::IonRasterOverlay>(
5050
TCHAR_TO_UTF8(*this->MaterialLayerKey),
5151
this->IonAssetID,
5252
TCHAR_TO_UTF8(*token),
5353
options,
5454
apiUrl);
55+
56+
if (!this->AssetOptions.IsEmpty()) {
57+
pOverlay->setAssetOptions(TCHAR_TO_UTF8(*this->AssetOptions));
58+
}
59+
60+
return pOverlay;
5561
}
5662

5763
void UCesiumIonRasterOverlay::PostLoad() {
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Copyright 2020-2025 CesiumGS, Inc. and Contributors
2+
3+
#pragma once
4+
5+
#include "CesiumRasterOverlay.h"
6+
#include "CoreMinimal.h"
7+
#include "CesiumGoogleMapTilesRasterOverlay.generated.h"
8+
9+
/**
10+
* The possible values of the `MapType` property.
11+
*/
12+
UENUM(BlueprintType)
13+
enum class EGoogleMapTilesMapType : uint8 {
14+
/**
15+
* Satellite imagery.
16+
*/
17+
Satellite,
18+
19+
/**
20+
* The standard Google Maps painted map tiles.
21+
*/
22+
Roadmap,
23+
24+
/**
25+
* Terrain imagery. When selecting terrain as the map type, you must
26+
* also add "Roadmap" to the `LayerTypes` property.
27+
*/
28+
Terrain
29+
};
30+
31+
/**
32+
* The possible values of the `Scale` property.
33+
*/
34+
UENUM(BlueprintType)
35+
enum class EGoogleMapTilesScale : uint8 {
36+
/**
37+
* @brief The default.
38+
*/
39+
ScaleFactor1x UMETA(DisplayName = "1x"),
40+
41+
/**
42+
* @brief Doubles label size and removes minor feature labels.
43+
*/
44+
ScaleFactor2x UMETA(DisplayName = "2x"),
45+
46+
/**
47+
* @brief Quadruples label size and removes minor feature labels.
48+
*/
49+
ScaleFactor4x UMETA(DisplayName = "4x"),
50+
};
51+
52+
/**
53+
* The possible values of the `LayerTypes` property.
54+
*/
55+
UENUM(BlueprintType)
56+
enum class EGoogleMapTilesLayerType : uint8 {
57+
/**
58+
* Required if you specify terrain as the map type. Can also be
59+
* optionally overlaid on the satellite map type. Has no effect on roadmap
60+
* tiles.
61+
*/
62+
Roadmap,
63+
64+
/**
65+
* Shows Street View-enabled streets and locations using blue outlines
66+
* on the map.
67+
*/
68+
Streetview,
69+
70+
/**
71+
* Displays current traffic conditions.
72+
*/
73+
Traffic
74+
};
75+
76+
/**
77+
* A raster overlay that directly accesses Google Map Tiles (2D). If you're
78+
* using Google Map Tiles via Cesium ion, use the "Cesium ion Raster Overlay"
79+
* component instead.
80+
*/
81+
UCLASS(ClassGroup = Cesium, meta = (BlueprintSpawnableComponent))
82+
class CESIUMRUNTIME_API UCesiumGoogleMapTilesRasterOverlay
83+
: public UCesiumRasterOverlay {
84+
GENERATED_BODY()
85+
86+
public:
87+
/**
88+
* The Google Map Tiles API key to use.
89+
*/
90+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
91+
FString Key;
92+
93+
/**
94+
* The type of base map.
95+
*/
96+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
97+
EGoogleMapTilesMapType MapType = EGoogleMapTilesMapType::Satellite;
98+
99+
/**
100+
* An IETF language tag that specifies the language used to display
101+
* information on the tiles. For example, `en-US` specifies the English
102+
* language as spoken in the United States.
103+
*/
104+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
105+
FString Language = "en-US";
106+
107+
/**
108+
* A Common Locale Data Repository region identifier (two uppercase letters)
109+
* that represents the physical location of the user. For example, `US`.
110+
*/
111+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
112+
FString Region = "US";
113+
114+
/**
115+
* Scales-up the size of map elements (such as road labels), while
116+
* retaining the tile size and coverage area of the default tile.
117+
*
118+
* Increasing the scale also reduces the number of labels on the map, which
119+
* reduces clutter.
120+
*/
121+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
122+
EGoogleMapTilesScale Scale = EGoogleMapTilesScale::ScaleFactor1x;
123+
124+
/**
125+
* Specifies whether to return high-resolution tiles.
126+
*
127+
* If the scale-factor is increased, `highDpi` is used to increase the size of
128+
* the tile. Normally, increasing the scale factor enlarges the resulting tile
129+
* into an image of the same size, which lowers quality. With `highDpi`, the
130+
* resulting size is also increased, preserving quality. DPI stands for Dots
131+
* per Inch, and High DPI means the tile renders using more dots per inch than
132+
* normal. If `true`, then the number of pixels in each of the x and y
133+
* dimensions is multiplied by the scale factor (that is , 2x or 4x). The
134+
* coverage area of the tile remains unchanged. This parameter works only with
135+
* `Scale` values of `2x` or `4x`. It has no effect on `1x` scale tiles.
136+
*/
137+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
138+
bool HighDPI = false;
139+
140+
/**
141+
* The layer types to be added to the map.
142+
*/
143+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
144+
TArray<EGoogleMapTilesLayerType> LayerTypes;
145+
146+
/**
147+
* An array of JSON style objects that specify the appearance and
148+
* detail level of map features such as roads, parks, and built-up areas.
149+
*
150+
* Styling is used to customize the standard Google base map. The `styles`
151+
* parameter is valid only if the `MapType` is `Roadmap`. For the complete
152+
* style syntax, see the [Style
153+
* Reference](https://developers.google.com/maps/documentation/tile/style-reference).
154+
*/
155+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
156+
TArray<FString> Styles;
157+
158+
/**
159+
* Specifies whether `LayerTypes` rendered as a separate overlay, or combined
160+
* with the base imagery.
161+
*
162+
* When `true`, the base map isn't displayed. If you haven't defined any
163+
* `LayerTypes`, then this value is ignored.
164+
*/
165+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
166+
bool Overlay = false;
167+
168+
protected:
169+
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
170+
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
171+
};

Source/CesiumRuntime/Public/CesiumIonRasterOverlay.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ class CESIUMRUNTIME_API UCesiumIonRasterOverlay : public UCesiumRasterOverlay {
5454
AdvancedDisplay)
5555
UCesiumIonServer* CesiumIonServer;
5656

57+
/**
58+
* Extra options to pass to Cesium ion when accessing the asset. This
59+
* should be a JSON string.
60+
*/
61+
UPROPERTY(
62+
EditAnywhere,
63+
BlueprintReadWrite,
64+
Category = "Cesium",
65+
AdvancedDisplay)
66+
FString AssetOptions;
67+
5768
/**
5869
* Check if the Cesium ion token used to access this raster overlay is working
5970
* correctly, and fix it if necessary.

0 commit comments

Comments
 (0)