使用mysql在地图上搜索点时处理集群

时间:2013-06-10 06:44:23

标签: mysql geolocation cluster-analysis spatial points

我已经找到了各种类似于这个问题的解决方案的问题,但到目前为止还没有任何关于钱的问题。非常感谢任何帮助。

我有一个mysql(v.5.6.10)数据库,其中包含一个名为POSTS的表,可以在地图上存储数百万行纬度/经度。每个点被分类为几种不同类型中的一种。每行的结构为id, type, coords

  • id unsigned bigint +主键。对于插入的每个新行,这会自动递增。
  • type unsigned tinyint用于编码兴趣点的类型。
  • coords一个mysql地理空间POINT数据类型,表示兴趣点的纬度/经度。

'coords'上有一个SPATIAL索引。

我需要找到一种有效的方法来查询表格并返回特定纬度/经度位置半径(“ R ”)内最近插入的点的X(“的位置“)。数据库非常动态,因此请假设每次查询表时数据都完全不同。

如果X是无限的,问题就是微不足道的。我只需要执行类似的查询:

SELECT id, type, AsText(coords) FROM POSTS WHERE MBRContains(GeomFromText(BoundingBox, Position))

其中'BoundingBox'是一个mysql POLYGON数据类型,它完美地包围了位置半径为R的圆。当然,使用边界框并不是一个完美的解决方案,但这对我正在尝试解决的特定问题并不重要。我可以使用“ORDER BY ID DESC”来排序结果,以便首先检索和处理最近插入的点。

如果X小于无穷大,那么我只需将上述内容修改为:

SELECT id, type, AsText(coords) FROM POSTS WHERE MBRContains(GeomFromText(BoundingBox, Position)) ORDER BY id DESC LIMIT X

我想解决的问题是,当该区域中的点被大量聚集时(例如,在地图搜索区域内的城市内),如何从地图上的给定区域获得一组良好的代表性结果集? 。例如:

enter image description here

在上面的示例中,我站在X并在黑框边界框中搜索最近插入的5个黑色点。如果这些点全部插入到右下角的聚类中(假设聚类是伦敦),那么我的结果集将不包括搜索区域右上角附近的黑点。这对我的应用程序来说是一个问题,因为我不希望给用户的印象是在点聚集的任何区域之外没有兴趣点。

我考虑了一些潜在的解决方案,但是当行数很大(数百万)时,我找不到一个有效的解决方案。到目前为止我尝试过的方法包括:

  1. 将搜索区域划分为S个正方形(即,将其转换为网格)并在每个正方形内搜索最多x / S点 - 即,对网格中的每个正方形执行单独的mysql查询。这适用于少量行,但当行数很大时变得效率低,因为您需要将区域划分为大量方块以使方法有效工作。如果只有少量方块,则无法保证每个方块不包含人口密集的群集。大量的正方形意味着大量的mysql搜索会导致事情发生。

  2. 向表中的每一行添加一列,用于存储每个点到最近邻居的距离。当将点插入表中时,计算给定点的最近邻距离。通过这种结构,我可以按最近邻距离列对搜索结果进行排序,以便最后返回簇中的任何点。此解决方案仅在我搜索搜索区域内的所有点时有效。例如,请考虑上图所示的情况。如果我想找到5个最近插入的绿色类型的点,则为每个点记录的最近邻居距离将不正确。即使使用像KD树这样的高效算法,重新计算每个查询的这些距离也会非常昂贵。

  3. 事实上,我看不到任何需要在表行中预处理数据的方法(或者换句话说,'触摸'相关搜索区域数据集中的每个点)在行数时是可行的变大了。我考虑过k-means / DBSCAN等算法,但鉴于上面解释的用例,我找不到任何能够充分发挥效率的算法。

    任何珍珠?我的直觉告诉我这可以解决但到目前为止我很难过。

1 个答案:

答案 0 :(得分:1)

在这种情况下的后处理似乎更有效。获取给定类型的最后X个点。查找是否存在某些聚类,例如:相对于您的视点距离,太多的点太靠近在一起。删除最旧的(或非常接近的 - 可能是您的数据引用相同的POI)。多少 - 取决于你。获取下一个X点并查看其中是否有一些不在群集中,或者您可以根据远程性和近期性计算每个点的值,并根据该值计算丢弃点。

相关问题