有谁知道在距点的给定距离内获取 MySQL 数据库中所有多边形的方法?实际距离并不那么重要,因为它是稍后为每个找到的多边形计算的,但是仅对“接近”的多边形进行该计算将是一个巨大的优化。
我查看了 MBR 并包含函数,但问题是一些多边形不包含在围绕该点绘制的边界框中,因为它们非常大,但它们的一些顶点仍然很接近。
有什么建议么?
慢版本(没有空间索引):
SELECT *
FROM mytable
WHERE MBRIntersects(mypolygon, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))
要使用空间索引,您需要对表进行非规范化,以便每个多边形顶点都存储在自己的记录中。
然后SPATIAL INDEX
在包含顶点坐标的字段上创建并发出以下查询:
SELECT DISTINCT polygon_id
FROM vertices
WHERE MBRContains(vertex, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))
UTM
如果您在数据库中存储坐标而不是纬度和经度,事情会容易得多。
我不认为有一个单一的答案。这通常是一个如何组织数据的问题,以便它利用问题固有的空间局部性。
我脑海中浮现的第一个想法是使用网格,将每个点分配给一个正方形,然后检查选择该点所在的正方形及其周围的正方形。如果我们说的是无限网格,那么使用正方形的哈希值,这会给你比需要的更多的点(你有碰撞的地方),但仍然会减少一堆。当然,这并不立即适用于多边形,这只是一次头脑风暴。一种可能产生太多冲突的可能方法是将所有散列值 OR 在一起,并选择所有与该值进行 AND 的散列非零的条目(不确定这在 MySQL 中是否可行),您可能想要使用大虽然位数。
这种方法的问题是,假设我们正在谈论的球坐标(纬度,经度通常是)是奇点,因为随着您接近两极,网格“正方形”会变窄。解决这个问题的简单方法是......不要将任何点放在两极附近...... :)
为所有多边形创建一个边界框(可选地将这些结果存储在数据库中,这对于复杂的多边形来说会更快)。然后,您可以将每个多边形的边界框与所需大小的圆点进行比较。选择所有具有相交边界框的多边形。