欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UE4 C++ 通过gdal2.3.1插件读取矢量数据文件

程序员文章站 2022-06-10 23:27:19
...

此处读取的线类型的文件,不过其他类型的都相差不大,可作为参考。

#include <gdal.h>
#include <cpl_conv.h>
#include <gdal_priv.h>
#include <ogrsf_frmts.h>
#include <HAL/FileManager.h>
#include <HAL/FileManagerGeneric.h>
#include <ogr_spatialref.h>


bool readPolylineShp(const FString &filename, TArray<TArray<FVector>> &pts)
{
	IFileManager& mgr = IFileManager::Get();
	
	// if this file exist, else exit!
	if (mgr.FileExists(*filename))
	{
		UE_LOG(LogTemp, Log, TEXT("This .shp file exist. %s"), *filename);

		//注册所有的文件格式驱动,这个函数注册了GDAL/OGR支持的所有格式
		GDALAllRegister();
		CPLSetConfigOption("SHAPE_ENCODING", "");
		
		//下一步我们将打开输入的OGR数据文件。数据文件可以是文件,关系型数据库,文件路径,甚至可能是远程的网络服务,这点取决于我们使用的驱动。
		//但是,数据源的名字通常只是一个简单的字符串。既然这样拿我们就编写一个打开shapefile的程序。
		//第二个参数(FLALSE)告诉OGRSFDriverRegistrar::Open() 函数我们不需要update access。如果失败返回NULL,并报错。
		GDALDataset *poDS;
		poDS = (GDALDataset*)GDALOpenEx(TCHAR_TO_UTF8(*filename), GDAL_OF_VECTOR, NULL, NULL, NULL);
		if (poDS == NULL)
		{
			UE_LOG(LogTemp, Log, TEXT("Failed in opening adding shp file:%s"), *filename);
			GDALDestroyDriver(poDS);
			return false;
		}
		//一个OGRDataSource可能包含很多的层。所包含层的数量我们可以用过调        OGRDataSource::GetLayerCount()得到,
		//并且其中每一个曾我们利用索引调用OGRDataSource::GetLayer()得到。也可以利用层的名字得到。
		int layerN = poDS->GetLayerCount();
		UE_LOG(LogTemp, Log, TEXT("layer count is::%d"), layerN);

		OGRLayer *poLayer;
		poLayer = poDS->GetLayer(0);
		if (poLayer == NULL)
		{
			UE_LOG(LogTemp, Error, TEXT("Failed in getting layer in existing .shp file:%s"), *filename);
			GDALDestroyDriver(poDS);
			return false;
		}

		// get vertexes on lines
		pts.Empty();

		OGREnvelope rect;
		poLayer->GetExtent(&rect);

		//自从我们开始fresh with这个层,就没有这么严格了。很明智地我们需要调用Layer::ResetReading()来确保我们是从层的开头开始。
		poLayer->ResetReading();
		// 现在我们开始读取层里面的features。在开始之前我们需要指定一个attribute或者spatial filter来严格控制我们得到的feature。不过现在我们只是得到所有的features。
		OGRSpatialReference *source = poLayer->GetSpatialRef();     // geographical projection information

		//#设置输出坐标系为WGS84
//		OGRSpatialReference target;
//		OGRErr err2 = target.importFromEPSG(32650);//32650通过qgis软件查看得到epsg WGS84

// 		char* text = nullptr;
// 		source->exportToWkt(&text);//导出打印wkt
// 		UE_LOG(LogTemp, Log, TEXT("source: %s"), text);
// 		target.exportToWkt(&text);//导出打印wkt
// 		UE_LOG(LogTemp, Log, TEXT("target: %s"), text);
// 
// 		if (err2 != OGRERR_NONE)
// 		{
// 			UE_LOG(LogTemp, Error, TEXT("target: %s"), text);
// 			return false;
// 		}
		
		//初始化坐标转换类,防止文件中存储的不是wgs84坐标系
//		OGRCoordinateTransformation *coord = OGRCreateCoordinateTransformation(source, &target);

		//
	//	int iFeatureCount = poLayer->GetFeatureCount();
	//	pts.Reset(iFeatureCount);

		OGRFeature *poFeature = NULL;
		while ((poFeature = poLayer->GetNextFeature()) != NULL)
		{
			
			//feature里面提取出几何(geometry)数据
			OGRGeometry *poGeometry = poFeature->GetGeometryRef();
			OGRwkbGeometryType geotype;
			geotype = poGeometry->getGeometryType();
			OGRLineString *poLine = NULL;
			//确定这个几何数据的类型,如果是点,我们将他标为点并且进行操作,如果是其他的内省我们write占位符。这里的类型是多段线
			if (wkbLineString == geotype)
			{
				poLine = (OGRLineString*)poGeometry;
				int pNUM = poLine->getNumPoints();
				pts.Add(TArray<FVector>());
				for (int i = 0; i < pNUM; ++i)
				{
					double X = poLine->getX(i);
					double Y = poLine->getY(i);
					double Z = poLine->getZ(i);

					//	进行坐标转换
//					coord->Transform(1, &X, &Y, &Z);

					pts[flag_line].Add(FVector(X, Y, Z));
				}
			}
			
			delete poLine;
		}
		//资源清理
		GDALClose(poDS);
		return true;
	}

	UE_LOG(LogTemp, Error, TEXT("This .shp file is not exist! %s"), *filename);
	return false;
}

 

相关标签: UE4 UE4 GDAL