Zumbe.net

Comenzando a programar una web

Calcular la distacia entre dos puntos de GPS (latitud, longitud)

Ante la necesidad de crear una función que mida distancia entre un par de puntos expresados en latitud y longitud, busqué por la red, y encontré realmente poco, y la mayoría utilizaba muchos senos y cosenos, lo cual hacía que fallara el código continuamente.

Al final tomé la decisión de hacer mi propio código, con que os lo dejo aquí.

La primera función que os propongo consiste en, dados un par de puntos con latitud/longitud cada uno, calcular la distacia esférica en metros.

Código: php
  1. function distAB($lat1,$lng1,$lat2,$lng2)
  2. {
  3.         $lats = $lat1 - $lat2;
  4.         $lngs = $lng1 - $lng2;
  5.        
  6.         //Paso a metros
  7.         $latm = $lats * 60 * 1845;
  8.         $lngm = $lngs * 60 * 1845;
  9.        
  10.         $dist = sqrt(pow($latm,2)+pow($lngm,2));
  11.         return $dist;
  12. }

Esta función está especialmente indicada para distancias cortas. Y dado que en las distancias cortas la altitud cuenta, usé una función que además usa la altitud. En los sistemas GPS las altitudes vienen en pies, conque se usa el factor de conversión pies-metros (0.3048)

Código: php
  1. function distAB($lat1,$lng1,$alt1,$lat2,$lng2,$alt2)
  2. {
  3.         $lats = $lat1 - $lat2;
  4.         $lngs = $lng1 - $lng2;
  5.         $alts = $alt1 - $alt2;
  6.        
  7.         //Paso a metros
  8.         $latm = $lats * 60 * 1845;
  9.         $lngm = $lngs * 60 * 1845;
  10.         $altm = $alts * 0.3048; //pies a metros
  11.        
  12.         $dist = sqrt(pow($latm,2)+pow($lngm,2)+pow($altm,2));
  13.         return $dist;
  14.  }

Eso es todo. Yo lo necesitaba para calcular la distancia total de un recorrido, de modo que hice un bucle con todas las tríadas de puntos, que va sumando las distancias. El resultado final se acerca mucho al real (Un error máximo de 3Km en un recorrido de 40)

Enlaces:
Gacetilla Matemática

13 Julio 2007 · Tags php |

12 Comentarios

Leonardo dice:

Hola, interesante, pero podrias aclarar de donde sale la constante: 1845 que utilizaste?

Me intriga saber porque usaste esa constante y no otra.

Muy bueno el artículo.


14 de Septiembre del 2007 a las 18:16
admin dice:

Muchas gracias, Leonardo.

Esa constante está relacionada con el tamaño de la tierra. Corresponde, si no me equivoco ahora mismo, a la cantidad de metros por grado en la esfera terrestre.


14 de Septiembre del 2007 a las 19:11
Jorgito dice:

Hola!
En referencia a la primera cuestión, el 1845 no es una constante, pretende ser la cantidad de metros que hay en un minuto (recorrido sobre el ecuador o un meridiano). Ya que un minuto se corresponde con 1 NM (milla naútica) = 1852m (no los 1845m). Y la fórmula expuesta arriba lo que hace es traducir los grados en minutos (al multiplicar por 60).

Otro error de la fórmula es que no tiene en cuenta la disminución del radio de la tierra conforme aumenta la latitud, y en consecuencia la distancia recorrida en un grado de paralelo es cada vez menor.
Las fórmulas quedarían de la siguiente forma:
function distAB($lat1,$lng1,$lat2,$lng2)
{
$lats = $lat1 - $lat2;
$lngs = $lng1 - $lng2;

//Paso a metros
$latm = $lats * 60 * 1852;
$lngm = ($lngs / cos $lat1) * 60 * 1852;

$dist = sqrt(pow($latm,2)+pow($lngm,2));
return $dist;
}

Está fórmula es válida para distancias cortas, o que se muevan a través del mismo, o muy próximo, paralelo. Y el efecto de la altitud se considera despreciable, ya que en un radio 6840km, el efecto de ir a ras de suelo, o a 10km de altura no produce diferencias significativas.


4 de Noviembre del 2007 a las 13:55
admin dice:

Muchas gracias, Jorgito por tu aportación.

