GEOS的一些自己的见解和注意点

GEOS的前身是JTS,JTS提供了全功能的,强大的空间操作和空间判断。
后来PostGIS缺少一套完整的空间查询操作,于是就将JTS移植成为C++版本,正式命名为GEOS。GEOS为开源库,它包括了完整的空间查询和一大部分空间操作,是从事图形操作和GIS行业开发人员经常接触的开发库。较为知名的使用GEOS的GIS软件就有QGIS,QGIS使用GEOS的c接口,c接口函数名称不会经常发生更改,具有更多的稳定性。

                          图一

图一为GEOS定义的数据类型:点 多点 线串 闭合线串 多线串 多边形 Multi多边形 几何集合

GEOS是基于九交模型来判断空间关系的,不了解九交模型的请移步http://www.cnblogs.com/denny402/p/4968201.html,其实九交模型名字很高大上,理解起来是很简单的,一个geometry分为三种空间关系,外部、内部、边界三种,空间相对关系是相对于多个几何体来说的,九交模型是对于两个几何体的空间关系来说的,也就是3*3中,例如边界对于边界相交则为多点集合,维度为0维(面在GEOS内定义为2维,线的维度则为1维,点的维度为0维)。
由于C++ 接口有API文档可以查阅,我不做太多介绍,想要查阅的请移步http://geos.osgeo.org/doxygen/
我主要介绍一下C接口,通过查看GEOS的源码发现,c接口内部调用的还是c++的接口函数,只是在外部封了一层,但GEOS的官网上为什么会说C的接口稳定?我也不是很理解,希望大神们和我探讨一下
c接口只有一个头文件geo_c.h介绍过于少,其中有需要注意的地方:
一、要注意C接口中空间操作GEOSUnion等空间分析API,这些API是具有深拷贝行为的,但create、get之类的接口,比如createPolygon()只是获得了指向内外环的指针,是浅拷贝。
二、GEOSBoundary()是对几何体对象进行降维操作,例如获得一个多边形的内外环线,得到外环线使用GEOSGeomGetExteriorRing(),内环线是GEOSGeomGetInteriorRingN()
三、C接口的创建面的基本顺序是与C++创建顺序是相同的,首先创建一个点序列,再创建一个闭合线串(点序列首末点需相同),最后使用闭合线串创建面。
四、每一个API后都会有一个加_r的相同功能的API,通过查看源码发现,内部定义了一个空间操作上下文,用意是什么,不太确定,希望大神可以告知
五、c接口的运行时间是与几何图形的复杂度成正比关系的,具体的复杂度我没有查看源码,无法确定,但你的几何图形只要十分复杂且点数稍多,接口计算时间就会变长,大家可以参考DEM转换出的矢量图,点数在30w左右,几何图形复杂QGIS调用GEOS_C的API,合并 拓扑化 相交等控件操作时间都会变长。特别对于intersection操作,性能十分敏感。

问题:基于GEOS的空间操作的不稳定性,比如:使用QGIS操作矢量要素,多次分割一个面要素,然后合并要素,竟然合不上!查看源码基本定位到GEOS接口的不稳定性上,进一步研究发现,只要两个点的xy坐标到15位不相同,GEOS就认为这两个点不是同一个点!原因基本是因为GEOS的精度模型是很高的,同时使用双精度数据的空间判断很不稳定,但GEOS提供了精度模型类,通过demo程序设置,不起作用!最近我们小组一直在纠结这个问题,大神们有没有什么解决方法。。。。。
通过源码查看,GEOS内部有几种策略,如果需要设置精度模型,需要设置相关的策略,精度模型才能起效。
基本上可以确认,GEOS是使用double值来计算,关于空间计算的库,例如boost的geometry等,只要使用了双精度计算,都会存在数值不稳定型问题,根源再于四舍五入的问题!在高精度的计算中,这个问题显得尤为严重,可以引发这个geometry不合法,发生拓扑错误,GEOS内部也设置了许多策略来克服这个问题,但都没有很完美的解决,只能降低发生的概率,不能完全解决。
我了解的c接口需要注意的就这么多,有什么问题大家可以私信我或者在下面评论,大家一起讨论哈。
附上自己写的代码…

