UE4 GDAL 生成Landscape
使用GDAL加载DEM&DOM影像数据,在UE4中构建Landscape。
DEM& DOM
UnrealGDAL
UnrealGDAL 插件
Code
加载GeoTIFF
加载高度图(DEM),加载纹理RGB (DOM)。
GDALDatasetRef heightmap = mergetiff::DatasetManagement::openDataset(TCHAR_TO_UTF8(*(this->HeightmapDataset)));
if (!heightmap) {
return TEXT("Failed to open the heightmap dataset");
}
GDALDatasetRef rgb = mergetiff::DatasetManagement::openDataset(TCHAR_TO_UTF8(*(this->RGBDataset)));
if (!rgb) {
return TEXT("Failed to open the RGB dataset");
}
查询影像投影信息MetaData
坐标投影信息及Extent(Corners)。
FString heightmapWkt = GetProjectionWkt(heightmap);
if (heightmapWkt.IsEmpty()) {
return TEXT("Failed to retrieve the projected coordinate system used by the heightmap dataset");
}
FString rgbWkt = GetProjectionWkt(rgb);
if (rgbWkt.IsEmpty()) {
return TEXT("Failed to retrieve the projected coordinate system used by the RGB dataset");
}
RasterCornerCoordinatesRef heightmapCorners = GDALHelpers::GetRasterCorners(heightmap);
if (!heightmapCorners) {
return TEXT("Failed to compute the projected corner coordinates of the heightmap dataset");
}
RasterCornerCoordinatesRef rgbCorners = GDALHelpers::GetRasterCorners(rgb);
if (!rgbCorners) {
return TEXT("Failed to compute the projected corner coordinates of the RGB dataset");
}
影像数据预处理
将DEM数据处理成GDT_Float32 ,将DOM数据处理成GDT_Byte 。
if (heightmap->GetRasterBand(1)->GetRasterDataType() != GDT_Float32)
{
heightmap = GDALHelpers::Translate(heightmap, GDALHelpers::UniqueMemFilename(),
GDALHelpers::ParseGDALTranslateOptions({
TEXT("-ot"),
TEXT("Float32"),
})
);
if (!heightmap) {
return TEXT("Failed to convert the heightmap to Float32 format");
}
}
if (rgb->GetRasterBand(1)->GetRasterDataType() != GDT_Byte)
{
rgb = GDALHelpers::Translate(rgb, GDALHelpers::UniqueMemFilename(),
GDALHelpers::ParseGDALTranslateOptions({
TEXT("-ot"),
TEXT("Byte"),
})
);
if (!rgb) {
return TEXT("Failed to convert the rgb to Byte format");
}
}
读取数据
data.HeightBufferX = heightmap->GetRasterXSize();
data.HeightBufferY = heightmap->GetRasterYSize();
mergetiff::RasterData<float> heightmapData = GDALHelpers::AllocateAndWrap<float>(data.HeightBuffer, 1, data.HeightBufferY, data.HeightBufferX, 0.0f);
if (mergetiff::RasterIO::readDataset(heightmap, heightmapData, {1}) == false) {
return TEXT("Failed to read the data from the heightmap");
}
data.ColorBufferX = rgb->GetRasterXSize();
data.ColorBufferY = rgb->GetRasterYSize();
data.PixelFormat = EPixelFormat::PF_R8G8B8A8;
mergetiff::RasterData<uint8> rgbaData = GDALHelpers::AllocateAndWrap<uint8>(data.ColorBuffer, 4, data.ColorBufferY, data.ColorBufferX, 255);
if (mergetiff::RasterIO::readDataset(rgb, rgbaData, {1,2,3}) == false) {
return TEXT("Failed to read the data from the RGB dataset");
}
生成 Landscape
ALandscape* Landscape = WorldContext->GetWorld()->SpawnActor<ALandscape>();
Landscape->ComponentSizeQuads = 255;
Landscape->SubsectionSizeQuads = 255;
Landscape->NumSubsections = 1;
Landscape->SetLandscapeGuid(FGuid::NewGuid());
Landscape->LandscapeMaterial = GenerateUnlitLandscapeMaterial(LandscapeName, FString::Printf(TEXT("%s.%s"), *PackageName, *Name), FMath::CeilToInt(GISData.HeightBufferX / 255), FMath::CeilToInt(GISData.HeightBufferY / 255), 255);
Landscape->CreateLandscapeInfo();
Landscape->SetActorTransform(FTransform(FQuat::Identity, FVector(), ScaleVector));
HeightmapDataPerLayers.Add(FGuid(), HeightGDAL);
MaterialLayerDataPerLayer.Add(FGuid(), TArray<FLandscapeImportLayerInfo>());
Landscape->Import(Landscape->GetLandscapeGuid(), 0, 0, GISData.HeightBufferX - 1,
GISData.HeightBufferY - 1, Landscape->NumSubsections, Landscape->SubsectionSizeQuads, HeightmapDataPerLayers,
TEXT("NONE"), MaterialLayerDataPerLayer, ELandscapeImportAlphamapType::Layered
);
FVector LandscapeOrigin;
FVector LandscapeBounds;
Landscape->GetActorBounds(false, LandscapeOrigin, LandscapeBounds);
Landscape->SetActorLocation(FVector(0, 0, LandscapeBounds.Z));
Landscape->ReregisterAllComponents();
ULandscapeComponent* lastComponent = Landscape->LandscapeComponents.Last();
Landscape->CreateLandscapeInfo();
Landscape->SetActorLabel(LandscapeName);
参考
- UE4 GDAL 生成 Landscape
|