Calculer la distance réelle entre 2 adresses géolocalisées

Publié le 28 Oct 2020

La distance réelle ou "distance à vol d'oiseau" peut être utile parfois si vous souhaitez, par exemple, trouver tous les points d'interêts que vous avez référencés dans un rayon de XX km.

La complexité est que la terre n'est pas plate et que, si nous souhaitons utiliser les latitudes / longitudes, nous devons transformer les valeurs. 

Pour réaliser cette distance réelle, nous avons deux cas possibles :

  • Vous n'avez que l'adresse du point A et du point B,
  • Vous avez les coordonnées GPS (latitude et longitude) des point A et B.

Les coordonnées latitude et longitude sont essentielles pour pouvoir récupérer et calculer la distance réelle entre deux positions ou deux adresses.

Nous allons donc voir comment récupérer ces informations à l'aide de l'API Google Map.

Pour notre exemple, nous allons partir sur les deux adresses suivantes :

  • Point A : 9, rue Tronchet - 69006 Lyon,
  • Point B : Gare de Lyon, Place Louis-Armand, 75571 Paris.

Récupérer les données GPS à partir de l'API Google Map

Cette étape va se définir en 2 parties :

  • Obtenir une clé d'API,
  • Faire un appel à l'API Google Maps pour récupérer les données de l'adresse du point A et du point B,

Obtenir une clé d'API

Pour ceci, je vous conseille de suivre ce tuto de Google : https://developers.google.com/maps/documentation/javascript/get-api-key

Il faut que les API Google Map Places API, Geocoding API et Location API soient bien activées.

Appel à l'API Google Maps et récupération des données

A partir des deux adresses et de la clé Google API, vous allez pouvoir récupérer les coordonnées de géolocalisation : 


        $locationArray['pointA'] = "9, rue Tronchet, 69006 Lyon";
$locationArray['pointB'] = "Gare de Lyon, Place Louis-Armand, 75571 Paris";
$googleApiKey = "XXXX";
$positionArray = [];
foreach($locationArray as $point => $location){
  $locationUrl = urlencode($location);
  $json = file_get_contents("https://maps.google.com/maps/api/geocode/json?key=" . $googleApiKey . "&components=locality:" . $locationUrl);
  $googleData = json_decode($json);
  if ($googleData->status == 'OK') {
    $result = $googleData->results[0];
    $positionArray[$point]['lat'] = $result->geometry->location->lat;
    $positionArray[$point]['lng'] = $result->geometry->location->lng;
  }
}
    

A partir de ce moment, vous allez avoir un tableau sous cette forme :


        $positionArray['pointA']['lat'] = 4.8422638;
$positionArray['pointA']['lng'] = 45.7696717;
$positionArray['pointB']['lat'] = 2.3743773;
$positionArray['pointB']['lng'] = 48.8443038;
    

Nous pouvons maintenant passer à la partie distance réelle.

Calcul de la distance réelle entre deux points

Contrairement à ce que peuvent affirmer certains, notre planète Terre est bien ronde.

Elle est donc soumise à un calcul de dimension en fonction d'un rayon et de degrés.

Malgré ce qu'on peut croire, ce point est très important car il vous permettra d'affiner au mieux votre calcul en suivant la courbe de la terre et non en faisant une ligne droite qui reviendrait à creuser un tunne entre deux points.

Notre calcul va donc être réalisé selon la méthode suivante :

On récupère le rayon de la terre :


        $radiusEarthKm = 6371.07103;
    

On converti les latitudes d'une unité de degrés à radian :


        $radiusLatFrom = $positionArray['pointA']['lat'] * (pi() /180);
$radiusLatTo = $positionArray['pointB']['lat'] * (pi() /180);
    

On calcule la différence entre la latitude du point B au point A :


        $latDiff = $radiusLatTo - $radiusLatFrom;
    

On calcule la différence entre la longitude du point B au point A et on converti cette différence de degré en radian :


        $lngDiff = ($positionArray['pointB']['lng'] - $positionArray['pointA']['lng']) * (pi() /180);
    

On calcule la distance entre les 2 points :


        $distance = 2 * $radiusEarthKm * sin(sqrt(sin($latDiff/2) * sin($latDiff/2) + cos($radiusLatFrom) * cos($radiusLatTo) * sin($lngDiff/2)*sin($lngDiff/2)));
    

On a maintenant notre distance entre nos deux points.

Je veux tout le code !


        $locationArray['pointA'] = "9, rue Tronchet, 69006 Lyon";
$locationArray['pointB'] = "Gare de Lyon, Place Louis-Armand, 75571 Paris";
$googleApiKey = "XXXX";
$positionArray = [];
foreach($locationArray as $point => $location){
      $locationUrl = urlencode($location);
  $json = file_get_contents("https://maps.google.com/maps/api/geocode/json?key=" . $googleApiKey . "&components=locality:" . $locationUrl);
  $googleData = json_decode($json);
  if ($googleData->status == 'OK') {
            $result = $googleData->results[0];
    $positionArray[$point]['lat'] = $result->geometry->location->lat;
    $positionArray[$point]['lng'] = $result->geometry->location->lng;
  }
}
// Radius in Km
$radiusEarthKm = 6371.07103;
// Convert degrees to radians
$radiusLatFrom = $positionArray['pointA']['lat'] * (pi() /180);
$radiusLatTo = $positionArray['pointB']['lat'] * (pi() /180);
// Radian difference (latitudes)
$latDiff = $radiusLatTo - $radiusLatFrom;
// Radian difference (longitudes)
$lngDiff = ($positionArray['pointB']['lng'] - $positionArray['pointA']['lng']) * (pi() /180);
// Distance
$distance = 2 * $radiusEarthKm * sin(sqrt(sin($latDiff/2) * sin($latDiff/2) + cos($radiusLatFrom) * cos($radiusLatTo) * sin($lngDiff/2)*sin($lngDiff/2)));
echo "Real distance from ".$locationArray['pointA']." to ".$locationArray['pointB']." is ".$distance.";