Клуб API Карт

Функция расчета расстояния между двумя метками

Kichee
22 января 2011, 08:36

Здравствуйте. Требуется функция на PHP для расчета расстояния (в метрах) между двух меток.

Имеются координаты:

1) 30.325557,60.052094

2) 30.321651,60.055935

Пробывал пользоваться функцией, найденной на просторах интернета, но результаты не верные, подозреваю тип координат отличается

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);


}
4 комментария
Подписаться на комментарии к посту
Много кода - не осилил.
А вообще пересчет делается с помощью одной формулы.
И относительно недавно в клубе обсуждалась эта самая формула - пролистайте назад до ноября/октября.
Все гораздо проще. Держи, студент :-)

function calc_distance($lon1,$lat1,$lon2,$lat2) {
  $theta = $lon1 - $lon2;
  $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
  $dist = acos($dist);
  $dist = rad2deg($dist);
  return ceil($dist * 111000);
}
Вы меня спасли, большое спасибо :)
Такие образчики кода, как вы нашли нужно сразу в корзину :-)

http://gettingreal.37signals.com/GR_rus.php