Клуб API Карт

Расстояние между точками. Слишком просто?

Пост в архиве.

Здравствуйте. Есть проблема.

1. Имеется база данных. В ней лежат координаты вершин полилинии (изображает автобусный маршрут).

2. Имеется приложение на C#, считывающее координаты, превращающее их в 2 числа типа double.

Мне требуется узнать расстояние в метрах, между двумя точками, координаты которых выражены в яндексовских decimal degrees (DD).

В Я.Картах есть метод distance, в С# его нету, но ведь это дело 2-х минут, НО алгоритм мне не известен...

В педивикии пишут, в параграфе Accuracy, что 4, 5, 6 знаков после запятой это где-то 11.1, 1.11, 0.111 метров соответственно.

Я на Я.Картах отметил расстояние линейкой в 993 метра (примерно 1 км), и по краям щелкнул и получил координаты точек, затем, дедовским способом, с помощью калькулятора и формулы расстояния между двумя точками вычислил оное в DD.   

Первая точка: 92.864533,56.025027, вторая точка: 92.880562,56.025543
Расстояние:   0,01603730329575393420357557636428 == 993 m
Округляем до 6 знаков после запятой: 0,016037
Значит исходя из Педивикии:
0.01 =        1110 м
0.006 =       666 м
0.0000 =     0 м
0.00003 =   3.33 м
0.000007 = 0.777 м
В итоге мои 993 метра получились равными 1780,107 метров!
Расчеты:
sqrt( sqr(92.864533 - 92.880562) + sqr(56.025027 - 56.025543) )
sqrt( sqr(0,016029) + sqr(0,000516) )
sqrt( 0,000256928841 + 0,000000266256 )
sqrt( 0,000257195097 )

получается, что из-за того, что Красноярск довольно далеко от экватора, погрешность составляет почти 100%.

Так вот, собственно, какой помощи я жду от клуба. Есть у кого исходник метода distance? Шучу.

Не знает ли кто-нибудь алгоритм расчета расстояния между точками в Я.Картах?

9 комментариев

Okay... Попробую, отпишусь, или выкину алгоритм на С подобном коде.

Я воспользовался ссылкой, ввел те же коордитаны, что считал в блокноте...

Ответ: 1790,34.

Я действительно ошибся на 10 метров! =(

Не помогает ссылка.

Михаил Королев
28 января 2016, 06:08

по этой формуле у меня между

Первая точка: 92.864533,56.025027, вторая точка: 92.880562,56.025543
получилось 1001.10615322804
очевидно вы перепутали широту и долготу

 

Fuck yeah! Я их перепутал. =)

 

В NMEA, в гугле, в яндексе, десятичные, обычные - я уже запутался что первое, что второе идет. =(
Вот код на C#. (врезки нет при комментировании =/ )

 

       // Возвращает расстояние в метрах между любыми двумя точками по их координатам в формате DD
        private double distance(double startLongitude, double startLatitude, double endLongitude, double endLatitude)
        {
            double d2r = Math.PI / 180;           // Множитель для перевода градусов в радианы
            double major = 6378137.0;            // Большая полуось
            double minor = 6356752.314245;   // Малая полуось
            double e2 = 0.006739496742337;  // Площадь эксцентриситета эллипсоида О_о
            double flat = 0.003352810664747; // Свед`ение эллипсоида
            // Получаем разницы между широтами-долготами
            double lambda = (startLongitude - endLongitude) * d2r;          // Разность долгот
            double phi = (startLatitude - endLatitude) * d2r;                     // Разность широт
            double phiMean = ((startLatitude + endLatitude) / 2.0) * d2r;  // Средняя широта
            // Расчет мередианального и траверсного радиусов кривизны в средних широтах О_о
            double temp = 1 - e2 * (Math.Pow( Math.Sin(phiMean), 2.0 )); // Временная переменная
            double rho = (major * (1 - e2)) / Math.Pow(temp, 1.5);             // Меридиональный радиус кривизны
            double nu = major / Math.Sqrt( 1 - e2 * Math.Pow( Math.Sin(phiMean), 2.0));  // Поперечный РК
            // Расчет углового расстояния
            double z = Math.Sqrt( Math.Pow( Math.Sin(phi / 2.0), 2.0 ) + Math.Cos(endLatitude * d2r) * Math.Cos(startLatitude * d2r) * Math.Pow( Math.Sin(lambda / 2.0), 2.0 ) );
            z = 2 * Math.Asin(z);          // Угловое расстояние в центре сфероида
            // Расчет азимута
            double alpha = Math.Cos(endLatitude * d2r) * Math.Sin(lambda) * 1 / Math.Sin(z);
            alpha = Math.Asin(alpha);   // Азимут
            // Используем Теорему Эйлера для определения радиуса сферической Земли
            double r = rho * nu / ( rho * Math.Pow( Math.Sin(alpha), 2.0 ) + nu * Math.Pow( Math.Cos(alpha), 2.0 ) );
            // Устанавливаем азимут и расстояние
            return z * r; // Дистанция
        }

Использование

distance(92.864533, 56.025027, 92.880562, 56.025543)

Где 92.864533, 56.025027 - первая точка

       92.880562, 56.025543 - вторая точка

 

//функция определения расстояния между двумя точками на php

    function distance($lat1,$lng1,$lat2,$lng2) //(x1,y1,x2,y2)

     { 

        $lat1=deg2rad($lat1); 

        $lng1=deg2rad($lng1); 

        $lat2=deg2rad($lat2); 

        $lng2=deg2rad($lng2); 

        $delta_lat=($lat2 - $lat1); 

        $delta_lng=($lng2 - $lng1); 

        return round( 6378137 * acos( cos( $lat1 ) * cos( $lat2 ) * cos( $lng1 - $lng2 ) + sin( $lat1 ) * sin( $lat2 ) ) ); 

     }

 

по данной формуле если координаты точки одинаковы, например: $y0 - 56.838607
$x0 - 60.605514, результат дает результат - 3567023, в чем причина такого отклонения, в какой величине дается расстояние, даже если оно в миллиметрах, получается расстояние между двумя одинаковыми точками равно 3 км, а если оно в метрах, то 3500 км? Что не так в этой формуле? Координаты взяты из Яндекс карт.

Русенко Игорь
28 января 2016, 06:08

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

Вот тут написано прекрасно с примером: https://www.kobzarev.com/programming/calculation-of-distances-between-cities-on-their-coordinates.html