【问题标题】:Checking whether point is within polygon returns wrong results in Shapely检查点是否在多边形内会在 Shapely 中返回错误结果
【发布时间】:2019-11-25 10:47:09
【问题描述】:

我有一个多边形作为 wkt 格式的字符串:

polygon_as_string = 'POLYGON ((1190500.159499999 7144386.067199998, 1190487.2751 7144390.519699998,...,1190500.159499999 7144386.067199998))'

我将其转换为 Shapely 的 Polygon 对象:

import shapely.wkt
polygon = shapely.wkt.loads(polygon_as_string)

然后我使用within()contains() 函数检查该点是否在我的多边形中。

from shapely.geometry import Point, Polygon
point = Point(1190500.159499999, 7144386.067199998)
polygon.contains(point)
point.within(polygon)

这两个函数都返回False,尽管我认为这实际上是在polygon 内部。 这里有什么问题?

【问题讨论】:

    标签: python polygon point shapely


    【解决方案1】:

    您使用了错误的predicate 来检查一个点是否在多边形的内或边界上

    来自documentation on contains(与within相反):

    object.contains(other)
    如果没有其他点,则返回 True 位于对象的外部并且至少有一点 interior other 位于 interior object

    相反,由于您的点位于边界上,您应该使用intersects

    object.intersects(other)
    如果对象的边界或内部以任何方式与其他对象的边界或内部相交,则返回 True

    换句话说,如果几何对象有任何边界,它们就会相交 或内部共同点

    (强调我的)。


    可重现的小例子:

    >>> from shapely.geometry import Point, Polygon
    >>> Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]).contains(Point(1, 1))
    False
    >>> Point(1, 1).within(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]))
    False
    >>> Point(1, 1).intersects(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]))
    True
    

    但是请注意,由于精度错误,您确实可能会得到意想不到的结果:

    >>> Point(2/3, 2).intersects(Polygon([(0, 0), (1, 0), (1, 3)]))
    False
    >>> Point(2/3, 2).distance(Polygon([(0, 0), (1, 0), (1, 3)]))
    >>> 0.0
    

    在这种情况下,您可以考虑检查到多边形的距离,如上所示,或者使用buffer 稍微扩大多边形:

    >>> Point(2/3, 2).intersects(Polygon([(0, 0), (1, 0), (1, 3)]).buffer(1e-9))
    True
    

    【讨论】:

    • 说的很清楚很有帮助,我完全理解了,万分感谢!
    【解决方案2】:

    原因可能是您正在测试的点恰好位于其中一个顶点的顶部,并且由于舍入误差,该点实际上移动了一点并且不再位于多边形的边缘。

    要检查这个假设,请尝试将测试点稍微移向多边形的中心。

    【讨论】:

    • 非常感谢!我取了这个多边形的质心,它起作用了)
    猜你喜欢
    • 2014-04-26
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 2020-05-30
    相关资源
    最近更新 更多