Enlem / boylam ve km mesafesiyle çalışmak için basit hesaplamalar?


119

Aramalar için bir sınırlayıcı kutu hesaplamak için km'yi bir enlem veya boylam kayan noktaya ekleyebileceğim bir değere dönüştürecek basit bir hesaplama var mı? Tamamen doğru olmasına gerek yok.

Örneğin: Londra, İngiltere (51.5001524, -0.1262362) için bana enlem / boylam verilseydi ve bu noktadan itibaren enlemin 25 km doğu / batı ne olacağını ve bunun 25 km kuzey / güneyde ne olacağını hesaplamak istedim noktası, yukarıdaki değerlere eklemek için 25 km'yi ondalık sayıya dönüştürmek için ne yapmam gerekir?

Genel bir pratik kural arıyorum, yani: 1km == +/- 0.XXX

Düzenle:

İlk "lat lon" aramam bu sonucu döndürmedi:

Belirli bir enlem / boylam konumu için sınırlayıcı kutu nasıl hesaplanır?

Kabul edilen cevap, gereksinimlerime uygun görünüyor.


Yanıtlar:


221

Yaklaşık dönüşümler:

  • Enlem: 1 derece = 110,574 km
  • Boylam: 1 derece = 111.320 * cos (enlem) km

Bu, Dünya'nın kutupsal düzleşmesi için tam olarak doğru değildir - çünkü muhtemelen WGS84 referans elipsoidini (GPS için kullanılan model) kullanarak daha karmaşık bir formül isteyeceksiniz. Ancak hata muhtemelen sizin amaçlarınız için önemsizdir.

Kaynak: http://en.wikipedia.org/wiki/Latitude

Dikkat : Enlem uzunluğundaki koordinatların derece cinsinden ifade edildiğini, ancak cosçoğu (tümü?) Dildeki fonksiyon tipik olarak radyan kabul eder, bu nedenle bir derece radyan dönüşümü gereklidir.


İkinci formülde cos (boylam) mı demek istiyorsunuz?
Odys

1
Bunu nasıl buldunuz? Bir şeyi kaçırıyorum, Boylam hesaplamalarını biraz daha detaylandırır mısınız? Ty
Odys

5
@Odys: Aynı boylam çizgisinde (kuzey / güney) bulunan iki noktayı karşılaştırıyorsanız, bunlar büyük bir çemberin üzerindedir ve dönüşüm faktörü sadece Dünya'nın kutup çevresinin 360 dereceye bölünmesidir. Ancak doğu-batı ölçümleri için farklıdır, çünkü (ekvator hariç) "büyük bir daire" boyunca ölçüm yapmıyorsunuz, bu nedenle belirli bir enlemdeki "çevre" daha küçüktür. Ve düzeltme faktörünün enlemin kosinüsü olduğu ortaya çıkıyor.
Jim Lewis

17
Açıklamam: cos(0°) = 1=> Bu nedenle ekvatorda hesaplama yapılırken uygulanan herhangi bir düzeltme faktörü yoktur. Boylamlar orada en geniştir. cos(90°) = 0=> Kutuplarda boylamlar bir noktada buluşur. Hesaplanacak bir mesafe yok.
Jenny O'Reilly

4
@Stijn: Math.cos () 'u çağırmadan önce dereceden radyana çevirmeniz gerekir.
Jim Lewis


1

http://www.jstott.me.uk/jcoord/ - bu kitaplığı kullanın

            LatLng lld1 = new LatLng(40.718119, -73.995667);
            LatLng lld2 = new LatLng(51.499981, -0.125313);
            Double distance = lld1.distance(lld2);
            Log.d(TAG, "Distance in kilometers " + distance);


1

Jim Lewis'e harika cevabı için teşekkürler ve bu çözümü Swift'deki işlevimle açıklamak istiyorum:

func getRandomLocation(forLocation location: CLLocation, withOffsetKM offset: Double) -> CLLocation {
        let latDistance = (Double(arc4random()) / Double(UInt32.max)) * offset * 2.0 - offset
        let longDistanceMax = sqrt(offset * offset - latDistance * latDistance)
        let longDistance = (Double(arc4random()) / Double(UInt32.max)) * longDistanceMax * 2.0 - longDistanceMax

        let lat: CLLocationDegrees = location.coordinate.latitude + latDistance / 110.574
        let lng: CLLocationDegrees = location.coordinate.longitude + longDistance / (111.320 * cos(lat / .pi / 180))
        return CLLocation(latitude: lat, longitude: lng)
    }

Bu fonksiyonda mesafeyi dönüştürmek için aşağıdaki formülleri kullanıyorum:

latDistance / 110.574
longDistance / (111.320 * cos(lat / .pi / 180))

Sanırım "lat * pi / 180"
olmalı

1

Neden doğru formüle edilmiş jeo-uzamsal sorgular kullanmıyorsunuz ???

STContains geospatial fonksiyonundaki SQL sunucusu referans sayfası:

https://docs.microsoft.com/en-us/sql/t-sql/spatial-geography/stcontains-geography-data-type?view=sql-server-ver15

veya kutu ve radyan dönüşümünü kullanmak istemiyorsanız, ihtiyacınız olan noktaları bulmak için her zaman uzaklık işlevini kullanabilirsiniz:

DECLARE @CurrentLocation geography; 
SET @CurrentLocation  = geography::Point(12.822222, 80.222222, 4326)

SELECT * , Round (GeoLocation.STDistance(@CurrentLocation ),0) AS Distance FROM [Landmark]
WHERE GeoLocation.STDistance(@CurrentLocation )<= 2000 -- 2 Km

Hemen hemen her veritabanı için benzer işlevsellik olmalıdır.

Jeo uzamsal indekslemeyi doğru bir şekilde uyguladıysanız, aramalarınız kullandığınız yaklaşımdan çok daha hızlı olacaktır.


1
Aracılığıyla okumak için bir dakikanızı ayırın düzenleme yardım içinde yardım merkezindeki . Stack Overflow'da biçimlendirme diğer sitelerden farklıdır.
Dharman
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.