Как рассчитать азимут между двумя точками в PostGIS?

У меня есть ГИС API на основе OpenLayers. Я пытался реализовать вычисление азимута в JavaScript, и мне нужно было каким-то образом рассчитать азимут для выполнения тестов.

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

-- Example 1 - Result 90

SELECT ST_Azimuth(
   ST_Transform(st_geomfromtext('POINT(-81328.998084106 7474929.8690234)', 900913), 4326),
   ST_Transform(st_geomfromtext('POINT(4125765.0381464 7474929.8690234)', 900913), 4326)
)/pi()*180

-- Example 2 - Result 155.692090425822
SELECT degrees(
   ST_Azimuth(
   ST_MakePoint(-81328.998084106, 7474929.8690234)::geography,
   ST_MakePoint(4125765.0381464, 7474929.8690234)::geography)
)

-- Example 3 - Result 90

SELECT degrees(
   ST_Azimuth(
   ST_MakePoint(-81328.998084106, 7474929.8690234),
   ST_MakePoint(4125765.0381464, 7474929.8690234))
)

Как правильно рассчитать азимут в PostGIS? Конечно, я хочу рассмотреть геодезические координаты.

Есть ли способ узнать, как PostGIS выполняет расчеты? Я имею в виду, можно ли увидеть способ реализации функции "ST_Azimuth"?

1 ответ

Решение

Чтобы ответить на ваш второй вопрос в первую очередь, есть в основном два типа вычисления азимута: те, которые выполняются на плоских координатах, и те, которые выполняются на сфере или сфероиде, как в случае с типом данных географии. В азимутальной статье Википедии это хорошо объясняется.

В первом случае расчет предельно прост, будучи по сути просто atan между двумя парами точек. Вы можете увидеть исходный код на github в методе azimuth_pt_pt,

Во втором случае вычисления немного сложнее, они находятся на сфере, и вы можете снова найти фактический расчет на github в методе. spheroid_direction,

Причина 2 в том, что вы используете тип данных geography, который должен находиться в диапазоне [-180,180],[-90,90]. На самом деле, я удивлен, что это не дает ошибку.

Примеры 1 и 3 практически одинаковы, так как вы просто переключились с одной системы координат на другую, поэтому относительное направление точек не изменилось.

Нет правильного способа сделать это, но если вы хотите использовать geodetic coordinates затем используйте geography datatype,

Обратите внимание, что есть разница между:

select degrees(
   st_azimuth(
       st_makepoint(0, 0)::geography, 
       st_makepoint(45, 45)::geography)
);

что дает 35,4100589051161

в то время как,

select degrees(
    st_azimuth(
       st_setsrid(st_makepoint(0, 0),4326),
       st_setsrid(st_makepoint(45, 45),4326))
);

дает 45. Один выполняет указание азимута на плоскости, в то время как другой выполняет азимут сфероида, как следует из названий их функций.

Другие вопросы по тегам