zoukankan      html  css  js  c++  java
  • GDAL对空间数据的管理

    使用GDAL可以很方便的对空间数据进行管理(这里的管理主要是指复制、移动和删除)。有人可能会说这个功能不用GDAL也能很方便的实现,其实不然。很多的空间数据不是由一个单一的文件组成,而是由一些列文件共同组成,相信大家都对Erdas的img格式比较熟悉吧,这种图像格式,对于小图像来说一般常用就只有两个,那就是img和rrd格式,如果对于一个超级大的img格式,那么一个数据可能就会有四个文件组成,后缀名分别是img、ige、rrd、rge。如果对这个数据进行复制的话,你需要写四个复制语句,同样对于矢量数据中最常用Shapfile格式,一个shp文件最少也有有三个文件组成shp、shx、dbf,常用的还有prj等其他的。对于这样的数据进行管理,还是比较繁琐的,好在GDAL中提供了相关的函数,只要一个函数,该文件所有的相关文件都会被进行管理。

    下面分别对栅格数据和矢量数据进行说明。主要用到的类就是两个驱动类,GDALDirver(http://www.gdal.org/classGDALDriver.html)和 OGRSFDriver(http://www.gdal.org/ogr/classOGRSFDriver.html)。

    一、栅格数据格式 

    1、复制数据

    用到的函数是CopyFiles,函数原型是:

    CPLErr GDALDriver::CopyFiles(const char *pszNewName, const char *pszOldName)	
    参数pszNewName是复制后新栅格数据的路径,pszOldName是原始图像数据的路径。比如我要复制一个img文件【C:\Test.img】到【D:\New.img】,可以这样写:

    pDriver->CopyFiles("D:\\New.img", "C:\\Test.img");
    执行完之后,你会发现,不但把img文件复制过去,同时还把rrd文件复制过去了。这里还有一点需要说明一下,不要以为img文件找对应的rrd是根据文件名查找的(当然这样大多数情况下是对的),其实在img文件中保存了rrd文件的路径和名称,感兴趣的同学可以看看Erdas的HFA文件格式说明。

    2、移动数据

    移动数据用到的函数是Rename,函数原型是:

    CPLErr GDALDriver::Rename(const char *pszNewName, const char *pszOldName)

    参数pszNewName是移动后新栅格数据的路径,pszOldName是原始图像数据的路径。比如我要移动一个img文件从【C:\Test.img】到【D:\New.img】,可以这样写:

    pDriver->Rename("D:\\New.img", "C:\\Test.img");
    同上,移动后,所有的相关文件都会被移动过去。

    3、删除数据

    删除数据用到的函数是Delete,函数原型是:

    CPLErr GDALDriver::Delete(const char *	pszFilename) 
    
    删除数据只有一个参数,就是要删除的图像的路径,调用该函数后,和该图像依赖的所有的文件均会被删除。

    二、矢量数据格式

    矢量数据中,OGR库中只提供了删除数据的函数,至于移动和拷贝暂时还没有,不过自己通过OGRDataSource实现一个也不是很难,下面就只对删除数据的接口做一个说明。

    删除数据用到的函数是DeleteDataSource,函数原型是:

    OGRErr OGRSFDriver::DeleteDataSource(const char * pszDataSource ) 
    参数依旧是矢量数据的路径。没什么好说的。

    下面是我根据上面的函数写的几个我自己常用的函数,用来删除数据的,希望对大家有用。函数的说明以及参数都在注视里面,后面就不多说了。

    头文件:

    	/**
    	* @brief 判断该文件是否为图像数据
    	* @param strFileName	文件路径
    	* @return 成功返回true,否则false
    	*/
    	bool IsRasterFile(string strFileName);
    
    	/**
    	* @brief 判断该文件是否为矢量数据
    	* @param strFileName	文件路径
    	* @return 成功返回true,否则false
    	*/
    	bool IsVectorFile(string strFileName);
    
    	/**
    	* @brief 删除栅格图像
    	* @param pszFile			图像路径
    	* @return 是否删除成功,成功为RE_SUCCESS
    	*/
    	int RasterDelete(const char* pszFile);
    
    	/**
    	* @brief 重命名栅格图像
    	* @param pszOldFile			原始图像路径
    	* @param pszNewFile			新图像路径
    	* @return 是否删除成功,成功为RE_SUCCESS
    	*/
    	int RasterRename(const char* pszOldFile, const char* pszNewFile);
    
    	/**
    	* @brief 删除矢量数据
    	* @param pszFile			矢量路径
    	* @return 是否删除成功,成功为RE_SUCCESS
    	*/
    	int VectorDelete(const char* pszFile);
    
    	/**
    	* @brief 重命名矢量数据
    	* @param pszOldFile			原始矢量路径
    	* @param pszNewFile			新矢量路径
    	* @return 是否删除成功,成功为RE_SUCCESS
    	*/
    	int VectorRename(const char* pszOldFile, const char* pszNewFile);
    

    源文件:
    int RasterDelete(const char* pszFile)
    {
    	path fp = pszFile;
    	if (!exists(fp))	//文件不存在,直接返回
    		return RE_SUCCESS;
    
    	GDALAllRegister();
    
    	//打开图像
    	GDALDataset *pDS = (GDALDataset *)GDALOpen(pszFile, GA_ReadOnly);
    	if (pDS == NULL)
    		return remove(pszFile);
    
    	GDALDriver *pDriver = pDS->GetDriver();
    	if( pDriver == NULL )
    	{
    		GDALClose((GDALDatasetH) pDS);
    		return remove(pszFile);
    	}
    
    	GDALClose((GDALDatasetH) pDS);
    
    	if(pDriver->Delete(pszFile) == CE_None)
    		return RE_SUCCESS;
    	else
    		return remove(pszFile);
    }
    
    int RasterRename(const char* pszOldFile, const char* pszNewFile)
    {
    	path fp = pszOldFile;
    	if (!exists(fp))	//文件不存在,直接返回
    		return RE_FILENOTEXIST;
    
    	GDALAllRegister();
    
    	//打开图像
    	GDALDataset *pDS = (GDALDataset *)GDALOpen(pszOldFile, GA_ReadOnly);
    	if (pDS == NULL)
    		return rename(pszOldFile, pszNewFile);
    
    	GDALDriver *pDriver = pDS->GetDriver();
    	if( pDriver == NULL )
    	{
    		GDALClose((GDALDatasetH) pDS);
    		return remove(pszOldFile);
    	}
    
    	GDALClose((GDALDatasetH) pDS);
    
    	if(pDriver->Rename(pszNewFile, pszOldFile) == CE_None)
    		return RE_SUCCESS;
    	else
    		return rename(pszOldFile, pszNewFile);
    }
    
    int VectorDelete(const char* pszFile)
    {
    	path fp = pszFile;
    	if (!exists(fp))	//文件不存在,直接返回
    		return RE_SUCCESS;
    
    	OGRRegisterAll();
    
    	//打开矢量
    	OGRDataSource *poDS = OGRSFDriverRegistrar::Open(pszFile, FALSE );
    	if( poDS == NULL )
    		return remove(pszFile);
    
    	OGRSFDriver *poDriver = poDS->GetDriver();
    	if( poDriver == NULL )
    	{
    		OGRDataSource::DestroyDataSource( poDS );
    		return remove(pszFile);
    	}
    
    	OGRDataSource::DestroyDataSource( poDS );
    	if(poDriver->DeleteDataSource(pszFile) == OGRERR_NONE)
    		return RE_SUCCESS;
    	else
    		return remove(pszFile);
    }
    
    int VectorRename(const char* pszOldFile, const char* pszNewFile)
    {
    	path fp = pszOldFile;
    	if (!exists(fp))	//文件不存在,直接返回
    		return RE_FILENOTEXIST;
    
    	OGRRegisterAll();
    
    	//打开矢量
    	OGRDataSource *poDS = OGRSFDriverRegistrar::Open(pszOldFile, FALSE );
    	if( poDS == NULL )
    		return rename(pszOldFile, pszNewFile);
    
    	OGRSFDriver *poDriver = poDS->GetDriver();
    	if( poDriver == NULL )
    	{
    		OGRDataSource::DestroyDataSource( poDS );
    		return rename(pszOldFile, pszNewFile);
    	}
    
    	OGRDataSource* poNewDS = poDriver->CopyDataSource(poDS, pszNewFile, NULL);
    	if (poNewDS == NULL)
    	{
    		OGRDataSource::DestroyDataSource( poDS );
    		return rename(pszOldFile, pszNewFile);
    	}
    
    	OGRDataSource::DestroyDataSource( poDS );
    	OGRDataSource::DestroyDataSource( poNewDS );
    
    	if(poDriver->DeleteDataSource(pszOldFile) == OGRERR_NONE)
    		return RE_SUCCESS;
    	else
    		return rename(pszOldFile, pszNewFile);
    }
    
    bool IsRasterFile(string strFileName)
    {
    	string strExt = CPLGetExtension(strFileName.c_str());
    	to_lower(strExt);
    	if(strExt == "rrd" || strExt == "aux"|| strExt=="ovr")
    		return false;
    
    	GDALAllRegister();
    	GDALDatasetH hDS = GDALOpen(strFileName.c_str(), GA_ReadOnly);
    	if(hDS == NULL)
    		return false;
    
    	GDALClose(hDS);
    	return true;
    }
    
    bool IsVectorFile(string strFileName)
    {
    	string strExt = CPLGetExtension(strFileName.c_str());
    	to_lower(strExt);
    	if(strExt == "dbf" || strExt == "shx")
    		return false;
    
    	OGRRegisterAll();
    	OGRDataSource *poDS = OGRSFDriverRegistrar::Open(strFileName.c_str(), FALSE );
    	if( poDS == NULL )
    		return false;
    
    	OGRDataSource::DestroyDataSource( poDS );
    	return true;
    }
    
    这里需要说明一下,返回值的定义可以参考我之前的博客,还有就是用到了Boost库中的filesystem库和algorithm库,要不然可能编译不过去。BOOST库的头文件具体是:

    #include "boost/algorithm/string.hpp"
    #include "boost/filesystem.hpp"
    using namespace boost;
    using namespace boost::filesystem;

  • 相关阅读:
    Excel 2016 Power View选项卡不显示的问题
    Base64编码
    MAPI错误0x80040107
    命令行界面 (CLI)、终端 (Terminal)、Shell、TTY的区别
    C函数调用过程原理及函数栈帧分析
    SIFT(Scale-invariant feature transform) & HOG(histogram of oriented gradients)
    Jupyter NoteBook 的快捷键
    endnote插入参考文献后的对齐方式和缩进空格
    赏月斋源码共享计划 第四期 约瑟夫问题
    LRU和LFU的区别
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6313976.html
Copyright © 2011-2022 走看看