【问题标题】:How would I sort a set of lat/lons by distance from a single lat/lon?我如何按与单个纬度/经度的距离对一组经度/经度进行排序?
【发布时间】:2013-06-28 16:28:56
【问题描述】:

用户注册我的网站并输入他们的邮政编码。我想查询其他用户,并按距离排序。

我有一个充满邮政编码的数据库,每个邮政编码都有纬度/经度点。

zip_code (char)
lat (float)
lon (float)

我有一种方法可以计算两组纬度/经度之间的距离,但是在我的数据库中的每个其他邮政编码上运行它是昂贵的。我需要在每个邮政编码组合上运行它。我想我可以做一次并将其存储在某个地方,但是我将它存储在哪里呢?每个邮政编码都有一个表格,其中包含到每个其他邮政编码的距离,这似乎很奇怪。有没有一种干净的方法可以做到这一点?

【问题讨论】:

  • 你需要一个图(存储在缓存中):networkx.github.io。只需使用距离初始化边的权重,并使用 zip_code ID 初始化节点。这样你就有 O(1) (节点查找)+ O(|E|) (节点的度数线性)
  • 我认为你的问题的标题具有误导性,因为这不是你想知道的。
  • 您的用户在美国吗?然后根据 lon 对 lat/lon 进行排序。这样您就不需要测试 lon 距离 2 度或更多度的点。

标签: python geocoding geospatial geo


【解决方案1】:

做一次并将其存储在某个地方对我来说听起来不错。以下是一些在不牺牲准确性的情况下考虑存储空间的想法可能会提供良好的性能:

大约有 43,191 个邮政编码,因此完整的邮政编码为 1,865,462,481。但是距离当然是对称的,self-to-self 是无用的,它立即减少到 932,709,645 个条目。我们还可以通过意识到一堆邮政编码或者彼此相同,或者一个包含另一个(例如 10178 似乎在 10016 内,并且它们在地理上都很小)来减少空间。许多邮政编码根本没有用户,因此我们可能会避免在需要它们之前填充它们(即延迟加载缓存)。最后,您可能会丢弃大距离结果,其中大被定义为大于对您的用户有用的距离。

有关更算法的观点,请参阅上一个问题:Calculate distance between zip codes and users

额外提示:不要忘记非美国用户。可怜的非美国用户。

【讨论】:

    【解决方案2】:

    这是一个开销相当大的解决方案,但随着您的数据集大小、用户群和/或交易数量的增长,这将得到回报:

    如果您还没有,请使用支持空间类型和空间索引的数据库。我推荐 PostGres 的 PostGIS 扩展,但这些步骤中的大部分都适用于其他支持空间的数据库:

    1. 将您的邮政编码位置存储为点几何类型,而不是两列用于纬度和经度。
    2. 针对点几何列创建空间索引。每次添加新邮政编码时,其位置都会自动添加到空间索引中。
    3. 假设您不想显示数千英里外的“最近”邻居,请使用 Within 函数(PostGIS 中的ST_DWithin)过滤掉那些太远的邮政编码。这将显着减少近邻的搜索空间。
    4. 最后使用距离函数(PostGIS 中的ST_Distance)计算您感兴趣的邮政编码与其更近的邻居之间的距离,并使用数据库返回按距离排序的结果。

    通过使用具有空间索引的数据库和使用该索引的过滤功能,您可以显着加快搜索速度。当需要进行更多空间分析或显示地图时,您将已经有了一个框架来支持该新功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-23
      • 2014-01-22
      • 1970-01-01
      • 2011-08-16
      • 2016-08-29
      • 2015-01-06
      • 2011-10-01
      • 1970-01-01
      相关资源
      最近更新 更多