Distancia entre dos puntos georeferenciados (PHP y MySQL)

Con el uso de APIs de mapas como Google Maps y la -cada día más- posibilidad de georeferenciación del contenido, es posible que en algún momento necesitemos calcular la distancia entre dos puntos georeferenciados.

Sin más explicaciones físicas, escribimos la función en PHP:

function distancia($punto1, $punto2){
    	$km = 111.302;
    	$coo1 = explode(',',$punto1);
    	$coo2 = explode(',',$punto2);
    	return floor(acos(sin((double)$coo1[0]) * sin((double)$coo2[0]) + (cos((double)$coo1[0]) * cos((double)$coo2[0]) * cos((double)$coo1[1] - (double)$coo2[1]))) * (double)$km);
    }

No vamos a entrar en demasiados detalles de la función, nos tenemos que creer la fórmula creada por nuestros amigos físicos, pero sí os explicaremos que hemos dado a la variable $km es la distancia en kilómetros que abarca un grado de circunferencia del planeta tierra (por tanto los habitantes de otros mundos tendréis que ajustar este valor).

Tambien és posible que guardemos en base de datos una lista de “elementos” georeferenciados (con latitud y longitud). En nuestro caso almacenamos la latitud y longitud en una misma columna de tipo varchar(255), pero se podía guardar en dos columnas diferentes o en una columna de tipo POINT.

Para nuestra llamada hemos creado una función strSplit que nos ayudará a dividir la cadena de latitud/longitud en cada valor:

CREATE
 
FUNCTION `strSplit`(x varchar(255), delim varchar(12), pos int)
  RETURNS varchar(255) CHARSET latin1
DETERMINISTIC
BEGIN
   RETURN replace(substring(substring_index(x, delim, pos),
      length(substring_index(x, delim, pos - 1)) + 1), delim, '');
 
-- end the stored function code block
END$$

La condición del WHERE de la consulta que devolvería todos los puntos a una distancia menor o igual que $distancia quedaría de la siguiente manera:

WHERE ACOS(
	SIN(strSplit(coordenadas,',',1)) * SIN($latitud) +
	COS(strSplit(coordenadas,',',1)) * COS($latitud) * COS(strSplit(coordenadas,',',2) - ($longitud))
      ) * 111.302 <= $distancia

Linkografía:
– En GeoNames se puede descargar varias bases de datos de información georeferenciada del planeta
Fórmula Haversine del cálculo de distancias geográficas

2 comentarios

  1. enemit cardona
    25 abril, 2012 a las 11:03 | Permalink

    los punto georeferenciados son importantes para el calculo

  2. 4 mayo, 2014 a las 7:17 | Permalink

    En que formato pasas los puntos georeferenciados a la función? Cada coordenada debería estar indicada por 2 valores: latitud y longitud. No?

1 blog nos enlaza

  1. […] el calculo y ordenar el resultado. Aquí tienes un ejemplo de como puedes hacer la consulta con algo de MySQL avanzado. Personalmente me parece ineficiente ya que a simple vista parece que realiza el mismo calculo en […]

Deja tu comentario

Tu correo nunca será compartido. Los campos marcados con * son obligatorios

*
*