本文参考自https://blog.youkuaiyun.com/liminlu0314/article/details/6203554
在上面的基础上做了一些改动,适用于gdal201或更高版本。
这里主要对gdal提供的GDALPolygonize接口封装了一个函数,但是里面一些东西应该按照具体情况做修改。比如说:
- 默认处理栅格的第一个波段。
- 转化的矢量图层属性字段写死为"DF",字段类型写死为"OFTInteger"。
接口介绍
CPLErr CPL_DLL CPL_STDCALL
GDALPolygonize( GDALRasterBandH hSrcBand, //输入栅格图像波段
GDALRasterBandH hMaskBand, //掩码图像波段,可以为NULL
OGRLayerH hOutLayer, //矢量化后的矢量图层
int iPixValField, //需要将像元DN值写入矢量属性字段的字段索引
char **papszOptions, //算法选项,目前算法中没有用到,设置为NULL即可
GDALProgressFunc pfnProgress, //进度条回调函数
void * pProgressArg ); //进度条参数
一个封装的例子:
//栅格矢量化,默认处理第一波段
int ImagePolygonize(const char*pszSrcFile,const char*pszDstFile,const char* pszFormat="ESRI Shapefile", int BandNum=1)
{
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");//支持中文路径
GDALAllRegister();
OGRRegisterAll();
GDALDataset* poSrcDS = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
if (poSrcDS==NULL)
{
printf("无法打开栅格文件");
return 0;
}
GDALDriver* poDriver;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if (poDriver == NULL)
{
GDALClose((GDALDatasetH)poSrcDS);
return 0;
}
//根据文件名创建输出矢量文件
GDALDataset* poDstDS = poDriver->Create(pszDstFile, 0, 0, 0, GDT_Unknown, NULL);
if (poDstDS == NULL)
{
GDALClose((GDALDatasetH)poSrcDS);
return 0;
}
// 定义空间参考,与输入图像相同
OGRSpatialReference* poSpatialRef = new OGRSpatialReference(poSrcDS->GetProjectionRef());
OGRLayer* poLayer = poDstDS->CreateLayer("Result", poSpatialRef, wkbPolygon, NULL);
if (poDstDS == NULL)
{
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDS);
delete poSpatialRef;
poSpatialRef = NULL;
return 0;
}
//创建属性表
OGRFieldDefn ofieldDef("DF", OFTInteger);
if (poLayer->CreateField(&ofieldDef) != OGRERR_NONE)
{
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDS);
delete poSpatialRef;
poSpatialRef = NULL;
return 0;
}
GDALRasterBandH hSrcBand = (GDALRasterBandH)poSrcDS->GetRasterBand(1);
if (GDALPolygonize(hSrcBand, NULL, (OGRLayerH)poLayer, 0, NULL, GDALTermProgress, NULL) != CE_None)
{
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDS);
delete poSpatialRef;
poSpatialRef = NULL;
return 0;
}
GDALClose((GDALDatasetH)poSrcDS);
GDALClose(poDstDS);
//delete poSpatialRef;
poSpatialRef = NULL;
return 1;
}