2010-06-11 18 views
7

Potrzebuję funkcję, która mapuje pozycje GPS do X/Y wartości tak:przekształcić długości geograficznej szerokości geograficznej w metrach

getXYpos(GeoPoint relativeNullPoint, GeoPoint p){ 
    deltaLatitude=p.latitude-relativeNullPoint.latitude; 
    deltaLongitude=p.longitude-relativeNullPoint.longitude; 
    ... 
    resultX=latitude (or west to east) distance in meters from p to relativeNullPoint 
    resultY=longitude (or south to north) distance in meters from p to relativeNullPoint 
} 

Widziałem kilka implementacje „odległości dwóch geoPoints”, ale wszystkie one po prostu obliczyć powietrze -line odległość. Myślę, że deltaLongitude można przekształcić w metry bezpośrednio, ale deltaLatitude zależy od długości geograficznej. Czy ktoś wie, jak rozwiązać ten problem?

Odpowiedz

13

Na początek, myślę, że masz swoją latitude i longitude odwrócone. Długość mierzy X, a szerokość geograficzna Y.

Szerokość geograficzna łatwo jest zmienić na odległość północ-południe. Wiemy, że 360 ​​stopni to pełne koło wokół Ziemi przez bieguny i that distance is 40008000 meters. Dopóki nie musisz uwzględniać błędów związanych z ziemią, która nie jest idealnie sferyczna, formuła ta to deltaLatitude * 40008000/360.

Najtrudniejszą częścią jest zamiana długości na X, jak podejrzewasz. Ponieważ zależy to od szerokości geograficznej, musisz zdecydować, z której szerokości geograficznej będziesz korzystać - możesz wybrać szerokość geograficzną swojego początku, szerokość geograficzną miejsca docelowego lub dowolny dowolny punkt pośredni. Obwód na równiku (szerokość geograficzna 0) wynosi 40075160 metrów. Obwód koła o danej szerokości geograficznej będzie proporcjonalny do cosinusa, więc formuła będzie wynosiła deltaLongitude * 40075160 * cos(latitude)/360.

Edytuj: Twój komentarz wskazuje, że miałeś problem ze wzorem długości; możesz użyć stopni zamiast radianów w wywołaniu cos, to typowy błąd debiutanta. Aby upewnić się, że nie ma dwuznaczności, oto działający kod w Pythonie.

def asRadians(degrees): 
    return degrees * pi/180 

def getXYpos(relativeNullPoint, p): 
    """ Calculates X and Y distances in meters. 
    """ 
    deltaLatitude = p.latitude - relativeNullPoint.latitude 
    deltaLongitude = p.longitude - relativeNullPoint.longitude 
    latitudeCircumference = 40075160 * cos(asRadians(relativeNullPoint.latitude)) 
    resultX = deltaLongitude * latitudeCircumference/360 
    resultY = deltaLatitude * 40008000/360 
    return resultX, resultY 

Wybrałem użycie względnej szerokości NullPoint do obliczenia X. Ma to tę zaletę, że jeśli skonwertujesz wiele punktów o tej samej długości geograficznej, będą one miały takie same X; linie północ-południe będą pionowe.

Ponownie edytuj: Powinienem był zauważyć, że jest to bardzo prosta formuła i powinieneś znać jej ograniczenia. Oczywiście Ziemia nie jest płaska, więc każda próba mapowania jej na współrzędne XY będzie wiązała się z pewnymi kompromisami. Powyższy wzór I działa najlepiej, gdy przekształcany obszar jest wystarczająco mały, aby uznać go za płaski i gdzie lekką krzywiznę i brak równoległości linii północ-południe można zignorować. Istnieje cała nauka do mapowania prognoz; jeśli chcesz zobaczyć pewne możliwości, dobrym miejscem do rozpoczęcia będzie Wikipedia. Ta konkretna projekcja jest znana jako the Equirectangular projection, z pewnym dodatkowym skalowaniem.

+0

OK próbowałem tego, a obliczenia szerokości geograficznej są bardzo dokładne :), ale wartości długości geograficznej są zawsze od 1,3 do dużego współczynnika dla testowania szerokości geograficznej. Myślę, że nie jest to dobry pomysł, aby po prostu podzielić przez ten czynnik, ponieważ prawdopodobnie będzie różnił się dla różnych szerokościach geograficznych, może trzeba obliczyć kierunek Ziemi względem obecnej szerokości geograficznej? –

+0

@Sponge, sprawdź aktualizację. –

+0

wielkie dzięki! działa świetnie :) –

1

Istnieją biblioteki na jstott.me.uk dla PHP, Java i Javascript które to zrobić, na przykład

var lld1 = new LatLng(40.718119, -73.995667); // New York 
document.write("New York Lat/Long: " + lld1.toString() + "<br />"); 
var lld2 = new LatLng(51.499981, -0.125313); // London 
document.write("London Lat/Long: " + lld2.toString() + "<br />"); 
var d = lld1.distance(lld2); 
document.write("Surface Distance between New York and London: " + d + "km"); 
Powiązane problemy