2011-05-02 24 views
7

Necesito calcular la latitud y longitud de un punto dado.Calcular latitud y longitud teniendo metros de distancia desde otro punto de latitud/longitud

Conozco la latitud y la longitud de un punto de referencia, y un valor que indica los metros en los ejes x e y desde el punto de referencia. A partir de estos datos, tengo que encontrar la latitud y la longitud del punto.

He buscado preguntas similares, pero parece que la mayoría de las preguntas son sobre la búsqueda de distancia entre dos puntos lat/long. Necesito hacer lo contrario.

¿Cómo puedo hacer? Yo uso Java

+0

** ¡Bienvenido a StackOverflow! ** Saludos. –

Respuesta

9

Aquí está el mejor punto de partida para estas preguntas: Aviation Formulary. Tienen todas las fórmulas para hacer ese tipo de cosas.

De este formulario, creé mi propia clase de Java util. Utiliza muchas cosas internas, por lo que no puedo publicar la clase real aquí, sino darle algunos ejemplos sobre cómo convertir el conocimiento del formulario en código Java.

Acá algunos métodos básicos:

/** 
* the length of one degree of latitude (and one degree of longitude at equator) in meters. 
*/ 
private static final int DEGREE_DISTANCE_AT_EQUATOR = 111329; 
/** 
* the radius of the earth in meters. 
*/ 
private static final double EARTH_RADIUS = 6378137; //meters 
/** 
* the length of one minute of latitude in meters, i.e. one nautical mile in meters. 
*/ 
private static final double MINUTES_TO_METERS = 1852d; 
/** 
* the amount of minutes in one degree. 
*/ 
private static final double DEGREE_TO_MINUTES = 60d; 


/** 
* This method extrapolates the endpoint of a movement with a given length from a given starting point using a given 
* course. 
* 
* @param startPointLat the latitude of the starting point in degrees, must not be {@link Double#NaN}. 
* @param startPointLon the longitude of the starting point in degrees, must not be {@link Double#NaN}. 
* @param course  the course to be used for extrapolation in degrees, must not be {@link Double#NaN}. 
* @param distance  the distance to be extrapolated in meters, must not be {@link Double#NaN}. 
* 
* @return the extrapolated point. 
*/ 
public static Point extrapolate(final double startPointLat, final double startPointLon, final double course, 
           final double distance) { 
    // 
    //lat =asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc)) 
    //dlon=atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(lat)) 
    //lon=mod(lon1+dlon +pi,2*pi)-pi 
    // 
    // where: 
    // lat1,lon1 -start pointi n radians 
    // d   - distance in radians Deg2Rad(nm/60) 
    // tc   - course in radians 

    final double crs = Math.toRadians(course); 
    final double d12 = Math.toRadians(distance/MINUTES_TO_METERS/DEGREE_TO_MINUTES); 

    final double lat1 = Math.toRadians(startPointLat); 
    final double lon1 = Math.toRadians(startPointLon); 

    final double lat = Math.asin(Math.sin(lat1) * Math.cos(d12) 
     + Math.cos(lat1) * Math.sin(d12) * Math.cos(crs)); 
    final double dlon = Math.atan2(Math.sin(crs) * Math.sin(d12) * Math.cos(lat1), 
     Math.cos(d12) - Math.sin(lat1) * Math.sin(lat)); 
    final double lon = (lon1 + dlon + Math.PI) % (2 * Math.PI) - Math.PI; 

    return new Point(Math.toDegrees(lat), Math.toDegrees(lon)); 
} 

/** 
* calculates the length of one degree of longitude at the given latitude. 
* 
* @param latitude the latitude to calculate the longitude distance for, must not be {@link Double#NaN}. 
* 
* @return the length of one degree of longitude at the given latitude in meters. 
*/ 
public static double longitudeDistanceAtLatitude(final double latitude) { 

    final double longitudeDistanceScaleForCurrentLatitude = Math.cos(Math.toRadians(latitude)); 
    return DEGREE_DISTANCE_AT_EQUATOR * longitudeDistanceScaleForCurrentLatitude; 
} 
+2

¿Responde esto a tu pregunta? - Entonces acepta la respuesta. – BertNase

0

