PHP MySql 和地理位置

Posted

技术标签:

【中文标题】PHP MySql 和地理位置【英文标题】:PHP MySql and geolocation 【发布时间】:2011-04-06 02:08:37 【问题描述】:

我正在编写一个网站,该网站主要使用 phpmysql 查找纬度和经度半径 25 英里范围内的地点。

我想知道这样的事情是如何工作的?

我会将经度和经度传递给脚本,并让它仅从我的位置数据库中提取距离经度和经度不超过 25 英里的位置。

最好的方法是什么?

编辑: 我找到了这段代码来计算两点之间的距离。

    function distance($lat1, $lon1, $lat2, $lon2, $unit)  

  $theta = $lon1 - $lon2; 
  $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 
  $dist = acos($dist); 
  $dist = rad2deg($dist); 
  $miles = $dist * 60 * 1.1515;
  $unit = strtoupper($unit);

  if ($unit == "K") 
    return ($miles * 1.609344); 
   else if ($unit == "N") 
      return ($miles * 0.8684);
     else 
        return $miles;
      

有没有办法在 MYSQL 查找中执行此计算,所以我只能在英里 =

【问题讨论】:

它从哪里拉出其他位置?您是否将每个预期位置的纬度/经度存储在数组或数据库中? 我编辑了这个问题。我将在我的数据库中有某些位置,并查看它们是否在 25 英里范围内。如果不是,则不返回任何内容。 更多信息:***.com/questions/20865747/geolocation-mysql-query 【参考方案1】:

使用该函数计算距离在计算上非常昂贵,因为它涉及一大堆超越函数。当您有大量行要过滤时,这将是一个问题。

这是一种替代方法,一种计算成本更低的近似值:

以英里为单位的大致距离:

sqrt(x * x + y * y)

where x = 69.1 * (lat2 - lat1) 
and y = 53.0 * (lon2 - lon1) 

您可以通过添加余弦数学函数来提高这种近似距离计算的准确性:

改进的近似距离(以英里为单位):

sqrt(x * x + y * y)

where x = 69.1 * (lat2 - lat1) 
and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3) 

来源:http://www.meridianworlddata.com/Distance-Calculation.asp


我用随机生成的数据集进行了一系列测试。

3 种算法的准确度差异很小,尤其是在短距离时 当然,最慢的算法是具有三角函数的算法(您的问题中的那个)。它比其他两个慢 4 倍。

绝对不值得。只用一个近似值。 代码在这里:http://pastebin.org/424186


要在 MySQL 上使用它,请创建一个 stored procedure,它接受坐标参数并返回距离,然后您可以执行以下操作:

SELECT columns 
  FROM table 
 WHERE DISTANCE(col_x, col_y, target_x, target_y) < 25

【讨论】:

【参考方案2】:

您可以分两步轻松完成:

在该点的每个方向上查找 25 英里内的所有位置。这看起来像:WHERE lat BETWEEN $lat1 AND $lat2 AND lng BETWEEN $lng1 AND $lng2

然后循环遍历每个结果并使用您的代码检查它是否真的在 25 英里范围内。 (即,过滤掉那些位于正方形角落的位置。)

对于第一部分,这是我放置的一些代码(不记得源代码):

$lat_range = $radius / ((6076 / 5280) * 60);
$lng_range = $radius / (((cos(($city['lat'] * 3.141592653589 / 180)) * 6076) / 5280) * 60);

基本上只使用($lat - $lat_range, $lat + $lat_range)($lng - $lng_range, $lng + $lng_range) 半径以英里为单位。

显然你可以稍微清理一下数学。

编辑:我忘了提到,如果您需要支持赤道附近的位置、国际日期变更线等,您需要对其进行一些调整。显然,对于北美来说,按原样就可以了。

【讨论】:

这当然有需要两个过滤步骤的缺点,因为它返回了不必要的行。 是的,但它避免了对整个数据库执行计算。对于小半径和大数据集,这很重要。【参考方案3】:

您可能想看看this solution - 一个非常棒的解决方法。

【讨论】:

以上是关于PHP MySql 和地理位置的主要内容,如果未能解决你的问题,请参考以下文章

将 HTML5 地理定位与 PHP 和 MySql 结合使用

php PDO 和 mysql:如何插入地理点类型?

如何将 php 数组从 mysql 返回到谷歌地理位置

Android GPS使用php在Mysql中保存当前位置

在 PhP、Wordpress 和 MySQL 中,查找最近的位置的功能不适用于自定义表

如何根据用户位置查询 mySQL [关闭]