Формулы для расчета географической близости

Мне нужно реализовать поиск близости Geo в моем приложении, но я очень запутался в правильной формуле для использования. После некоторых поисков в Интернете и в StackOverflow я обнаружил, что решения следующие:

  1. Используйте формулу гаверсина
  2. Используйте Формулу расстояния большого круга
  3. Используйте систему пространственного поиска в базе данных

Вариант №3 действительно не вариант для меня банкомат. Я немного сбит с толку, поскольку всегда думал, что Формула расстояния по Большому кругу и формула Хаверсина были синонимами, но, видимо, я ошибался?

Формула Хаверсина

Приведенный выше снимок экрана был взят из великолепного географического (близкого) поиска с помощью MySQL paper и использует следующие функции:

ASIN, SQRT, POWER, SIN, PI, COS

Я также видел варианты от той же формулы (Сферический закон косинусов), например этот:

(3956 * ACOS(COS(RADIANS(o_lat)) * COS(RADIANS(d_lat)) * COS(RADIANS(d_lon) - RADIANS(o_lon)) + SIN(RADIANS(o_lat)) * SIN(RADIANS(d_lat))))

Это использует следующие функции:

ACOS, COS, RADIANS, SIN

Я не математик, но одинаковы ли эти формулы? Я встречал еще несколько вариантов и формул (например, Сферический закон косинусов и формулы Винсенти точнее всего) и это меня еще больше сбивает с толку ...

Мне нужно выбрать хорошую формулу общего назначения для реализации в PHP / MySQL. Может ли кто-нибудь объяснить мне различия между формулами, которые я упомянул выше?

  • Какой из них вычисляется быстрее всего?
  • Какой из них обеспечивает наиболее точные результаты?
  • Какой из них лучший с точки зрения скорости / точности результатов?

Я ценю ваше понимание этих вопросов.


Основываясь на ответе theonlytheory, я протестировал следующие формулы расстояния большого круга:

  • Формула Винсенти
  • Формула гаверсина
  • Сферический закон косинусов

Формула Винсенти очень медленная, но довольно точная (до 0,5 мм).

Формула Хаверсина намного быстрее, чем формула Винсенти, я смог выполнить 1 миллион вычислений примерно за 6 секунд, что вполне приемлемо для моих нужд.

Формула сферического закона косинусов оказалась почти в два раза быстрее, чем формула Хаверсинуса, а разница в точности заключается в пренебрежении для большинства случаев использования.


Вот несколько тестовых мест:

  • Штаб-квартира Google (37.422045, -122.084347)
  • Сан-Франциско, Калифорния (37.77493, -122.419416)
  • Эйфелева башня, Франция (48.8582, 2.294407)
  • Оперный театр, Сидней (-33.856553, 151.214696)

Штаб-квартира Google - Сан-Франциско, Калифорния:

  • Формула Винсенти: 49 087.066 meters
  • Формула Хаверсина: 49 103.006 meters
  • Сферический закон косинусов: 49 103.006 meters

Штаб-квартира Google - Эйфелева башня, Франция:

  • Формула Винсенти: 8 989 724.399 meters
  • Формула Хаверсина: 8 967 042.917 meters
  • Сферический закон косинусов: 8 967 042.917 meters

Штаб-квартира Google - Оперный театр, Сидней:

  • Формула Винсенти: 11 939 773.640 meters
  • Формула Хаверсина: 11 952 717.240 meters
  • Сферический закон косинусов: 11 952 717.240 meters

Как видите, нет заметной разницы между формулой Хаверсинуса и сферическим законом косинусов, однако оба имеют смещение расстояния до 22 километров по сравнению с формулой Винсенти, потому что он использует эллипсоидальное приближение Земли вместо сферического.


person Alix Axel    schedule 19.01.2010    source источник
comment
У меня была похожая проблема давно, в проекте, который я никогда не начинал ... в своих заметках я нашел эту формулу: AB=sqrt(pow(($Xb-$Xa),2)+pow(($Yb-$Ya),2)));, я никогда не понимал, что именно он делает ... надеюсь, может вам помочь;)   -  person Strae    schedule 20.01.2010
comment
@DaNieL: Проверьте ответ theonlytheory, он объясняет, когда следует использовать указанную вами формулу. знак равно   -  person Alix Axel    schedule 20.01.2010
comment
FWIW: для тех, кого смущает 3956, то есть радиус Земли в милях, однако, согласно Википедии, это должно быть приблизительно 3959 en.wikipedia.org/wiki/Earth_radius, если вы хотите работать с расстояниями в км, которые вместо этого будут 6371. Я не уверен, повлияет ли это на ваш ответ @Alix, но в зависимости от того, какой # вы использовали, ваши единицы могут быть выключены и вместо этого должны быть в милях.   -  person Chris Marisic    schedule 29.10.2010
comment
Если ваш «диапазон поиска» достаточно мал (<500 км), вы можете просто использовать Pythagoras для упорядочивания результатов. Расстояния не будут точными (мир не плоский, и это очень плохо), но порядок расстояний будет.   -  person Rudie    schedule 16.05.2011
comment
Кстати: orig.lat - dest.lat не ошибается с координатами [-180, 180]? Что будет, если orig.lat = -170 и dest.lat = 170? Дистанция 340 град? Нет, на самом деле их всего 20. Как решить эту проблему, если вы работаете с реальными координатами Земли (атласом)?   -  person Rudie    schedule 16.05.2011
comment
pow(lat-lat2, 2) + pow(1/cos(radians(lat)) * min(abs(lon-lon2), 360-abs(lon-lon2)), 2) = ›distance_squared   -  person Cees Timmerman    schedule 05.04.2012
comment
Было бы здорово, если бы кто-нибудь мог добавить результаты к этой формуле Вопроса о Плоской Земле! Также добавление дополнительного набора данных (близкого к существующему набору данных на расстоянии ~ 1 км) поможет оценить точность на небольших расстояниях. Я бы сделал это сам, но мое понимание трех формул не так хорошо, поэтому я здесь: D   -  person Jethro    schedule 27.12.2015


