24 votos

Buscar características dentro de unas coordenadas y distancia dadas utilizando MySQL

Tengo una tabla MySQL con nombre de usuario, latitud y longitud del usuario.

Me gustaría obtener una lista de usuarios que están dentro del círculo o cuadrado de una latitud y longitud dadas con una distancia dada. Por ejemplo, mi entrada Lat = 78.3232 y Long = 65.3234 y la distancia = 30 millas. Me gustaría obtener la lista de usuarios que están dentro de 30 millas de distancia desde el punto 78.3232 y 65.3234.

¿Es posible resolverlo con una sola consulta? ¿O puede darme una pista para empezar a resolver esta consulta?

44voto

pablobm Puntos 108

Respuesta de Mapperz no es válido. El seno debe calcularse a partir de la latitud y NO de la longitud. Así que la sentencia SQL correcta es:

SELECT
    id, (
      3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;

38voto

Erik Öjebo Puntos 6937

La sentencia SQL que encontrará las 20 localidades más cercanas que se encuentran en un radio de 30 millas a la coordenada 78.3232, 65.3234. Calcula la distancia basándose en la latitud/longitud de esa fila y la latitud/longitud de destino, y luego pide sólo las filas en las que el valor de la distancia es inferior a 30 millas, ordena toda la consulta por distancia y la limita a 20 resultados. Para buscar por kilómetros en lugar de millas, sustituya 3959 por 6371.

SELECT
  id, (
    3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
  ) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;

Para ello se utiliza la API v3 de Google Maps con un backend MySQL del que ya dispones.

https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql

4voto

Marcos Puntos 21

Es 2020, usted debe utilizar el construido en función espacial de la RDBS. En este caso se busca el ST_Distancia función.

-- geo column in users table is of Geometry data type, with a spatial index
SET @g1 = ST_SRID(POINT(78.3232, 65.3234), 4326);
SELECT * from users WHERE ST_Distance(users.geo, @g1, 'foot') < 158400; -- 5280 feet per mile

2voto

Kombo Puntos 126

Podría ser la base para crear una función .. así que usted puede reutilizar otras áreas. También haría que su consulta un poco más limpio ... Al menos ese es mi 2 centavos.

DELIMITER $$

CREATE FUNCTION calcDistance(lat FLOAT, lng FLOAT, pnt_lat FLOAT, pnt_lng FLOAT)
    RETURNS FLOAT
BEGIN

    DECLARE dist FLOAT;
    SET dist =
          3959 * acos(
                cos(radians(pnt_lat))
                * cos(radians(lat))
                * cos(radians(lng) - radians(pnt_lng))
            + sin(radians(pnt_lat))
                    * sin(radians(lat))
          );

    RETURN dist;

END

0voto

GrayWizardx Puntos 163

Aquí está mi variante de consulta, parece un poco más fácil ( http://dexxtr.com/post/83498801191/how-to-determine-point-inside-circle-using-mysql )

SELECT 
    *
FROM 
    `locator`
WHERE
    SQRT(POW(X(`center`) - 49.843317 , 2) + POW(Y(`center`) - 24.026642, 2)) * 100 < `radius`

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X