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
  • 相关阅读:
    Hello China最新开发进展
    虚拟软驱影像文件制作程序下载路径:http://download.csdn.net/source/738137
    Swing透明和变换
    利用Java存储过程简化数据库操作
    Hello China V1.5 源码下载地址
    防止程序重复执行的单元
    判断文件大小的函数
    TMainMenu 隐藏与显示菜单
    最简单的Delphi程序(控制台)
    测试代码
  • 原文地址:https://www.cnblogs.com/LiangXiaoBa/p/4962617.html
Copyright © 2011-2022 走看看