Jak przekonwertować szerokość lub długość geograficzną na metry?

127

Jeśli mam odczyt szerokości lub długości geograficznej w standardowym formacie NMEA, czy istnieje łatwy sposób / wzór na konwersję tego odczytu na liczniki, które mogę następnie zaimplementować w Javie (J9)?

Edycja: Ok wydaje się, że to, co chcę zrobić, nie jest łatwe , jednak naprawdę chcę zrobić:

Powiedzmy, że mam szerokość i długość punktu nawigacyjnego oraz szerokość i długość użytkownika. Czy istnieje łatwy sposób na ich porównanie, aby zdecydować, kiedy powiedzieć użytkownikowi, że znajdują się w rozsądnej odległości od punktu nawigacyjnego? Zdaję sobie sprawę, że rozsądek jest tematem, ale czy jest to łatwe do wykonania, czy nadal jest przesadnie matematyczne?

Adam Taylor
źródło
2
Czy masz na myśli UTM? en.wikipedia.org/wiki/…
Adrian Archer
1
Co masz na myśli, przeliczając szerokość / długość na metry? metrów skąd? Szukasz sposobu na obliczenie odległości wzdłuż powierzchni Ziemi od jednej współrzędnej do drugiej?
Baltimark
2
Zdefiniuj „punkt trasy”. Zdefiniuj „rozsądne”. Czy naprawdę chcesz wiedzieć: „jak obliczyć odległość między dwoma punktami, biorąc pod uwagę ich szerokość i długość geograficzną?”
Baltimark
2
Natknąłem się na to pytanie, chcąc wykonywać zapytania SQL dotyczące szerokości i długości geograficznej, i znalazłem ten wspaniały artykuł z kodem Java na dole. To też może Cię zainteresować.
Kristof Van Landschoot

Odpowiedzi:

173

Oto funkcja 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
}

Wyjaśnienie: https://en.wikipedia.org/wiki/Haversine_formula

Wzór haversine określa odległość po ortodromie między dwoma punktami na kuli, biorąc pod uwagę ich długości i szerokości geograficzne.

bh-
źródło
2
Dla tych, którzy szukają biblioteki do konwersji między wgs i utm
Aram
3
Byłoby naprawdę wdzięczne, gdyby ktoś mógł dodać kilka komentarzy wyjaśniających do powyższego kodu. Z góry dziękuję!
Ravindranath Akila
Znalazłem to, co wydaje się być przyjęciem tego komentarza. Link mówi również, że jest oparty na tym artykule na temat obliczania odległości. Dlatego wszelkie pytania bez odpowiedzi powinny znajdować się w oryginalnym linku. :)
Joachim
Jak dodać wysokość do tych obliczeń?
dangalg
62

Biorąc pod uwagę, że szukasz prostego wzoru, jest to prawdopodobnie najprostszy sposób, aby to zrobić, zakładając, że Ziemia jest kulą o obwodzie 40075 km.

Długość w metrach 1 ° szerokości geograficznej = zawsze 111,32 km

Długość w metrach 1 ° długości geograficznej = 40075 km * cos (szerokość geograficzna) / 360

Ben
źródło
2
Jak działa równanie długości geograficznej? przy 90 stopniach szerokości geograficznej można by się spodziewać, że pokaże się blisko 111 km; ale zamiast tego pokazuje 0; podobnie, wartości zbliżone do niego są również bliskie 0.
Reece,
9
Szerokość geograficzna wynosi 0 ° na równiku i 90 ° na biegunie (a nie odwrotnie). Wzór na równik daje 40075 km * cos (0 °) / 360 = 111 km. Dla bieguna wzór daje 40075 * cos (90 °) / 360 = 0 km.
Ben
Myślę, że to podejście jest proste, zwłaszcza że w pytaniu nie chodziło o dokładną odległość między dwoma punktami, ale raczej o to, czy są one „wystarczająco blisko”. Dzięki tym formułom łatwo sprawdzimy, czy użytkownik znajduje się w kwadracie wyśrodkowanym na punkcie drogi . O wiele łatwiej jest sprawdzić kwadrat niż koło.
Ben
29

