SQL abs计算 - 使用纬度和经度 - MATH!

时间:2010-07-04 18:29:36

标签: php sql math

我有一个sql查询,它根据一定范围内的坐标从数据库中提取位置。现在我试图通过接近一些数学来对它们进行排序 - 但无论我在纸上写出多少次,我似乎无法找到一个有效的解决方案。

让我们描述一些变量:

  • $ plat(地方的纬度)
  • $ plong(这个地方的经度)
  • $ slat(搜索位置的纬度)
  • $ slong(搜索位置的经度)

需要注意的一件大事是,我已经将所有坐标转换为正数,并且有另一个确定正面或负面的场地 - 但是为此我假设我已经正确地查询了附近的坐标。

为了以这种方式订购,我看到人们使用“ORDER BY abs(coord-coords)”来做一些简单的事情 - 但我需要的更像是:

[($ slat - $ plat)*($ slong - plong)] - 但是这会导致问题,因为如果一方产生的计算结果为零 - 那么在乘以之后结果也将为零 - 使其无效。

任何想法 -

2 个答案:

答案 0 :(得分:1)

纬度/经度坐标之间距离的解决方案称为haversine formula。这很复杂,因为除非你的距离非常短,否则你需要考虑地球的曲率。

这是一篇关于使用PHP和MySQL实现定位器应用程序的文章:Creating a Store Locator with PHP, MySQL & Google Maps

您还可以在Stack Overflow上找到有关计算坐标之间距离的许多其他问题:https://stackoverflow.com/search?q=longitude+distance

如果你只需要计算5公里内的距离,那么地球的曲率可能并不显着。您可以使用普通distance formula。如果您只需要使用此值来排序哪一个更接近,您甚至可以跳过平方根计算。

SELECT s.location_id,
  (s.lat-p.lat)*(s.lat-p.lat) + (s.long-p.long)*(s.long-p.long) AS distance_squared
FROM Locations s, Locations p
WHERE p.location_id = ?
ORDER BY distance_squared;
  

我选择的表格('locations')有纬度/经度坐标(让我们称之为$ plat和$ plong)。

不,那些是PHP变量。您需要计算数据库表每行的纬度/经度坐标的距离。

问题是SQL通常一次只能从一个行计算内容。因此,您需要将两行组合成一行,因此计算可以使用两个位置的坐标。您可以使用自联接执行此操作。这基本上是将每一行与同一个表中的另一行配对。这就是为什么我列出Locations两次,并给它们两个不同的别名,sp(技术术语是相关名称)。

如果您习惯使用PHP,请将此自连接视为与嵌套循环类似:

foreach ($locations as &$s) {
    foreach ($locations as &$p) {
        // calculate the distance between $s and $p
    }
}

WHERE子句将p的行限制在您开始的位置(您将单个值替换为?占位符),因此它只是查询与所有对齐的一行表的行。

另一个提示:我跳过使用SQRT(),因为没有必要按距离排序。也就是说,如果三个位置距离我10公里,15公里和20公里,那么我可以按100,225和400进行排序并获得相同的排序,就像我按10,15和20排序一样。优点是我'已经消除了计算平方根,这有点降低了我的查询成本。

答案 1 :(得分:0)

如果您想要精确测量它,可以使用haversine公式来计算纬度/经度对之间的距离。如果你只是用它来进行排序,那么你可以回到毕达哥拉斯公式来计算近似值,或者使用距离的平方(以消除平方根)。