Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Узнать расстояние между координатами на карте


Автор: Cache 12.3.2010, 15:09
Здравствуйте!
Делаю проект на PHP и api яндекс карт
Можно ли в PHP вычислить расстояние (например в метрах) между двумя точками на карте
точки для примера:
37.63 55.75 и 37.61 55.75
между ними чуть больше 1 км.

Автор: ksnk 12.3.2010, 17:06
А какие проблемы? Немного тригонометрии, гугла и магии ;) Радиус земли можно поискать в Гугле, остальное - в учебнике тригонометрии, магия - для демонстрации результата...

Автор: skyboy 12.3.2010, 17:46
Cache, а в АПИ нет никакого метода?
можно и посчитать, но для эллипсоида это сложнее, чем для шара. кроме того, что Земля - не идеальный эллипсоид.

Автор: solenko 12.3.2010, 17:56
Цитата(ksnk @  12.3.2010,  16:06 Найти цитируемый пост)
Немного тригонометрии

Ну не тригонометрии, а сферический геометрии...
Но гугл, естественно, http://www.google.com.ua/search?rlz=1C1GGLS_ukUA359UA359&aq=f&sourceid=chrome&ie=UTF-8&q=расстояние+между+двумя+точками+земной+поверхности

Автор: Cache 12.3.2010, 18:30
skyboy, в API есть функция только для JS
расстояния, между которыми нужно будет искать длину пути, у меня совсем небольшие - около 100км., что по земным меркам не особо внушительно) поэтому и сфера должна подойти
сейчас попробую написать скрипт, после - выложу исходник

Автор: Cache 12.3.2010, 18:56
мм, вот например:

S = 111,2×arccos(sin φ1 × sin φ2 + cos φ1 × cos φ2 × cos (L2-L1)),
где S - расстояние, км;
φ1 и L1 - широта и долгота точки 1 (для северной широты и восточной долготы со знаком плюс, для южной широты и западной долготы со знаком минус), градусы;
φ2 и L2 - широта и долгота точки 2, градусы;
константа 111,2 - средняя длина дуги в один градус на поверхности Земли, км.

http://mk.semico.ru/dr_info19.htm

тогда все просто:
Код

function echoDistance($s1,$d1,$s2,$d2){
    return 111.2 * acos(sin($s1)*sin($s2) + cos($s1) * cos($s2) * cos($d2-$d1));
}
echo round(echoDistance(55.771033,37.64309,55.78245,37.669182),2)."km";

выдает - 2.44km
но яндекс по тем же координатам выдает - 2.09 км.
из-за чего такая погрешность? действительно из-за формы планеты?

*UPDATE*
попробовал еще 2 раза с другими координатами - погрешность стала гораздо ниже - на 25км - 200м
в принципе меня такая ситуация устраивает, но если возможно что-то точнее - буду рад если поделитесь)

всем спасибо!

Автор: wOOx 12.3.2010, 19:07
ну я бы вообще считал для плоскости
мне кажется, холмистость местности может повлиять на точность результата сильнее, чем форма планеты smile

Автор: solenko 12.3.2010, 19:08
Погрешность вызвана тем, что в одном градусе очень разное количество километров в зависимости от широты.
Сравните, сколько километов между меридианами на экваторе и на полюсе )

Добавлено через 3 минуты и 40 секунд
Цитата(wOOx @  12.3.2010,  18:07 Найти цитируемый пост)
ну я бы вообще считал для плоскости

ну, приведенный код и считает для плоскости

Автор: ksnk 13.3.2010, 12:01
Цитата(Cache @  12.3.2010,  18:56 Найти цитируемый пост)
 acos(sin($s1)*sin($s2) + cos($s1) * cos($s2) * cos($d2-$d1));...
echoDistance(55.771033,...

Мой экспириенс в тригонометрии невысок, однако меня смушает в этой формуле отсутствие магического числа Pi и тот факт, что синус - периодическая функция с периодом 2*Pi...

Если вообразить себе гео-сферическую систему координат, вообразить себе , что земля нифига не геоид, а идеальная сфера, считать, что точки, между которыми нужно мерить расстояние расположены близко друг к другу, помянуть незлым тихим словом Евклида и наплевать на сферическую геометрию, порисовать все это добро на бумажке, немного бумажку почирикать, то вполне вероятно, получится что-то такое:
длина минуты (1 градус) широты = 2*Pi*R/360, где Pi и в Африке Pi, а R - радиус Земли. Длина же минуты долготы будет примерно такой = 2*Pi*R*cos(M_PI*$s1/180)/360, где $s1 - одна из "широт" (они расположены близко!).
Итого, формула вычисления расстояния по координатам, после не очень сложных сокращений, будет примерно такой.
Код

function echoDistance($s1,$d1,$s2,$d2){
    return 111.2 *sqrt(pow(($s1-$s2),2)+pow(($d1-$d2)*cos(M_PI*$s1/180),2));
};
echo round(echoDistance(55.771033,37.64309,55.78245,37.669182),2)."km";

Что дает нам 2.07км для заявленных координат. Примерно похоже на то, что дает нам гугл в неисповедимой мудрости его...


Автор: ReDComraD 7.6.2010, 08:28
ksnk - Спасибо Тебе большое, действительно формула Твоя дает очень точный результат и не надо API гугла загружать для высчита расстояния.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)