Cálculo de nueva longitud, latitud a partir de antiguos + n metros

84

Quiero crear 2 nuevas longitudes y 2 nuevas latitudes basadas en una coordenada y una distancia en metros, quiero crear un bonito cuadro delimitador alrededor de cierto punto. Es para una parte de la ciudad y un máximo de ± 1500 metros. Por tanto, no creo que deba tenerse en cuenta la curvatura de la tierra.

Entonces tengo 50.0452345(x) e 4.3242234(y) y quiero saber x + 500 metros, x - 500 metros, y - 500 metros, y + 500 metros

Encontré muchos algoritmos, pero casi todos parecen lidiar con la distancia entre puntos.

Benjamin Udink ten Cate
fuente

Respuestas:

122

El número de kilómetros por grado de longitud es aproximadamente

(2*pi/360) * r_earth * cos(theta)

donde thetaestá la latitud en grados y r_earthes aproximadamente 6378 km.

El número de kilómetros por grado de latitud es aproximadamente el mismo en todas las ubicaciones, aprox.

(2*pi/360) * r_earth = 111 km / degree 

Entonces puedes hacer:

new_latitude  = latitude  + (dy / r_earth) * (180 / pi);
new_longitude = longitude + (dx / r_earth) * (180 / pi) / cos(latitude * pi/180);

Siempre que dxy dysean pequeños en comparación con el radio de la tierra y no te acerques demasiado a los polos.

nibot
fuente
2
para convertir de grados a radianes se multiplica con py y se divide por 180. Pero se escribecos(latitude*180/pi)
josch
9
@josch: Buen partido. Trate de corregir la respuesta la próxima vez en lugar de simplemente proponer una corrección. Mucha gente simplemente copia y pega el código de StackOverflow pensando que es correcto y está listo para usar.
Alex Essilfie
4
ok, cual sera la direccion? Quiero decir, si quiero agregar 50 metros, ¿dónde se agregarán? ¿Derecha, izquierda, arriba o abajo?
Tushar Monirul
3
La Tierra no es perfectamente esférica, por lo que usar un solo valor para "radio" es una aproximación. Wikipedia dice que "las distancias desde los puntos en la superficie hasta el centro varían entre 6.353 km y 6.384 km". También dice "Varias formas diferentes de modelar la Tierra como una esfera, cada una produce un radio medio de 6.371 km", lo que indica su valor. Realmente, si esta corrección es significativa en su aplicación, debería utilizar un algoritmo mejor de todos modos.
nibot
4
Para cualquiera que no esté seguro, la variable r_earth debe estar en metros y debe ser igual a aproximadamente 6371000.0
Amit Assaraf
26

La respuesta aceptada es perfectamente correcta y funciona. Hice algunos ajustes y me convertí en esto:

double meters = 50;

// number of km per degree = ~111km (111.32 in google maps, but range varies
   between 110.567km at the equator and 111.699km at the poles)
// 1km in degree = 1 / 111.32km = 0.0089
// 1m in degree = 0.0089 / 1000 = 0.0000089
double coef = meters * 0.0000089;

double new_lat = my_lat + coef;

// pi / 180 = 0.018
double new_long = my_long + coef / Math.cos(my_lat * 0.018);

Espero que esto también ayude.

Numan Karaaslan
fuente
27
0.0000089? Intenta evitar los números mágicos, nadie lo entenderá.
Scai
2
Es una versión abreviada del diámetro de la tierra y los números pi en el código. no magia.
Numan Karaaslan
16
Sigue siendo mágico si nadie sabe cómo reproducir este número. ¿Por qué no pones el cálculo completo en tu código?
scai
13
1 grado en el mapa de Google es igual a 111,32 kilómetros. 1 Grado = 111,32 KM. 1KM en grados = 1 / 111.32 = 0.008983. 1M en grados = 0.000008983.
Muhammad Azeem
7
Debería haber hecho un comentario en su respuesta, ponerlo en los comentarios no es útil.
chutsu
18

Para la latitud, haga:

var earth = 6378.137,  //radius of the earth in kilometer
    pi = Math.PI,
    m = (1 / ((2 * pi / 360) * earth)) / 1000;  //1 meter in degree

