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

关于线构面,这个过程中也是挺曲折的,在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();
  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()>)
  46. {
  47. for(int i=;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<) 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=;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();
  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()>)
  187. {
  188. for(int i=;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=;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. }

GDAL线面互转换(2)的更多相关文章

  1. GDAL线面互转换

    最近因为项目需要,需做GDAL线面互转的功能,查阅部分资料完成,下面把核心部分的代码贴出来,留个记录,也欢迎大家提问题指正完善. /* * @brief ConvertPolygonToPolylin ...

  2. opengl中场景变换|2D与3D互转换(转)

    opengl中场景变换|2D与3D互转换 我们生活在一个三维的世界——如果要观察一个物体,我们可以: 1.从不同的位置去观察它.(视图变换) 2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我 ...

  3. PHP时间戳和日期互转换

    在php中我们要把时间戳转换日期可以直接使用date函数来实现,如果要把日期转换成时间戳可以使用strtotime()函数实现,下面我来给大家举例说明. 1.php中时间转换函数 strtotime ...

  4. Javascript Array和String的互转换。

    Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...

  5. Javascript Array和String的互转换

    Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...

  6. C#二进制与字符串互转换,十六进制转换为字符串、float、int

    /// <summary>     /// 将 字符串 转成 二进制 “10011100000000011100011111111101” /// </summary> /// ...

  7. Image与Base64String的互转换

    public Image Base64ToImage(string base64String) { // Convert Base64 String to byte[] byte[] imageByt ...

  8. Gdal 1.11.0 添加 Postgresql 9.1 sqlite3 支持

    OS环境Ubuntu12.04 32bit 因为公司一个功能要用到gdal 的ogr2ogr命令转换shp数据,需要能往postgis和sqlite 中插入数据. 用gdal1.11.0的源码默认安装 ...

  9. c#中将IP地址转换成无符号整形数的方法与逆变换方法

    我们知道 IP地址就是给每个连接在Internet上的主机分配的一个32bit地址. 按照TCP/IP协议规定,IP地址用二进制来表示,每个IP地址长32bit,比特换算成字节,就是4个字节.而c#中 ...

随机推荐

  1. centos安装 Anaconda3及使用

    下载安装 下载地址https://www.anaconda.com/download/ 旧版本下载https://repo.continuum.io/archive/ 比如下载Anaconda3-4. ...

  2. mysql主从同步详细教程

    1.安装好主数据库和从数据库,这个大家肯定都会,如果不是很明白,可以参考我前面的安装教程. 例子: 假如我需要同步test1.test2数据库 系统:centos7 主库主机:192.168.1.25 ...

  3. Netty核心概念(6)之Handler

    1.前言 本节介绍Netty中第三个重要的概念——Handler,这个在前两节都提到了,尤其是Channel和Handler联系紧密.handler本身的设计非常简单,但是所起到的作用却很大,Nett ...

  4. 在Vue的webpack中结合runder函数

    在Vue的webpack中结合runder函数 1.引入: <h1>下面是vue的内容:</h1> <div id="app"> <log ...

  5. 基于flex的不定个数的按钮组

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. ActiveMQ发布-订阅消息模式

    一.订阅杂志我们很多人都订过杂志,其过程很简单.只要告诉邮局我们所要订的杂志名.投递的地址,付了钱就OK.出版社定期会将出版的杂志交给邮局,邮局会根据订阅的列表,将杂志送达消费者手中.这样我们就可以看 ...

  7. zookeeper集群搭建及Leader选举算法源码解析

    第一章.zookeeper概述 一.zookeeper 简介 zookeeper 是一个开源的分布式应用程序协调服务器,是 Hadoop 的重要组件. zooKeeper 是一个分布式的,开放源码的分 ...

  8. js拼图

    ;(function($){ function arrayIndexOf(r, num){ if( Array.prototype.indexOf ){ return r.indexOf(num); ...

  9. 笔记一:python安装和执行

    一:学习内容 python安装 python简介 python执行 二:python安装 1. 下载python,网地址:https://www.python.org/,进入地址后,点击下载downl ...

  10. Oracle数据库 中的基础的一些语法结构

    方括号里的内容为可选项 大括号是必填 1PL/SQL结构块 DECLARE /* * 声明部分——定义常量.变量.复杂数据类型.游标.用户自定义异常 */ BEGIN /* * 执行部分——PL/SQ ...