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

War es hilfreich?

Lösung

Es scheint, wie dies die Probleme in Ihrem Code sind:

  1. Sie müssen lat1 und lon1 in Radiant konvertieren, bevor Sie Ihre Funktion aufrufen.
  2. Sie können radialDistance werden Skalierung falsch.
  3. 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 als x == y zum Testen zwei Gleitkommazahlen x und y für die Gleichstellung.
  4. Ich glaube, Sie lat und lon 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

Im Grunde scheint es, dass Ihr Problem ist, dass Sie Breite, Länge sind vorbei und Lager als Grad statt Radiant. Versuchen Sie sicher, dass Sie immer Radiant in Ihre Funktion übergeben und sehen Sie, was Ihnen in Verbindung.

PS: siehe ähnliche Probleme diskutiert hier und here .

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

Lager
y = 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top