如何计算距离从纬度/长在php


How to calculate distance from lat/long in php?

我要做的是我在数据库中有一个后期/长期存储与他们的条目。我想计算用户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);
?>

我不建议在SQL语句中转储距离计算,尽管我承认'denil'提供的解决方案非常巧妙。

有3个缺点:代码维护,sql server过载和(最重要的是)地球是不对称的(它就像一个旧的凹陷的棒球被卡车碾过)。这意味着你可能想在将来更改代码(有一些非常复杂的算法在那里- 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);
?>

有许多免费软件(试试GPS trackmaker),可以让你检查你所在地区的误差范围(如果你需要精度)。对于上述的纬度/长度对,误差在+/- 0.1%以内(根据当地地形学家)。

注意:这个公式给出的是制图距离(海平面距离),而不是地形距离(不考虑地形)。

我几周前就这么做了。

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

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

即使你不使用他们的API,他们的PHP和SQL查询真的很有帮助。

试试这个查询。我在谷歌上找到了这个,但忘了是谁创建的

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

$lat和$long变量是用户的当前位置。

为条目的经度和纬度。

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>";
?>

测试了3个函数和3个查询,只有一个显示良好的距离:

在米:

SELECT *,
(
    (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180))+cos((".$latitude."*pi()/180))    * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344) 
    * 1000
) as `distance`
FROM `table`
ORDER BY `distance` ASC
在公里:

SELECT *,
(
    (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180))+cos((".$latitude."*pi()/180))    * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344) 
) as `distance`
FROM `table`
ORDER BY `distance` ASC

这个查询对我来说是完美的:

$latitude = "23.139422";  //your current lat
$longitude = "-82.382617"; //your current long
SELECT ( 3959 * acos( cos( radians( '.$latitude.' ) ) * cos( radians( latitude ) ) * 
 cos( radians( longitude ) - radians( '.$longitude.' ) ) + sin( radians( '.$latitude.' )
 ) * sin( radians( latitude ) ) ) ) AS distance from TABLE 
 HAVING distance <= 100 ORDER BY distance ASC

最简单的方法

<?php
    $lat1 = Yourstart_latitude;
    $lon1 = Yourstart_longitude;
    $lat2 = Yourend_latitude;
    $lon2 = Yourend_longitude;
    $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 = 'K';
                                $km   = $miles*1.609344;
                              echo number_format($km,1);
                            ?>

使用距离矩阵google api计算经纬度之间的距离

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, 
    'https://maps.googleapis.com/maps/api/distancematrix/json?origins='.$prev_add.'&destinations='.$curr_add.'&key=keyyouhavetogenerate'
);
$content = curl_exec($ch);
$array = json_decode($content);
$obj = json_decode($content, TRUE);
$distance = $obj['rows'][0]['elements'][0]['distance']['text'];

要使用这个API,您将需要key,了解更多关于如何生成key访问https://developers.google.com/maps/documentation/distance-matrix/intro

对于那些试图远离Google(和其他)api的人,我已经使用这个api一段时间了。

因为地球是圆的,对于大尺度半径的提交会有一些奇怪的结果。在相距500英里以内的地点可以很好地工作。

/**
 * The max Latitude and Longitude coordinates within a specified milage radius.
 * 
 * @param int $miles
 * @param float $longitude
 * @param float $latitude
 *
 * @return array
 */
public function getMaxCoordinates($miles = 50, $longitude, $latitude) {
    $oneDegree = 69; // 69 Miles = 1 degree
    // Calculate the minimum/maximum possible coordinates.
    $lng_min = $longitude - $miles / abs(cos(deg2rad($latitude)) * $oneDegree);
    $lng_max = $longitude + $miles / abs(cos(deg2rad($latitude)) * $oneDegree);
    $lat_min = $latitude  - ($miles / $oneDegree);
    $lat_max = $latitude  + ($miles / $oneDegree);
    return ([
        'lat_max' => $lat_max,
        'lat_min' => $lat_min,
        'lng_max' => $lng_max,
        'lng_min' => $lng_min,
        'miles'   => $miles,
    ]);
}