earthdistance — вычисление ортодромии (расстояния по дуге большого круга; кратчайшего расстояния между двумя точками на поверхности Земли)

Модуль earthdistance предоставляет два разных способа вычисления ортодомических (по дуге большого круга) расстояний на поверхности Земли. Первый описанный способ зависит от модуля cube. Второй основан на встроенном типе данных point, использующим в качестве координат долготу и широту.

В этом модуле Земля считается идеальной сферой. (Если для вас это недостаточно точно, обратите внимание на проект PostGIS.)

Прежде чем устанавливать earthdistance, необходимо установить модуль cube (хотя можно воспользоваться параметром CASCADE команды CREATE EXTENSION и установить сразу оба расширения).

ВНИМАНИЕ!
Настоятельно рекомендуется устанавливать модули earthdistance и cube в одну схему, и при этом в данной схеме недоверенные пользователи не должны в настоящем и будущем получить право CREATE. В противном случае, если схема модуля earthdistance будет содержать объекты, определенные злонамеренным пользователем, во время установки возникнет угроза безопасности. Более того, при использовании функций модуля earthdistance после установки расширения весь путь поиска должен содержать только доверенные схемы.


Земные расстояния по кубам

Данные хранятся в кубах, представляющих собой точки (оба угла куба совпадают) по 3 координатам, выражающим расстояния x, y и z от центра Земли. Этот модуль предоставляет домен earth на базе типа cube, включающий проверки того, что значение соответствует этим ограничениям и достаточно близко к реальной поверхности Земли.

Радиус Земли выдает функция earth(). Он выражается в метрах. Однако, изменив одну эту функцию, можно сделать так, чтобы модуль работал с какими-то другими единицами, либо использовать другое значение радиуса, которое кажется более подходящим.

Этот пакет также может применяться в астрономических базах данных. Вероятно, астрономы предпочтут изменить функцию earth(), чтобы та возвращала радиус, равный 180/pi(), и, как следствие, расстояния выдавались в градусах.

В этом модуле реализованы функции, поддерживающие ввод данных, выражающих широту и долготу (в градусах), вывод широты и долготы, вычисление ортодромического расстояния между двумя точками и простое указание ограничивающего прямоугольника, полезного для поиска по индексу.

Предоставляемые функции показаны ниже.

earth () → float8

Возвращает предполагаемый радиус Земли.

sec_to_gc ( float8 ) → float8

Преобразует расстояние по обычной прямой (секущей) между двумя точками на поверхности Земли в ортодромическое расстояние между ними.

gc_to_sec ( float8 ) → float8

Преобразует ортодромическое расстояние между двумя точками на поверхности Земли в расстояние по обычной прямой (секущей) между ними.

ll_to_earth ( float8, float8 ) → earth

Возвращает положение точки на поверхности Земли по заданным широте (аргумент 1) и долготе (аргумент 2) в градусах.

latitude ( earth ) → float8

Возвращает широту (в градусах) точки на поверхности Земли.

longitude ( earth ) → float8

Возвращает долготу (в градусах) точки на поверхности Земли.

earth_distance ( earth, earth ) → float8

Возвращает ортодромическое расстояние между двумя точками на поверхности Земли.

earth_box ( earth, float8 ) → cube

Возвращает ограничивающий прямоугольник, подходящий для поиска по индексу с применением реализованного для типа cube оператора @> для точек в пределах заданного ортодромического расстояния от цели. Некоторые точки в этом прямоугольнике будут отстоять от цели дальше, чем на заданное ортодромическое расстояние, поэтому в запрос следует включить вторую проверку с функцией earth_distance.


Земные расстояния по точкам

Вторая часть этого модуля основана на представлении точек на Земле в виде значений типа point, в которых первый компонент представляет долготу в градусах, а второй — широту в градусах. Точки воспринимаются как (долгота, широта), а не наоборот, так как долгота ближе к интуитивному представлению оси x, а широта — оси y.

Модуль предоставляет один оператор:

point <@> point → float8

Вычисляет расстояние в сухопутных милях между двумя точками на поверхности Земли.

Обратите внимание, что, в отличие от части модуля на основе cube, в этой части единицы запрограммированы жестко: изменение функции earth() не повлияет на результаты этого оператора.

Единственный недостаток представления в виде долготы/широты состоит в том, что вам придется учитывать граничные условия возле полюсов и в районе +/- 180 градусов долготы. Представление на основе cube лишено таких нарушений непрерывности.