Определение расстояния между точками по их координатам (PHP & MySQL)

Для задач, связанных с геопозиционированием может потребоваться определение расстояния между точками по их координатам.

Подробное описание решения данной задачи с реализацией на Python и Excel представлено на этом сайте.

Ниже представлена моя реализация той же задачи в виде хранимой процедуры MySQL и функции PHP.

Определение расстояния между точками в метрах с помощью MySQL:

CREATE FUNCTION dist(lat1 float, lon1 float, lat2 float, lon2 float) RETURNS float
  BEGIN

  declare d_lon float;
  declare x float;
  declare y float;

  set lat1 = lat1 * pi() / 180;
  set lon1 = lon1 * pi() / 180;
  set lat2 = lat2 * pi() / 180;
  set lon2 = lon2 * pi() / 180;

  set d_lon = lon1 - lon2;

  set y = POWER(COS(lat2) * SIN(d_lon), 2) + POWER(COS(lat1) * SIN(lat2) - SIN(lat1) * COS(lat2) * COS(d_lon), 2);
  set x = SIN(lat1) * SIN(lat2) + COS(lat1) * COS(lat2) * COS(d_lon);

  RETURN ATAN2(SQRT(y), x) * 6372795;
END;

Пример использования:


SELECT dist(59.927071, 30.320438, 59.848480, 30.457394); -- 11610.8427734375


Определение расстояния между точками в метрах на PHP:

<?php

// Расстояние в метрах между двумя точками
public static function getDistance($lat1, $lon1, $lat2, $lon2) {
  $lat1 *= M_PI / 180;
  $lat2 *= M_PI / 180;
  $lon1 *= M_PI / 180;
  $lon2 *= M_PI / 180;
  
  $d_lon = $lon1 - $lon2;
  
  $slat1 = sin($lat1);
  $slat2 = sin($lat2);
  $clat1 = cos($lat1);
  $clat2 = cos($lat2);
  $sdelt = sin($d_lon);
  $cdelt = cos($d_lon);
  
  $y = pow($clat2 * $sdelt, 2) + pow($clat1 * $slat2 - $slat1 * $clat2 * $cdelt, 2);
  $x = $slat1 * $slat2 + $clat1 * $clat2 * $cdelt;
  
  return atan2(sqrt($y), $x) * 6372795;
}

Comments

  • Отличное решение!

    Alex24.09.2013
  • Спасибо!

    Sprut16.11.2013
  • У кого падает ошибка #1064 пишем так
    delimiter //
    CREATE FUNCTION dist(lat1 float, lon1 float, lat2 float, lon2 float) RETURNS float
    BEGIN

    declare d_lon float;
    declare x float;
    declare y float;

    set lat1 = lat1 * pi() / 180;
    set lon1 = lon1 * pi() / 180;
    set lat2 = lat2 * pi() / 180;
    set lon2 = lon2 * pi() / 180;

    set d_lon = lon1 — lon2;

    set y = POWER(COS(lat2) * SIN(d_lon), 2) + POWER(COS(lat1) * SIN(lat2) — SIN(lat1) * COS(lat2) * COS(d_lon), 2);
    set x = SIN(lat1) * SIN(lat2) + COS(lat1) * COS(lat2) * COS(d_lon);

    RETURN ATAN2(SQRT(y), x) * 6372795;
    END;//
    delimiter ;

    Sprut16.11.2013
  • Спасибо!

    Василий26.11.2016
  • Спасибо!

    Дмитрий19.01.2017

Добавить комментарий для Дмитрий Отменить ответ