Enlem veya boylamı metreye nasıl çevirebilirim?


127

Standart NMEA biçiminde bir enlem veya boylam okumam varsa, bu okumayı ölçere dönüştürmenin kolay bir yolu / formülü var mı, daha sonra bunu Java'da (J9) uygulayabilirim?

Düzenleme: Tamam, yapmak istediğim şey kolay mümkün değil gibi görünüyor , ancak gerçekten yapmak istediğim şey:

Diyelim ki bir enlem ve uzun bir ara noktam var ve bir kullanıcının enlem ve boylamı, kullanıcıya yol noktasına oldukça yakın bir mesafede olduklarını ne zaman söyleyeceğine karar vermenin kolay bir yolu var mı? Makul bir konu olduğunun farkındayım ama bu kolayca yapılabilir mi yoksa yine de aşırı matematik-y?


2
UTM mi demek istiyorsun? en.wikipedia.org/wiki/…
Adrian Archer

1
Enlem / boylamı metreye çevirmekle ne demek istiyorsun? metre nereden? Dünyanın yüzeyi boyunca bir koordinattan diğerine olan mesafeyi hesaplamanın bir yolunu mu arıyorsunuz?
Baltimark

2
"Ara nokta" yı tanımlayın. "Makul" kelimesini tanımlayın. Gerçekten bilmek istediğiniz şey bu mu: "Enlem ve boylamlarına göre iki nokta arasındaki mesafeyi nasıl hesaplarsınız?"
Baltimark

2
Enlem ve boylamla ilgili SQL sorguları yapmak isteyen bu soruya rastladım ve bu harika makaleyi altta bazı Java kodlarıyla buldum . Seni de ilgilendirebilir.
Kristof Van Landschoot

Yanıtlar:


173

İşte bir javascript işlevi:

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
}

Açıklama: https://en.wikipedia.org/wiki/Haversine_formula

Haversine formülü, boylamları ve enlemleri göz önüne alındığında bir küre üzerindeki iki nokta arasındaki büyük daire mesafesini belirler.


2
Wgs ve utm arasında dönüştürme yapacak bir kütüphane arayanlar için: github.com/urbanetic/utm-converter
Aram

3
Biri yukarıdaki koda bazı açıklayıcı yorumlar ekleyebilirse gerçekten minnettar olurum. Şimdiden teşekkürler!
Ravindranath Akila

Bulunan bu bu yayın bir evlat edinme gibi görünüyor hangi. Bağlantı ayrıca , mesafe hesaplaması hakkındaki bu makaleye dayandığını söylüyor . Bu nedenle, yanıtlanmamış tüm sorular orijinal bağlantıda bulunmalıdır. :)
Joachim

Bu hesaplamaya nasıl yükseklik eklerim?
dangalg

62

Basit bir formül aradığınız düşünüldüğünde, Dünya'nın 40075 km'lik bir çevresi olan bir küre olduğunu varsayarsak, bunu yapmanın muhtemelen en basit yolu budur.

1 ° enlemin metre cinsinden uzunluğu = her zaman 111,32 km

1 ° boylamın metre cinsinden uzunluğu = 40075 km * cos (enlem) / 360


2
Boylam denklemi nasıl çalışır? 90 derece enlem ile 111 km civarında göstermesini beklersiniz; ancak bunun yerine 0 gösterir; benzer şekilde, ona yakın değerler de 0'a yakın.
Reece

9
Enlem ekvatorda 0 ° ve kutupta 90 ° dir (tersi değil). Ekvator için formül 40075 km * cos (0 °) / 360 = 111 km verir. Kutup için formül 40075 * cos (90 °) / 360 = 0 km verir.
Ben

Bence bu yaklaşım, özellikle soru iki nokta arasındaki kesin mesafeyi sormadığından, daha çok "yeterince yakın" olup olmadıklarını sorduğundan basittir. Bu formüllerle, kullanıcının ara noktaya ortalanmış bir kare içinde olup olmadığını kolayca kontrol ederiz . Bir kareyi kontrol etmek bir daireden çok daha kolaydır.
Ben

