Función de MySQL para determinar Código postal de proximidad / Gama
Pregunta
he sido capaz de crear la función php para determinar una lista de códigos postales dentro de un cierto rango de un código postal determinado. Sin embargo, mi siguiente tarea es un poco más complejo.
Digamos que la tabla tiene las siguientes columnas:
id,
username
info
latitude
longitude
range
Cada registro tiene un identificador único fila, alguna información, una latitud, una longitud, y un alcance máximo de las coordenadas que la persona quiere que esta entrada se encuentra a. Por lo tanto, si se crea una entrada con las coordenadas -20, 50 con un alcance de 15, lo que significa que sólo quiero que la gente dentro de 15 millas de las coordenadas -20, 50 para ser capaz de ver mi entrada. Averiguar la latitud y longitud del usuario que ejecuta la búsqueda es un asunto trivial.
Cuando un usuario está buscando a través de la base de datos, todos los registros debe ser recuperada por las coordenadas de latitud y longitud en el valor de la gama de los usuarios de latitud / longitud.
Así, un ejemplo no funcional de código usando la fórmula de distancia para ilustrar esto sería
$userLat
= La latitud del usuario que ejecuta la búsqueda
$userLong
= La longitud del usuario que ejecuta la búsqueda
SELECT info FROM table
WHERE sqrt(($userLat - lat)^2 - ($userLong - long)^2) <= range
ORDER BY username ASC
Eso sería lo ideal, pero no es válido desde el punto de vista de codificación. ¿Hay alguna forma de ejecutar las comparaciones anteriores usando PHP y MySQL en una consulta? Esto implicaría ser capaz de ejecutar operaciones utilizando múltiples valores de columna de una fila dada.
ACTUALIZACIÓN + SOLUCIÓN
I creó otra entrada pregunta que aborda esta cuestión y tiene una función muy compacto para hacer lo que quería esta pregunta. La función dada por coderpros servido de inspiración para ella (su función tiene un mucho mejor manejo de ciertas situaciones). Sin embargo, ya que estoy usando mi función con un alto grado de control sobre la entrada, creé una función separada. Se puede encontrar en el siguiente enlace:
MySQL función definida por el usuario para Latitud Longitud Sintaxis
Solución
Esta función lil mySQL ingenioso que he escrito definitivamente debe hacer el truco para ti.
BEGIN
DECLARE x decimal(18,15);
DECLARE EarthRadius decimal(7,3);
DECLARE distInSelectedUnit decimal(18, 10);
IF originLatitude = relativeLatitude AND originLongitude = relativeLongitude THEN
RETURN 0; -- same lat/lon points, 0 distance
END IF;
-- default unit of measurement will be miles
IF measure != 'Miles' AND measure != 'Kilometers' THEN
SET measure = 'Miles';
END IF;
-- lat and lon values must be within -180 and 180.
IF originLatitude < -180 OR relativeLatitude < -180 OR originLongitude < -180 OR relativeLongitude < -180 THEN
RETURN 0;
END IF;
IF originLatitude > 180 OR relativeLatitude > 180 OR originLongitude > 180 OR relativeLongitude > 180 THEN
RETURN 0;
END IF;
SET x = 0.0;
-- convert from degrees to radians
SET originLatitude = originLatitude * PI() / 180.0,
originLongitude = originLongitude * PI() / 180.0,
relativeLatitude = relativeLatitude * PI() / 180.0,
relativeLongitude = relativeLongitude * PI() / 180.0;
-- distance formula, accurate to within 30 feet
SET x = Sin(originLatitude) * Sin(relativeLatitude) + Cos(originLatitude) * Cos(relativeLatitude) * Cos(relativeLongitude - originLongitude);
IF 1 = x THEN
SET distInSelectedUnit = 0; -- same lat/long points
-- not enough precision in MySQL to detect this earlier in the function
END IF;
SET EarthRadius = 3963.189;
SET distInSelectedUnit = EarthRadius * (-1 * Atan(x / Sqrt(1 - x * x)) + PI() / 2);
-- convert the result to kilometers if desired
IF measure = 'Kilometers' THEN
SET distInSelectedUnit = MilesToKilometers(distInSelectedUnit);
END IF;
RETURN distInSelectedUnit;
END
Se necesita originLatitude, originLongitude, relativeLatitude, relativeLongitude, y medida como parámetros. Medida puede ser simplemente Miles
o Kilometers
Espero que ayude!