Berechnen angegebenen Koordinaten ein Lager und einen Abstand
-
22-08-2019 - |
Frage
ich Probleme habe, die hier beschriebene Funktion Implementierung hier .
Das ist meine Java-Implementierung:
private static double[] pointRadialDistance(double lat1, double lon1,
double radianBearing, double radialDistance) {
double lat = Math.asin(Math.sin(lat1)*Math.cos(radialDistance)+Math.cos(lat1)
*Math.sin(radialDistance)*Math.cos(radianBearing));
double lon;
if(Math.cos(lat) == 0) { // Endpoint a pole
lon=lon1;
}
else {
lon = ((lon1-Math.asin(Math.sin(radianBearing)*Math.sin(radialDistance)/Math.cos(lat))
+Math.PI) % (2*Math.PI)) - Math.PI;
}
return (new double[]{lat, lon});
}
Ich konvertiere den Grad Lager in Radiant und wandeln die Entfernung (km) in einen Radiant Abstand vor dem Funktionsaufruf -. So ist das nicht das Problem
Wenn ich jedoch Eingabekoordinaten wie zum Beispiel: lat = 49,25705; lon = -123,140259; mit einem Lager von 225 (Süd-West) und einem Abstand von 1 km
ich dies zurück: lat: -1,0085434360125864 lon: -3,7595299668539504
Es ist offensichtlich nicht richtig ist, kann man sehen, was ich falsch mache?
Danke
Lösung
Es scheint, wie dies die Probleme in Ihrem Code sind:
- Sie müssen
lat1
undlon1
in Radiant konvertieren, bevor Sie Ihre Funktion aufrufen. - Sie können
radialDistance
werden Skalierung falsch. - Testen einer Gleitkommazahl für die Gleichstellung ist gefährlich. Zwei Zahlen, die nach genauer Arithmetik gleich sind möglicherweise nicht genau gleich nach Gleitkommaarithmetik. So ist
abs(x-y) < threshold
sicherer alsx == y
zum Testen zwei Gleitkommazahlenx
undy
für die Gleichstellung. - Ich glaube, Sie
lat
undlon
von Radiant in Grad konvertieren möchten.
Hier ist meine Implementierung des Codes in Python:
#!/usr/bin/env python
from math import asin,cos,pi,sin
rEarth = 6371.01 # Earth's average radius in km
epsilon = 0.000001 # threshold for floating-point equality
def deg2rad(angle):
return angle*pi/180
def rad2deg(angle):
return angle*180/pi
def pointRadialDistance(lat1, lon1, bearing, distance):
"""
Return final coordinates (lat2,lon2) [in degrees] given initial coordinates
(lat1,lon1) [in degrees] and a bearing [in degrees] and distance [in km]
"""
rlat1 = deg2rad(lat1)
rlon1 = deg2rad(lon1)
rbearing = deg2rad(bearing)
rdistance = distance / rEarth # normalize linear distance to radian angle
rlat = asin( sin(rlat1) * cos(rdistance) + cos(rlat1) * sin(rdistance) * cos(rbearing) )
if cos(rlat) == 0 or abs(cos(rlat)) < epsilon: # Endpoint a pole
rlon=rlon1
else:
rlon = ( (rlon1 - asin( sin(rbearing)* sin(rdistance) / cos(rlat) ) + pi ) % (2*pi) ) - pi
lat = rad2deg(rlat)
lon = rad2deg(rlon)
return (lat, lon)
def main():
print "lat1 \t lon1 \t\t bear \t dist \t\t lat2 \t\t lon2"
testcases = []
testcases.append((0,0,0,1))
testcases.append((0,0,90,1))
testcases.append((0,0,0,100))
testcases.append((0,0,90,100))
testcases.append((49.25705,-123.140259,225,1))
testcases.append((49.25705,-123.140259,225,100))
testcases.append((49.25705,-123.140259,225,1000))
for lat1, lon1, bear, dist in testcases:
(lat,lon) = pointRadialDistance(lat1,lon1,bear,dist)
print "%6.2f \t %6.2f \t %4.1f \t %6.1f \t %6.2f \t %6.2f" % (lat1,lon1,bear,dist,lat,lon)
if __name__ == "__main__":
main()
Hier ist die Ausgabe:
lat1 lon1 bear dist lat2 lon2
0.00 0.00 0.0 1.0 0.01 0.00
0.00 0.00 90.0 1.0 0.00 -0.01
0.00 0.00 0.0 100.0 0.90 0.00
0.00 0.00 90.0 100.0 0.00 -0.90
49.26 -123.14 225.0 1.0 49.25 -123.13
49.26 -123.14 225.0 100.0 48.62 -122.18
49.26 -123.14 225.0 1000.0 42.55 -114.51
Andere Tipps
Ich denke, es ist ein Problem in dem Algorithmus in Meldung bereitgestellt 5.
Es funktioniert aber nur für die Breite, die Länge ein Problem wegen der Zeichen ist.
Die Daten sprechen für sich:
49,26 -123,14 225,0 1,0 49,25 -123,13
Wenn Sie von -123,14 ° beginnen und gehen WEST sollten Sie etwas FAR im Westen haben. Hier gehen wir wieder auf dem EAST (-123,13)!
Die Formel sollte enthält irgendwo:
degreeBearing = ((360-degreeBearing)% 360)
vor Radiant convertion.
Als ich das umgesetzt, meine resultierenden Breiten waren richtig, aber die Längen waren falsch. Zum Beispiel Ausgangspunkt: 36.9460678N 9.434807E, Lager 45,03334, Entfernung 15.0083313km Das Ergebnis war 37.0412865N 9.315302E Das ist weiter westlich als mein Ausgangspunkt, anstatt weiter nach Osten. In der Tat ist es, als ob das Lager war 315,03334 Grad.
Weitere Web-Suche führte mich zu: http: //www.movable- type.co.uk/scripts/latlong.html Der Längencode ist unten zeigen (in C # mit allem, was in Radiant)
if ((Math.Cos(rLat2) == 0) || (Math.Abs(Math.Cos(rLat2)) < EPSILON))
{
rLon2 = rLon1;
}
else
{
rLon2 = rLon1 + Math.Atan2(Math.Sin(rBearing) * Math.Sin(rDistance) * Math.Cos(rLat1), Math.Cos(rDistance) - Math.Sin(rLat1) * Math.Sin(rLat2));
}
Das scheint gut für mich zu arbeiten. Ich hoffe, es ist hilfreich.
Vielen Dank für Ihre Python-Code Ich habe versucht, es in meinem Anwendungsfall einstellen wo ich versuche, die lat lon eines Punktes zwischen zwei anderen zu finden in einem bestimmten Abstand von dem ersten Punkt so ist es recht, um Ihren Code similare appart, dass mein Lager dynamisch berechnet
Startpunkt (LAT1) LON1 / LAT1 = 55,625541, -21,142463
Endpunkt (LAT2) LON2 / LAT2 = 55,625792, -22,142248
mein Ergebnis sollte einen Punkt zwischen diesen beiden bei lon3 / LAT3 sein unfortunetly ich lon3 / LAT3 = 0.0267695450609,0.0223553243666
Ich dachte, dies könnte ein Unterschied in lat lon, aber keine wenn ich hinzufüge oder Unter es nicht gut ist,
Jede Beratung wäre wirklich toll Dank
hier ist meine Implementierung
Abstand = 0,001 epsilon = 0.000001
Berechnung dynamisch
Lagery = math.sin(distance) * math.cos(lat2);
x = math.cos(lat1)*math.sin(lat2) - math.sin(lat1)*math.cos(lat2)*math.cos(distance);
bearing = math.atan2(y, x)
Berechnung LAT3 lon3 dynamisch
rlat1 = (lat1 * 180) / math.pi
rlon1 = (lon1 * 180) / math.pi
rbearing = (bearing * 180) / math.pi
rdistance = distance / R # normalize linear distance to radian angle
rlat = math.asin( math.sin(rlat1) * math.cos(rdistance) + math.cos(rlat1) * math.sin(rdistance) * math.cos(rbearing) )
if math.cos(rlat) == 0 or abs(math.cos(rlat)) < epsilon: # Endpoint a pole
rlon=rlon1
else:
rlon = ( (rlon1 + math.asin( math.sin(rbearing)* math.sin(rdistance) / math.cos(rlat) ) + math.pi ) % (2*math.pi) ) - math.pi
lat3 = (rlat * math.pi)/ 180
lon3 = (rlon * math.pi)/ 180
Alles funktioniert wie vorgesehen, aber das Problem ist, dass Ihre Mathe die Erde nimmt eine Kugel zu sein, wenn es in Wirklichkeit einen Ellipsoid annähert.
Ein schnelles Schleppnetz Ihrer gewünschte Suchmaschine für ‚Vincenty Formel‘ wird hoffentlich nützlich erweisen.