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;
转载自:https://blog.csdn.net/liminlu0314/article/details/8599945