【问题标题】:select places with nearly same location (duplicates) by latitude/longitude按纬度/经度选择位置几乎相同(重复)的地方
【发布时间】:2011-09-13 17:43:55
【问题描述】:

假设我有一个表venues,其中包含以下列:

id
user_id
name
latitude
longitude

纬度和经度保存为 FLOAT(10,6) 值。随着不同用户添加场地,场地重复。如何从表中选择范围内的所有重复项,最多可以说 50 米(因为在不同纬度,经度米当量不同,因此这绝对是近似值,因此可能很难实现)?查询应该选择所有场所:VenueA 和 VenueB(可能有 VenueC、VenueD 等),以便我可以比较它们。它应该过滤掉范围内每个位置实际上只有一个的场所(我只关心重复)。

【问题讨论】:

  • 你能澄清你的问题吗?在添加新场所时检测重复比在添加新场所时检测重复要有效得多,因为唯一实用的方法是检查每个场所与所有其他未检查场所。添加场地时不检查场地的原因是什么?在这种情况下,之前建议的方法是有效的,尽管通过使用半正弦公式可以获得最佳结果,该公式可以合并到一个查询中,该查询也对纬度范围进行简单检查。后者可以使用索引,而 hasrsine 不能轻易这样做。

标签: mysql sql gps latitude-longitude


【解决方案1】:

我一直在寻找答案,但不得不自己回答。

SELECT s1.id, s1.name, s2.id, s2.name FROM venues s1, venues s2
WHERE s2.id > s1.id AND 
(POW(s1.latitude - s2.latitude, 2) + POW(s1.longitude - s2.longitude, 2) < 0.001)

第一个条件是只选择矩阵的一半,因为相似场所的顺序并不重要。第二个是简化的距离计算器。正如 user185631 建议的那样,如果您需要更高的精度,则使用 haversine 公式应该可以解决问题,但我不需要它,因为我正在寻找具有相同坐标但无法解决 s1.latitude = s2.latitude AND s1.longitude = s2 的重复项.longitude 由于我的数据库中的浮点/十进制损坏。

当然,在插入时检查这个会更好,但如果你得到损坏的数据库,你需要以某种方式清理它。另请注意,如果您的表很大,则此查询在服务器上会很繁重。

【讨论】:

    【解决方案2】:

    创建一个计算纬度/经度之间距离的函数。对于较小/不太准确的距离(这里就是这种情况),您可以使用 Equirectangular 近似(请参阅此处的部分:http://www.movable-type.co.uk/scripts/latlong.html)。如果距离小于您选择的阈值 (50m),则它是重复的。

    【讨论】:

      【解决方案3】:

      根据经度和经度确定 50 米。然后加上和减去你的起始位置,得出纬度和经度的最大值和最小值。那么……

      SELECT id FROM venues WHERE latitude < (your max latitude) AND latitude > (your min latitude) AND longitude < (your max longitude) AND longitude > (your min longitude);
      

      将米转换为纬度/经度非常棘手,因为它取决于起点在地球上的位置。在此处查看页面的中间部分:http://www.uwgb.edu/dutchs/usefuldata/utmformulas.htm

      【讨论】:

      • 我可以确定 50 米的纬度和经度,但这将如何从表中选择我的副本?我想要一个提供所有重复项的查询,而不是检查某个 lat/lng 是否存在重复项的查询(这很简单,但与我的问题无关)
      • 啊,抱歉,我以为你有一个目标位置,想要的位置基本上是它的副本。
      • @Veseliq:简单,朋友。 “请”比投反对票和施瓦辛格式的评论更进一步。 :)
      • @Veseliq:一切都很好,伙计。只要意识到我们不是在为支持投票而工作,所以一点礼貌会有很长的路要走。另一方面,我认为答案的一部分有 is 值,它讲述了从米到纬度/经度的转换,因为它不仅仅是一个公式。它实际上非常复杂。请参阅链接。祝你好运!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多