如何通过经纬度找到最近的位置?

8
这是loc_coordinate表的结构:

enter image description here

以下是从数据库获取最近地点并显示存储在数据库中的地点名称的代码。
<?php
include("config.php");
$lat = "3.107685";
$lon = "101.7624521";

        $sql="SELECT ((ACOS(SIN($lat * PI() / 180) * SIN(lat * PI() / 180) + COS($lat * PI() / 180) * COS(lat * PI() / 180) * COS(($lon – lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS 'distance' FROM loc_coordinate HAVING 'distance'<='10' ORDER BY 'distance' ASC";
        $stmt =$pdo->prepare($sql);
        $stmt->execute();


        while($row = $stmt->fetch())
        {
          echo $row['place'];
        }

?>

这个错误信息如下所示:
致命错误: 在C:\wamp\www\mysite\by_coor.php的第8行
PDO异常:在C:\wamp\www\mysite\by_coor.php的第8行
通过echo $sql得到的输出内容如下:
SELECT ((ACOS(SIN(3.107685 * PI() / 180) * SIN(lat * PI() / 180) + COS(3.107685 * PI() / 180) * COS(lat * PI() / 180) * COS((101.7624521 - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS 'distance' FROM loc_coordinate HAVING 'distance'<='10' ORDER BY 'distance' ASC
我不确定为什么会出现这个错误。这是我参考的SQL查询网站:http://zcentric.com/2010/03/11/calculate-distance-in-mysql-with-latitude-and-longitude/

输出 $sql 并查看其中的错误。 - u_mulder
看起来你忘记在SIN(lat * PI() / 180)中加上$符号了,请检查你的变量。 - Yosra Nagati
2
SO - 你的查询中的 – 是什么意思? - u_mulder
这是一个假的减号 - 请用真正的减号替换它 - 我在我的数据库上尝试了这个查询,但因为它而失败了 - 替换成减号后就没问题了 - 大致上。查询已运行,但不知道是否会返回数据,因为我没有你的数据或表格。 - Professor Abronsius
@RamRaider,我在我的代码中更新了HTML,并加上了charset=utf-8",现在减号没有问题了。另外,我还更新了我上面帖子中的表格结构。 - 112233
显示剩余6条评论
3个回答

25

试试这个

     SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(( $lat - LatOnTable) *  pi()/180 / 2), 2) +COS( $lat * pi()/180) * COS(LatOnTable * pi()/180) * POWER(SIN(( $long - LongOnTable) * pi()/180 / 2), 2) ))) as distance  
from yourTable  
having  distance <= 10 
order by distance

在您的表格中将“LatOnTable”替换为纬度表格列名称,并将“longOnTable”替换为您的经度列名称。


尝试过了,没有显示错误,但也没有返回结果。我将10英里改为100英里,仍然没有结果。 - 112233
1
我的建议是先在你的数据库上尝试一下,然后再执行到 PHP 代码中。 - Yosra Nagati
1
当我在数据库中使用硬编码的纬度和经度值进行尝试时,它可以工作...现在我应该能够解决它了..谢谢。 - 112233
1
如果您想了解其背后的逻辑,请勾选此项。请查看以下链接:http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL - Yosra Nagati
2
在结尾添加“limit 1”将获取“最近”的位置,而不是最近位置的列表。 - Mirror318
显示剩余4条评论

5
这是一个 SQL 语句,用于查找距离给定坐标10英里以内的最近位置。它基于该行和目标纬度/经度的距离计算,并仅返回距离值小于等于10的行,按距离排序整个查询。如需使用公里而非英里进行搜索,请将3959替换为6371
SELECT
  id, (
    3959 * acos (
      cos ( radians($lat) )
      * cos( radians( tableLatColName ) )
      * cos( radians( tableLogColName ) - radians($long) )
      + sin ( radians($lat) )
      * sin( radians( tableLatColName ) )
    )
  ) AS distance
FROM table_name
HAVING distance <= 10
ORDER BY distance;

使用Google Maps API v3和MySQL后端-

https://developers.google.com/maps/solutions/store-locator/clothing-store-locator#findnearsql

我正在处理同样的问题,发现了这个问题,所以想分享一下.. :)


2
这对我有效:
SELECT restoran.id,restoran.restoran , (6371 * 2 * ASIN(SQRT( POWER(SIN(( -6.9831375276568055 - restoran.lat) *  pi()/180 / 2), 2) +COS( -6.9831375276568055 * pi()/180) * COS(restoran.lat * pi()/180) * POWER(SIN(( 110.40925562381744 - restoran.lng) * pi()/180 / 2), 2) ))) as distance  from restoran having  distance <= 10 order by distance

6371个数字是用来转换成千米的


更新正确的描述。 - KARTHIKEYAN.A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接