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

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

#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;
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值