如何检测分割多边形何时可能是多边形

How to detect when split polygon could have been multipolygon

当我分割一个多边形使得有两个断开连接的部分时,我得到一个 MultiPolygon。但是当它们在一条线上相切时,它会给我一个多边形,就像这个例子。

'POLYGON ((0 0.5, 0 0.95, 2 1.95, 2 1.1, 1.5 1.1, 1.5 1.5, 1.1 1.5, 1.1 1.1, 1 1.1, 1 1.2, 0.5 1.2, 0.5 0.5, 0 0.5))'

我原以为很容易检测到它们,因为它们会有交点。我天真地希望查看外部坐标以查找重复项。但是,它可以在两点之间的线上相交,例如示例多边形(它是用 shapely.ops.split(poly, line) 和对角线分割产生的两个几何图形之一):

在我看来,这应该产生了一个多面体。事实上,我相信在这种情况下我应该将它转换成一组正多边形,所以除了检测这些形状之外,如果你也有一种动态的方式将它分割成一个多多边形(或多边形列表),那就太棒了.我希望检测可以比查看点和由每对点组成的线串之间的交点更快,因为那会很慢:

def remove_self_tangents(S: Polygon) -> Polygon:
    """sketch approach to remove self tangents"""
    for i, (a,b) in enumerate(zip(S.exterior.coords, S.exterior.coords[1:])):
        for c in S.exterior.coords:
            if c == a or c == b:
                continue
            if c.touches(LineString([a, b])):
                S = Polygon(S.exterior.coords[:-1].insert(i+1,c)).simplify(TOLERANCE) # don't actually expect simplify will do it but, ...
    return S

编辑:

我现在有我的过程,上面的样本永远不会生成,但仍然会生成非常接近的未命中,例如: 'POLYGON ((0.5 0.5, 1 0.5, 1 1.110223024625157e-16, 0 0.9999999999999998, 0 2, 1 2, 1 1.2, 0.5 1.2, 0.5 0.5))'

解决这个问题的简单算法是四舍五入到一定的精度..但是.simplify在这里不起作用,我必须手动完成吗?

这是我使用的解决方案

# TOLERANCE = 1e-14 or something
def polygon_has_no_self_tangents(S: Polygon) -> Polygon:
    for a,b in zip(S.exterior.coords, S.exterior.coords[1:]):
        for c in S.exterior.coords:
            if c == a or c == b:
                continue
            np = nearest_points(LineString([a, b]), Point(c))
            if np[0].distance(np[1]) < TOLERANCE:
                return False
    return True