var new_latitude = latitude + (your_meters * m);

Para la longitud haz:

var earth = 6378.137,  //radius of the earth in kilometer
    pi = Math.PI,
    cos = Math.cos,
    m = (1 / ((2 * pi / 360) * earth)) / 1000;  //1 meter in degree

var new_longitude = longitude + (your_meters * m) / cos(latitude * (pi / 180));

La variable your_meterspuede contener un valor positivo o negativo.

ssten
fuente
8

¿Ha comprobado: ¿Cómo encuentro la latitud / longitud que está x km al norte de una latitud / longitud determinada ?

Estos cálculos son molestos en el mejor de los casos, he hecho muchos de ellos. La fórmula haversine será tu amiga.

Alguna referencia: http://www.movable-type.co.uk/scripts/latlong.html

Ryan Ternier
fuente
Si trabaja para un área bastante pequeña, ¿es realmente malo hacer una latitud-0.09 y una longitud-0.0148 para obtener aproximadamente un área de km cuadrados?
Benjamin Udink ten Cate
Yo diría que no es realmente malo. El kilómetro cuadrado a ese nivel no se verá distorsionado por la curvatura de la Tierra, siempre y cuando la Lat / Lng con la que está tratando sea decimal.
Ryan Ternier
1
@BenjaminUdinktenCate Eso funcionará en Amsterdam, pero será inexacto en otras partes del mundo. Haciendo "longitud-0.0148" sólo obtendrá aproximadamente 0.16 km en el ecuador.
nibot
3

Tuve que pasar aproximadamente dos horas para resolver la solución de @nibot, simplemente necesitaba un método para crear un cuadro de límite dado su punto central y ancho / alto (o radio) en kilómetros:

No entiendo la solución matemática / geográficamente. Modifiqué la solución (por intento y error) para obtener las cuatro coordenadas:

Norte:

private static Position FromKmToNPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_latitude = p.Lat + (km / r_earth) * (180 / pi);
    return new Position(new_latitude, p.Long);
}

Este:

private static Position FromKmToEPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_longitude = p.Long + (km / r_earth) * (180 / pi) / Math.Cos(p.Lat * pi / 180);
    return new Position(p.Lat, new_longitude);
}

Sur:

private static Position FromKmToSPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_latitude = p.Lat - (km / r_earth) * (180 / pi);
    return new Position(new_latitude, p.Long);
}

Oeste:

private static Position FromKmToWPosition(Position p, double km)
{
    double r_earth = 6378;
    var pi = Math.PI;
    var new_longitude = p.Long - (km / r_earth) * (180 / pi) / Math.Cos(p.Lat * pi / 180);
    return new Position(p.Lat, new_longitude);
}
mshwf
fuente
1

si no tiene que ser muy exacto, entonces: cada 10000 metros es aproximadamente 0,1 para latitud y longitud. por ejemplo, quiero cargar ubicaciones 3000 metros alrededor de point_A de mi base de datos:

double newMeter =  3000 * 0.1 / 10000;
double lat1 = point_A.latitude - newMeter;
double lat2 = point_A.latitude + newMeter;
double lon1 = point_A.longitude - newMeter;
double lon1 = point_A.longitude + newMeter;
Cursor c = mDb.rawQuery("select * from TABLE1  where lat >= " + lat1 + " and lat <= " + lat2 + " and lon >= " + lon1 + " and lon <= " + lon2 + " order by id", null);
farhad.kargaran
fuente
0
public double MeterToDegree(double meters, double latitude)
{
    return meters / (111.32 * 1000 * Math.Cos(latitude * (Math.PI / 180)));
}
M Komaei
fuente
-1
var meters = 50;
var coef = meters * 0.0000089;
var new_lat = map.getCenter().lat.apply() + coef;
var new_long = map.getCenter().lng.apply() + coef / Math.cos(new_lat * 0.018);
map.setCenter({lat:new_lat, lng:new_long});
Eyni Kave
fuente
2
Agregue alguna explicación a su respuesta.
Anna
Si desea mover el objeto del mapa a unos 50 metros cerca del centro del mapa actual, puede usar este código con +, - números como reemplazo de +50
Eyni Kave