如何在php中计算lat/long的距离?

iPh*_*Dev 10 php latitude-longitude

我想要做的是我在数据库中有条目存储lat/long.我想计算用户lat/long和条目lat/long(在DB中)之间的距离.在那之后,我想回应距离小于500米的那些.到目前为止,我能够使用它foreach.

<?php
mysql_connect("localhost", "beepbee_kunwarh", "kunwar") or die('MySQL Error.');
mysql_select_db("beepbee_demotest") or die('MySQL Error.');

$Lat = $_REQUEST['Lat'];
$long = $_REQUEST['long'];

$query = mysql_query("SELECT a.*, 3956 * 2 * ASIN(SQRT( POWER(SIN(($Lat - Lat) * pi()/180 / 2), 2) + COS($Lat * pi()/180) * COS(Lat * pi()/180) *POWER(SIN(($long - long) * pi()/180 / 2), 2) )) as distance FROM userResponse GROUP BY beepid HAVING distance <= 500 ORDER by distance ASC;");
$data = array();
while ($row = mysql_fetch_array($query)) {
    $data[] = $row;
}
echo json_encode($data);
?>
Run Code Online (Sandbox Code Playgroud)

ton*_*gil 16

我不建议在你的sql语句中转储距离计算,即使我承认'denil'提供的解决方案是巧妙的.

有三个缺点:代码维护,SQL服务器过载和(首先)地球不对称(它就像一个被卡车碾过的旧的凹陷棒球).这意味着您可能希望将来更改代码(有一些非常复杂的算法 - http://en.wikipedia.org/wiki/Geographical_distance).

我建议使用一个单独的函数,用一个简单的通用算法计算距离(如果与denil不相似,则类似).我提交这个纯PHP的代码(不需要使用googlemaps api):

<?php

function distanceGeoPoints ($lat1, $lng1, $lat2, $lng2) {

    $earthRadius = 3958.75;

    $dLat = deg2rad($lat2-$lat1);
    $dLng = deg2rad($lng2-$lng1);


    $a = sin($dLat/2) * sin($dLat/2) +
       cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
       sin($dLng/2) * sin($dLng/2);
    $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    $dist = $earthRadius * $c;

    // from miles
    $meterConversion = 1609;
    $geopointDistance = $dist * $meterConversion;

    return $geopointDistance;
}

// YOUR CODE HERE
echo distanceGeoPoints(22,50,22.1,50.1);

?>
Run Code Online (Sandbox Code Playgroud)

有许多免费软件(试试gps trackmaker)可以让你检查你所在地区的误差范围(如果你需要精确度).对于上述纬度/长度对,误差在+/- 0.1%之内(根据当地地形测量师的说法).

注意:此公式为您提供CARTOGRAPHIC距离(海平面距离),而不是TOPOGRAPHIC距离(disconsiders地形).

  • @ErichBSchulz是的,米.我的错 :( (2认同)

Lat*_*tox 13

几个星期前我这样做了.

这个链接是你最好的选择:

http://code.google.com/apis/maps/articles/phpsqlsearch.html

即使您不使用他们的API,他们的PHP和SQL查询也很有帮助.


den*_*nil 7

试试这个查询.我在google搜索时找到了这个,但忘记了创建它的人

SELECT a.*,
            3956 * 2 * ASIN(SQRT( POWER(SIN(($lat - lat) * pi()/180 / 2), 2) + COS($lat * pi()/180) * COS(lat * pi()/180) *
            POWER(SIN(($long - longi) * pi()/180 / 2), 2) )) as
            distance FROM table
            GROUP BY id HAVING distance <= 500 ORDER by distance ASC
Run Code Online (Sandbox Code Playgroud)

$ lat和$ long变量是用户的当前位置.lat和longi是条目的纬度和长度


lbs*_*eek 5

http://www.geodatasource.com/developers/php

<?php

/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*::                                                                         :*/
/*::  This routine calculates the distance between two points (given the     :*/
/*::  latitude/longitude of those points). It is being used to calculate     :*/
/*::  the distance between two locations using GeoDataSource(TM) Products    :*/
/*::                                                                         :*/
/*::  Definitions:                                                           :*/
/*::    South latitudes are negative, east longitudes are positive           :*/
/*::                                                                         :*/
/*::  Passed to function:                                                    :*/
/*::    lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)  :*/
/*::    lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)  :*/
/*::    unit = the unit you desire for results                               :*/
/*::           where: 'M' is statute miles                                   :*/
/*::                  'K' is kilometers (default)                            :*/
/*::                  'N' is nautical miles                                  :*/
/*::  Worldwide cities and other features databases with latitude longitude  :*/
/*::  are available at http://www.geodatasource.com                          :*/
/*::                                                                         :*/
/*::  For enquiries, please contact sales@geodatasource.com                  :*/
/*::                                                                         :*/
/*::  Official Web site: http://www.geodatasource.com                        :*/
/*::                                                                         :*/
/*::         GeoDataSource.com (C) All Rights Reserved 2014                  :*/
/*::                                                                         :*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
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;
      }
}

echo distance(32.9697, -96.80322, 29.46786, -98.53506, "M") . " Miles<br>";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "K") . " Kilometers<br>";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "N") . " Nautical Miles<br>";

?>
Run Code Online (Sandbox Code Playgroud)