29

İki koordinat arasındaki kısa mesafeleri tahmin etmek için http://en.wikipedia.org/wiki/Lat-lon'daki formülleri kullandım :

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

.

Aşağıdaki kodda, wikipedia'daki formülle ilişkilerini göstermek için ham sayıları bıraktım.

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

Wikipedia girişi, mesafe hesaplamalarının boylamasına 100km için 0.6m ve enlemesine 100km için 1cm içinde olduğunu belirtir, ancak bu doğruluğun benim kullanımım için uygun olduğunu doğrulamadım.


3
2017'de Wikipedia sayfasının başka bir (iyileştirilmiş gibi görünüyor) formülü olduğunu unutmayın.
Gorka Llona

3
Evet, Wikipedia'daki formül biraz farklı, ancak diğer Wikipedia formülü, birinin hesaplamalardan geçtiği bu harika SO cevabından elde edilen benzer sonuçlara dayanıyor gibi görünüyor .
not2qubit

10

Enlemler ve boylamlar mesafeleri değil noktaları belirtir, bu nedenle sorunuz biraz anlamsızdır. İki (enlem, boylam) nokta arasındaki en kısa mesafeyi soruyorsanız , büyük daire mesafeleri hakkındaki bu Wikipedia makalesine bakın .


9
Referans dönüşümden bahsediyor, bu yüzden cevabınız asıl konu değil (kelime anlamı yok)
Paulo Neves

1
Ve referans olarak GPS konumlarının veri dönüşümü için bir dönüşüm kılavuzu. www.microem.ru/pages/u_blox/tech/dataconvert/GPS.G1-X-00006.pdf
Paulo Neves

2
2 nokta arasındaki mesafeyi bulabilmek için metre başına kaç derece olduğunu bilmek istiyor. Satır aralarını oku.
theAnonymous

1
ve cevabınız çok daha saçma
jerinho.com

7

Bunu kolaylaştıracak birçok araç var. Neler dahil olduğu hakkında daha fazla ayrıntı için monjardin'in cevabına bakın .

Ancak, bunu yapmak mutlaka zor değil. Java kullanıyormuşsunuz gibi görünüyor, bu yüzden GDAL gibi bir şeye bakmanızı tavsiye ederim . Rutinleri için java sarmalayıcılar sağlar ve Lat / Lon'dan (coğrafi koordinatlar) UTM'ye (öngörülen koordinat sistemi) veya başka bir makul harita projeksiyonuna dönüştürmek için gerekli tüm araçlara sahiptirler.

UTM güzeldir, çünkü metredir, çalışmak çok kolaydır. Ancak, iyi bir iş çıkarması için uygun UTM bölgesini edinmeniz gerekecektir . Enlem / boylam çifti için uygun bir bölge bulmak için googling aracılığıyla kullanılabilen bazı basit kodlar vardır.


7

Dünya can sıkıcı derecede düzensiz bir yüzeydir, bu yüzden bunu tam olarak yapmanın basit bir formülü yoktur. Dünyanın yaklaşık bir modeliyle yaşamalı ve koordinatlarınızı ona yansıtmalısınız. Genelde bunun için kullanıldığını gördüğüm model WGS 84'tür . GPS cihazlarının genellikle aynı sorunu çözmek için kullandığı şey budur.

NOAA, bu konuda yardımcı olmak için web sitesinde indirebileceğiniz bazı yazılımlara sahiptir .


6

İşte her ihtimale karşı bh-fonksiyonunun R versiyonu :

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

Bir deniz mili (1852 metre), ekvatorda bir yay dakikalık boylam olarak tanımlanır . Ancak, dönüşümün gerçekten mantıklı olması için içinde çalıştığınız bir harita projeksiyonu (ayrıca bkz. UTM ) tanımlamanız gerekir .


