Distancia entre dos puntos geográficos con MySql

Es un problema poco habitual ya que no siempre se trabaja con coordenadas geográficas en las aplicaciones web, pero en estos últimos años con la irrupción de Google Maps y servicios similares es muy habitual encontrarnos con Mashup que giran en torno a mapas.

Antes de comenzar a desarrollar y solucionar el problema veamos sus posibles funciones dentro de las aplicaciones web:

  • Encontrar localizaciones cercanas a un punto dado
  • Red Social: encontrar amigos cercanos a ti
  • Mapas sociales: encontrar puntos de interes cercanos
  • Páginas Amarillas: encontrar servicios cercanos a un punto dado

Distancia entre dos puntos

En la superficie de la Tierra no nos movemos por un plano recto por lo que en todos los cálculos de distancia debemos tener en cuenta el arco que describe el recorrido entre dos puntos, es pura trigonometria.

Para entender la solución al problema es muy importante entender la formula Haversine, es una ecuación muy importante para la navegación en la que podemos obtener la distancia entre dos puntos geográficos (longitud y latitud) dados.

En este tipo de cálculos omitimos el hecho de que la Tierra no es perfectamente redonda lo que haría aún más complejo el cálculo, en principio este hecho no nos debe afectar y con la solución dada nos será más que suficiente.

Distancia entre dos puntos geográficos con MySql

Aquí tenemos la solución para calcular la distancia entre dos puntos con MySql:

Habitualmente cuando trabajamos con mapas en nuestra aplicación web utilizamos dos campos en la base de datos para almacenar la geolocalización de un punto, estos dos datos son la latitud (su línea de base es el Ecuador) y la longitud (su línea de base es el Meridiano de Greenwich).

Cogemos dos puntos aleatorios, por ejemplo Catedral de Málaga y Plaza de Colón de Madrid.

Catedral Málaga Plaza de Colón
latitud 36.720139 40.425797
longitud -4.419422 -3.690462



Radio de la Tierra: 6378 km.

SELECT (acos(sin(radians(36.720139)) * sin(radians(40.425797)) + 
cos(radians(36.720139)) * cos(radians(40.425797)) *
cos(radians(-4.419422) - radians(-3.690462))) * 6378) as
distanciaMalagaMadrid;


+-----------------------+
| distanciaMalagaMadrid |
+-----------------------+
|       417.34812304175 |
+-----------------------+

El resultado es de 417,348 Kilómetros.

Veamos la soluciónd e una manera más limpia:

PUNTO 1 PUNTO 2
latitud LATITUD_1 LATITUD_2
longitud LONGITUD_1 LONGITUD_2



SELECT (acos(sin(radians(LATITUD_1)) * sin(radians(LATITUD_2)) + 
cos(radians(LATITUD_1)) * cos(radians(LATITUD_2)) *
cos(radians(LONGITUD_1) - radians(LONGITUD_2))) * 6378) as
distanciaPunto1Punto2;


Distancia entre dos puntos geográficos con Javascript

Esta sería la Formula de Haversine anteriormente citada:

Radio de la Tierra: 6378 km.

R = earth’s radius (mean radius = 6,378km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c

Y esta sería su implementación en código Javascript:

var R = 6371; // km
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;

Comentarios

calcular distancia

Quiero calcular la distancia entre la iglesia de O Conforto(pontenova-Lugo) y finca galea(A Seara-Alfoz_lugo)

puntoa geografio

estaria bueno que pongan como se marcan los puntos geograficos asi es mas facil aprender a marcarlos y no poner tanta info por que es mucho al divino boton ademas porai solo necesita algo de la info y tiene que andar leyendo todo este fue mi comentari byeeeeeeeee

Aqui te lo muestro echo en php

function getDistance($lat1, $long1, $lat2, $long2)
{
$earth = 6371; //km change accordingly
//$earth = 3960; //miles

//Point 1 cords
$lat1 = deg2rad($lat1);
$long1= deg2rad($long1);

//Point 2 cords
$lat2 = deg2rad($lat2);
$long2= deg2rad($long2);

//Haversine Formula
$dlong=$long2-$long1;
$dlat=$lat2-$lat1;

$sinlat=sin($dlat/2);
$sinlong=sin($dlong/2);

$a=($sinlat*$sinlat)+cos($lat1)*cos($lat2)*($sinlong*$sinlong);

$c=2*asin(min(1,sqrt($a)));

$d=($earth*$c);

return $d;
}

Enviar un comentario nuevo

El contenido de este campo se mantiene como privado y no se muestra públicamente.
  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Saltos automáticos de líneas y de párrafos.

Más información sobre opciones de formato