【问题标题】:PHP Sorting nearest coordinatesPHP排序最近的坐标
【发布时间】:2012-06-02 00:12:42
【问题描述】:

我在 PHP 网络服务中有一个 MySQL 表,其中包含经度和纬度。 我只想向用户发送 5 个最近的坐标。 我编写了计算从坐标到用户在 POST 请求中发送的坐标的距离的方法,但我不确定如何对其进行排序,只发回一些。

这里是距离法:

function  distance($longToCompare,$latToCompare) {
    $dlong = $request_long - $longToCompare;
    $dlat = $request_lat - $latToCompare;
    $a = pow(sin($dlat/2)) + cos($latToCompare)*cos($request_lat)*pow(sin($dlong/2));
    $c = 2*atan2(sqrt($a),sqrt(1-$a));
    return 6373*$c; 
}

并且用户当前获得了整个数据库(目前,虽然开发它很小,但将来它可能会相当大)

$q = mysql_query("SELECT * FROM Coordinates");
$coordinates = array ();
while ($e = mysql_fetch_assoc($q)) {
    $coordinates[] = $e;
}
print (json_encode($coordinates));

谁能指出我正确的方向?我对 PHP 比较陌生,我知道我可以使用 uasort 创建自定义排序,但我不太确定如何使用这个距离函数来使用它。

编辑: 使用@Norse 的解决方案,当前查询是:

$request_long = $_POST['longitude'];
$request_lat = $_POST['latitude'];
    $km = 0.5;
        $query = "SELECT *, 
    ( 6373 * acos( cos( radians('$request_lat') ) * 
    cos( radians( latitude ) ) * 
    cos( radians( longitude ) - 
    radians('$request_long') ) + 
    sin( radians('$request_lat') ) * 
    sin( radians( latitude ) ) ) ) 
    AS distance FROM Coordinates HAVING distance < '$km' ORDER BY distance ASC LIMIT 0, 5";
        $coordinates = array ();
        while ($e = mysql_fetch_assoc($query)) {
            $coordinates[] = $e;
        }
        print (json_encode($coordinates));

【问题讨论】:

  • 你有没有考虑写mysql函数并在sql查询中使用?
  • 我对这整个数据库很陌生。你能详细说明一下吗?
  • 是 Junaio AR 平台的吗?
  • 不知道它是什么,所以我猜不是。它最终适用于 iPhone 和 Android 应用
  • @WojtekT 的意思是您使用 PHP 编写函数,但您可以使用 MySQL 的编程语言将其编写为 MySQL 存储函数。这样您就可以直接在查询中使用它,如下所示:SELECT * FROM table ORDER BY shortest_distance_to(X1, Y1, X2, Y2) ASC,这比从数据库中检索所有坐标到 PHP 快得多解释器并在那里比较它们,特别是如果您的数据集非常大。

标签: php mysql sorting


【解决方案1】:

使用谷歌的算法:

$lon = //your longitude
$lat = //your latitude
$miles = //your search radius

$query = "SELECT *, 
( 3959 * acos( cos( radians('$lat') ) * 
cos( radians( latitude ) ) * 
cos( radians( longitude ) - 
radians('$lon') ) + 
sin( radians('$lat') ) * 
sin( radians( latitude ) ) ) ) 
AS distance FROM yourtable HAVING distance < '$miles' ORDER BY distance ASC LIMIT 0, 5"

此查询中的latitudelongitude 将是您的纬度/经度列名。

【讨论】:

  • 谢谢,我收到一个错误:mysql_fetch_assoc(): 提供的参数不是有效的 MySQL 结果 $lon 和 $lat 是从设备的 GPS 接收的,例如 35.21371 的形式跨度>
  • 嗯。我看不出错误来自哪里。我只是再次运行此查询以确保它对我来说很好。
  • 编辑了问题以包含当前代码。你能检查一下有没有问题?
  • 问题是你没有执行查询。 $runquery = mysql_query($query);
  • 添加 var_dump 后,我注意到它说的是字符串。因此,当我得到 $_POST 时,我现在将其转换为 double (double) $_POST['longitude'] 并且它可以工作。不知道为什么它将它们作为字符串发送,但它可以工作
【解决方案2】:

我最近遇到了同样的问题。我决定写一个mysql函数来计算距离,然后在sql查询中使用它。 mysql函数:

CREATE FUNCTION distance(lat1 float, lon1 float, lat2 float, lon2 float) 
RETURNS float
RETURN ACOS(SIN(RADIANS(lat1))*SIN(RADIANS(lat2))+COS(RADIANS(lat1))*COS(RADIANS(lat2))*COS(RADIANS(lon2-lon1)))*6371

如果您的 Coordinates 表有列 f.e. latitudelongitude 那么代码可能如下所示:

$q = mysql_query("SELECT * FROM Coordinates ORDER BY 
     distance(latitude, longitude, $lat, $lon) LIMIT 5";

其中$lat$lon 包含提供的位置。

【讨论】:

  • CREATE FUNCTION 去哪儿了?在 PHP 脚本中,还是在 MySQL 管理中使用查询?
  • 您必须使用任何用于管理 mysql 数据库的工具执行一次。
  • 谢谢,当使用 SQLBuddy 中的方法时,我收到一个错误,即访问被拒绝..
  • 这可能是因为您的数据库权限不允许您创建函数。在这种情况下,请查看@Norse 提供的答案。
【解决方案3】:

在查询中嵌入排序更有效。

这个精彩的教程将为您提供帮助(并提供满足您需求的查询): https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql

【讨论】:

  • 现在看来。可以重试吗?
猜你喜欢
  • 1970-01-01
  • 2015-10-06
  • 2022-11-17
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2016-01-31
  • 2018-11-22
  • 1970-01-01
相关资源
最近更新 更多