【问题标题】:Implementing "Search nearby users" function on server在服务器上实现“搜索附近用户”功能
【发布时间】:2014-11-26 18:49:27
【问题描述】:

假设我有一个数据库,存储了一个城市中不同用户的 1000000 个地理位置。如果我使用列表或数组来保存所有地理位置并一一比较距离,那么服务器执行命令SearchNearbyUsers(myLocation, 50) 会很痛苦。

服务器使用 C# 和 Web API 2 编码。是否有任何库设计用于使用地理位置进行此类计算?

如果没有可用的库,应该使用什么数据结构来简化计算?之前看过R-tree,但是说实话,逻辑我也不是很明白,而且好像挺复杂的。

这是地理定位类的样子:

public class GeoLocation
{
    public float latitude { get; set; }
    public float longitude { get; set; }
}

纬度和经度都是客户端发送的。值通过navigator.geolocation.getCurrentPosition()获取。

【问题讨论】:

  • 如果您使用的是 MongoDB 或 MySQL 等数据库系统,它可以为您完成工作,您只需先进行设置。对于 MySQL,请仔细阅读本章:dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html。否则(我希望你有充分的理由不这样做),R-trees 要走的路,你必须研究它们!

标签: c# algorithm data-structures geolocation


【解决方案1】:

通常这些空间操作是使用空间索引完成的。 R-Tress 只是其中一个复杂的例子,但您也可能会得到更简单的例子。只需将您的整个区域划分为更小的部分(例如矩形)并在适合与给定坐标共享索引的区域内搜索。所以我建议在你的服务器上启用空间索引,然后使用GDAL之类的空间库。

因此,如果您有一个坐标 (4,5),则首先查看与您的点周围的 witdh x 缓冲区相交的所有矩形。现在您只需在位于这些矩形内的所有几何图形中进行搜索。

编辑: 在 SQL Server 上,您还可以使用其空间扩展来检索那些附近的要素(请参阅here)。基本上使用STBuffer 在您的输入几何周围创建一个缓冲区,然后对该缓冲区执行相交。使用所描述的空间索引,这些操作非常快。

【讨论】:

  • 如果两个用户实际上彼此非常接近但位于不同的空间块中怎么办?
  • @AldourCheng,R-trees 旨在避免此类问题......查询机制将保证您将找到给定空间区域中的每个对象(存储在树中)。它们通常是数据库系统中空间索引的核心:)
  • 这就是为什么我写了看看与缓冲区相交的矩形。因此,一个点最多可以得到四个矩形(这仍然比搜索整个区域要少得多)。
【解决方案2】:

如果您是初学者并且想避免使用树木...

  1. 创建支持区域的网格图

    • 只是一个简单的 2D 单元格网格
    • 每个单元格都有其坐标i,j 或索引ix=i+j*ni,其中ni 是每个i 轴的单元格数
    • 因此,您可以简单地计算每个点的单元所有权
    • 列出每个单元格的点
    • 类似:
    • Vector<int> map[nj][ni];
    • 并用单元格内的点索引填充列表...
  2. 比较

    • 计算用户单元位置
    • 并仅比较该单元格和 8 个相邻单元格中的点...
    • 单元格网格越密集,您的速度就越快
    • 如果您的单元格小于比较范围,则还比较更多邻居
    • 安全覆盖整个范围

【讨论】:

  • 如果所有的地理位置数据最初都存储在数据库中,而不是存储在代码中定义的字典中怎么办?
  • @AldourCheng 您可以简单地编写一个遍历所有点的 for 循环,并在实现添加/删除点例程之前用点索引填充地图...
  • @AldourCheng 唯一的显着缺点是删除点需要更新所有点索引,然后将其减一...在所有单元格中。但这可以通过在点列表中添加 _deleted 标志来避免...
【解决方案3】:

好吧,如果您将数据存储在 SQL Server 中,您将使用空间索引http://msdn.microsoft.com/en-us/library/bb934196.aspx

【讨论】:

    【解决方案4】:

    如果您使用像 Mongo 这样的数据存储,地理空间查询非常简单且非常好。这里是Docs

    您可以尝试研究类似的内容。这是我在最近的一个项目中让客户下载位置相关数据的工具,它实现了梦想。

    编辑要使用经纬度在现实世界中查找位置,要在查询距离时获得正确的结果,您必须使用球形索引

    This Question 将帮助您使用 mongo c# 驱动程序进行近距离查询。

    编辑 2 在了解您使用 MS SQL 之后,这里有一些有用的链接可以与另一个答案中提供的 Phillip 一起使用。

    Query Spatial Data For Nearest Neighbour
    Spatial Data

    【讨论】:

    • 是否适用于 MS SQL 服务器?
    • 遗憾的是,MongoDB 本身就是一个数据库。您是否与 MS SQL 紧密相关?您在使用 MS SQL 处理地理空间查询时给自己造成了障碍。 Mongo 甚至不是唯一的选择。有很多数据库比 MS SQL 更好地支持地理空间查询
    • 感谢您的信息。似乎 MS SQL 现在正在为处理空间数据添加更多功能。我指的是PhillipH发布的链接。
    • 那里有更多信息。我会用更多链接更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多