#include <iostream>
#include "geos_c.h"
int main()
{// 初始化GEOSContextHandle_t handle = GEOS_init_r();GEOSCoordSequence* seq = nullptr;GEOSGeometry* trian = nullptr;GEOSGeometry* triPolygon = nullptr;GEOSGeometry* boxLr = nullptr;GEOSGeometry* boxP = nullptr;// 创建三角形seq = GEOSCoordSeq_create_r(handle, 4, 0);// 赋值坐标// 0GEOSCoordSeq_setX_r(handle, seq, 0, 300.0);GEOSCoordSeq_setY_r(handle, seq, 0, 0.0);// 1GEOSCoordSeq_setX_r(handle, seq, 1, 400.0);GEOSCoordSeq_setY_r(handle, seq, 1, 0.0);// 2GEOSCoordSeq_setX_r(handle, seq, 2, 300.0);GEOSCoordSeq_setY_r(handle, seq, 2, 100.0);// 3GEOSCoordSeq_setX_r(handle, seq, 3, 300.0);GEOSCoordSeq_setY_r(handle, seq, 3, 0);//创建环线trian = GEOSGeom_createLinearRing_r(handle, seq);// 创建线串//创建三角面triPolygon = GEOSGeom_createPolygon_r(handle, trian, nullptr, 0);// 创建 面seq = GEOSCoordSeq_create_r(handle, 5, 0);// 赋值坐标// 0GEOSCoordSeq_setX_r(handle, seq, 0, -200.0);GEOSCoordSeq_setY_r(handle, seq, 0, -200.0);// 1GEOSCoordSeq_setX_r(handle, seq, 1, 200.0);GEOSCoordSeq_setY_r(handle, seq, 1, -200.0);// 2GEOSCoordSeq_setX_r(handle, seq, 2, 200.0);GEOSCoordSeq_setY_r(handle, seq, 2, 200.0);// 3GEOSCoordSeq_setX_r(handle, seq, 3, -200.0);GEOSCoordSeq_setY_r(handle, seq, 3, 200.0);// 4GEOSCoordSeq_setX_r(handle, seq, 4, -200);GEOSCoordSeq_setY_r(handle, seq, 4, -200);//创建环线boxLr = GEOSGeom_createLinearRing_r(handle, seq);//创建面boxP = GEOSGeom_createPolygon_r(handle, boxLr, nullptr, 0);// 测试空间关系//char contains = GEOSContains_r(handle, boxP, triPolygon);//char insert = GEOSIntersects_r(handle, boxP, triPolygon);//char within = GEOSWithin_r(handle, boxP, triPolygon);//std::cout << insert << std::endl;// 空间切割GEOSGeometry* geom = GEOSClipByRect_r(handle, triPolygon, 300, 0, 350, 50);char isValid = GEOSisValid_r(handle, geom);int num = GEOSGetNumCoordinates_r(handle, geom);//IDint id = GEOSGeomTypeId_r(handle, triPolygon);// 删除内存GEOSGeom_destroy_r(handle, triPolygon);GEOSGeom_destroy_r(handle, boxP);// 结束句柄GEOS_finish_r(handle);return 0;}

GEOS库一些自己的见解和注意点相关推荐

  1. 使用VS2010编译64的Geos库

    Geos库在cmake中总是报错,所以我决定试试nmake编译64位的库.现将编译过程记录如下: 1.下载Geos,我下的是最新版3.5.0,地址在 http://trac.osgeo.org/geo ...

  2. 【GEOS】GEOS库学习之简单几何图形的创建

    一.GEOS库介绍 GEOS的前⾝是JTS,JTS提供了全功能的,强⼤的空间操作和空间判断. 后来PostGIS缺少⼀套完整的空间查询操作,于是就将JTS移植成为C++版本,正式命名为GEOS. GE ...

  3. GIS开源库GEOS库学习教程(二):geos中的几何图形(Geometry)

    前言   上一节我们学过了GEOS库的介绍和环境编译及示例代码,在这一节我们将了解一下geos中的各种几何图形类,它们大部分都是从Geometry类派生的.而几何图形(Geometry)是geos里面 ...

  4. GIS开源库GEOS库学习教程(一):编译及示例代码

    1.介绍   GEOS库是一个集合形状的拓扑关系操作实用库,简单得说,就是判断两个几何形状之间关系和对两个几何形状进行操作以形成新的几何形状的库.GEOS是仿照JTS库做的,是JTS的C++实现.下面 ...

  5. 用pip安装cartopy(windows平台),解决GEOS库的问题

    对象:cartopy Cartopy官方网站介绍: Cartopy is a Python package designed for geospatial data processing in ord ...

  6. GEOS库的学习之一:介绍和编译

    对GEOS库的学习,源于一个项目:要在c++中判断二维平面中两个多边形的关系(无论凹凸).也就是判断两个多边形是否相交.相容等.听起来很简单,可实现起来却比较难,而项目又催得紧.于是我去搜索了一下,看 ...

  7. nmake构建Geos库

    1.下载源码包 下载地址 http://download.osgeo.org/geos/geos-3.6.1.tar.bz2 下载之后解压即可. 2.编译 geos源码包中自带了makefile.vc ...

  8. 【GEOS】GEOS库学习之几何关系判断

    原理在前面的章节已经介绍过了,这篇就直接进行程序练习: #include "geos.h"GeometryFactory factory;//创建一条环线,与线的区别就是环线是闭合 ...

  9. C++的GEOS库实现几何计算,多个面和一条线相交后得到多条线段的例子。

    在vcpkg包管理工具的环境下使用VisualStudio,vcpkg确认已安装gdal:x64-windows库. #include <drogon/drogon.h> #include ...

  10. Tools: geos 使用指南

    1. 下载geos 2. 进入VS开发人员命令提示 3.依次执行如下命令 >VCVARS32.BAT >cd D:\DevTool\geos-3.7.0 >atuogen.bat & ...

最新文章

  1. 可逼近信道容量编码技术之霍夫曼编码的实现
  2. 互联网直播云计算架构介绍
  3. java实现多路分发
  4. Qt Creator自定义构建过程
  5. java更改包名称_更改Java包名称如何改变我的系统架构
  6. 拜登将主持商讨网络安全问题,苹果和微软CEO参加
  7. Java经典实例:进阶版堆栈实现,支持任何对象类型
  8. 如何评估一个算法效果
  9. 运维笔记-lnmp一键安装问题
  10. Win7 启动 0xc0000034错误 - 解决
  11. 2006 IBM SOA主题会开始座席预定工作
  12. 经典Excel VBA代码
  13. 关于错误: [Error] ld returned 1 exit status
  14. Arch 中 fcitx5 提示拼音不可用的解决过程
  15. 计算机丢失rtl100.bpl,处理“未曾找到 rtl100.bpl,因而这个利用过程未能启用。重新安装利用过程可能会修复此问题。”...
  16. 共享打印机显示服务器错误代码,使用共享打印机 出现错误代码0x00000709的解决办法...
  17. matlab——自带的隐马尔科夫工具箱的使用
  18. 【Windows10自带杀毒软件关闭?】
  19. linux重启python服务_linux重启服务命令
  20. C语言写整数类(Integer)

热门文章

  1. DSA数字签名原理及python实现
  2. 1~3年产品经理经典面试题
  3. PC软件标题修改器 支持加壳
  4. psvimg格式PSV存档文件解包工具psvimgtools在macOS环境下的使用教程
  5. RuntimeError: Exporting the operator uniform to ONNX opset version 12 is not supported.
  6. 抖音下载小助手GUI版
  7. php爬虫模拟登陆爬取数据全过程
  8. 华为鸿蒙操作系统国美通讯,国美通讯(600898)03月06日14:30大单揭秘
  9. 控制算法简析3——LKA中PID控制的error选取
  10. 微信加人就服务器频繁,微信加同一个人好友,提示操作过于频繁,请稍后重试!这个是什么意思啊?...