47

如果多边形的任何线段相交,包括共线的线段,Shapely 将多边形定义为无效。许多软件包将创建一个带有“切口”的区域或区域,如下所示,它具有共线段:

在此处输入图像描述

>>> pp = Polygon([(0,0), (0,3), (3,3), (3,0), (2,0), 
                  (2,2), (1,2), (1,1), (2,1), (2,0), (0,0)])
>>> pp.is_valid
WARNING:shapely.geos:Self-intersection at or near point 2 0
False

自然地,切口可以在 Shapely 中本地实现,或者这个相同的几何可以实现为两个有效的多边形,但是如果我只有上面显示的点列表,是否有一个容易“修复”的方法(从这个创建有效的几何点列表)?

4

6 回答 6

53

我找到了一个适用于特定情况的解决方案:

>>> pp2 = pp.buffer(0)
>>> pp2.is_valid
True
>>> pp2.exterior.coords[:]
[(0.0, 0.0), (0.0, 3.0), (3.0, 3.0), (3.0, 0.0), (2.0, 0.0), (0.0, 0.0)]
>>> pp2.interiors[0].coords[:]
[(2.0, 1.0), (2.0, 2.0), (1.0, 2.0), (1.0, 1.0), (2.0, 1.0)]
于 2014-01-01T22:08:57.213 回答
3

Shapely 针对这个问题实施了一个解决方案。通过 pip 您可以使用 shapely 1.8a3 版本并以这种方式导入:

从 shapely.validation 导入 make_valid

不幸的是,如果您必须通过 conda 安装其他库,例如 geopandas,您可能会面临依赖问题,因为此时 conda 仅提供了 1.7.1 版本。因此,您可以在程序中使用 shapely 解决方案,如下所示:

def make_valid(ob):

from shapely.geometry.base import geom_factory
from shapely.geos import lgeos

if ob.is_valid:
    return ob
return geom_factory(lgeos.GEOSMakeValid(ob._geom))
于 2021-09-22T12:10:38.107 回答
3

未经测试,但现在 Shapely 似乎添加了一个功能来支持这一点。

https://shapely.readthedocs.io/en/latest/manual.html#validation.make_valid

于 2021-07-08T23:56:42.983 回答
1

最简单的解决方案

new_polygon = pp.buffer(0)
new_polygon.is_valid

也许它会工作。

于 2021-11-09T02:01:36.617 回答
0

这是我第一次尝试修复几何功能。我必须处理将多边形转换为多多边形的特殊情况,在这种情况下make_validb/c 不起作用len(make_valid(feature)) !=1

from shapely.validation import make_valid

def fix_geom(in_feature):

    # avoid changing original geodf
    in_feature = in_feature.copy(deep=True)    
        
    # drop any missing geometries
    in_feature = in_feature[~(in_feature.is_empty)]
    
    # Repair broken geometries
    for index, row in in_feature.iterrows(): # Looping over all polygons
        if row['geometry'].is_valid:
            next
        else:
            fix = make_valid(row['geometry'])

            try:
                in_feature.loc[[index],'geometry'] =  fix # issue with Poly > Multipolygon
            except ValueError:
                in_feature.loc[[index],'geometry'] =  in_feature.loc[[index], 'geometry'].buffer(0)
    return in_feature
于 2022-02-23T03:34:35.910 回答
0

我经常使用 .buffer(0) 方法,但它在 Windows 和 Linux 上给出了不同的结果。因此,如果您遇到这样的问题,请记住:

警告:shapely 的 .buffer(0) 函数在不同的操作系统(即 Windows 和 Linux)上可能表现不同。我有一些例子,在 Linux 上返回一个空的多边形,而在 Windows 上返回正确的非空多边形!

这个问题花了我几天的时间来解决,这就是为什么我想将其添加为答案(我对已接受答案的建议编辑被遗憾地拒绝了)。

于 2021-10-03T16:56:16.353 回答