在我的项目中有两个用例。在第一种情况下,红色和蓝色形状不重叠,但在第二种情况下却重叠。
在我的测试代码中,我尝试了来自 Shapely 的各种谓词,但无论如何都找不到区分它们的方法。
from shapely import LinearRing
# first use-case
blue_sq = LinearRing([(1, 1), (1, 2), (2, 2), (2, 1), (1, 1)])
red_one = LinearRing([(0, 0), (0, 3), (3, 3), (3, 2), (1, 2), (1, 0), (0, 0)])
print(blue_sq.overlaps(red_one))
print(blue_sq.intersects(red_one))
print(blue_sq.crosses(red_one))
print(blue_sq.contains(red_one))
print(blue_sq.touches(red_one))
print(blue_sq.within(red_one))
# second use-case
blue_ln = LinearRing([(2, 1), (2, 2), (7, 2), (7, 1), (2, 1)])
red_two = LinearRing([(1, 0), (1, 1), (2, 1), (2, 2), (3, 2), (3, 0), (1, 0)])
print(blue_ln.overlaps(red_two))
print(blue_ln.intersects(red_two))
print(blue_ln.crosses(red_two))
print(blue_ln.contains(red_two))
print(blue_ln.touches(red_two))
print(blue_ln.within(red_two))
结果总结于下表中。
形状谓词 | 案例1 | 案例2 |
---|---|---|
重叠 | 正确 | 正确 |
相交 | 正确 | 正确 |
十字 | 错误 | 错误 |
包含 | 错误 | 错误 |
触动 | 错误 | 错误 |
内 | 错误 | 错误 |
两种情况看似交叉和重叠,但两种情况都没有交叉、包含、接触或位于对方之内。我确信我错过了一些明显的东西:-)
LinearRing 仍然只是一条线...所以考虑到这两种情况确实非常相似,并且谓词的结果没有差异。
当您将坐标视为曲面的外边界时,就会出现差异。要使用这样的线条,您需要使用它们来创建形状良好的多边形。如果你这样做,你会得到预期的不同结果。
代码示例:
from shapely import Polygon
# first use-case
blue_sq = Polygon([(1, 1), (1, 2), (2, 2), (2, 1), (1, 1)])
red_one = Polygon([(0, 0), (0, 3), (3, 3), (3, 2), (1, 2), (1, 0), (0, 0)])
print(f"{blue_sq.overlaps(red_one)=}")
print(f"{blue_sq.intersects(red_one)=}")
print(f"{blue_sq.crosses(red_one)=}")
print(f"{blue_sq.contains(red_one)=}")
print(f"{blue_sq.touches(red_one)=}")
print(f"{blue_sq.within(red_one)=}")
# second use-case
blue_ln = Polygon([(2, 1), (2, 2), (7, 2), (7, 1), (2, 1)])
red_two = Polygon([(1, 0), (1, 1), (2, 1), (2, 2), (3, 2), (3, 0), (1, 0)])
print(f"{blue_ln.overlaps(red_two)=}")
print(f"{blue_ln.intersects(red_two)=}")
print(f"{blue_ln.crosses(red_two)=}")
print(f"{blue_ln.contains(red_two)=}")
print(f"{blue_ln.touches(red_two)=}")
print(f"{blue_ln.within(red_two)=}")
输出:
blue_sq.overlaps(red_one)=False
blue_sq.intersects(red_one)=True
blue_sq.crosses(red_one)=False
blue_sq.contains(red_one)=False
blue_sq.touches(red_one)=True
blue_sq.within(red_one)=False
blue_ln.overlaps(red_two)=True
blue_ln.intersects(red_two)=True
blue_ln.crosses(red_two)=False
blue_ln.contains(red_two)=False
blue_ln.touches(red_two)=False
blue_ln.within(red_two)=False