Формулы для вычисления геопространственности

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

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

Вариант № 3 действительно не вариант для меня ATM. Теперь я немного смущен, так как всегда, хотя Формула расстояний на большие расстояния и Формула Хаверсина были синонимами, но, видимо, я был неправ?

Формула Хаверсина http://img.ruphp.com/php/30shbn6.png

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

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 ответа, я протестировал следующие Формулы расстояния по Большому кругу:

  • Формула Vincenty
  • Формула Хаверсина
  • Сферический закон косинусов

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

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

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


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

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

Google HQ – Сан-Франциско, Калифорния:

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

Google HQ – Эйфелева башня, Франция:

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

Google HQ – Оперный театр, Сидней:

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

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

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

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

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

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

Какой из них наиболее точным?

Vicenty.

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

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

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

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

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

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