Do przybliżania krótkich odległości między dwiema współrzędnymi użyłem wzorów z 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 );

.

W poniższym kodzie zostawiłem surowe liczby, aby pokazać ich związek ze wzorem z Wikipedii.

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) );

Wpis wikipedii stwierdza, że ​​obliczane odległości mieszczą się w granicach 0,6 m na 100 km podłużnie i 1 cm na 100 km szerokości, ale nie zweryfikowałem tego, ponieważ gdziekolwiek blisko tej dokładności jest w porządku dla mojego użytku.

JJones
źródło
3
Zauważ, że w 2017 roku strona Wikipedii ma inną (wydaje się wyrafinowaną) formułę.
Gorka Llona
3
Tak, formuła w Wikipedii jest nieco inna, ale wydaje się, że druga formuła Wikipedii opiera się na podobnych wynikach z tej świetnej odpowiedzi SO , gdzie ktoś faktycznie przeszedł przez obliczenia.
not2qubit
10

Szerokość i długość geograficzna określają punkty, a nie odległości, więc twoje pytanie jest nieco bezsensowne. Jeśli pytasz o najkrótszą odległość między dwoma (szer., Dł.) Punktami, przeczytaj ten artykuł w Wikipedii o ortodromie.

John Feminella
źródło
9
Mówi o konwersji referencyjnej, więc twoja odpowiedź nie jest trafna (gra słów nie jest zamierzona)
Paulo Neves,
1
I w celach informacyjnych przewodnik konwersji dla transformacji odniesienia pozycji GPS. www.microem.ru/pages/u_blox/tech/dataconvert/GPS.G1-X-00006.pdf
Paulo Neves
2
Chce wiedzieć, ile stopni na metr, aby mógł znaleźć odległość między 2 punktami. Czytać między wierszami.
Anonymous
1
a Twoja odpowiedź jest znacznie bardziej bezsensowna
jerinho.com
7

Jest wiele narzędzi, które to ułatwią. Zobacz odpowiedź Monjardina, aby uzyskać więcej informacji o tym, co się z tym wiąże.

Jednak zrobienie tego niekoniecznie jest trudne. Wygląda na to, że używasz Javy, więc polecam zajrzeć do czegoś takiego jak GDAL . Zapewnia otoki java dla ich procedur i mają wszystkie narzędzia wymagane do konwersji z Lat / Lon (współrzędne geograficzne) na UTM (rzutowany układ współrzędnych) lub inne rozsądne odwzorowanie mapy.

UTM jest fajny, ponieważ to liczniki, więc łatwo się z nim pracuje. Będziesz jednak musiał uzyskać odpowiednią strefę UTM , aby wykonał dobrą robotę. Istnieje kilka prostych kodów dostępnych w wyszukiwarce Google, aby znaleźć odpowiednią strefę dla par długich / długich.

Reed Copsey
źródło
7

Ziemia jest irytująco nieregularną powierzchnią, więc nie ma na to prostego wzoru. Musisz żyć z przybliżonym modelem Ziemi i rzutować na niego swoje współrzędne. Model, który zazwyczaj używany do tego celu, to WGS 84 . Właśnie tego urządzenia GPS zwykle używają do rozwiązania tego samego problemu.

NOAA ma oprogramowanie, które możesz pobrać, aby pomóc w tym na swojej stronie internetowej .

PRZETRZĄSAĆ
źródło
6

Oto wersja R funkcji bh- , na wszelki wypadek:

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
}
Rodrigo
źródło
2

Jedna mila morska (1852 metry) jest definiowana jako jedna minuta łuku długości geograficznej na równiku. Musisz jednak zdefiniować odwzorowanie mapy (zobacz także UTM ), w którym pracujesz, aby konwersja naprawdę miała sens.

