Proste obliczenia do pracy z odległościami w szerokości / długości i km?

119

Czy istnieje proste obliczenie, które mogę wykonać, które zamieni km na wartość, którą mogę dodać do wartości zmiennoprzecinkowej szerokości lub długości, aby obliczyć obwiednię wyszukiwania? Nie musi być całkowicie dokładne.

Na przykład: gdybym dostał szerokość / długość dla Londynu w Anglii (51.5001524, -0.1262362) i chciałbym obliczyć, jaka byłaby szerokość 25 km na wschód / zachód od tego punktu, a jaka byłaby długość 25 km na północ / południe od tego punktu punkt, co musiałbym zrobić, aby zamienić 25 km na ułamek dziesiętny, aby dodać do powyższych wartości?

Szukam ogólnej praktycznej zasady, czyli: 1km == +/- 0.XXX

Edytować:

Moje pierwotne wyszukiwanie hasła „lat lon” nie zwróciło tego wyniku:

Jak obliczyć prostokąt ograniczający dla podanej lokalizacji szerokości / lng?

Przyjęta odpowiedź wydaje się adekwatna do moich wymagań.

Phillip B Oldham
źródło

Odpowiedzi:

221

Przybliżone konwersje to:

  • Szerokość geograficzna: 1 st. = 110,574 km
  • Długość geograficzna: 1 st = 111,320 * cos (szerokość geograficzna) km

Nie jest to w pełni poprawne dla spłaszczenia biegunowego Ziemi - do tego prawdopodobnie potrzebowałbyś bardziej skomplikowanego wzoru wykorzystującego elipsoidę odniesienia WGS84 (model używany dla GPS). Ale błąd jest prawdopodobnie nieistotny dla twoich celów.

Źródło: http://en.wikipedia.org/wiki/Latitude

Uwaga : należy pamiętać, że współrzędne długości geograficznej prostopadłej są wyrażane w stopniach, podczas gdy cosfunkcja w większości (wszystkich?) Języków zazwyczaj akceptuje radiany, dlatego potrzebny jest stopień konwersji na radiany .

Jim Lewis
źródło
Czy masz na myśli cos (długość geograficzną) w drugim wzorze?
Odys,
1
Jak to wymyśliłeś? Coś mi brakuje, czy mógłbyś rozwinąć obliczenia długości geograficznej? Ty
Odys,
5
@Odys: Jeśli porównujesz dwa punkty leżące na tej samej linii długości geograficznej (północ / południe), leżą one na wielkim okręgu, a współczynnik konwersji to po prostu obwód biegunowy Ziemi podzielony przez 360 stopni. Ale jest inaczej w przypadku pomiarów wschód-zachód, ponieważ (z wyjątkiem równika) nie mierzy się wzdłuż „wielkiego koła”, więc „obwód” na danej szerokości geograficznej jest mniejszy. A współczynnik korygujący okazuje się być cosinusem szerokości geograficznej.
Jim Lewis,
17
Moje wyjaśnienie: cos(0°) = 1=> Dlatego nie stosuje się współczynnika korygującego do obliczeń na równiku. Najszersze są tam długości geograficzne. cos(90°) = 0=> Na biegunach długości spotykają się w jednym punkcie. Nie ma odległości do obliczenia.
Jenny O'Reilly
4
@Stijn: Musisz przekonwertować stopnie na radiany przed wywołaniem Math.cos ().
Jim Lewis
5

Jeśli używasz języka Java, JavaScript lub PHP, istnieje biblioteka, która wykona te obliczenia dokładnie, używając zabawnie skomplikowanej (ale wciąż szybkiej) trygonometrii:

http://www.jstott.me.uk/jcoord/

skaffman
źródło
Witryna ma teraz bibliotekę.
99
2
Link jest uszkodzony!
chatzich
W przypadku PHP możesz użyć tego widelca: github.com/dvdoug/PHPCoord
dearsina
1

http://www.jstott.me.uk/jcoord/ - użyj tej biblioteki

            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);
Nikhil Dinesh
źródło
1

Dziękuję Jimowi Lewisowi za świetną odpowiedź i chciałbym zilustrować to rozwiązanie moją funkcją w Swift:

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

W tej funkcji do przeliczania odległości używam następujących wzorów:

latDistance / 110.574
longDistance / (111.320 * cos(lat / .pi / 180))
Serj Kultenko
źródło
Myślę, że powinno to być „lat * pi / 180”
magamig
1

Dlaczego nie używać poprawnie sformułowanych zapytań geoprzestrzennych ???

Oto strona odniesienia serwera SQL w funkcji geoprzestrzennej STContains:

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

lub jeśli nie chcesz używać konwersji w postaci pól i radianów, możesz zawsze użyć funkcji odległości, aby znaleźć potrzebne punkty:

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

Powinna istnieć podobna funkcjonalność dla prawie każdej bazy danych.

Jeśli poprawnie zaimplementowałeś indeksowanie geoprzestrzenne, Twoje wyszukiwania będą znacznie szybsze niż metoda, której używasz

George Karadov
źródło
1
Poświęć chwilę na przeczytanie pomocy dotyczącej edycji w Centrum pomocy . Formatowanie w witrynie Stack Overflow jest inne niż w innych witrynach.
Dharman