Расчет расстояний между городами по их координатам

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

Введение

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

Начальный азимут — азимут, взяв который при начале движения из точки А, следуя по большому кругу на кратчайшее расстояние до точки B, конечной точкой будет точка B. При движении из точки A в точку B по линии большого круга азимут из текущего положения на конечную точку B постоянно меняется. Начальный азимут отличен от постоянного, следуя которому, азимут из текущей точки на конечную не меняется, но маршрут следования не является кратчайшим расстоянием между двумя точками.

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

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

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

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

Известно, что более точно описывает форму Земли не сфера, а эллипсоид, однако в данной статье рассматривается вычисление расстояний именно на сфере, для вычислений используется сфера радиусом 6372795 метров, что может привести к ошибке вычисления расстояний порядка 0.5%.

Формулы

Существует три способа расчета сферического расстояния большого круга.

1. Сферическая теорема косинусов

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

φ1, λ1; φ2, λ2 — широта и долгота двух точек в радианах

Δλ — разница координат по долготе

Δδ — угловая разница

Δδ = arccos {sin φ1 sin φ2 + cos φ1 cos φ2 cos Δλ}

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

2. Формула гаверсинусов

Используется, чтобы избежать проблем с небольшими расстояниями.

3. Модификация для антиподов

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

Моя реализация на РНР


<?php

// Радиус земли
define('EARTH_RADIUS', 6372795);

/*
 * Расстояние между двумя точками
 * $φA, $λA - широта, долгота 1-й точки,
 * $φB, $λB - широта, долгота 2-й точки
 * Написано по мотивам http://gis-lab.info/qa/great-circles.html
 * Михаил Кобзарев <kobzarev@inforos.ru>
 *
 */
function calculateTheDistance ($φA, $λA, $φB, $λB) {

    // перевести координаты в радианы
    $lat1 = $φA * M_PI / 180;
    $lat2 = $φB * M_PI / 180;
    $long1 = $λA * M_PI / 180;
    $long2 = $λB * M_PI / 180;

    // косинусы и синусы широт и разницы долгот
    $cl1 = cos($lat1);
    $cl2 = cos($lat2);
    $sl1 = sin($lat1);
    $sl2 = sin($lat2);
    $delta = $long2 - $long1;
    $cdelta = cos($delta);
    $sdelta = sin($delta);

    // вычисления длины большого круга
    $y = sqrt(pow($cl2 * $sdelta, 2) + pow($cl1 * $sl2 - $sl1 * $cl2 * $cdelta, 2));
    $x = $sl1 * $sl2 + $cl1 * $cl2 * $cdelta;

    //
    $ad = atan2($y, $x);
    $dist = $ad * EARTH_RADIUS;

    return $dist;
}
?>

Пример вызова функции:


<?php
$lat1 = 77.1539;
$long1 = -139.398;
$lat2 = -77.1804;
$long2 = -139.55;

echo calculateTheDistance($lat1, $long1, $lat2, $long2) . " метров";
// Вернет "17166029 метров"
?>

Статья взята с сайта gis-lab.info Автор: Максим Дубинин

Ссылки

Для вставки кода используйте HTML-теги
<pre><code class="php">ваш код</code></pre>

  • Александр Аваков

    Спасибо за метод

    • Всегда пожалуйста!

  • Добрый день!
    Спасибо — очень пригодилось!
    Может вы сможете помочь мне с еще одной проблемой (которую я давно не могу решить, обгуглил уже все вдоль и поперек)
    Задача следующая: необходимо получить координаты вершин многоугольника имя координаты (lat,lng) центра и радиус (в км или м — не важно)
    Натолкните на мысль….

    • Может квадрата, раз радиус есть? Получается надо найти вершины квадрата, в который вписана окружность с известным радиусом и центром?

  • Большое спасибо, за подбор формул, очень помогли!

  • egor

    syntax error, unexpected ‘$’, expecting ‘&’ or variable

  • А тут долгота с широтой не перепутаны случайно? А то у меня с гуглом совпало, только после того, как поменял их местами.

  • Micael

    помогите как можно расчитать расстояние между несколькими точками есть масив данных выводится через WHILE в PHP, грубо говоря есть х точек (трек) нужно расчитать его длину.

  • BlackTomCat

    Существует Vincenty формула, которая позволяет со значительной точностью рассчитываеть расстояние между пунками на Земле. Формула базируется на представлении Земли в виде эллипсоида. Причем можно использовать варианты WGS-84, на котором базируется современная геодезия, либо альтернативы. Для WGS-84 a=6378137m, b=6356752.314245m. Саму формулу легко найти на страницах. Точность около 0.115 mm

  • спасибо, кому надо адаптировал для javascript

    [javascript]
    function calculateDistance(latA, longA, latB, longB) {
    var EARTH_RADIUS = 6372795;

    lat1 = latA * Math.PI / 180;
    lat2 = latB * Math.PI / 180;
    long1 = longA * Math.PI / 180;
    long2 = longB * Math.PI / 180;

    cl1 = Math.cos(lat1);
    cl2 = Math.cos(lat2);
    sl1 = Math.sin(lat1);
    sl2 = Math.sin(lat2);
    delta = long2 — long1;
    cdelta = Math.cos(delta);
    sdelta = Math.sin(delta);

    y = Math.sqrt(Math.pow(cl2 * sdelta, 2) + Math.pow(cl1 * sl2 — sl1 * cl2 * cdelta, 2));
    x = sl1 * sl2 + cl1 * cl2 * cdelta;

    ad = Math.atan2(y, x);
    dist = Math.ceil(ad * EARTH_RADIUS);

    return dist;
    }
    [/javascript]

  • Добрый день! Дополните статью примером вызова Вашей функции. Как правильно передать в функцию координаты точек? Спасибо!

    • Дополнил статью примером вызова функции расчета расстояния.

  • Ян

    У меня проблема. Я считал аналогичным способом опираясь на координаты с карт гугл. Потом пересчитал по Вашим формулам. Результат один и тот же. Но он не совпадает в полтора раза с данными померяными линейкой в том же гугл earth.
    как получить результат приближенный к картам?

    • Кривизну учитывали?

      • Jluc

        А как её нужно учесть?
        Просьба привести примеры методов дающих хорошую точность вычислений.

  • А дистанция в каких единицах выражается???

    • > единицы конечного расстояния будут равны единицам,
      > в которых выражен радиус
      > (в данном случае – метры).

      • Павел

        Да нет, в метрах

        • Спасибо, уже исправил. (Сам провожу вычисления в километрах)

  • Легко разобраться в большом разнообразии гис, если знать цели применения

  • суперский

  • Максим, приношу извинения. Пометил ваше авторство более заметным способом. Спасибо за понимание.

  • Мы не против когда используют материалы нашего сайта, но их использование должно сопровождаться _четким_ указанием источника.

    Согласитесь, взять 1 в 1 авторский текст и иллюстрации и дать источник в разделе ссылки среди других никак не определяет кто же написал этот текст и создал эти иллюстрации.

    Надеюсь на понимание и исправление этого мелкого недоразумения. Автор статьи.