Вычисление расстояния и начального азимута между двумя точками на сфере
Измерение расстояния и начального азимута между точками без проекционных преобразований |
Введение
Длина дуги большого круга – кратчайшее расстояние между любыми двумя точками находящимися на поверхности сферы, измеренное вдоль линии соединяющей эти две точки (такая линия носит название ортодромии) и проходящей по поверхности сферы или другой поверхности вращения. Сферическая геометрия отличается от обычной Эвклидовой и уравнения расстояния также принимают другую форму. В Эвклидовой геометрии, кратчайшее расстояние между двумя точками – прямая линия. На сфере, прямых линий не бывает. Эти линии на сфере являются частью больших кругов – окружностей, центры которых совпадают с центром сферы.
Начальный азимут - азимут, взяв который при начале движения из точки А, следуя по большому кругу на кратчайшее расстояние до точки B, конечной точкой будет точка B. При движении из точки A в точку B по линии большого круга азимут из текущего положения на конечную точку B постоянно меняется. Начальный азимут отличен от постоянного, следуя которому, азимут из текущей точки на конечную не меняется, но маршрут следования не является кратчайшим расстоянием между двумя точками.

Через любые две точки на поверхности сферы, если они не прямо противоположны друг другу (то есть не являются антиподами), можно провести уникальный большой круг. Две точки, разделяют большой круг на две дуги. Длина короткой дуги – кратчайшее расстояние между двумя точками. Между двумя точками-антиподами можно провести бесконечное количество больших кругов, но расстояние между ними будет одинаково на любом круге и равно половине окружности круга, или pi*R, где R – радиус сферы.

На плоскости (в прямоугольной системе координат), большие круги и их фрагменты, как было упомянуто выше, представляют собой дуги во всех проекциях, кроме гномонической, где большие круги - прямые линии. На практике это означает, что самолеты и другой авиатранспорт всегда использует маршрут минимального расстояния между точками для экономии топлива, то есть полет осуществляется по расстоянию большого круга, на плоскости это выглядит как дуга.
Форма Земли может быть описана как сфера, поэтому уравнения для вычисления расстояний на большом круге важны для вычисления кратчайшего расстояния между точками на поверхности Земли и часто используются в навигации.
Вычисление расстояния этим методом более эффективно и во многих случаях более точно, чем вычисление его для спроектированных координат (в прямоугольных системах координат), поскольку, во-первых, для этого не надо переводить географические координаты в прямоугольную систему координат (осуществлять проекционные преобразования) и, во-вторых, многие проекции, если неправильно выбраны, могу привести к значительным искажениям длин в силу особенностей проекционных искажений.
Известно, что более точно описывает форму Земли не сфера, а эллипсоид, однако в данной статье рассматривается вычисление расстояний именно на сфере, для вычислений используется сфера радиусом 6372795 метров, что может привести к ошибке вычисления расстояний порядка 0.5%.
Формулы
Существует три способа расчета сферического расстояния большого круга.
Сферическая теорема косинусов
В случае маленьких расстояний и небольшой разрядности вычисления (количество знаков после запятой), использование формулы может приводить к значительным ошибкам связанным с округлением.
- широта и долгота двух точек в радианах
- разница координат по долготе
- угловая разница

Для перевода углового расстояния в метрическое, нужно угловую разницу умножить на радиус Земли (6372795 метров), единицы конечного расстояния будут равны единицам, в которых выражен радиус (в данном случае - метры).
Формула гаверсинусов используется, чтобы избежать проблем с небольшими расстояниями.

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

Скачать пример расчета расстояния большого круга и начального азимута в Excel.
На языке Avenue, используя последнюю формулу для вычисления расстояния большого круга между двумя точками, можно использовать следующий код (точки для вычисления передаются другим скриптом, либо добавляются в начало данного в виде pnt = point.make(long, lat)) (скачать скрипт):
'pnt1, pnt2 - точки между которыми вычисляются расстояния
'pi - число pi, rad - радиус сферы (Земли), num - количество
знаков после запятой
pi = 3.14159265358979
rad = 6372795 num = 7
'получение координат точек в радианах
lat1 = pnt1.getY*pi/180
lat2 = pnt2.getY*pi/180
long1 = pnt1.getX*pi/180
long2 = pnt2.getX*pi/180
'косинусы и синусы широт и разниц долгот
cl1 = lat1.cos
cl2 = lat2.cos
sl1 = lat1.sin
sl2 = lat2.sin
delta = long2 - long1
cdelta = delta.cos
sdelta = delta.sin
'вычисления длины большого круга
p1 = (cl2*sdelta)^2
p2 = ((cl1*sl2) - (sl1*cl2*cdelta))^2
p3 = (p1 + p2)^0.5
p4 = sl1*sl2
p5 = cl1*cl2*cdelta
p6 = p4 + p5
p7 = p3/p6
anglerad = (p7.atan).SetFormatPrecision (num) dist = anglerad*rad
'вычисление начального азимута x = (cl1*sl2) - (sl1*cl2*cdelta) y = sdelta*cl2 z = (-y/x).ATan.AsDegrees if (x < 0) then z = z+180 end z = -(z + 180 mod 360 - 180).AsRadians anglerad2 = z - ((2*pi)*((z/(2*pi)).floor))
angledeg = (anglerad2*180)/pi
'возврат значений длины большого круга и начального азимута distlist = {dist, angledeg} return distlist
|
Для вызова процедуры расчета длин приведенной выше, можно также воспользоваться следующим скриптом, результатом его работы будет расчет длин между точкой testpont до всех точек активной темы вида и запись результата в поле Newdist атрибутивной таблицы этой темы:
atheme = av.getactivedoc.getactivethemes.get(0)
aftab = atheme.getftab
f_shape = aftab.findfield("Shape")
f_dist = aftab.findfield("dist") f_ang = aftab.findfield("ang")
'testpoint - точка отсчета
testpoint = point.make(25.85, 55.15)
aftab.seteditable(true)
'для каждой точки темы до которых считают расстояния от точки отсчета
for each rec in aftab
pnts = {}
apoint = aftab.returnvalue(f_shape, rec)
pnts.add(apoint.getx)
pnts.add(testpoint.getx)
pnts.add(apoint.gety)
pnts.add(testpoint.gety)
'Вызов процедуры расчета расстояний
'"Calc-distance" - название скрипта с процедурой в проекте
param = av.run("Calc-distance", pnts)
aftab.setvalue(f_dist, rec, param.get(0))
aftab.setvalue(f_ang, rec, param.get(1))
end
aftab.seteditable(false)
|
Обсудить в форуме (Комментариев - 2)
См. также:
Вычисление азимута из одной точки на другую и угла образованного тремя точками на сфере >>>
Вычисление постоянного азимута и длины линии румба между двумя точками для геодезических координат >>>
Сравнение разных способов вычисления длин и азимутов >>>
Great-circle distance. Wikipedia >>> |
Последнее обновление: February 25 2008 (Наверх) |