2010-11-30 3 views
3

Ich versuche den Abstand zwischen zwei Längen- und Breitenpunkten zu finden. Ich versuche, die great circle distance zu verwenden. Dies ist die Formel: alt textEntfernung zwischen Breiten-/Längenpunkten mit der hairsine Formel

Ich bin mir nicht sicher, warum, aber mein Programm funktioniert nicht. Dies ist das Ergebnis erhalte ich:

Change Angle: 0.00016244370761414 
Earth Radius: 6371 

RESULTS: 
Correct Distance: 24.883 km 
Computed Distance: 1.0349288612097 

Quelle:

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

Antwort

2

ist ein Back-of-the-Umschlag Lassen Sie Prüfung eine planare Annäherung verwendet wird. Der Unterschied in der Breite beträgt 0,006 °, und der Unterschied in der Länge beträgt 0,01 °, aber multipliziert mit dem Kosinus der Breite, um 0,0075 ° zu erhalten. Bewerben Pythagoras:

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

das ist etwa 0,000167 Radianten, ganz in der Nähe Ihrer Berechnung. (Noch mehr Schecks aus dem Umschlag: ein Abschluss ist ungefähr 69 Meilen, was ein bisschen über 100 km ist, also sollten 0,01 ° ein bisschen über 1 km sein.)

Also ich denke es ist dein angeblicher " Korrekte Entfernung "Das ist falsch, nicht deine Berechnung.

+0

Yepp. Ich hatte falsche Eingaben. – sixtyfootersdude

1

Ihr Ansatz basiert lose auf Pythagoras Theorem - ich habe es immer auf die harte Art gemacht, dh so etwas wie (In Wirklichkeit berechne ich die Werte für die Achse vor und speichere sie in der Datenbank neben den Daten):

$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

Ihre Formel sieht anders aus als meine Implementierung. Aber meine ist in .NET, aber ich habe es getestet und es funktioniert gut.

Es ist eine leicht neu geschriebene Version dieses: 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

Danke, das ist sehr hilfreich. Ich habe deinen Code benutzt, um meinen zu überprüfen. Es stellte sich heraus, dass ich einen meiner Eingabewerte falsch eingegeben hatte. Ich schwöre, dass ich das dreifach überprüft habe, aber ich denke nicht. – sixtyfootersdude

Verwandte Themen