En este post te voy a mostrar una fórmula de MySQL para calcular la distancia entre dos coordenadas GPS (latitud y longitud) en metros, de modo que podrás calcular la cantidad de metros que existen entre 2 puntos geográficos al hacer consultas SQL.
Debido a que vamos a definir la fórmula como una función de MySQL vas a poder usarla al hacer cualquier operación como SELECT o INSERT.
Vamos a usar la fórmula de Haversine también llamada semiverseno, misma que permite conocer la distancia de círculo máximo entre dos puntos de un globo sabiendo su longitud y su latitud.
La siguiente función para calcular la distancia entre 2 coordenadas con MySQL te va a devolver la distancia en metros; obviamente puedes convertirla a kilómetros o metros.
El código SQL es el siguiente:
DELIMITER //
CREATE FUNCTION haversine(lat1 DOUBLE, lon1 DOUBLE, lat2 DOUBLE, lon2 DOUBLE)
RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE RADIO_TIERRA_EN_KILOMETROS DOUBLE DEFAULT 6371.0;
DECLARE deltaLongitud DOUBLE;
DECLARE deltaLatitud DOUBLE;
DECLARE halfChordLengthSquared DOUBLE;
DECLARE angularDistanceRadians DOUBLE;
DECLARE distanciaMetros DOUBLE;
-- Convertir las coordenadas de grados a radianes
SET lat1 = RADIANS(lat1);
SET lon1 = RADIANS(lon1);
SET lat2 = RADIANS(lat2);
SET lon2 = RADIANS(lon2);
-- Calcular las diferencias
SET deltaLongitud = lon2 - lon1;
SET deltaLatitud = lat2 - lat1;
-- Aplicar la fórmula del haversine
SET halfChordLengthSquared = POW(SIN(deltaLatitud / 2), 2) + COS(lat1) * COS(lat2) * POW(SIN(deltaLongitud / 2), 2);
SET angularDistanceRadians = 2 * ATAN2(SQRT(halfChordLengthSquared), SQRT(1 - halfChordLengthSquared));
SET distanciaMetros = RADIO_TIERRA_EN_KILOMETROS * angularDistanceRadians * 1000; -- Convertir a metros
RETURN distanciaMetros;
END //
DELIMITER ;
Solo debes ejecutarlo en tu base de datos una vez, y después vas a poder calcular la distancia entre coordenadas con MySQL en cualquier tabla. Incluso puedes probarla sin tabla, por ejemplo:
SELECT haversine(19.416326917410476, -99.12479042256915, 23.097069089850933, -82.35006433419622);
La salida de esa consulta será 1784668.3798590573 lo cual es correcto según mi otro post de Haversine con JS. No olvides que en este caso la salida está en metros.
A continuación se presenta un ejemplo de una consulta usando esta fórmula:
INSERT INTO
ubicaciones_conductores (
id_conductor, fecha,
latitud, longitud, precision_horizontal,
id_ruta_destino, id_ruta_origen,
id_parada_mas_cercana, distancia_parada_mas_cercana
)
SELECT ?, ?,
?, ?, ?,
?, ?,
subconsulta.id, subconsulta.distancia
FROM
(
SELECT
id,
haversine(latitud, longitud, ?, ?) AS distancia
FROM
paradas
ORDER BY
distancia ASC
LIMIT
1
) AS subconsulta;
Si quisieras un ejemplo más sencillo podrías hacer algo como:
SELECT haversine(lat1, lon1, lat2, lot2) AS distancia FROM tabla;
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.