Haversine公式与PHP [英] Haversine formula with php

查看:93
本文介绍了Haversine公式与PHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在php中使用这个公式。我有一个数据库,保存了经度和纬度的一些值。

我想在输入中查找具有经度和纬度特定值的数据库中每个点的所有距离(以km为单位)。为此,我使用googlemaps api上的公式:

 (6371 * acos(cos(radians(37))* cos (弧度(lat))* cos(弧度(lng) - 弧度(-122))+ sin(弧度(37))* sin(弧度(lat))))

当然,在php中我用 deg2rad 取代了弧度。值37,-122是我的输入值和经度值,lng是我在数据库中的值。



下面是我的代码。问题是有什么问题,但我不明白。距离的价值当然是错误的。

  //纬度和纬度的输入值(罗马 -  eur,IT)
$ center_lat =41.8350;
$ center_lng =12.470;

//连接到数据库。它工作
(..)

//获取数据库中的每个值:
$ query =SELECT * FROM Dati;
$ result = mysql_query($ query);
while($ row = @mysql_fetch_assoc($ result)){
$ lat = $ row ['Lat']);
$ lng = $ row ['Lng']);
$ distance =(6371 * acos((cos(deg2rad($ center_lat)))*(cos(deg2rad($ lat)))*(cos(deg2rad($ lng) - deg2rad($ center_lng))) +((sin(deg2rad($ center_lat)))*(sin(deg2rad($ lat))))));

$ / code>

例如:
$ lat = 41.9133741000
$ lng = 12.5203​​944000

我输出的距离=4826.9341106926

解决方案 div>

您使用的公式似乎是,而不是 haversine 公式。半球公式确实更适合计算球体上的距离,因为它不容易出现对数点误差。

> / **
*计算两点之间的大圆距离,带有
*的Haversine公式。
* @param float $ latitudeFrom开始点的纬度,以[十进制小数]为单位
* @param float $ longitudeFrom以[十进制小数点]开始的经度
* @param float $ latitudeTo纬度以[十进制小数]为单位的目标点
* @参数float $ longitudeTo目标点的经度,单位为[deg十进制]
* @参数float $ earthRadius平均地球半径[m]
* @return float [m]中点之间的距离(与earthRadius相同)
* /
函数haversineGreatCircleDistance(
$ latitudeFrom,$ longitudeFrom,$ latitudeTo,$ longitudeTo,$ earthRadius = 6371000)
{
//从度数转换为弧度
$ latFrom = deg2rad($ latitudeFrom);
$ lonFrom = deg2rad($ longitudeFrom);
$ latTo = deg2rad($ latitudeTo);
$ lonTo = deg2rad($ longitudeTo);

$ latDelta = $ latTo - $ latFrom;
$ lonDelta = $ lonTo - $ lonFrom;

$ angle = 2 * asin(sqrt(pow(sin($ latDelta / 2),2)+
cos($ latFrom)* cos($ latTo)* pow(sin( $ lonDelta / 2),2)));
返回$ angle * $ earthRadius;
}

我在你的代码中找不到错误,那么它是否是你写下的错字? $ lat = 41.9133741000 $ lat = 12.5203​​944000 ?也许你只是用$ lat = 12.5203​​944000和$ long = 0来计算,因为你覆盖了你的$ lat变量。

编辑:

测试代码并返回正确的结果:

  $ center_lat = 41.8350; 
$ center_lng = 12.470;
$ lat = 41.9133741000;
$ lng = 12.5203​​944000;

//使用反余弦公式测试
$ distance =(6371 * acos((cos(deg2rad($ center_lat)))*(cos(deg2rad($ lat)))*( cos(deg2rad($ lng) - deg2rad($ center_lng)))+((sin(deg2rad($ center_lat)))*(sin(deg2rad($ lat))))));
print($ distance); //打印9.662174538188

//用我的haversine公式测试
$ distance = haversineGreatCircleDistance($ center_lat,$ center_lng,$ lat,$ lng,6371);
print($ distance); //打印9.6621745381693


I want to use this formula with php. I have a database with some values of latitute and longitude saved.

I want to find, with a certain value of latitude and longitude in input, all the distances (in km) from this point with each point in the database. To do this, I used the formula on googlemaps api:

( 6371 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) )

Of course using that in php I replaced radians with deg2rad.The values 37,-122 are my values of input and lat,lng are my values in the database.

Below there is my code. The problem is that there is something wrong but I don't understand what. The value of distance is of course wrong.

//values of latitude and longitute in input (Rome - eur, IT)
$center_lat = "41.8350";
$center_lng =  "12.470";

//connection to database. it works
(..)

//to take each value in the database:
    $query = "SELECT * FROM Dati";
    $result = mysql_query($query);
    while ($row = @mysql_fetch_assoc($result)){
        $lat=$row['Lat']);
        $lng=$row['Lng']);
    $distance =( 6371 * acos((cos(deg2rad($center_lat)) ) * (cos(deg2rad($lat))) * (cos(deg2rad($lng) - deg2rad($center_lng)) )+ ((sin(deg2rad($center_lat))) * (sin(deg2rad($lat))))) );
    }

For values for example: $lat= 41.9133741000 $lng= 12.5203944000

I have the output of distance="4826.9341106926"

解决方案

The formula you used, seems to be the arccosine instead of the haversine formula. The haversine formula is indeed more appropriate to calculate the distance on a sphere, because it is not prone to rounding errors with antipodal points.

/**
 * Calculates the great-circle distance between two points, with
 * the Haversine formula.
 * @param float $latitudeFrom Latitude of start point in [deg decimal]
 * @param float $longitudeFrom Longitude of start point in [deg decimal]
 * @param float $latitudeTo Latitude of target point in [deg decimal]
 * @param float $longitudeTo Longitude of target point in [deg decimal]
 * @param float $earthRadius Mean earth radius in [m]
 * @return float Distance between points in [m] (same as earthRadius)
 */
function haversineGreatCircleDistance(
  $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
  // convert from degrees to radians
  $latFrom = deg2rad($latitudeFrom);
  $lonFrom = deg2rad($longitudeFrom);
  $latTo = deg2rad($latitudeTo);
  $lonTo = deg2rad($longitudeTo);

  $latDelta = $latTo - $latFrom;
  $lonDelta = $lonTo - $lonFrom;

  $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
    cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
  return $angle * $earthRadius;
}

P.S. I couldn't find an error in your code, so is it just a typo that you wrote $lat= 41.9133741000 $lat= 12.5203944000 ? Maybe you just calculated with $lat=12.5203944000 and $long=0 because you overwrote your $lat variable.

Edit:

Tested the code and it returned a correct result:

$center_lat = 41.8350;
$center_lng = 12.470;
$lat = 41.9133741000;
$lng = 12.5203944000;

// test with your arccosine formula
$distance =( 6371 * acos((cos(deg2rad($center_lat)) ) * (cos(deg2rad($lat))) * (cos(deg2rad($lng) - deg2rad($center_lng)) )+ ((sin(deg2rad($center_lat))) * (sin(deg2rad($lat))))) );
print($distance); // prints 9.662174538188

// test with my haversine formula
$distance = haversineGreatCircleDistance($center_lat, $center_lng, $lat, $lng, 6371);
print($distance); // prints 9.6621745381693

这篇关于Haversine公式与PHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