【问题标题】:Points in which polygon多边形中的点
【发布时间】:2025-12-06 03:05:02
【问题描述】:

我有几个(M 的顺序)点 [(x0,y0),...,(xn,yn)]。我的六边形数量也有限。我想找到每个点落在哪个六边形中。使用 shapely 可以一次完成 1 个点,因此下面的循环可以完成这项工作。但是有没有其他方法可以更快地做到这一点?

from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
zones = np.zeros(n)-1
for j,p in enumerate(points):
    point = Point(p)
    for i in range(len(poly_hex)): #poly_hex = list of hexagonal polygones
        polygon = Polygon(poly_hex[i])
        if polygon.contains(point):
            zones[j] = int(i)
            break

【问题讨论】:

  • 这件事会被多次(并且经常)完成吗?
  • 您可以使用multiprocessing 库并行运行多个进程,因为检查点是否在多边形内是一项独立的任务。
  • 它们是正六边形吗?它们的大小都一样吗?它们在六边形网格中吗?它们可以相交吗?
  • 是的。这是一个六边形网格。不,没有路口。

标签: python coordinates polygon point shapely


【解决方案1】:

加快速度的一些想法:

  • 不要在内循环的每一步将六边形转换为polygon = Polygon(poly_hex[i])。在循环之前计算一次并将它们存储在一个列表中。
  • 由于六边形的表面接近一个圆,所以也列出六边形的中心和半径。在循环内部,首先测试点p 与每个六边形的中心之间的距离,并与半径进行比较。仅当p 小于到中心的半径时,才进行显式测试以查看它是否在六边形内。
  • 如果这仍然不够快,并且取决于六边形相对于您的点有多小以及相距多远,您可以使用四叉树或网格进一步加快速度。但这不那么微不足道。如果大部分点在所有六边形之外,您可以先测试p 是否在六边形的凸包内。

一些备注:

  • 我不明白你的zone[j] = int(i)。您将 i 转换为整数,而它已经是整数。此外,您存储它的方式意味着一个点最多只能在一个六边形内。因此,您可以在遇到这样的六边形时立即停止循环。 (在极少数情况下,一个点正好位于两个六边形之间的边缘。这可能会将其分配给遇到的第一个六边形。或者,由于舍入误差,甚至可能位于两个六边形之外。)
  • 如果要将区域保存为整数,请将其创建为:zones = np.zeros(n, dtype=int)-1
  • 如果您的六边形形成一个规则的六边形网格,您可以简单地从 x 和 y 坐标找到确切的六边形,而无需进行多边形内测试。

【讨论】:

  • 感谢您的想法。对于评论,如果没有 int(i),它会将区域编号保存为 float (1.0, 2.0, ...),这不是我想要的。没错,六边形不会重叠,因此每个点在一个六边形中都处于最大值。当找到第一个六边形时,我实际上是在打破内部循环。
  • 区域仍然保存为浮点数,因为您有一个通用的 numpy 数组(类型为 np.float64)。尝试zones = np.zeros(n, dtype=int)-1 获取整数。