2010-11-30 47 views
3

我正在嘗試查找兩個經度和緯度點之間的距離。我正在嘗試使用great circle distance。這是公式: alt text使用海峽網格公式的緯度/長點之間的距離

我不知道爲什麼,但我的程序無法正常工作。這是我得到的結果:

Change Angle: 0.00016244370761414 
Earth Radius: 6371 

RESULTS: 
Correct Distance: 24.883 km 
Computed Distance: 1.0349288612097 

來源:

$latStart = 44.638; 
$longStart = -63.587; 

$latFinish = 44.644; 
$longFinish = -63.597; 


# Convert Input to Radians 
$latStart = deg2Rad($latStart); 
$longStart = deg2Rad($longStart); 

$latFinish = deg2Rad($latFinish); 
$longFinish = deg2Rad($longFinish); 

# Because the Earth is not perfectly spherical, no single value serves as its 
# natural radius. Distances from points on the surface to the center range from 
# 6,353 km to 6,384 km (≈3,947–3,968 mi). Several different ways of modeling the 
# Earth as a sphere each yield a convenient mean radius of 6371 km (≈3,959 mi). 
# http://en.wikipedia.org/wiki/Earth_radius 
$earthRadius = 6371; 

# difference in Long/Lat 
$latChange = $latFinish - $latStart; 
$longChange = $longFinish - $longStart; 



# haversine formula 
# numerically stable for small distances 
# http://en.wikipedia.org/wiki/Great-circle_distance 
$changeAngle = 2 * asin(
       sqrt(
         pow(sin($latChange/2),2) + 
         cos($latStart) * cos($latFinish) * pow(sin($longChange/2),2) 
       ) 
     ); 



echo "Change Angle: $changeAngle\n"; 
echo "Earth Radius: $earthRadius\n"; 

回答

2

讓我們做使用平面近似背的最信封檢查。緯度差值爲0.006°,經度差值爲0.01°,但乘以緯度餘弦值得到0.0075°。應用畢達哥拉斯:

>>> sqrt(0.006 ** 2 + 0.0075 ** 2) 
0.0096046863561492727 

這是約0.000167弧度,非常接近您的計算。 (甚至更多的信封檢查:一個程度是大約69英里,這是有點超過100公里,所以0.01°應該有點超過1公里。)

所以我認爲這是你所謂的「正確的距離「這是錯誤的,而不是你的計算。

+0

YEPP。我有錯誤的輸入。 – sixtyfootersdude 2010-11-30 19:58:32

1

你的方法鬆散地基於畢達哥拉斯的定理 - 我一直這樣做是艱難的,也就是說(事實上,我預先計算軸的值並將它們與數據一起存儲在數據庫中):

$startXAxis = cos(deg2Rad($latStart)) * cos(deg2Rad($longStart)); 
$startYAxis = cos(deg2Rad($latStart)) * sin(deg2Rad($longStart)); 
$startZAxis = sin(deg2Rad($latStart)); 
$finishXAxis = cos(deg2Rad($latFinish)) * cos(deg2Rad($longFinish)); 
$finishYAxis = cos(deg2Rad($latFinish)) * sin(deg2Rad($longFinish)); 
$finishZAxis = sin(deg2Rad($latFinish)); 

$changeAngle = acos($startXAxis * $finishXAxis + $startYAxis * $finishYAxis + $startZAxis * $finishZAxis); 
1

你的公式看起來與我的實現不同。不過,我的.NET,但我已經測試過它,它運作良好。

這是這一個稍微改寫版本:http://megocode3.wordpress.com/2008/02/05/haversine-formula-in-c/

/// <summary> 
/// Implementation of the Haversine formula 
/// For calculating the distance between 2 points on a sphere 
/// http://en.wikipedia.org/wiki/Haversine_formula 
/// </summary> 
public class Haversine 
{ 
    /// <summary> 
    /// Calculate the distance between 2 points in miles or kilometers 
    /// http://megocode3.wordpress.com/2008/02/05/haversine-formula-in-c/ 
    /// 
    /// This assumes sea level 
    /// </summary> 
    public double Distance(LatLon pos1, LatLon pos2, DistanceType type) 
    { 
     const double RADIUS_OF_EARTH_IN_MILES = 3963.1676; 
     const double RADIUS_OF_EARTH_IN_KILOMETERS = 6378.1; 

     //radius of the earth 
     double R = (type == DistanceType.Miles) ? RADIUS_OF_EARTH_IN_MILES : RADIUS_OF_EARTH_IN_KILOMETERS; 

     //Deltas 
     double dLat = ToRadian(pos2.Lat - pos1.Lat); 
     double dLon = ToRadian(pos2.Lon - pos1.Lon); 

     double a = Math.Sin(dLat/2)*Math.Sin(dLat/2) + Math.Cos(ToRadian(pos1.Lat))*Math.Cos(ToRadian(pos2.Lat)) * Math.Sin(dLon/2) * Math.Sin(dLon/2); 
     double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a))); 

     double d = R*c; 
     return d; 
    } 

    /// <summary> 
    /// Convert to Radians. 
    /// </summary> 
    private double ToRadian(double val) 
    { 
     return (Math.PI/180) * val; 
    } 
} 
+0

謝謝,這非常有幫助。我用你的代碼來檢查我的。原來,我錯誤地輸入了我的一個輸入值。我發誓我已經摔倒了,但我猜不是。 – sixtyfootersdude 2010-11-30 19:58:14

相關問題