Как перевести широту или долготу в метры? - PullRequest
101 голосов
/ 12 марта 2009

Если у меня есть значения широты или долготы в стандартном формате NMEA, есть ли простой способ / формула для преобразования этого значения в метры, которое я затем могу реализовать в Java (J9)?

Edit: Хорошо, кажется, то, что я хочу сделать, невозможно легко , однако я действительно хочу сделать следующее:

Скажем, у меня есть широта и длинна промежуточной точки и широта и длинна пользователя, есть простой способ сравнить их, чтобы решить, когда сказать пользователю, что он находится на разумно близком расстоянии точки пути? Я понимаю, что разумное - это предмет, но легко ли это сделать или все еще слишком математично?

Ответы [ 15 ]

138 голосов
/ 24 июня 2012

Вот функция JavaScript:

function measure(lat1, lon1, lat2, lon2){  // generally used geo measurement function
    var R = 6378.137; // Radius of earth in KM
    var dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
    var dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    return d * 1000; // meters
}

Объяснение: https://en.wikipedia.org/wiki/Haversine_formula

Формула haversine определяет расстояние большого круга между двумя точками на сфере с учетом их долготы и широты.

32 голосов
/ 17 сентября 2016

Учитывая, что вы ищете простую формулу, это, вероятно, самый простой способ сделать это, предполагая, что Земля представляет собой сферу по периметру 40075 км.

Длина в метрах 1 ° широты = всегда 111,32 км

Длина в метрах 1 ° долготы = 40075 км * cos (широта) / 360

27 голосов
/ 14 октября 2013

Для аппроксимации коротких расстояний между двумя координатами я использовал формулы из http://en.wikipedia.org/wiki/Lat-lon:

m_per_deg_lat = 111132.954 - 559.822 * cos( 2 * latMid ) + 1.175 * cos( 4 * latMid);
m_per_deg_lon = 111132.954 * cos ( latMid );

.

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

double latMid, m_per_deg_lat, m_per_deg_lon, deltaLat, deltaLon,dist_m;

latMid = (Lat1+Lat2 )/2.0;  // or just use Lat1 for slightly less accurate estimate


m_per_deg_lat = 111132.954 - 559.822 * cos( 2.0 * latMid ) + 1.175 * cos( 4.0 * latMid);
m_per_deg_lon = (3.14159265359/180 ) * 6367449 * cos ( latMid );

deltaLat = fabs(Lat1 - Lat2);
deltaLon = fabs(Lon1 - Lon2);

dist_m = sqrt (  pow( deltaLat * m_per_deg_lat,2) + pow( deltaLon * m_per_deg_lon , 2) );

Запись в Википедии гласит, что расчеты расстояний находятся в пределах 0,6 м для 100 км в продольном направлении и 1 см для 100 км в продольном направлении, но я не проверял это, так как где-то близко эта точность подходит для моего использования.

12 голосов
/ 12 марта 2009

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

8 голосов
/ 12 марта 2009

Земля - ​​досадно неправильная поверхность, поэтому нет простой формулы, чтобы сделать это точно. Вы должны жить с приблизительной моделью Земли и проецировать на нее свои координаты. Модель, которую я обычно вижу, используется для этого WGS 84 . Это то, что устройства GPS обычно используют для решения точно такой же проблемы.

NOAA имеет некоторое программное обеспечение, которое вы можете скачать, чтобы помочь с этим на их сайте .

7 голосов
/ 12 марта 2009

Есть много инструментов, которые сделают это легко. См. ответ monjardin для получения более подробной информации о том, что происходит.

Однако сделать это не обязательно сложно. Похоже, вы используете Java, поэтому я бы порекомендовал посмотреть что-то вроде GDAL . Он предоставляет java-обертки для своих подпрограмм, и у них есть все инструменты, необходимые для преобразования из широты / долготы (географические координаты) в UTM (проекционная система координат) или в какую-либо другую разумную проекцию карты.

UTM хорош, потому что это метров, с которыми легко работать. Тем не менее, вам нужно будет получить соответствующую UTM зону , чтобы она хорошо работала. Есть несколько простых кодов, доступных через поиск в Google, чтобы найти подходящую зону для пары широта / долгота.

5 голосов
/ 06 февраля 2015

Вот версия R функции b-h-s , на всякий случай:

measure <- function(lon1,lat1,lon2,lat2) {
    R <- 6378.137                                # radius of earth in Km
    dLat <- (lat2-lat1)*pi/180
    dLon <- (lon2-lon1)*pi/180
    a <- sin((dLat/2))^2 + cos(lat1*pi/180)*cos(lat2*pi/180)*(sin(dLon/2))^2
    c <- 2 * atan2(sqrt(a), sqrt(1-a))
    d <- R * c
    return (d * 1000)                            # distance in meters
}
2 голосов
/ 12 марта 2009

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

попробуйте http://www.movable -type.co.uk / scripts / latlong.html для небольшого количества методов и кода на разных языках.

2 голосов
/ 12 марта 2009

Одна морская миля (1852 метра) определяется как одна угловая минута долготы на экваторе. Однако вам нужно определить проекцию карты (см. Также UTM ), в которой вы работаете, чтобы преобразование действительно имело смысл.

1 голос
/ 28 августа 2013

На основе среднего расстояния для разложения на Земле.

1 ° = 111 км;

Для пересчета в радианы и деления на метры возьмите магическое число для RAD в метрах: 0,000008998719243599958;

тогда:

const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
...