2010-02-20 16 views
0

J'ai un de l'emplacement (latitude, longitude) et à l'emplacement (latitude, longitude). Après le calcul, il devrait me montrer ce qui serait le moyen le plus proche d'utiliser une boussole. Ce qui suit est le code PHP pour le faire, mais il montre la mauvaise direction, j'ai besoin de peu d'aide à ce sujet.mathématiques complexes avec grand cercle formule

function GreatCircleDirection ($OrigLat, $DestLat, $OrigLong, $DestLong, $Distance) 
{ 
    $Result = 0.0; 

    $L1 = deg2rad($OrigLat); 
    $L2 = deg2rad($DestLat); 
    $D = deg2rad($Distance/60); # divide by 60 for nautical miles NM to degree 

    $I1 = deg2rad($OrigLong); 
    $I2 = deg2rad($DestLong); 
    $Dlong = $I1 - $I2; 

    $A = sin($L2) - cos($D + $L1 - pi()/2); 
    $B = acos($A/(cos($L1) * sin($D)) + 1); 

    if ((abs($Dlong) < pi() and $Dlong < 0) or (abs($Dlong) > pi() and $Dlong > 0)) 
    { 
     //$B = (2 * pi()) - $B; 
    } 

    $Result = $B; 
    return rad2deg($Result); 
} 


function GreatCircleDistance ($OrigLat , $DestLat, $OrigLong, $DestLong) 
    { 
     $L1 = deg2rad($OrigLat); 
     $L2 = deg2rad($DestLat); 
     $I1 = deg2rad($OrigLong); 
     $I2 = deg2rad($DestLong); 

     $D = acos(cos($L1 - $L2) - (1 - cos($I1 - $I2)) * cos($L1) * cos($L2)); 
     # One degree of such an arc on the earth's surface is 60 international nautical miles NM 
     return rad2deg($D * 60); 
    } 

Bug sur si la condition: ce sont les valeurs de la fonction si la condition de greatCircleDirection, besoin de savoir ce qu'il faut changer pour y remédier.

if (0.57700585070933 < 3.1415926535898 and 0.57700585070933 < 0) or (0.57700585070933 > 3.1415926535898 and 0.57700585070933 > 0) 

exemple:

from lat: 33.71, 
to lat: 21, 
from long: 73.06, 
to long: 40 , 
distance: 1908.842544944 
direction 104.96527938779 (direction should be 255.87 or so) 
+0

exemple ajouté .. – Basit

Répondre

1

calcul de la distance est inutile; il ajoute simplement plus d'opérations et peut introduire plus d'erreurs numériques. Utilisation de votre style de codage, quelque chose comme cela devrait fonctionner:

function GreatCircleDirection($OrigLat, $OrigLong, $DestLat, $DestLong) 
{ 
    $L1 = deg2rad($OrigLat); 
    $I1 = deg2rad($OrigLong); 
    $L2 = deg2rad($DestLat); 
    $I2 = deg2rad($DestLong); 
    return rad2deg(atan2((sin($I2-$I1),cos($L1)*tan($L2)-sin($L1)*cos($I2-$I1))); 
} 

La fonction atan2 prend soin d'identifier le quadrant correct pour la direction, et vous donne l'angle entre -180 à 180 mesurée à partir du nord vrai, par exemple, GreaterCircleDirection (39, -77,21,40) évalue à 56,76 degrés. Convention de signe utilisée: les latitudes sont positives au nord, négatives au sud; les longitudes sont positives à l'est, négatives à l'ouest.

Le calcul est discuté dans, entre autres, http://patriot.net/~abdali/ftp/qibla.pdf.

1

Eh bien, votre calcul de distance vérifie. Mais je vois que la réponse que vous obtenez pour le roulement initial est (0 + 105) mod360 plutôt que (0-105) mod360 (environ) donc je soupçonne un mauvais signe quelque part dans l'instruction if dans votre fonction GreatCircleDirection.

+0

oui vous avez raison, que si la condition est mal .. pouvez-vous me aider à réparer, je ne sais pas quoi faire pour y remédier. – Basit

+0

c'est si condition: (0.57700585070933 <3.1415926535898 et 0.57700585070933 <0) ou (0.57700585070933> 3.1415926535898 et 0.57700585070933> 0) – Basit

+0

devrais-je changer les signes plus ou moins en face? cela fonctionnerait-il? mais principalement, est-ce que ce serait une bonne chose à faire dans le calcul? – Basit