Подписаться на блог через FeedBurner

Вычисление расстояния между двумя геокоординатами на PHP

Как определить прямолинейное расстояние(без учета дорог и перепадов высот) между двумя геокоординатами? Очень просто, функция, реализованная на PHP приводится ниже.

Передаем в функцию пару координат, она нам возвращает дистанцию между точками в метрах.

function calcDistance($lat1, $lon1, $lat2, $lon2)
{
   if ($lat1 == $lat2 && $lon1 == $lon2) {
      return 1;
   }
 
   // Параметры эллипсоида:
   $a = 6378245.0;
   $f = 1 / 298.3;
   $b = (1 - $f) * $a;
   $EPS = 0.5E-30;
   $PI = M_PI;
 
   //Пересчет значений координат в радианы
   $lon1 = $lon1 * $PI / 180;
   $lat1 = $lat1 * $PI / 180;
   $lon2 = $lon2 * $PI / 180;
   $lat2 = $lat2 * $PI / 180;
 
   $TanU1 = (1 - $f) * tan($lat1);
   $TanU2 = (1 - $f) * tan($lat2);
   $U1 = atan($TanU1);
   $U2 = atan($TanU2);
 
   $SinU1 = sin($U1);
   $CosU1 = cos($U1);
   $SinU2 = sin($U2);
   $CosU2 = cos($U2);
 
   $OMEGA = $lon2 - $lon1;
   $lambda = $OMEGA;
 
   do //Начало цикла итерации
   {
      $LambdaPrev = $lambda;
      $SinL = sin($lambda);
      $CosL = cos($lambda);
 
      $SinSQSigma = ($CosU2 * $SinL * $CosU2 * $SinL) +
                    ($CosU1 * $SinU2 - $SinU1 * $CosU2 * $CosL) *
                    ($CosU1 * $SinU2 - $SinU1 * $CosU2 * $CosL);
 
      $CosSigma = $SinU1 * $SinU2 + $CosU1 * $CosU2 * $CosL;
 
      $TanSigma = sqrt($SinSQSigma) / $CosSigma;
      if ($TanSigma > 0) {
         $Sigma = atan($TanSigma);
      } else {
         $Sigma = atan($TanSigma) + $PI;
      }
 
      if ($SinSQSigma == 0) {
         $SinAlpha = 0;
      } else {
         $SinAlpha = $CosU1 * $CosU2 * $SinL / sqrt($SinSQSigma);
      }
 
      if ((cos(asin($SinAlpha)) * cos(asin($SinAlpha))) == 0) {
         $Cos2SigmaM = 0;
      } else {
         $Cos2SigmaM = $CosSigma - (2 * $SinU1 * $SinU2 / (cos(asin($SinAlpha)) * cos(asin($SinAlpha))));
      }
 
      $CPARAM = ($f / 16) * cos(asin($SinAlpha)) * cos(asin($SinAlpha)) *
                (4 + $f * (4 - 3 * cos(asin($SinAlpha)) * cos(asin($SinAlpha))));
 
      $lambda = $OMEGA + (1 - $CPARAM) * $f * $SinAlpha * (acos($CosSigma) +
                $CPARAM * sin(acos($CosSigma)) * ($Cos2SigmaM + $CPARAM * $CosSigma *
                (-1 + 2 * $Cos2SigmaM * $Cos2SigmaM)));
 
   } while (abs($lambda - $LambdaPrev) >= $EPS); // Конец цикла итерации
 
   $USQR = cos(asin($SinAlpha)) * cos(asin($SinAlpha)) *
           ($a * $a - $b * $b) / ($b * $b);
   $APARAM = 1 + ($USQR / 16384) * (4096 + $USQR * (-768 + $USQR * (320 - 175 * $USQR)));
   $BPARAM = ($USQR / 1024) * (256 + $USQR * (-128 + $USQR * (74 - 47 * $USQR)));
   $DSigma = $BPARAM * sqrt($SinSQSigma) * ($Cos2SigmaM + $BPARAM / 4 *
             ($CosSigma * (-1 + 2 * $Cos2SigmaM * $Cos2SigmaM) - $BPARAM / 6 * $Cos2SigmaM *
             (-3 + 4 * $SinSQSigma) * (-3 + 4 * $Cos2SigmaM * $Cos2SigmaM)));
 
   return $b * $APARAM * ($Sigma - $DSigma);
}

к статье “Вычисление расстояния между двумя геокоординатами на PHP”

  1. Не могли бы уточнить – в каком датуме производятся вычисления? И, какие формулы (чей алгоритм) используется? Как я понял используются параметры эллипсоида Красовского? Спасибо.

Оставить комментарий