Question

J'ai trouvé une fonction dans une page PHP qui calcule le nombre de miles entre 2 points, mais elle est défectueuse. C’est censé fonctionner avec Google Maps, mais la différence de distances va de 1,3 à 1,65 fois plus loin dans Google Maps (ce qui est plus précis).

Voici la fonction:

$M =  69.09 * rad2deg(acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2))));

Je trouve que c'est un peu compliqué et que je ne connais pas grand chose à la géométrie pour savoir si c'est correct ou non.

Est-ce que quelqu'un avec un peu plus de savoir-faire peut regarder cela et voir ce qui ne va pas?

Était-ce utile?

La solution

Peut-être comparez-vous la "distance à vol d'oiseau" (ligne directe entre deux points) avec la distance de conduite?

voir cet article pour calculer la distance entre deux points en PHP.

Autres conseils

Vous recherchez la la formule de Haversine pour calculer la distance entre deux points que vous avez longitude et latitude pour.

Une implémentation simple en Javascript est disponible ici . , ce qui devrait être facile à convertir en PHP.

Il existe au moins trois méthodes de calcul de distance différentes à la surface de la Terre, dont l’exactitude et le calcul requis varient.

  1. Loi sphérique des cosinus [pas très précis, très simple à calculer]
  2. Formule Haversine [précise à l'exception de petites distances, toujours relativement simple à calculer]
  3. Vincenty Formula [extrêmement précis et peut utiliser plusieurs différents modèles ellipsoïdes de la surface de la Terre, plus compliqués à calculer]

L'exemple que vous avez fourni semble correspondre à la loi du calcul des cosinus, tandis que Google Maps est plus précis puisqu'il utilise la formule Vincenty. (Je trouve que le lien Vincenty explique la formule plus en détail que la page Wikipedia)

Modifier: J'ai vu un commentaire ci-dessus selon lequel l'erreur introduite par la déviation de la surface de la Terre est triviale et ne peut pas composer l'erreur que vous voyez. Je crains que ce ne soit vrai que sur de très grandes distances. À des distances de quelques centaines de kilomètres ou moins, les erreurs peuvent être résolument non négligeables.

Voici une version plus simple, mais inexacte pour des sites très distants:

    const ONE_DEGREE = 111120;

public function distance( $point ) {
    $coef = cos( $this->getLatitude() / 180 * M_PI );
    $x = $this->getLatitude() - $point->getLatitude();
    $y = ( $this->getLongitude() - $point->getLongitude() ) * $coef;
    $result = sqrt( $x * $x + $y * $y ) * self::ONE_DEGREE;
    return $result;
}

$ point et $ this sont des instances de la classe Location avec les méthodes getLatitude () et getLongitude ().

Je ne connais rien à la géométrie non plus, mais google a suggéré de cette page . Peut-être que vous le trouverez utile

Il semble que la formule soit exacte - voir, par exemple, Wikipedia sur " ; grande distance de cercle " . Le facteur de 69,09 en face est, je crois, le nombre de milles dans un degré mesuré le long d’un grand cercle (par exemple, des milles dans un degré de longitude à l’équateur), de sorte que votre réponse sera exprimée en milles.

L'idée de Jonstjohn selon laquelle vous pourriez peut-être comparer incorrectement la distance en ligne droite avec la distance de conduite me semble l'explication la plus probable.

ÉDITER : ou bien il pourrait s'agir de l'erreur d'arrondi mentionnée par Wikipedia, si vous travaillez avec de petites séparations. Mais je signalerais d’abord la différence distance directe / distance de conduite.

Il semble que le calcul que vous référencez utilise un système de coordonnées sphériques. La formule est presque correcte. Le rayon que vous utilisez est en partie à l'origine de vos calculs. Le 69.09 est le rayon de la sphère (la terre dans ce cas). Comme vous le savez peut-être, la Terre n'est pas vraiment une sphère, mais un ellipsoïde. Je suggère d'essayer la formulation ci-dessous:

3963 * acos(sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($lon1 - $lon2)));

Pour des résultats plus précis, utilisez des calculs Vincenty ou Haversine.

EDIT: Pour clarifier, je n’essaie pas d’impliquer que le gros de l’erreur que vous signalez est dû à l’utilisation d’un calcul de coordonnées sphériques. Cette erreur est beaucoup plus petite que ce que vous voyez. L’ajustement de formule que j’ai fourni était censé être une version plus claire de la formule, car le 69.09 était une valeur du rayon de la Terre ajustée à un système de degrés, ce qui est moins intuitif que la simple utilisation de radians. En outre, il convient de noter que, pour calculer de très petites distances, l’utilisation de la formule ci-dessus est très précise (jusqu’à environ 1 m), tant que le système effectuant le calcul utilise suffisamment de décimales. L'utilisation d'un float dans l'informatique moderne vous donne cette précision.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top