Python / Shapely 相交包含

2 投票
1 回答
1598 浏览
提问于 2025-04-18 16:18

我正在尝试写一个算法,用来检查一个多边形是否在另一个多边形里面,但它们有共同的边界。

from shapely.geometry import Polygon
poly = Polygon(((0, 0), (0, 2), (2, 2), (2, 0)))
poly2 = Polygon(((0, 0), (0, 1), (1, 1), (1, 0)))
# poly.contains(poly2) will return False

有没有其他的方法可以判断,除了检查poly2中的至少一个点是否在poly里面,并且它们不相交(也就是有的点在poly里面,有的点在外面)?

from shapely.geometry import Polygon
poly = Polygon(((0, 0), (0, 2), (2, 2), (2, 0)))
poly2 = Polygon(((0, 0), (0, 1), (1, 1), (1, 0)))
poly3 = Polygon(((0, 0), (0, 1), (-1, 1), (-1, 0)))
# desired result poly.func(poly2) == True poly.func(poly3) == False

1 个回答

2

你可以使用 DE-9IM 模型来详细检查空间关系,比如“相交”、“包含”等等。这些数据可以通过 relate 获取:

A = poly
B = poly2
rel = A.relate(B)
print(rel)  # 212F11FF2

在 JTS TestBuilder 中查看效果如下:

DE-9IM

如果你想找出“至少有一个点在 poly2 内部,并且它们不相交(即有些点在 poly 内部,有些在外部)”,同时还要检查它们是否“共享边界”,这就需要满足所有条件:

  • I(A) ∩ I(B) = 2 或 rel[0] == '2',这表示至少有一个点在 B 内部,导致了区域相交
  • B(A) ∩ B(B) = {0, 1} 或 rel[5] in '01',用来检查这两个形状是否共享边界(可以是点或线)
  • E(A) ∩ I(B) = F 或 rel[6] == 'F',用来判断 B 是否没有在 A 的外部相交

所以,你可以自己创建一个空间谓词:

def my_criteria(A, B):
    rel = A.relate(B)
    return rel[0] == '2' and rel[5] in '01' and rel[6] == 'F'

my_criteria(poly, poly2)  # True
my_criteria(poly2, poly)  # False

撰写回答