使用 php mysql 按半径搜索经纬度数据库

Posted

技术标签:

【中文标题】使用 php mysql 按半径搜索经纬度数据库【英文标题】:Search database with lat and long by radius using php mysql 【发布时间】:2012-05-24 04:21:07 【问题描述】:

我正在尝试开发一个小型站点,该站点通过设置的半径从数据库中检索结果并将它们放置在地图上。 我使用 Google maps api 从那里获取经纬度搜索条件,将它们传递给我的 php 脚本,该脚本查询数据库并将结果集作为 JSON 对象返回。

我在使用 json 将 lat 和 long 发送到 php 时遇到了一个小问题。

我的主要问题是我搜索数据库的 sql 似乎是错误的,因为它只检索了我数据库中的前 10 个结果。我希望它返回搜索点半径内的前 10 个结果。

这是我的 ajax 代码

function showCarPark(location)

    var lat = location.lat();
    var lng = location.lng();
    //alert("Lat: " +lat.toFixed(6));
    //alert("Lng: " +lng.toFixed(6));
    document.getElementById('carParkResults').innerhtml = "";
    var criterion = document.getElementById("address").value;
    var count = 0;
    $.ajax(    
              url: 'process.php',
              type: 'GET',
              data: "lat=" + lat + "&lng=" + lng,
              dataType: 'json',
              success: function(data) 
              
                  jQuery.each(data, function()
                  
                    $('<p>').text("Car Park: " + data[count].name).appendTo('#carParkResults');
                    placeCarParks(data[count].postcode,data[count].name, data[count].street, data[count].type);
                    count++;
                  );
              ,
              error: function(e) 
              
                //called when there is an error
                console.log(e.message);
                alert("error" + e.message);
              
    );

这是我的 php 脚本

$rad = 20;
$lat = $_GET['lat'];
$lng = 1.4681464; //put a temporary number in as it wont pass the lng in the JSON

$sql="SELECT *, (3959 * acos(cos(radians('".$lat."')) * cos(radians(lat)) * cos( radians(long) - radians('".$lng."')) + sin(radians('".$lat."')) * 
sin(radians(lat)))) 
AS distance 
FROM carpark HAVING distance < 15 ORDER BY distance LIMIT 0 , 10";

$result = mysql_query($sql);

while($r = mysql_fetch_assoc($result)) $rows[] = $r;

echo json_encode($rows);

我表中的列称为 lat 和 long 任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

对于您的情况,请尝试使用 WHERE 而不是 HAVING

SELECT *, (3959 * acos(cos(radians('".$lat."')) * cos(radians(lat)) * cos( radians(long) - radians('".$lng."')) + sin(radians('".$lat."')) * 
sin(radians(lat)))) 
AS distance 
FROM carpark WHERE distance < 15 ORDER BY distance LIMIT 0 , 10

【讨论】:

它不适用于 WHERE,因为您使用的是计数变量。所以你需要使用 HAVING,而不是它的工作。玩得开心;) 对于那些想知道3959 代表什么的人,它是以英里为单位的地球半径。 6378 以公里为单位。【参考方案2】:

我在使用 HAVING 时没有遇到任何问题。 iLLin 的回答具有误导性。下面是一个正确查询到纽约市距离的示例:

SELECT *, (3959 * acos(cos(radians('40.7142')) * cos(radians(latitudeColName)) * cos( radians(longitudeColName) - radians('-74.0064')) + sin(radians('40.7142')) * sin(radians(latitudeColName)))) AS distance FROM myTable HAVING distance < 15 ORDER BY distance LIMIT 0 , 10

更改 jQuery 请求中的行以使用此表示法 name : value, name : value:

          data: lat : lat, long : long,

【讨论】:

【参考方案3】:

Larry Ullman 在他的《PHP 5 Advanced: Visual Quickpro Guide》一书中做了非常相似的事情。

看他的示例代码,试试这个来计算距离:

ROUND(DEGREES(ACOS(SIN(RADIANS($lat)) 
* SIN(RADIANS(latitude)) 
+ COS(RADIANS($lat))  
* COS(RADIANS(latitude))
* COS(RADIANS($long - longitude)))) * 69.09) AS distance

【讨论】:

【参考方案4】:
"SELECT *, ( 3959 * acos( cos( radians(".$lat.") ) * cos( radians( ".$lat." ) ) * cos( radians( ".$long." ) - radians(".$long.") ) + sin( radians(".$lat.") ) * sin( radians( ".$lat." ) ) ) ) AS distance FROM carpark HAVING distance < 15 ORDER BY distance LIMIT 0, 10"

您需要修复查询以获取纬度和经度值。你只是在几个地方传递了 lat/long 这个词。将此查询与您的进行比较,以了解我的意思。

【讨论】:

这很容易受到 SQL 注入的攻击。 仅当变量没有被引用时。谁说他们没有更进一步?无论如何,这不是问题所在。 指出来还是不错的。如果说没有人在 Google 搜索后在 Stack Overflow 上找到答案,然后复制并粘贴答案,那就太天真了。 我不是在和你争论这个问题,但也许你应该强调原始作者的问题,因为这显然是 SQL 注入。为什么你选择这个评论我不知道,它甚至不是公认的答案。因此,如果您的意图是强调这一点,我认为您选择了错误的答案:P

以上是关于使用 php mysql 按半径搜索经纬度数据库的主要内容,如果未能解决你的问题,请参考以下文章

PHP 半径搜索

使用经纬度IOS搜索附近的人

Radius 搜索 PHP、MYSQL 和谷歌地图

在 PHP 中计算纬度/经度 GPS 点周围的半径

计算半径内的 100 英里

显示用户在PHP中当前位置的10公里半径范围内的用户