la formule d'Haversine mise en pratique

Bonjour !

Aujourd'hui, nous allons essayer d'appréhender la formule d'haversine, mais tout d'abord, à quoi ça sert ?

La formule d'haversine permet, grâce à une expression mathématique,de trouver la distance à vol d'oiseau entre deux points sur terre. Cette formule est basée sur les coordonnées géographiques et les fonctions trigonométriques.

Toujours dans la présentation, je vais vous dévoiler la formule en question. Elle peut vous sembler obscure, mais ne vous inquiétez pas, je vous l'explique par la suite !

 a = sin(\frac{\Delta_\theta}{2})^2+cos(\theta_1)*cos(\theta_2)*sin(\frac{\Delta_\lambda}{2})^2

 c= 2*atan2(\sqrt{a}, \sqrt{1-a})

 d= R*c

Quelques précisions, sinon vous ne pourrez pas comprendre cette formule : On divise toujours cette formule en 3 parties pour la rendre plus digeste, c'est en quelque sorte une convention. Ensuite, les \theta sont des latitudes, les \lambda des longitudes et R est le rayon de la terre. Enfin,  \Delta_\theta = \theta_2 - \theta_2 et \Delta_\lambda = \lambda_2 - \lambda_1

Nous avons bien sur le souci de la précision, nous allons donc chercher un rayon de la terre le plus précis possible, et pour ce genre de recherche scientifique, j'ai un favori, wolfram alpha . Selon ce moteur de recherche, R=6367,5 km (si vous voulez essayer vous même, tapez "earth radius" dans le champ de recherche.)

Maintenant que les présentations sont faites, passons à la partie qui nous intéresse le plus : Le programme : Les habitudes ne changent pas, ce programme sera codé en PHP, mais en OO ,(Orienté Objet) car on m'a demandé des approfondissements sur ce sujet !

Partie 1 : Identifions les fonctions trigonométriques et mathématiques à utiliser dans le code.

Tout d'abord, les latitudes sont fournies en degrés, il faut les convertir en radians, et pour cela on utilisera la fonction deg2rad(nombre)

Les fonctions trigonométriques utilisées ici (sin, cos, atan2) sont nativements intégrées à PHP sous leur nom d'origine, pas besoin de plus de détails.

Partie 2 : Créons le "squelette" de notre code.

Je vous l'ai dit plus haut, nous allons faire de la POO, pour cela, il faut changer ses habitudes par rapport au procédurale et créer une nouvelle forme de document comme ce qui suit :


<?php

