Shapely.Polygon.intersection报错:TopologyException: Input geom 1 is invalid: Ring Self-intersection...

报错信息

使用shapely中的Polygon类构建的多边形计算intersection的时候遇到如下报错:

TopologyException: Input geom 1 is invalid: Ring Self-intersection at or near point...

错误原因

给出的Polygon中包含了一个所谓的self intersection,根据报错和网上信息怀疑是因为多边形本身有重叠的部分(同一个多边形自己内部有个小多边形),示意图如下这种,大的多边形中间因为给定的坐标顺序的缘故,导致内部产生了包含其中的一个多边形。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w0mnJgVi-1582572426799)(…/image/self-intesect-polygon.jpg)]

解决办法

给构建的Polygon加一个较小的buffer:

poly = Polygon([(x0,y0),(x1,y1),(x2,y2),(x3,y3),...]) #原始的polygon
poly = poly.buffer(0.01) # 加一个较小的buffer

Problem Solved.

思考

这里的buffer在回答里没有说清楚,在官方api document中给出了一些例子来解释buffer的作用:

先看buffer的函数定义:

object.buffer(distance, resolution=16, cap_style=1, join_style=1, mitre_limit=5.0)

Returns an approximate representation of all points within a given distance of the this geometric object.

字面意义理解就是在给定的object上按照给定的范围(distance)形成一个近似表示。从下面的例子可以更好的理解这个定义。


a = Point(1, 1).buffer(1.5)
b = Point(2, 1).buffer(1.5)
a.difference(b)
<shapely.geometry.polygon.Polygon object at 0x…>

The buffer() method is used to produce approximately circular polygons in the examples of this section; it will be explained in detail later in this manual.
[结果图示][24406cc0]

从该例子中可以推测出,buffer的作用是在给定点周围按给定的值增加了范围:给出(1,1)点,给出buffer size是1.5,那么结果就是在(1,1)点周围形成了一个半径为1.5的圆。


这样就不难看出为何对本来有内部交叉(self-intersection/self-ring)的Ploygon对象使用buffer会解决这个内部交叉问题了:

首先我们给出的多边形object,产生的内部交叉往往是一个很小的ring,由给出的坐标点的顺序造成;使用buffer后,内部的ring被生成个的新的object的范围所覆盖(原始object面积增大),而覆盖了内部ring。

参考上面例子就是原本是一个点,使用buffer后其面积增大,其边界也变成了新的圆的边界,这样即使原来中心点周围有小的ring,都会被覆盖在新的圆中;

而此时如果计算新的圆与其他object的intersection的话,肯定是按照新的圆的边界来界定的,所以与原来的内部ring已经无关了。

参考

  • https://gis.stackexchange.com/questions/287064/dissolve-causes-no-shapely-geometry-can-be-created-from-null-value-in-geopanda
  • https://gis.stackexchange.com/questions/311209/how-to-fix-invalid-polygon-with-self-intersection-python
  • https://shapely.readthedocs.io/en/latest/manual.html
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

江前云后

文章结束的标识:打赏链接

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

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

打赏作者

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

抵扣说明:

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

余额充值