Pregunta

Estoy teniendo problemas para implementar la función descrita aquí aquí .

Esta es mi aplicación 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});
}

convierto el cojinete grados a radianes y convertir la distancia (km) en una distancia radianes antes de llamar a la función -. Por lo que no es el problema

Sin embargo, cuando las coordenadas de entrada, tales como: lat = 49,25705; lon = -123,140259; con un cojinete de 225 (sur-oeste) y una distancia de 1 km

Me sale este regresó: Lat: -1.0085434360125864 lon: -3,7595299668539504

Su obviamente no es correcta, puede alguien ver lo que estoy haciendo mal?

Gracias

¿Fue útil?

Solución

Parece que estos son los temas en su código:

  1. Es necesario para convertir lat1 y lon1 a radianes antes de llamar a su función.
  2. Es posible que se aumenta de escala radialDistance incorrectamente.
  3. Comprobación de un número de coma flotante por la igualdad es peligroso. Dos números que son iguales después de aritmética exacta podría no ser exactamente igual después de la aritmética de punto flotante. Por lo tanto es más seguro que abs(x-y) < threshold x == y para probar dos números de punto flotante y x y por la igualdad.
  4. Pienso que desea convertir lat y lon de radianes a grados.

Aquí está mi aplicación de su código en 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()

Aquí está la salida:

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

Otros consejos

En el fondo, parece que el problema es que está de paso latitud, longitud y teniendo como grados en lugar de radianes. Intenta garantizando así que siempre está de paso radianes a su función y ver lo que hay detrás.

PD: ver problemas similares discutidos aquí y here .

Creo que hay un problema en el algoritmo proporcionado en el mensaje 5.

Funciona, pero sólo para la latitud, de la longitud no es un problema debido a la señal.

Los datos hablan por sí solos:

  

49,26 -123,14 225,0 1,0 49,25 -123,13

Si se parte de -123,14 ° y vaya hacia el oeste usted debe tener algo lejos en el oeste. Aquí vamos de nuevo en el ESTE (-123,13)!

la fórmula debe incluye alguna parte:

  

degreeBearing = ((360-degreeBearing)% 360)

antes de la conversión en radianes.

Cuando implementé esto, mis latitudes resultantes eran correctas, pero las longitudes estaban equivocados. Por ejemplo, el punto de partida: 36.9460678N 9.434807E, Teniendo 45.03334, 15,0083313 kilometros Distancia El resultado fue 37.0412865N 9.315302E Eso es más al oeste que mi punto de partida, en lugar de hacia el este. De hecho, es como si el porte era 315.03334 grados.

Más Web búsqueda me llevó a: http: //www.movable- type.co.uk/scripts/latlong.html El código de longitud es mostrar a continuación (en C # con todo en radianes)

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

Esto parece funcionar bien para mí. Esperamos que sea útil.

Gracias por su código Python Traté de su puesta en marcha en mi caso de uso donde yo estoy tratando de encontrar la lon lat de un punto entre otros dos a una distancia determinada desde el primer punto lo que es muy similare a su código appart que mi rodamiento se calcula dinámicamente

punto de inicio (lat1) lon1 / lat1 = 55.625541, -21.142463

punto final (Lat2) Lon2 / Lat2 = 55.625792, -22.142248

mi resultado debe ser un punto entre estos dos en lon3 / Lat3 unfortunetly consigo lon3 / Lat3 = 0.0267695450609,0.0223553243666

pensé que esto podría haber una diferencia en lon lat pero sin cuando agrego o sub que no es bueno

Cualquier consejo sería realmente grande Gracias

aquí está mi aplicación

distancia = 0,001 epsilon = 0.000001

cálculo de rodamiento dinámicamente

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)

calcular lon3 Lat3 dinámica

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

Todo está funcionando según lo previsto, pero el problema es que tus cuentas asume que la Tierra es una esfera cuando en realidad se aproxima a un elipsoide.

Una rápida búsqueda de su motor de búsqueda favorito para 'Vincenty Fórmula' se espera que resulte útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top