zoukankan      html  css  js  c++  java
  • GDAL线面互转换(2)

         在上一个文章中介绍了线转化为面和面转化为线,其主要的实现思路就是把面中的点取出来构成线,把线中的点取出来构成面,实际上就是一个硬拷贝,无奈客户的实际需求并非如此,客户想要线转面的时候几条相交线构成面,面转线的时候相同的线去除,所以又重新对功能进行了调整。

         关于线构面,这个过程中也是挺曲折的,在GDAL的群里问了好久,大家给的答案一致是需要自己写,线构面的算法需要使用左转或者右转算法,并且在网上查了相关的资料,发现蒋波涛编著的《插件式GIS应用框架的设计与实现:基于C#和AE 9.2》一书中有ArcGIS实现GDAL的完整代码,没办法,埋头去干吧,先做了一部分前期的验证,验证的时候,公司一大牛问我OGRGeometry中的Polygonize ()方法是干啥的?仔细查阅相关资料,就是要做线转面的啊!赶紧验证,发现失败,后来又仔细分析,似乎该方法需要OGRGeometry的空间拓扑关系正确,如何保证这点儿呢?考虑用Union来把一根根线合并了拓扑关系应该没有问题吧,实际测试了一下,的确正确,心中窃喜。后来拿实际的省界线来合成省面,发现效率超级慢,跟踪代码发现,OGRGeometry合并的时候随着合并线段的增加时间也在快速的增加……问题找到,上网查找解决方案,看到两篇文章(http://www.docin.com/p-1155026547.html)(http://www.docin.com/p-1238395230.html)介绍说可以考虑使用UnionCascaded(级联求并)可以大大的加快效率,实际验证确不知道怎么使用,考虑到项目的进度要求,这个问题暂且搁置了,后续再提高吧。

         对于面构线,就相对简单了不少,先把一个个的面转化成线(硬拷贝,参考上一博文中的方法),再把转化成的线Union了,生成一个拓扑关系正确的OGRMultiPolygon,再调用Simplify方法,得到的结果即为想要的线,不过当线特别多还很复杂的时候效率也高,问题和线构面的时候一样。

         在此补充上源代码,在此留个记录,后续考虑怎么解决这个问题吧……

      1 /*
      2 * @brief ConvertPolygonToPolyline        面图层转换为线图层
      3 * @param[in] tString polylinePath        转换后线图层文件路径
      4 * @param[in] OGRLayer* pLayer            要转换的面图层文件    
      5 * @param[in] Envelope envelope            要转换数据的范围
      6 * @param[in] vector<long> vecFIDs        选中的要素ID列表
      7 * @param[in] pOGRSpatialReference        要转换的数据的空间参考(如果为空表示坐标系信息不变)
      8 * @return bool                    是否成功
      9 * @author 
     10 * @date 
     11 * @note 2015年11月04日 小八创建;
     12 */
     13 bool FeatureLayerOperator::ConvertPolygonToPolylineEx(tString polylinePath,OGRLayer* pLayer,Envelope envelope,vector<long> vecFIDs,OGRSpatialReference* pOGRSpatialReference)
     14 {
     15     // 判断
     16     if(pLayer==NULL) return false;
     17     if(true==polylinePath.empty()) return false;
     18 
     19     // 坐标系读取
     20     OGRSpatialReference* pOGRSpatialReference_Source=pLayer->GetSpatialRef();    
     21     bool isSameCoordSystem = false;
     22     if(pOGRSpatialReference == NULL)
     23     {
     24         pOGRSpatialReference=pOGRSpatialReference_Source;
     25         isSameCoordSystem=true;
     26     }
     27     else if(pOGRSpatialReference!=NULL && pOGRSpatialReference_Source!=NULL)
     28     { 
     29         isSameCoordSystem=pOGRSpatialReference_Source->IsSame(pOGRSpatialReference);
     30     }
     31 
     32     // 创建Shape文件
     33     OGRDataSource* pOGRDataSource=CreateShapeFile(polylinePath,pOGRSpatialReference,wkbLineString);
     34     if(pOGRDataSource==NULL) return false;
     35 
     36     OGRLayer* pOGRLayer=pOGRDataSource->GetLayer(0);
     37     if(pOGRLayer==NULL) return false;
     38 
     39     // 面转线再合并
     40     OGRFeature* pOGRFeature_Old;
     41     OGRGeometry* pTempGeometry=NULL;
     42     OGRGeometry* pTempGeometryUnion=NULL;
     43 
     44     // 当前选择导出
     45     if(false==vecFIDs.empty()&&vecFIDs.size()>0)
     46     {
     47         for(int i=0;i<vecFIDs.size();i++)
     48         {
     49             pOGRFeature_Old=pLayer->GetFeature(vecFIDs[i]);
     50             pTempGeometry=ConvertPolygonToPolylineGeo(pOGRFeature_Old->GetGeometryRef());
     51             pTempGeometry->assignSpatialReference(pOGRSpatialReference_Source);
     52             if(false == isSameCoordSystem)pTempGeometry->transformTo(pOGRSpatialReference);
     53 
     54             if(pTempGeometryUnion==NULL) pTempGeometryUnion=pTempGeometry;
     55             else pTempGeometryUnion=pTempGeometryUnion->Union(pTempGeometry);
     56         }
     57     }
     58     else
     59     {
     60         if(false!=envelope.isNull()&&envelope.getMaxX()!=envelope.getMinX()) 
     61         {        
     62             pLayer->SetSpatialFilterRect(envelope.getMinX(),envelope.getMinY(),envelope.getMaxX(),envelope.getMaxY());
     63         }
     64 
     65         pOGRFeature_Old=pLayer->GetNextFeature();
     66         while(NULL!= pOGRFeature_Old)
     67         {
     68             pTempGeometry=ConvertPolygonToPolylineGeo(pOGRFeature_Old->GetGeometryRef());
     69             pTempGeometry->assignSpatialReference(pOGRSpatialReference_Source);
     70             if(false == isSameCoordSystem)pTempGeometry->transformTo(pOGRSpatialReference);
     71 
     72             if(pTempGeometryUnion==NULL) pTempGeometryUnion=pTempGeometry;
     73             else pTempGeometryUnion=pTempGeometryUnion->Union(pTempGeometry);
     74 
     75             pOGRFeature_Old=pLayer->GetNextFeature();
     76         }
     77     }
     78 
     79     // 获得Simply的距离
     80     double distanceValue=0.0;
     81     if(NULL==pOGRSpatialReference) // 如果为空
     82     {
     83         OGREnvelope pTempOGREnvelope ;
     84         pTempGeometryUnion->getEnvelope(&pTempOGREnvelope);
     85         if(pTempOGREnvelope.MaxX<180) distanceValue=0.00000001;
     86         else distanceValue=0.01;
     87     }
     88     else if(true==pOGRSpatialReference->IsProjected()) // 如果是Project的
     89     {
     90         distanceValue=0.01;
     91     }
     92     else // 如果是Geo的
     93     {
     94         distanceValue=0.00000001;
     95     }
     96     pTempGeometryUnion=pTempGeometryUnion->Simplify(distanceValue);
     97 
     98     // 在ShapeFile文件中添加数据行
     99     OGRFeature* pOGRFeature_New;
    100     OGRGeometry* pOGRGeometry;
    101     OGRFeatureDefn* pOGRFeatureDefn=NULL;
    102     pOGRFeatureDefn=pOGRLayer->GetLayerDefn();
    103 
    104     OGRwkbGeometryType ogrGeometryType=pTempGeometryUnion->getGeometryType();
    105     ogrGeometryType=wkbFlatten(ogrGeometryType);
    106 
    107     if(ogrGeometryType==OGRwkbGeometryType::wkbMultiLineString)
    108     {
    109         OGRGeometryCollection* pOGRGeometryCollectionTarget=(OGRGeometryCollection*) pTempGeometryUnion;
    110         int geometryCount=pOGRGeometryCollectionTarget->getNumGeometries();
    111         for(int i=0;i<geometryCount;i++)
    112         {
    113             pOGRFeature_New=OGRFeature::CreateFeature(pOGRFeatureDefn);
    114             pOGRGeometry=pOGRGeometryCollectionTarget->getGeometryRef(i);
    115             pOGRFeature_New->SetGeometry(pOGRGeometry);
    116             pOGRLayer->CreateFeature(pOGRFeature_New);
    117 
    118             OGRFeature::DestroyFeature(pOGRFeature_New);
    119             pOGRFeature_New=NULL;
    120         }
    121     }
    122     else if(ogrGeometryType==OGRwkbGeometryType::wkbLineString)
    123     {
    124         pOGRFeature_New=OGRFeature::CreateFeature(pOGRFeatureDefn);
    125         pOGRGeometry=pTempGeometryUnion;
    126         pOGRFeature_New->SetGeometry(pOGRGeometry);
    127         pOGRLayer->CreateFeature(pOGRFeature_New);
    128 
    129         OGRFeature::DestroyFeature(pOGRFeature_New);
    130         pOGRFeature_New=NULL;
    131 
    132     }
    133     OGRDataSource::DestroyDataSource(pOGRDataSource);
    134 
    135     // 销毁pTargetGeometrys
    136     OGRGeometryFactory::destroyGeometry(pTempGeometryUnion);
    137     pTempGeometryUnion=NULL;
    138 
    139     return true;
    140 }
    141 
    142 /*
    143 * @brief ConvertPolygonToPolyline        线图层转换为面图层
    144 * @param[in] tString polylinePath        转换后面图层文件路径
    145 * @param[in] OGRLayer* pLayer            要转换的线图层文件    
    146 * @param[in] Envelope envelope            要转换数据的范围
    147 * @param[in] vector<long> vecFIDs        选中的要素ID列表
    148 * @param[in] pOGRSpatialReference        要转换的数据的空间参考(如果为空表示坐标系信息不变)
    149 * @return bool                    是否成功
    150 * @author 
    151 * @date 
    152 * @note 2015年11月04日 小八创建;
    153 */
    154 bool FeatureLayerOperator::ConvertPolylineToPolygonEx(tString polylinePath,OGRLayer* pLayer,Envelope envelope,vector<long> vecFIDs,OGRSpatialReference* pOGRSpatialReference)
    155 {
    156     // 判断
    157     if(pLayer==NULL) return false;
    158     if(true==polylinePath.empty()) return false;
    159 
    160     // 坐标系读取
    161     OGRSpatialReference* pOGRSpatialReference_Source=pLayer->GetSpatialRef();    
    162     bool isSameCoordSystem = false;
    163     if(pOGRSpatialReference == NULL)
    164     {
    165         pOGRSpatialReference=pOGRSpatialReference_Source;
    166         isSameCoordSystem=true;
    167     }
    168     else if(pOGRSpatialReference!=NULL && pOGRSpatialReference_Source!=NULL)
    169     { 
    170         isSameCoordSystem=pOGRSpatialReference_Source->IsSame(pOGRSpatialReference);
    171     }
    172 
    173     // 创建Shape文件
    174     OGRDataSource* pOGRDataSource=CreateShapeFile(polylinePath,pOGRSpatialReference,wkbPolygon);
    175     if(pOGRDataSource==NULL) return false;
    176 
    177     OGRLayer* pOGRLayer=pOGRDataSource->GetLayer(0);
    178     if(pOGRLayer==NULL) return false;
    179 
    180     // 面合并
    181     OGRFeature* pOGRFeature_Old;
    182     OGRGeometry* pTempGeometry=NULL;
    183     OGRGeometry* pTempGeometryUnion=NULL;
    184 
    185     // 当前选择导出
    186     if(false==vecFIDs.empty()&&vecFIDs.size()>0)
    187     {
    188         for(int i=0;i<vecFIDs.size();i++)
    189         {
    190             pOGRFeature_Old=pLayer->GetFeature(vecFIDs[i]);
    191             pTempGeometry=pOGRFeature_Old->GetGeometryRef();
    192             if(false == isSameCoordSystem)pTempGeometry->transformTo(pOGRSpatialReference);
    193 
    194             if(pTempGeometryUnion==NULL) pTempGeometryUnion=pTempGeometry;
    195             else pTempGeometryUnion=pTempGeometryUnion->Union(pTempGeometry);
    196         }
    197     }
    198     else
    199     {
    200         if(false!=envelope.isNull()&&envelope.getMaxX()!=envelope.getMinX()) 
    201         {        
    202             pLayer->SetSpatialFilterRect(envelope.getMinX(),envelope.getMinY(),envelope.getMaxX(),envelope.getMaxY());
    203         }
    204 
    205         pOGRFeature_Old=pLayer->GetNextFeature();
    206         while(NULL!= pOGRFeature_Old)
    207         {
    208             pTempGeometry=pOGRFeature_Old->GetGeometryRef();
    209             if(false == isSameCoordSystem)pTempGeometry->transformTo(pOGRSpatialReference);
    210 
    211             if(pTempGeometryUnion==NULL) pTempGeometryUnion=pTempGeometry;
    212             else pTempGeometryUnion=pTempGeometryUnion->Union(pTempGeometry);
    213 
    214             pOGRFeature_Old=pLayer->GetNextFeature();
    215         }
    216     }
    217 
    218     OGRGeometry* pOGRGeometryUnion = pTempGeometryUnion->Polygonize();
    219 
    220     // 在ShapeFile文件中添加数据行
    221     OGRFeature* pOGRFeature_New;
    222     OGRGeometry* pOGRGeometry;
    223     OGRFeatureDefn* pOGRFeatureDefn=NULL;
    224     pOGRFeatureDefn=pOGRLayer->GetLayerDefn();
    225 
    226     OGRwkbGeometryType ogrGeometryType=pOGRGeometryUnion->getGeometryType();
    227     ogrGeometryType=wkbFlatten(ogrGeometryType);
    228 
    229     if(ogrGeometryType==OGRwkbGeometryType::wkbGeometryCollection||ogrGeometryType==OGRwkbGeometryType::wkbMultiPolygon)
    230     {
    231         OGRGeometryCollection* pOGRGeometryCollectionTarget=(OGRGeometryCollection*) pOGRGeometryUnion;
    232         int geometryCount=pOGRGeometryCollectionTarget->getNumGeometries();
    233         for(int i=0;i<geometryCount;i++)
    234         {
    235             pOGRFeature_New=OGRFeature::CreateFeature(pOGRFeatureDefn);
    236             pOGRGeometry=pOGRGeometryCollectionTarget->getGeometryRef(i);
    237             pOGRFeature_New->SetGeometry(pOGRGeometry);
    238             pOGRLayer->CreateFeature(pOGRFeature_New);
    239 
    240             OGRFeature::DestroyFeature(pOGRFeature_New);
    241             pOGRFeature_New=NULL;
    242         }
    243     }
    244     else if(ogrGeometryType==OGRwkbGeometryType::wkbPolygon)
    245     {
    246         pOGRFeature_New=OGRFeature::CreateFeature(pOGRFeatureDefn);
    247         pOGRGeometry=pOGRGeometryUnion;
    248         pOGRFeature_New->SetGeometry(pOGRGeometry);
    249         pOGRLayer->CreateFeature(pOGRFeature_New);
    250 
    251         OGRFeature::DestroyFeature(pOGRFeature_New);
    252         pOGRFeature_New=NULL;
    253 
    254     }
    255     OGRDataSource::DestroyDataSource(pOGRDataSource);
    256 
    257     // 销毁pTargetGeometrys
    258     OGRGeometryFactory::destroyGeometry(pTempGeometryUnion);
    259     pTempGeometryUnion=NULL;
    260 
    261     return true;
    262 }
    View Code
  • 相关阅读:
    CODING x 百果园 _ 水果零售龙头迈出 DevOps 体系建设第一步
    Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞
    做云原生时代标准化工具,实现高效云上研发工作流
    打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
    WePack —— 助力企业渐进式 DevOps 转型
    CODING Compass —— 打造行云流水般的软件工厂
    Nocalhost —— 让云原生开发回归原始而又简单
    CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
    Nocalhost:云原生开发新体验
    使用 Nocalhost 开发 Kubernetes 中的 APISIX Ingress Controller
  • 原文地址:https://www.cnblogs.com/LiangXiaoBa/p/4962617.html
Copyright © 2011-2022 走看看