Shapely中polygon.contains()返回false但循环未排除多边形外点问题
Shapely多边形点过滤结果异常问题
问题背景
基于shapely库通过如下WKT定义构建多边形:
POLYGON ((28 0, 28 68, 44 68, 44 58, 46 0, 38 45, 46 0, 41 34, 46 0, 42 24, 46 0, 46 7, 46 0, 28 0))
编写点过滤逻辑判断网格点是否落在多边形范围内时,无法完全排除多边形外的点。
注:图中虚线代表多边形角点连线
以坐标点(44.5, 44.5)为例,该点明确位于多边形外部,却未被过滤流程排除。对应的过滤实现代码如下:
from shapely import geometry def getFieldGridPoints(pitchX, pitchY, poly): gridPoints = [] for i in range(1, pitchX + 1, 1): for j in range(1, pitchY + 1, 1): gridPoints.append(geometry.Point(i - 0.5, j - 0.5)) finalGrid = [] for p in gridPoints: if poly.contains(p): finalGrid.append([p.x, p.y]) print(finalGrid) return finalGrid
异常表现
getFieldGridPoints返回的finalGrid列表中包含多边形外的点,后续着色逻辑读取该列表时,会错误触发外点对应位置的着色- 单独调用
poly.contains(geometry.Point(44.5,44.5))时返回结果为False,和循环遍历中的判断表现不一致
问题根因
当前传入的多边形WKT存在拓扑错误:坐标序列多次重复折返到(46, 0)点,最终生成的是自交、存在大量重叠边的无效多边形。Shapely的空间判断逻辑(包括contains方法)仅对合法有效几何对象保证结果一致性,对无效几何执行运算时会出现结果不稳定、单次调用和批量遍历判断结果不符的异常。
解决方案
- 修正多边形WKT定义,删除坐标序列中重复的折返点,按多边形边界的连贯顺序排列坐标,保证多边形外环是无自交、无重复边的简单闭合环。和示意图形状匹配的参考WKT如下:
POLYGON ((28 0, 28 68, 44 68, 44 58, 38 45, 41 34, 42 24, 46 7, 46 0, 28 0))
- 几何对象构建完成后增加有效性校验,对无效几何自动修复,从根源避免无效对象参与空间运算:
from shapely.validation import make_valid # 多边形构建完成后执行校验修复 if not poly.is_valid: poly = make_valid(poly)
- 如果业务逻辑需要把落在多边形边界上的点也算作多边形内,将判断条件从
poly.contains(p)替换为poly.intersects(p),避免边界点被漏判。
内容的提问来源于stack exchange,提问作者Leo Gorael
相关产品推荐
相关产品推荐

