Як перетворити широту чи довготу в метри?


127

Якщо у мене є зчитування широти чи довготи у стандартному форматі NMEA, чи є простий спосіб / формула для перетворення цього зчитування в метри, який я потім можу реалізувати в Java (J9)?

Редагувати: Ок, здається, те, що я хочу зробити, неможливо легко , проте те, що я дійсно хочу зробити, це:

Скажіть, у мене є термін і довга точки шляху, а також лат і довгота користувача? Чи є простий спосіб порівняти їх, щоб вирішити, коли сказати користувачеві, що вони знаходяться на досить близькій відстані від точки шляху? Я розумію, що розумне є предметом, але чи це легко зробити або все ще занадто математично?


2
Ви маєте на увазі UTM? en.wikipedia.org/wiki/…
Адріан Арчер

1
Що ви маєте на увазі під перетворенням lat / long у метри? метрів звідки? Ви шукаєте спосіб обчислити відстань уздовж поверхні Землі від однієї координати до іншої?
Балтимарк

2
Визначте "крапку". Визначте "розумний". Це дійсно те, що ви хочете знати: "як обчислити відстань між двома точками з урахуванням їх широти та довготи?"
Балтимарк

2
Я наткнувся на це питання, бажаючи робити SQL запити про широту та довготу, і знайшов цю чудову статтю з деяким кодом Java внизу. Це може зацікавити і вас.
Крістоф Ван Ландшот

Відповіді:


173

Ось функція 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

Формула Гаверсина визначає велику відстань між двома точками на кулі, враховуючи їх довготу та широту.


2
Для тих, хто шукає бібліотеку для перетворення між wgs та utm: github.com/urbanetic/utm-converter
Арам Кочарян

3
Буду дуже вдячний, якби хтось міг додати деякі пояснювальні коментарі до вищевказаного коду. Спасибі заздалегідь!
Равіндранат Акіла

Знайдено це який цей коментар , здається, бути прийняття. Посилання також говорить про це на основі цієї статті про обчислення відстані. Тож будь-які питання без відповіді слід знайти у вихідному посиланні. :)
Йоахім

Як додати висоту в цей розрахунок?
dangalg

62

З огляду на те, що ви шукаєте просту формулу, це, мабуть, найпростіший спосіб зробити це, якщо припустити, що Земля - ​​це сфера з окружністю 40075 км.

Довжина в метрах 1 ° широти = завжди 111,32 км

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


2
Як працює рівняння довготи? з широтою 90 градусів ви очікуєте, що вона показуватиме близько 111 км; але натомість він показує 0; аналогічно, близькі до нього значення також знаходяться біля 0.
Рис

9
Широта 0 ° на екваторі та 90 ° на полюсі (а не протилежне). Для екватора формула дає 40075 км * cos (0 °) / 360 = 111 км. Для полюса формула дає 40075 * cos (90 °) / 360 = 0 км.
Бен

Я думаю, що такий підхід простий, особливо, оскільки питання не задає точну відстань між двома точками, а скоріше, якщо вони "достатньо близькі". За допомогою цих формул ми легко перевіряємо, чи користувач знаходиться в квадраті, зосередженому на точці шляху . Набагато простіше перевірити на квадрат, ніж на коло.
Бен

29

Для наближення коротких відстаней між двома координатами я використав формули з 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 );

.

У наведеному нижче коді я залишив вихідні цифри, щоб показати своє відношення до формули з wikipedia.

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 км в ширині, але я не підтвердив це, оскільки ніде поблизу ця точність є хорошою для мого використання.


3
Зауважте, що у 2017 році на сторінці Вікіпедії є ще одна (здається, витончена) формула.
Горка Льона

3
Так, формула у Вікіпедії дещо інша, але, схоже, інша формула Вікіпедії базується на подібних результатах з цієї великої відповіді ТА , де хтось насправді пройшов обчислення.
not2qubit

10

Широти і довготи визначають точки, а не відстані, тому ваше запитання дещо безглуздо. Якщо ви запитуєте про найкоротшу відстань між двома (лат., Лон) точками, дивіться цю статтю у Вікіпедії про великі відстані.


9
Він говорить про референційне перетворення, тож ваша відповідь не до суті (каламбур не призначений)
Пауло Невес

1
А для довідки посібник перетворення для перетворення даних позицій GPS. www.microem.ru/pages/u_blox/tech/dataconvert/GPS.G1-X-00006.pdf
Пауло Невес

2
Він хоче знати, скільки градусів на метр, щоб він міг знайти відстань між 2 балами. Прочитайте між рядків.
анонімний

1
а ваша відповідь набагато безглуздіша
jerinho.com

7

Є багато інструментів, які полегшать це. Дивіться відповідь monjardin для отримання більш детальної інформації про те, що пов'язано.

Однак зробити це не обов’язково складно. Це здається, що ви використовуєте Java, тому я рекомендую вивчити щось на зразок GDAL . Він забезпечує обгортки java для своєї програми, і вони мають усі інструменти, необхідні для перетворення з Lat / Lon (географічні координати) в UTM (проектована система координат) або якусь іншу розумну проекцію карти.

UTM приємний, тому що це метри, так легко працювати. Однак вам знадобиться отримати відповідну зону UTM, щоб зробити це добре. Існує кілька простих кодів, доступних через googling, щоб знайти відповідну зону для лат / довгої пари.