class Haversine{

public function calculate($lat1, $long1, $lat2, $long2){

//Ici notre code

}

?>

Nous avons donc créer une classe qui comporte une fonction qui elle même comporte des arguments: ces 4 arguments, ou paramètres, sont les coordonnées de deux points GPS, une latitude et une longitude par point.

Partie 3 : Codons notre formule.

Créez un fichier haversine.php ou tout autre nom tant que le fichier est bien en PHP, et on va le remplir au fur et à mesure :


<?php

class Haversine{

/* On créer une fonction avec 4 paramètres, ou arguments :

*2 latitudes et 2 longitudes qui définissent deux points GPS

*/

public function calculate($lat1, $long1, $lat2, $long2){

//On définie la constante R

$R = "6367.5";

//On calcul les deltas

$delta_lat =  deg2rad($lat2 - $lat1);

$delta_long = deg2rad($long2 - $long1);

//On calcul a

$a = sin($delta_lat/2)*sin($delta_lat/2)+cos(deg2rad($lat1))*cos(deg2rad($lat2))*sin($delta_long/2)*sin($delta_long/2);

//On calcul c

$c = 2*atan2(sqrt($a), sqrt(1-$a));

//On applique la formule

$d = $R*$c;

//On retourne la valeur pour pouvoir l'utiliser par le biais de cette classe.

return $d;

}

?>

Notre classe est codée et presque prête à l'emploi ! Pour qu'elle soit réellement prête, on va faire cela :


<?php

class Haversine{

public function calculate($lat1, ...,$long2){

//Le code est ici !

}}

$Haversine = new Haversine();

?>

Grâce à cette ligne, notre objet est déjà créer et pourra être utilisé directement dans le fichier qui contiendra ce code.

Partie 4 : Mettons en place un formulaire.

Nous allons maintenant mettre en place un formulaire pour permettre à nos utilisateurs de rentrer leurs propres données sans avoir à modifier notre code. Créez donc un fichier index.html et rentrez-y ceci :


<!doctype>

<html>

<head>

</head>

<body>

<form method="post" action="traitement.php">

<label for="lat1">Latitude 1 :</label><input type="text" name="lat1" id="lat1" />

<label for="long1">Longitude 1 :</label><input type="text" name="long1" id="long1" /> <br />

<label for="lat2">Latitude 2 :</label><input type="text" name="lat2" id="lat2" />

<label for="long2">Longitude 2 :</label><input type="text" name="long2" id="long2" />

<input type="submit" value="valider" />

</form>

</body>

</html>

Je ne me suis pas embêté avec le html, ce n'est pas l'objet de notre tutoriel donc, si vous comptez mettre en ligne cet outil, retouchez ce code !

Partie 5: The last, but not the least : Traitons et affichons les données !

Créons un fichier traitement.php . Nous allons maintenant vérifier que les champs n'étaient pas vides puis nous traiteront les données ! Je ne m'étendrais pas sur l'aspect sécurité, ce n'est pas l'objet de cet article, mais toujours si vous comptez mettre en ligne l'outil, vérifiez bien que les champs ne sont pas vides et que ce sont bien des chiffres !


<?php

extract($_POST); //$_POST['xxx'] devient $xxx

if(!empty($lat1) && !empty($long1) && !empty($lat2) && !empty($long2)){

require "haversine.php"; // On inclue notre classe.

$distance = $Haversine->calculate($lat1, $long1, $lat2, $long2);

echo $distance.' km';

}

?>

Et voilà, une classe tout à fait utilisable et très (trop) précise, en effet, vous trouvez un chiffre à 12 chiffres après la virgule. On aime la précision mais trop trop c'est trop, passons donc à 3 chiffres après la virgule !

Partie 6 : C'est vraiment la dernière, et on fignole !

Pour raccourci le chiffre, on va utiliser la fonction substr :


<?php
// On a notre distance, mais on ne l'a pas encore affichée (ligne 9)

$distance = substr($distance, 0, -10);

echo $distance;

?>

Et voilà, on a notre distance avec deux chiffres après la virgule, je vous laisse le choix de ce nombre (-9 = 3, -8 = 4 etc ..)

Ce tutoriel est fini, j'espère qu'il vous a plu autant qu'il m'a plu de l'écrire ! J'espère que vous aurez remarqué l'intégration de \LaTeX dans cet article pour m'aider à écrire les formules mathématiques, winiwake vous parlera de ça un de ces quatres !

A bientôt, et si vous avez des questions, c'est plus bas, dans les commentaires ou sur twitter : @sitewaide !

Ce contenu a été publié dans Codage, Découverte. Vous pouvez le mettre en favoris avec ce permalien.

3 réponses à la formule d'Haversine mise en pratique

  1. Brendan dit :

    Salut.
    Intéressant comme formule, d'ailleurs je savais pas que d'autre gens codaient dans le lycée.

    Au passage, je viens de voir ton article sur Dropbox, vas jeter un œil à sharea.net c'est un projet similaire que je développe ;D

  2. Xstyle dit :

    Salut !
    Ton site est très sympa ! Le seul reproche que je ferais est le formulaire d'inscription peut-être trop complet (je suis plutôt partisan de la séparation IRL/IVL) Mais sinon, la réalisation est nickel ! Peut-être de la promo dans un article à venir ;)
    Merci pour ton commentaire en tout cas, mais on est bien plus que deux à savoir coder au lycée ;)

  3. johann dit :

    Je recherchais des informations sur la formule d'Haversine, et ton billet m'a bien aidé ! Merci

    Juste pour info, la syntaxe avec SyntaxHighlighter est illisible (balise html,...)
    Et petit plus : Penses à utiliser une fonction statique (ou pourquoi pas un singleton) pour ta classe ~

    bye

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>