Domanda

Ho problemi di attuazione della funzione descritta qui qui .

Questa è la mia implementazione Java:

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

converto il cuscinetto gradi in radianti e convertire la distanza (km) in una distanza radianti prima di chiamare la funzione -. In modo che non è questo il problema

Tuttavia, quando coordinate I ingresso quali: lat = 49,25,705 mila; lon = -123,140259; con un cuscinetto di 225 (sud-ovest) e una distanza di 1 km

ottengo questo restituito: lat: -1,0085434360125864 lon: -3,7595299668539504

Il suo, ovviamente, non è corretto, chiunque può vedere quello che sto facendo male?

Grazie

È stato utile?

Soluzione

Sembra che questi sono i problemi nel codice:

  1. È necessario convertire lat1 e lon1 in radianti prima di chiamare la funzione.
  2. È possibile che venga ridimensionando radialDistance in modo non corretto.
  3. Verifica di un numero in virgola mobile per l'uguaglianza è pericoloso. Due numeri che sono uguali dopo aritmetica esatta potrebbero non essere esattamente uguale dopo virgola mobile. Così abs(x-y) < threshold è più sicuro di x == y per testare numeri due virgola mobile x e y per la parità.
  4. Penso che si desidera convertire lat e lon da radianti in gradi.

Ecco la mia implementazione del codice 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()

Ecco l'output:

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

Altri suggerimenti

In sostanza, sembra che il problema è che si sta passando latitudine, longitudine e tenendo in gradi anziché in radianti. Provate assicurando che si sono sempre passando radianti per la vostra funzione e vedere quello che si ottiene indietro.

PS: vedi problemi simili discussi qui e here .

Credo che ci sia un problema nel Algoritmo fornito in un messaggio 5.

Funziona, ma solo per la latitudine, la longitudine per la presenza di un problema a causa del segno.

I dati parlano da soli:

  

49.26 -123,14 225,0 1,0 49.25 -123,13

Se si inizia da -123,14 ° e andate a ovest si dovrebbe avere qualcosa di molto in Occidente. Qui torniamo a est (-123,13)!

La formula dovrebbe include da qualche parte:

  

degreeBearing = ((360-degreeBearing)% 360)

prima radianti conversione.

Quando ho implementato questo, le mie latitudini risultanti erano corretti ma le longitudini si sbagliavano. Per esempio punto di partenza: 36.9460678N 9.434807E, Bearing 45,03,334 mila, Distanza 15,0083,313 mila chilometri Il risultato è stato 37.0412865N 9.315302E Questo è più a ovest rispetto al mio punto di partenza, piuttosto che più a est. In realtà è come se il cuscinetto è stato 315.03334 gradi.

Più ricerca web mi ha portato a: http: //www.movable- type.co.uk/scripts/latlong.html Il codice di longitudine è mostrare al di sotto (in C # con tutto ciò che in radianti)

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

Questo sembra funzionare bene per me. La speranza è utile.

Grazie per il vostro codice Python Ho provato la sua creazione nel mio caso d'uso dove sto cercando di trovare il lon lat di un punto tra due altri ad una distanza impostata dal primo punto quindi è abbastanza similare al codice appart che il mio cuscinetto è dinamicamente calcolato

punto iniziale (LAT1) lon1 / LAT1 = 55,625,541 mila, -21,142463

punto finale (Lat2) lon2 / Lat2 = 55,625,792 mila, -22,142248

il mio risultato dovrebbe essere un punto tra questi due in lon3 / LAT3 unfortunetly Ottengo lon3 / LAT3 = 0.0267695450609,0.0223553243666

Ho pensato che questo potrebbe essere una differenza nel lon lat, ma non quando aggiungo o sub che non è buono

tutto il consiglio sarebbe davvero grande Grazie

ecco la mia realizzazione

distanza = 0.001 Epsilon = 0.000001

calcolo cuscinetto dinamicamente

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)

calcolo lon3 LAT3 dinamicamente

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

Tutto sta funzionando come previsto, ma il problema è che i tuoi calcoli si assume la Terra sia una sfera, quando in realtà si avvicina un ellissoide.

Un rapido a strascico del tuo motore di ricerca preferito per 'Vincenty Formula', si spera, rivelarsi utile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top