报错信息
使用shapely的Polygon类构建的多边形计算intersection的时候遇到如下报错:1
TopologyException: Input geom 1 is invalid: Ring Self-intersection at or near point...
错误原因
给出的Polygon中包含了一个所谓的self intersection
,根据报错和网上信息怀疑是因为多边形本身有重叠的部分(同一个多边形自己内部有个小多边形),示意图如下这种,大的多边形中间因为给定的坐标顺序的缘故,导致内部产生了包含其中的一个多边形。
解决办法
给构建的Polygon加一个较小的buffer:
1 | poly = Polygon([(x0,y0),(x1,y1),(x2,y2),(x3,y3),...]) #原始的polygon |
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)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.
从该例子中可以推测出,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已经无关了。