Ответы (2)


Закон косинусов и формула Хаверсинуса дадут идентичные результаты, если предположить, что машина обладает бесконечной точностью. Формула Хаверсина более устойчива к ошибкам с плавающей запятой. Однако современные машины имеют двойную точность порядка 15 значащих цифр, и закон косинусов может отлично работать для вас. Обе эти формулы предполагают сферическую Землю, тогда как итерационное решение Викенти (наиболее точное) предполагает эллипсоидальную Землю (на самом деле Земля даже не эллипсоид - это геоид). Некоторые ссылки: http://www.movable-type.co.uk/scripts/gis-faq-5.1.html

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

Какой из них вычислить быстрее всего?

В порядке от самого быстрого к самому медленному: закон косинусов (5 тригг. Вызовов) -> гаверсинус (включает sqrt) -> Vicenty (необходимо решать итеративно в цикле for)

Какой из них самый точный?

Vicenty.

Какой из них лучше, если учитывать скорость и точность?

Если ваша проблемная область такова, что для расстояний, которые вы пытаетесь рассчитать, Земля может считаться плоской, тогда вы можете разработать (я не буду приводить подробности) формулу вида x = kx * разница в долготе , y = ky * разница в широте. Тогда расстояние = sqrt (dx dx + dy dy). Если ваша проблемная область такова, что ее можно решить с помощью квадрата расстояния, вам не придется использовать sqrt, и эта формула будет максимально быстрой. Дополнительное преимущество заключается в том, что вы можете рассчитать расстояние vector: x - это расстояние в восточном направлении, а y - это расстояние в северном направлении. В противном случае поэкспериментируйте с 3 и выберите то, что лучше всего работает в вашей ситуации.

person morpheus    schedule 19.01.2010
comment
+1, очень хороший ответ, спасибо. Однако у меня все еще есть сомнения. Я думал, что существует только один вид широты, что отличает геоцентрическую широту от геодезической широты? И какую свободу действий предоставляет Google в API Карт Google? Что вы имеете в виду, говоря о формуле, которую предоставили вы и ДаНИЛ, когда считали Землю плоской? Вернет ли эта формула точные результаты, если я, например, захочу узнать расстояние между Нью-Йорком и Сиднеем? - person Alix Axel; 20.01.2010
comment
Я не знаю, какую широту Google предоставляет в Google Maps API, но предполагаю, что это будет геодезическая широта. Если расстояние порядка нескольких километров, то в таком масштабе Земля выглядит плоской, не так ли? Для Нью-Йорка - ›Сидней следует использовать закон косинусов. - person morpheus; 20.01.2010
comment
@theonlytheory: Еще раз спасибо, у меня есть последний вопрос: вы ничего не сказали о формуле расстояния большого круга ... Не могли бы вы рассказать немного о том, чем эта формула отличается от всех остальных? - person Alix Axel; 20.01.2010
comment
Не существует уникальной Формулы Великого Круга. Формулы, описанные выше, являются формулами для расчета расстояния по большому кругу. Можно сказать, что все они - формулы Великого круга. - person morpheus; 20.01.2010
comment
По слухам, Google Maps API предоставляет широту и долготу WGS84, что, я думаю, делает его геодезическим? - person MarkJ; 21.01.2010
comment
Да, широта WGS84 = геодезическая широта - person morpheus; 21.01.2010

Итак, вы хотите:

  • сортировать записи по расстоянию от p0
  • выбрать только записи, расстояние от которых до p0 меньше r

Хитрость в том, что для этого не нужно точно вычислять расстояние по большому кругу! Вы можете использовать любую функцию от пары точек до реального значения , которое строго растет с увеличением расстояния между точками по большому кругу. Таких функций много, и некоторые из них вычисляются намного быстрее, чем различные формулы для определения точного расстояния по большой окружности. Одна из таких функций - евклидово расстояние в 3D. Преобразование широты и долготы в трехмерную точку на сфере не требует обратных тригонометрических функций.

Когда у вас есть x, Y, Z, вы можете понять, что вам на самом деле не нужно расстояние от p0 до вашей точки, потому что вы также можете использовать расстояние от касательной плоскости в p0. Это расстояние также строго растет с увеличением расстояния по большому кругу и вычисляется из X, Y, Z как линейной комбинации - даже квадратный корень не требуется. Вам просто нужно предварительно вычислить коэффициенты и расстояние отсечки, которое соответствует желаемому расстоянию по большой окружности.

person BASTA    schedule 29.03.2012
comment
это невероятно хорошая идея. Обычно я не отправляю сообщения с хорошими идеями, но это круто! Предварительно вычислите расстояния для ваших показателей в таблице поиска - и вперед! Действительно, очень хороший совет. - person Eric Cope; 02.10.2012
comment
Есть ли место для дальнейшего чтения? - person Tural Asgar; 18.03.2021