Sin embargo el programa ha sido creado para medir distancias muy pequeñas, es deci, de varias decenas de metros la una de la otra. En estos casos la altura sí es importante.

El dato de la milla náutica lo desconocía, probaré a usarlo. De todas formas con el código actual hace unos cálculos muy certeros.

El problema de ajustarse a la realidad en el sentido de curvaturas y distancias cambiantes, es que se han de hacer cálculos muy complejos, y PHP no es el mejor lenguaje para matemáticas. Cuando probaba fórmulas trigonométricas me daba error constantemente. Por ello busqué esta fórmula tan simple y bastante efectiva.


4 de Noviembre del 2007 a las 14:33
Jorgito dice:

El código que te he puesto ciertamente está muy simplificado (y por eso solo sirve para medir dentro del mismo paralelo, o muy próximo) pero corrige la disminución del radio de la tierra conforme aumenta la latitud (y que introduciría cierto error en tu código original).
El efecto de la altitud…si estás midiendo del orden de decenas de metros, ciertamente tenga alguna relevancia, pero en cuanto hables de km esa relevancia se pierde.
Corrijo el código, ya que había puesto una cosa mal:

$lngm = ($lngs * cos ($lat1*3.14159/180)) * 60 * 1852;

quedando:

function distAB($lat1,$lng1,$lat2,$lng2)
{
$lats = $lat1 - $lat2;
$lngs = $lng1 - $lng2;

//Paso a metros
$latm = $lats * 60 * 1852;
$lngm = ($lngs * cos ($lat1*3.14159/180)) * 60 * 1852;
$dist = sqrt(pow($latm,2)+pow($lngm,2));
return $dist;
}

y teniendo en cuenta la altitud, quedando:

function distAB($lat1,$lng1,$alt1,$lat2,$lng2,$alt2)
{
$lats = $lat1 - $lat2;
$lngs = $lng1 - $lng2;
$alts = $alt1 - $alt2;

//Paso a metros
$latm = $lats * 60 * 1845;
$lngm = ($lngs * cos ($lat1*3.14159/180)) * 60 * 1852;
$altm = $alts * 0.3048; //pies a metros

$dist = sqrt(pow($latm,2)+pow($lngm,2)+pow($altm,2));
return $dist;
}

Nunca he usado las fórmulas trigonométricas en php, pero el error más comun es calcular el COS de un ángulo en cualquier lenguaje de programación es proporcionar el ángulo en grados. Pero el COS se calcula sobre un ángulo en radianes (360 grados equivalen a 2*3.14159 radianes –> toca regla de 3).

Un saludo y suerte!!


4 de Noviembre del 2007 a las 15:28
Luis López dice:

Buscando en Internet acerca de este calculo di con tu página, solo quería agradecerte por publicar este código que me será de mucha utilidad.

Saludos


14 de Enero del 2008 a las 20:52
admin dice:

Todo un placer


14 de Enero del 2008 a las 21:59
rene galvan dice:

gracias por tu talento lo usare para calcular la distancia de los huracanes a mi casa en los cabos mexico


28 de Marzo del 2008 a las 9:14
jesus dice:

una rueda de bicicleta con un diametro de 29 pulgadas da 52 bueltas ¿ que distancia recorrio en radianes,grados y metros?


11 de Junio del 2008 a las 16:51
jesus dice:

espero que me ayuden con est problema
ok. selos agradecere muccho


11 de Junio del 2008 a las 16:52
Adolfo Troncoso dice:

Estaba buscando como sacar la distancia entre puntos . Gracias por el articulo
yo estoy trabajando en un proyecto
de gps gprs y server
http://gps.aqui.cl


14 de Junio del 2008 a las 4:33
Javier dice:

Hola. Antes de nada agradecer el código pués posiblemente lo aproveche.
En cuanto al error máximo que comentas puede estar debido no ya a los cálculos sino a que los gps muchas veces simplifican los tracks eliminando puntos que ellos creen redundantes. Creo que le llaman compactar el track. En ese caso se iría acumulando el error.


17 de Junio del 2008 a las 4:08

Escribe un comentario!

Buscador

2005-2007 Zumbe.net Creada por Alex Barros con WordPress - Licencia Reconocimiento - RSS