GDAL栅格矢量化(GDAL 2.x 版)

6 篇文章 0 订阅

前言

一直在做Qt + GDAL的程序,因为接触到GDAL的时候比较晚,GDAL已经更新到了2.x,在参考各种文章时由于GDAL本身的更新换代,以至于很多涉及到矢量的代码已经用其他的代码代替,所以在做的时候费了很大的劲(翻阅GDAL原始文档简直是折磨),在这里想在李民录大神的代码上做一些更新,以适应更新的GDAL代码。
参考文档:

https://blog.csdn.net/ivan_ljf/article/details/9470419
https://www.cnblogs.com/carfield/archive/2013/06/08/3126614.html
http://www.cnblogs.com/yhlx125/archive/2012/12/22/2816049.html

代码的更新部分

GDAL主要对OGR类库进行了调整,这部分也是进行矢量数据处理时主要用到的类库,我会在说明之后,同时在代码中对更新部分进行标注:

  1. OGRDataSource :原网址:https://www.gdal.org/classOGRDataSource.html ;简单来说就是,OGRDataSource类已经几乎被舍弃不用了,GDAL鼓励使用新的GDALDataSet类,如果在代码中使用旧的类的话,会存在一些类型无法转换的问题。
  2. OGRSFDriver :原网址:https://www.gdal.org/classOGRSFDriver.html ;这个类将来会被GDALDriver类替代;
  3. OGRSFDriverRegistrar :原网址:https://www.gdal.org/classOGRSFDriverRegistrar.html ;这个类将来会被GDALDriverManager类替代;

栅格矢量化代码片段

    int Raster2shp::ImagePolygonize(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat, processsform *pProgress)
     {
         if (pProgress != NULL)
         {
             pProgress->ReSetProcess();
             pProgress->SetProgressTip("开始计算栅格矢量化...");
         }

     GDALAllRegister();
     OGRRegisterAll();

     GDALDataset* poSrcDS = (GDALDataset*) GDALOpen(pszSrcFile, GA_ReadOnly);    //打开栅格图像
     if (poSrcDS == NULL)
     {
         if (pProgress != NULL)
             pProgress->SetProgressTip("不能打开指定文件,请检查文件是否存在!");

         return 0;
     }

/*
    *此处,参考李民录老师的代码为:
    *OGRSFDriver* poDriver = OGRSFDriverRegistrar::GetRegistrar()->
    *GetDriverByName(pszFormat);
    *这里会报这样的错误:error: C2440: “初始化”: 无法从“GDALDriver *”转换为“OGRSFDriver *”
    *所以,我们用GDALDriver替代,但是GDALDriver类中没有定义GetRegistrar()方法,查阅了原始文档,发现可以用同作用的GetGDALDriverManager()方法进行获取驱动。
    */

     GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
     if (poDriver == NULL)
     {
         if (pProgress != NULL)
             pProgress->SetProgressTip("不能创建指定类型文件!");

         GDALClose((GDALDatasetH)poSrcDS);

         return 0;
     }

/*
*此处,参考李民录老师的代码为:
*OGRDataSource* poDstDS = poDriver->CreateDataSource(pszDstFile, NULL);
*上面的代码,我们将OGRDriver替代为GDALDriver,在这个类中没有CreateDataSource()的定义,
*可以用这个类中的 
*Create (const char *pszName, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszOptions) 
*替代,这个方法主要用于创建栅格文件的新数据集,其中nXSize,nYSize,nBands,都是对栅格文件的描述,**都置零后台会默认创建矢量数据集**
*/

     GDALDataset* poDstDS = poDriver->Create(pszDstFile,0,0,0,GDT_Unknown, NULL); //创建输出矢量文件
     if (poDstDS == NULL)
     {
         if (pProgress != NULL)
             pProgress->SetProgressTip("不能创建指定类型文件!");

         GDALClose((GDALDatasetH)poSrcDS);

         return 0;
     }

     OGRSpatialReference *poSpatialRef = new OGRSpatialReference(poSrcDS->GetProjectionRef());

     OGRLayer* poLayer = poDstDS->CreateLayer("Result", poSpatialRef, wkbPolygon, NULL);
     if (poLayer == NULL)
     {
         if (pProgress != NULL)
             pProgress->SetProgressTip("创建矢量图层失败!");

         GDALClose((GDALDatasetH)poSrcDS);
         GDALClose(poDstDS);

         OSRDestroySpatialReference(poSpatialRef);
         poSpatialRef = NULL;

         return 0;
     }

     OGRFieldDefn ofieldDef("DN", OFTInteger);    //创建属性表,只有一个字段即“DN”,里面保存对应的栅格的像元值
     if (poLayer->CreateField(&ofieldDef) != OGRERR_NONE)
     {
         if (pProgress != NULL)
             pProgress->SetProgressTip("创建矢量图层属性表失败!");

         GDALClose((GDALDatasetH)poSrcDS);
         GDALClose(poDstDS);

         OSRDestroySpatialReference(poSpatialRef);
         poSpatialRef = NULL;

         return 0;
     }

     GDALRasterBandH hSrcBand = (GDALRasterBandH) poSrcDS->GetRasterBand(1);    //获取图像的第一个波段

     if (GDALPolygonize(hSrcBand, NULL, (OGRLayerH)poLayer, 0, NULL, NULL, pProgress) != CE_None)//调用栅格矢量化
     {
         if (pProgress != NULL)
             pProgress->SetProgressTip("计算失败!");

         GDALClose((GDALDatasetH)poSrcDS);
         GDALClose(poDstDS);

/*这里在李民录老师的代码中是:delete poSpatialRef;  在我的程序运行过程中,会从此处跳出,然
*后我去找了替代的方法,OGRSpatialReference(OGR空间
*参考系统)的析构函数,这个类没有被替代掉,但是依然会跳出,所以直接被我注释掉了,这里由
*于不会进入if条件语句所以没有进行注释
*/

         OSRDestroySpatialReference(poSpatialRef);
         poSpatialRef = NULL;

         return 0;
     }

      GDALClose((GDALDatasetH)poSrcDS);    //关闭文件
      GDALClose(poDstDS);

    //      OSRDestroySpatialReference(poSpatialRef);
          poSpatialRef = NULL;
      if (pProgress != NULL)
          pProgress->SetProgressTip("计算成功!");

      return 1;
      }

结束语

这是我写的第一篇文档,如有纰漏,欢迎指正,另外,仔细看注释!!!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

airforcetop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值