7

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

NOAA має деяке програмне забезпечення, яке ви можете завантажити, щоб допомогти з цим на своєму веб-сайті .


6

Ось R-версія функції bh-,, про всяк випадок:

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

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


1
Ні, морська миля визначена міжнародним стандартом ( v en.wikipedia.org/wiki/Nautical_mile ) - 1852 м. Її відношення до вимірювання дуги на поверхні сфероїда, такого як Земля, тепер є і історичним, і приблизним.
Марка високої продуктивності

2

Існує досить багато способів обчислити це. Усі вони використовують апроксимації сферичної тригонометрії, де радіус - земний.

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


1
    'below is from
'http://www.zipcodeworld.com/samples/distance.vbnet.html
Public Function distance(ByVal lat1 As Double, ByVal lon1 As Double, _
                         ByVal lat2 As Double, ByVal lon2 As Double, _
                         Optional ByVal unit As Char = "M"c) As Double
    Dim theta As Double = lon1 - lon2
    Dim dist As Double = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + _
                            Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * _
                            Math.Cos(deg2rad(theta))
    dist = Math.Acos(dist)
    dist = rad2deg(dist)
    dist = dist * 60 * 1.1515
    If unit = "K" Then
        dist = dist * 1.609344
    ElseIf unit = "N" Then
        dist = dist * 0.8684
    End If
    Return dist
End Function
Public Function Haversine(ByVal lat1 As Double, ByVal lon1 As Double, _
                         ByVal lat2 As Double, ByVal lon2 As Double, _
                         Optional ByVal unit As Char = "M"c) As Double
    Dim R As Double = 6371 'earth radius in km
    Dim dLat As Double
    Dim dLon As Double
    Dim a As Double
    Dim c As Double
    Dim d As Double
    dLat = deg2rad(lat2 - lat1)
    dLon = deg2rad((lon2 - lon1))
    a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(deg2rad(lat1)) * _
            Math.Cos(deg2rad(lat2)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)
    c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a))
    d = R * c
    Select Case unit.ToString.ToUpper
        Case "M"c
            d = d * 0.62137119
        Case "N"c
            d = d * 0.5399568
    End Select
    Return d
End Function
Private Function deg2rad(ByVal deg As Double) As Double
    Return (deg * Math.PI / 180.0)
End Function
Private Function rad2deg(ByVal rad As Double) As Double
    Return rad / Math.PI * 180.0
End Function

Я бачу, посилання перерване.
thepang

1

Для перетворення широти та довготи у представлення x та y вам потрібно визначити, який тип проекції карти використовувати. Як на мене, Еліптичний Меркатор здається дуже вдалим. Тут ви можете знайти реалізацію (і на Java).


0

Якщо його достатньо близько, ви можете піти, розглядаючи їх як координати на плоскій площині. Це працює, скажімо, на рівні вулиці чи міста, якщо не потрібна досконала точність, і все, що вам потрібно, - це груба здогадка на відстані, яку потрібно здійснити для порівняння з довільною межею.


3
Ні, це не працює! Відстань х в м різна для різних значень широти. На екваторі ви можете відійти від нього, але чим ближче до полюсів ви отримаєте крайність ваших еліпсоїдів.
RickyA

3
Хоча ваш коментар є обґрунтованим, він не відповідає на запитання користувача про перетворення різниці ступенів lat / lng в метри.
JivanAmara

0

Виходячи із середньої відстані для занепаду Землі.

1 ° = 111км;

Перетворивши це для радіанів і розділивши на метри, візьмемо магічне число для RAD, у метрах: 0,000008998719243599958;

тоді:

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

3
нарешті, пряма відповідь :)
Бен Хатчісон

що якщо ширина - -179, а інша - 179, відстань x має бути 2 градуси замість 358
OMGPOP

7
Не використовуйте цю відповідь (чомусь це сприйнято). Немає жодного масштабу між довготою та відстані; Земля не плоска.
CPBL

1
Я вважаю, що це 111,1
Абель Каллехо

6
Зверніть увагу, що один градус довготи становить 111 км на екваторі, але менше для інших широт. Існує проста приблизна формула, щоб знайти довжину в км 1 ° довготи у функції широти: 1 ° довготи = 40000 км * cos (широта) / 360 (і, звичайно, це дає 111 км для широти = 90 °). Також зауважте, що 1 ° довготи майже завжди відрізняється від відстані 1 ° широти.
Бен

-1

Якщо ви хочете просте рішення, тоді використовуйте формулу Гаверсіна, як викладено в інших коментарях. Якщо у вас є точне застосування, майте на увазі, формула Гаверсіна не гарантує точність краще 0,5%, оскільки припускається, що земля - ​​це сфера. Для того, щоб вважати, що Земля - ​​це сплетений сфероїд, розглянемо, використовуючи формули Вінсенті . Крім того, я не впевнений, який радіус нам слід використовувати за формулою Гаверсіна: {Екватор: 6,378,137 км, Полярний: 6,356,752 км, Об'ємний: 6,371,0088 км}.


it is assuming the earth is a circle^^ Деякі дивні люди роблять це сьогодні ... але те, що ти маєш на увазі, швидше за все it is assuming the earth is a sphere;)
derHugo

-2

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.