Sędzia Maygarden
źródło
1
Nie, mila morska jest zdefiniowana w międzynarodowym standardzie ( v en.wikipedia.org/wiki/Nautical_mile ) jako 1852 m. Jego związek z pomiarem łuku na powierzchni sferoidy, takiej jak Ziemia, jest teraz zarówno historyczny, jak i przybliżony.
Znak wysokiej wydajności
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
dbasnett
źródło
Widzę, że link jest uszkodzony.
tshepang
1

Aby przekształcić szerokość i długość geograficzną w reprezentację xiy, musisz zdecydować, jakiego typu odwzorowania mapy użyć. Jak dla mnie, Elliptical Mercator wygląda bardzo dobrze. Tutaj możesz znaleźć implementację (również w Javie).

Megamozg
źródło
0

Jeśli jest wystarczająco blisko, można uciec, traktując je jako współrzędne na płaskiej płaszczyźnie. Działa to, powiedzmy, na poziomie ulicy lub miasta, jeśli nie jest wymagana doskonała dokładność, a wszystko, czego potrzebujesz, to zgadne oszacowanie odległości, aby porównać z dowolnym limitem.


źródło
3
Nie, to nie działa! Odległość x wm jest różna dla różnych wartości szerokości geograficznej. Na równiku może ci się to udać, ale im bliżej biegunów, tym bardziej ekstremalne będą twoje elipsoidy.
RickyA
3
Twój komentarz jest rozsądny, ale nie odpowiada na pytanie użytkownika dotyczące przeliczania różnicy stopni szerokości / długości geograficznej na metry.
JivanAmara
0

Na podstawie średniej odległości degresu na Ziemi.

1 ° = 111 km;

Konwertując to na radiany i dzieląc na metry, weź magiczną liczbę dla RAD w metrach: 0,000008998719243599958;

następnie:

const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
Jaykon
źródło
3
na koniec prosta odpowiedź :)
Ben Hutchison
co jeśli szerokość geograficzna to -179, a druga to 179, odległość x powinna wynosić 2 stopnie zamiast 358
OMGPOP
7
Nie używaj tej odpowiedzi (z jakiegoś powodu jest ona przegłosowana). Nie ma jednej skali między długością geograficzną a odległością; Ziemia nie jest płaska.
CPBL,
1
Myślę, że to 111,1
Abel Callejo
6
Zauważ, że jeden stopień długości geograficznej na równiku to 111 km, ale mniej na innych szerokościach geograficznych. Istnieje prosty, przybliżony wzór na obliczenie długości 1 ° długości geograficznej w km w funkcji szerokości geograficznej: 1 ° długości = 40000 km * cos (szerokość) / 360 (i oczywiście daje 111 km dla szerokości = 90 °). Zwróć również uwagę, że 1 ° długości geograficznej jest prawie zawsze inną odległością niż 1 ° szerokości geograficznej.
Ben
-1

Jeśli potrzebujesz prostego rozwiązania, użyj formuły Haversine, jak opisano w innych komentarzach. Jeśli masz aplikację wrażliwą na dokładność, pamiętaj, że wzór Haversine nie gwarantuje dokładności lepszej niż 0,5%, ponieważ zakłada się, że ziemia jest kulą. Aby uznać, że Ziemia jest spłaszczoną sferoidą, rozważ użycie wzorów Vincentego . Dodatkowo nie jestem pewien, jakiego promienia powinniśmy użyć ze wzorem Haversine: {Równik: 6 378,137 km, Biegunowy: 6 356,752 km, Objętościowy: 6 371,0088 km}.

Samuel Crawford Loveys
źródło
it is assuming the earth is a circle^^ Niektórzy dziwni ludzie robią to obecnie ... ale masz na myśli raczej raczej it is assuming the earth is a sphere;)
derHugo
-2

Musisz przekonwertować współrzędne na radiany, aby wykonać geometrię sferyczną. Po przeliczeniu możesz obliczyć odległość między dwoma punktami. Odległość można następnie przeliczyć na dowolną miarę.

Arlie Winters
źródło