Is there any way to draw lines and polygons that are aligned on the surface of the terrain?
@mylyt You should be able to accomplish this using the (relatively) new GeoJSON raster overlay. If you don’t have a GeoJSON file, you should be able to create your own FCesiumGeoJsonDocument containing the lines and polygons you’re looking to render, and pass it to the GeoJsonDocument property of the raster overlay. Let me know if you run into any issues with this approach!
Thanks for your reply! I will try this
Hello, @azrogers I tried this approach today, but I met a problem with FCesiumGeoJsonDocument which caused an error link2019: unable to resolve external sysmbol “public: __cdecl FCesiumGeoJsonDocument::FCesiumGeoJsonDocument(void)”, but I did include the header file of “CesiumGeoJsonDocumentRasterOverlay.h“ which already includes “CesiumGeoJsonDocument.h“, here’s the parts of the code:
#include "CesiumGeoJsonDocumentRasterOverlay.h"
//...
//In a function after created the GeoJsonString from given points
FCesiumGeoJsonDocument LineGeoJsonDoc;
if (UCesiumGeoJsonDocumentBlueprintLibrary::LoadGeoJsonFromString(GeoJsonString, LineGeoJsonDoc))
{
UCesiumGeoJsonDocumentRasterOverlay* LineGeoJsonOverlay = NewObject<UCesiumGeoJsonDocumentRasterOverlay>(this);
if (LineGeoJsonOverlay)
{
FCesiumVectorStyle VectorStyle;
VectorStyle.LineStyle = LineStyle;
LineGeoJsonOverlay->Source = ECesiumGeoJsonDocumentRasterOverlaySource::FromDocument;
LineGeoJsonOverlay->GeoJsonDocument = LineGeoJsonDoc;
LineGeoJsonOverlay->ComponentTags.Add(FName(Name));
LineGeoJsonOverlay->DefaultStyle = VectorStyle;
LineGeoJsonOverlay->MaterialLayerKey = TEXT("Overlay2");
AddInstanceComponent(LineGeoJsonOverlay);
LineGeoJsonOverlay->RegisterComponent();
RefreshTileset();
}
}
Hello, @azrogers I tried this approach today, but I met a problem with FCesiumGeoJsonDocument which caused an error link2019: unable to resolve external sysmbol “public: __cdecl FCesiumGeoJsonDocument::FCesiumGeoJsonDocument(void)”, but I did include the header file of “CesiumGeoJsonDocumentRasterOverlay.h“ which already includes “CesiumGeoJsonDocument.h“, here’s the parts of the code:
#include "CesiumGeoJsonDocumentRasterOverlay.h"
//...
//In a function after created the GeoJsonString from given points
FCesiumGeoJsonDocument LineGeoJsonDoc;
if (UCesiumGeoJsonDocumentBlueprintLibrary::LoadGeoJsonFromString(GeoJsonString, LineGeoJsonDoc))
{
UCesiumGeoJsonDocumentRasterOverlay* LineGeoJsonOverlay = NewObject<UCesiumGeoJsonDocumentRasterOverlay>(this);
if (LineGeoJsonOverlay)
{
FCesiumVectorStyle VectorStyle;
VectorStyle.LineStyle = LineStyle;
LineGeoJsonOverlay->Source = ECesiumGeoJsonDocumentRasterOverlaySource::FromDocument;
LineGeoJsonOverlay->GeoJsonDocument = LineGeoJsonDoc;
LineGeoJsonOverlay->ComponentTags.Add(FName(Name));
LineGeoJsonOverlay->DefaultStyle = VectorStyle;
LineGeoJsonOverlay->MaterialLayerKey = TEXT("Overlay2");
AddInstanceComponent(LineGeoJsonOverlay);
LineGeoJsonOverlay->RegisterComponent();
RefreshTileset();
}
}
For this problem, it’s because CesiumForUnreal does not export the struct FCesiumGeoJsonDocument, Original code:
USTRUCT(BlueprintType)
struct FCesiumGeoJsonDocument {
GENERATED_BODY()
/**
* @brief Creates an empty `FCesiumGeoJsonDocument`.
*/
FCesiumGeoJsonDocument();
/**
* @brief Creates a `FCesiumGeoJsonDocument` wrapping the provided
* `CesiumVectorData::GeoJsonDocument`.
*/
FCesiumGeoJsonDocument(
std::shared_ptr<CesiumVectorData::GeoJsonDocument>&& document);
/**
* @brief Checks if this FCesiumGeoJsonDocument is valid (document is not
* nullptr).
*/
bool IsValid() const;
/**
* @brief Returns the `CesiumVectorData::GeoJsonDocument` this wraps.
*/
const std::shared_ptr<CesiumVectorData::GeoJsonDocument>& GetDocument() const;
private:
std::shared_ptr<CesiumVectorData::GeoJsonDocument> _pDocument;
friend class UCesiumGeoJsonDocumentBlueprintLibrary;
};
After changed:
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumGeoJsonDocument {
GENERATED_BODY()
/**
* @brief Creates an empty `FCesiumGeoJsonDocument`.
*/
FCesiumGeoJsonDocument();
/**
* @brief Creates a `FCesiumGeoJsonDocument` wrapping the provided
* `CesiumVectorData::GeoJsonDocument`.
*/
FCesiumGeoJsonDocument(
std::shared_ptr<CesiumVectorData::GeoJsonDocument>&& document);
/**
* @brief Checks if this FCesiumGeoJsonDocument is valid (document is not
* nullptr).
*/
bool IsValid() const;
/**
* @brief Returns the `CesiumVectorData::GeoJsonDocument` this wraps.
*/
const std::shared_ptr<CesiumVectorData::GeoJsonDocument>& GetDocument() const;
private:
std::shared_ptr<CesiumVectorData::GeoJsonDocument> _pDocument;
friend class UCesiumGeoJsonDocumentBlueprintLibrary;
};
and as well as the class UCesiumGeoJsonDocumentBlueprintLibrary.
That rings a bell. Looking at old code (because I moved to loading geojson from Ion) I see I however used CesiumVectorData::GeoJsonDocument::fromGeoJson() with a GeoJsonDocument.h include.
Just can’t recall if I moved to Ion before trying that though.
Also before GeoJson came to Cesium for UE, I would use the UE canvas to draw lines to a rendertarget, then have a decal project the rendertarget onto the terrain.
I moved the location-based drawings to GeoJson and Ion, but still use the decal method for an area selection gizmo I move around on the terrain.