1
Hayır, deniz mili uluslararası standart ( v en.wikipedia.org/wiki/Nautical_mile ) tarafından 1852 m olarak tanımlanmıştır. Dünya gibi bir sferoitin yüzeyindeki bir yay ölçümü ile ilişkisi artık hem tarihsel hem de yaklaşıktır.
Yüksek Performans Mark


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

Bağlantının bozuk olduğunu görüyorum.
tshepang

1

Enlem ve boylamı x ve y gösteriminde dönüştürmek için hangi tür harita projeksiyonunu kullanacağınıza karar vermeniz gerekir. Bana gelince, Eliptik Mercator çok iyi görünüyor. Burada bir uygulama bulabilirsiniz (Java'da da).


0

Yeterince yakınsa, bunları düz bir düzlemde koordinatlar olarak ele alarak kurtulabilirsiniz. Bu, örneğin, mükemmel doğruluk gerekli değilse ve tek ihtiyacınız olan, keyfi bir sınırla karşılaştırmak için ilgili mesafe hakkında kaba bir tahminde bulunmaksa, örneğin cadde veya şehir düzeyinde çalışır.


3
Hayır, bu çalışmıyor! M cinsinden x mesafesi, farklı enlem değerleri için farklıdır. Ekvatorda bundan kurtulabilirsiniz, ancak kutuplara yaklaştıkça elipsoidleriniz daha da artar.
RickyA

3
Yorumunuz makul olsa da, kullanıcının enlem / boylam derece farkını metreye dönüştürmeyle ilgili sorusuna cevap vermiyor.
JivanAmara

0

Dünyadaki ortalama eğim mesafesine göre.

1 ° = 111km;

Bunu radyanlar için dönüştürmek ve metreye bölmek, RAD için metre cinsinden sihirli bir sayı alır: 0.000008998719243599958;

sonra:

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

3
nihayet basit bir cevap :)
Ben Hutchison

ya enlem -179 ve diğeri 179 ise, x mesafesi 358 yerine 2 derece olmalıdır
OMGPOP

7
Bu cevabı kullanmayın (bazı nedenlerden dolayı oy verildi). Boylam ve mesafe arasında tek bir ölçekleme yoktur; Dünya düz değil.
CPBL

1
Sanırım 111.1
Abel Callejo

6
Bir derecelik boylamın ekvatorda 111 km olduğunu, ancak diğer enlemler için daha az olduğunu unutmayın. Enlem fonksiyonu olarak 1 ° boylamın km cinsinden uzunluğunu bulmak için basit bir yaklaşık formül var: 1 ° boylam = 40000 km * cos (enlem) / 360 (ve tabii ki enlem = 90 ° için 111 km verir). Ayrıca 1 ° boylamın neredeyse her zaman 1 ° enlemden farklı bir mesafe olduğuna dikkat edin.
Ben

-1

Basit bir çözüm istiyorsanız , diğer yorumlarda belirtildiği gibi Haversine formülünü kullanın . Doğruluğa duyarlı bir uygulamanız varsa, Haversine formülünün, dünyanın bir küre olduğunu varsaydığı için% 0,5'ten daha iyi bir doğruluğu garanti etmediğini unutmayın. Dünya'nın basık bir küremsi olduğunu düşünmek için Vincenty'nin formüllerini kullanmayı düşünün . Ek olarak, Haversine formülüyle hangi yarıçapı kullanmamız gerektiğinden emin değilim: {Ekvator: 6,378,137 km, Polar: 6,356,752 km, Hacimsel: 6,371,0088 km}.


it is assuming the earth is a circle^^ Bugünlerde bazı garip insanlar bunu yapıyor ... ama demek istediğin muhtemelen daha çok it is assuming the earth is a sphere;)
derHugo

-2

Küresel geometri yapmak için koordinatları radyana dönüştürmeniz gerekir. Dönüştürüldükten sonra, iki nokta arasındaki mesafeyi hesaplayabilirsiniz. Mesafe daha sonra istediğiniz herhangi bir ölçüye dönüştürülebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.