esto no es realmente una respuesta, pero el apartado de comentarios es demasiado corta para lo que quiero para publicar, y este resultado habían subido bastante alto cuando estaba buscando en Google una respuesta. El código anterior de BertNase es bueno, y lo estoy usando. Sin embargo, hay algunas rarezas en los casos extremos. No estoy 100% seguro de que el código sea incorrecto, ya que todavía estoy aprendiendo cosas sobre geo, pero estoy agregando los parámetros de mi caso de prueba junit que escribí a su alrededor. Por ejemplo, la longitud va de 180 a -90 cuando me muevo hacia el sur durante 100m (caso 10)

/*0*/ { inputOf(0.0, 0.0), NORTH, shouldGiveAnswerOf(0.0009, 0.0) }, 
/*1*/ { inputOf(0.0, 0.0), SOUTH, shouldGiveAnswerOf(-0.0009, 0.0) }, 
/*2*/ { inputOf(0.0, 0.0), WEST, shouldGiveAnswerOf(0.0, -0.0009) }, 
/*3*/ { inputOf(0.0, 0.0), EAST, shouldGiveAnswerOf(0.0, 0.0009) }, 

/*4*/ { inputOf(90.0, 180.0), NORTH, shouldGiveAnswerOf(89.9991, -180.0) }, 
/*5*/ { inputOf(0.0, 180.0), NORTH, shouldGiveAnswerOf(0.0009, -180.0) }, 
/*6*/ { inputOf(-90.0, 180.0), NORTH, shouldGiveAnswerOf(-89.9991, -180.0) }, 
/*7*/ { inputOf(90.0, -180.0), NORTH, shouldGiveAnswerOf(89.9991, -180.0) }, 
/*8*/ { inputOf(0.0, -180.0), NORTH, shouldGiveAnswerOf(0.0009, -180.0) }, 
/*9*/ { inputOf(-90.0, -180.0), NORTH, shouldGiveAnswerOf(-89.9991, -180) }, 

/*10*/ { inputOf(90.0, 180.0), SOUTH, shouldGiveAnswerOf(89.9991, -90.0) }, 
/*11*/ { inputOf(0.0, 180.0), SOUTH, shouldGiveAnswerOf(-0.0009, -180.0) }, 
/*12*/ { inputOf(-90.0, 180.0), SOUTH, shouldGiveAnswerOf(-89.9991, -90.0) }, 
/*13*/ { inputOf(90.0, -180.0), SOUTH, shouldGiveAnswerOf(89.9991, -90.0) }, 
/*14*/ { inputOf(0.0, -180.0), SOUTH, shouldGiveAnswerOf(-0.0009, -180.0) }, 
/*15*/ { inputOf(-90.0, -180.0), SOUTH, shouldGiveAnswerOf(-89.9991, -90) }, 

/*16*/ { inputOf(90.0, 180.0), EAST, shouldGiveAnswerOf(89.9991, -90.0) }, 
/*17*/ { inputOf(0.0, 180.0), EAST, shouldGiveAnswerOf(0.0, -179.9991) }, 
/*18*/ { inputOf(-90.0, 180.0), EAST, shouldGiveAnswerOf(-89.9991, -90.0) }, 
/*19*/ { inputOf(90.0, -180.0), EAST, shouldGiveAnswerOf(89.9991, -90.0) }, 
/*20*/ { inputOf(0.0, -180.0), EAST, shouldGiveAnswerOf(0.0, -179.9991) }, 
/*21*/ { inputOf(-90.0, -180.0), EAST, shouldGiveAnswerOf(-89.9991, -90) }, 

/*22*/ { inputOf(10.0, 5.0), NORTH, shouldGiveAnswerOf(10.0009, 5.0) }, 
/*23*/ { inputOf(10.0, 5.0), SOUTH, shouldGiveAnswerOf(9.9991, 5.0) }, 
/*24*/ { inputOf(10.0, 5.0), WEST, shouldGiveAnswerOf(10.0, 4.999086) }, 
/*25*/ { inputOf(10.0, 5.0), EAST, shouldGiveAnswerOf(10.0, 5.000914) }, 

/*26*/ { inputOf(10.0, 5.0), NORTH_EAST, shouldGiveAnswerOf(10.000636, 5.000646) }, 
Cuestiones relacionadas