web-dev-qa-db-fra.com

Trouver la distance entre deux points en utilisant la latitude et la longitude dans mysql

Salut j'ai le tableau suivant

 --------------------------------------------
 |  id  |  city  |  Latitude  |  Longitude  |
 --------------------------------------------
 |  1   |   3    |   34.44444 |   84.3434   |
 --------------------------------------------
 |  2   |   4    | 42.4666667 | 1.4666667   |
 --------------------------------------------
 |  3   |   5    |  32.534167 | 66.078056   |
 --------------------------------------------
 |  4   |   6    |  36.948889 | 66.328611   |
 --------------------------------------------
 |  5   |   7    |  35.088056 | 69.046389   |
 --------------------------------------------
 |  6   |   8    |  36.083056 |   69.0525   |
 --------------------------------------------
 |  7   |   9    |  31.015833 | 61.860278   |
 --------------------------------------------

Maintenant, je veux obtenir la distance entre deux points. Disons qu'un utilisateur a une ville 3 et un utilisateur a une ville 7. Mon scénario est qu'un utilisateur ayant une ville et latitue et longtitude recherche la distance des autres utilisateurs de sa ville. Par exemple, l'utilisateur ayant la ville 3 effectue une recherche. Il veut obtenir la distance de l'utilisateur d'une autre ville, disons qu'il est 7. J'ai recherché et trouvé la requête suivante

SELECT `locations`.`city`, ( 3959 * acos ( cos ( radians(31.589167) ) * cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians(64.363333) ) + sin ( radians(31.589167) ) * sin( radians( Latitude ) ) ) ) AS `distance` FROM `locations` HAVING (distance < 50)

Pour autant que je sache, cette requête trouve la distance d'un point à tous les autres points. Maintenant, je veux obtenir la distance d'un point à un autre point.

Toute ligne de guidage sera très appréciée.

23
Enthusiast

Je pense que votre question dit que vous avez les valeurs city pour les deux villes entre lesquelles vous souhaitez calculer la distance.

Cette requête fera le travail pour vous, donnant la distance en km. Il utilise la formule de la loi du cosinus sphérique.

Notez que vous joignez la table à elle-même afin de pouvoir récupérer deux paires de coordonnées pour le calcul.

SELECT a.city AS from_city, b.city AS to_city, 
   111.111 *
    DEGREES(ACOS(LEAST(COS(RADIANS(a.Latitude))
         * COS(RADIANS(b.Latitude))
         * COS(RADIANS(a.Longitude - b.Longitude))
         + SIN(RADIANS(a.Latitude))
         * SIN(RADIANS(b.Latitude)), 1.0))) AS distance_in_km
  FROM city AS a
  JOIN city AS b ON a.id <> b.id
 WHERE a.city = 3 AND b.city = 7

Notez que la constante 111.1111 est le nombre de kilomètres par degré de latitude, basé sur l'ancienne définition napoléonienne du mètre comme un dix millième de la distance de l'équateur au pôle. Cette définition est suffisamment proche pour le travail de localisation.

Si vous voulez des milles terrestres au lieu de kilomètres, utilisez 69.0 au lieu.

http://sqlfiddle.com/#!2/abcc8/4/

Si vous recherchez des points à proximité, vous pourriez être tenté d'utiliser une clause comme celle-ci:

   HAVING distance_in_km < 10.0    /* slow ! */
    ORDER BY distance_in_km DESC

C'est (comme on dit près de Boston MA USA) méchant lentement.

Dans ce cas, vous devez utiliser un calcul de boîte englobante. Voir cet article sur la façon de procéder. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

63
O. Jones

Voici la requête et la fonction MySQL qui permettent d'obtenir la distance entre deux latitude et longitude et la distance retournera en KM.

Requête Mysql: -

SELECT (6371 * acos( 
                cos( radians(lat2) ) 
              * cos( radians( lat1 ) ) 
              * cos( radians( lng1 ) - radians(lng2) ) 
              + sin( radians(lat2) ) 
              * sin( radians( lat1 ) )
                ) ) as distance from your_table

Fonction Mysql: -

DELIMITER $$
CREATE FUNCTION `getDistance`(`lat1` VARCHAR(200), `lng1` VARCHAR(200), `lat2` VARCHAR(200), `lng2` VARCHAR(200)) RETURNS varchar(10) CHARSET utf8
begin
declare distance varchar(10);

set distance = (select (6371 * acos( 
                cos( radians(lat2) ) 
              * cos( radians( lat1 ) ) 
              * cos( radians( lng1 ) - radians(lng2) ) 
              + sin( radians(lat2) ) 
              * sin( radians( lat1 ) )
                ) ) as distance); 

if(distance is null)
then
 return '';
else 
return distance;
end if;
end$$
DELIMITER ;

Comment utiliser dans votre PHP Code

SELECT getDistance(lat1,lng1,$lat2,$lng2) as distance 
FROM your_table.
6
Umesh Jee

Vous ne savez pas comment se déroule votre calcul de distance, mais vous devez effectuer une self join votre table et effectuez le calcul en conséquence. Quelque chose comme ça probablement

select t1.id as userfrom, 
t2.id as userto, 
( 3959 * acos ( cos ( radians(31.589167) ) * cos( radians( t1.Latitude ) ) * 
cos( radians( t1.Longitude ) - radians(64.363333) ) + sin ( radians(31.589167) ) * 
sin( radians( t2.Latitude ) ) ) ) AS `distance` 
from table1 t1 
inner join table1 t2 on t2.city > t1.city
3
Rahul

Voici une fonction MySQL qui prendra deux paires latitude/longitude et vous donnera la distance en degrés entre les deux points. Il utilise la formule Haversine pour calculer la distance. Puisque la Terre n'est pas une sphère parfaite, il y a une erreur près des pôles et de l'équateur.

  • Pour convertir en milles, multipliez par 3961.
  • Pour convertir en kilomètres, multipliez par 6373.
  • Pour convertir en mètres, multipliez par 6373000.
  • Pour convertir en pieds, multipliez par (3961 * 5280) 20914080.
DELIMITER $$

CREATE FUNCTION \`haversine\`(

        lat1 FLOAT, lon1 FLOAT,
        lat2 FLOAT, lon2 FLOAT
     ) RETURNS float
    NO SQL
    DETERMINISTIC
    COMMENT 'Returns the distance in degrees on the Earth between two known points of latitude and longitude. To get miles, multiply by 3961, and km by 6373'

BEGIN

    RETURN DEGREES(ACOS(
              COS(RADIANS(lat1)) *
              COS(RADIANS(lat2)) *
              COS(RADIANS(lon2) - RADIANS(lon1)) +
              SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))
            ));

END;

DELIMITER;
3
Sloan Thrasher

Voici une formule que j'ai convertie à partir de https://www.geodatasource.com/developers/javascript

C'est une belle fonction propre qui calcule la distance en KM

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `FN_GET_DISTANCE`(
lat1 DOUBLE, lng1 DOUBLE, lat2 DOUBLE, lng2 DOUBLE
) RETURNS double
BEGIN
    DECLARE radlat1 DOUBLE;
    DECLARE radlat2 DOUBLE;
    DECLARE theta DOUBLE;
    DECLARE radtheta DOUBLE;
    DECLARE dist DOUBLE;
    SET radlat1 = PI() * lat1 / 180;
    SET radlat2 = PI() * lat2 / 180;
    SET theta = lng1 - lng2;
    SET radtheta = PI() * theta / 180;
    SET dist = sin(radlat1) * sin(radlat2) + cos(radlat1) * cos(radlat2) * cos(radtheta);
    SET dist = acos(dist);
    SET dist = dist * 180 / PI();
    SET dist = dist * 60 * 1.1515;
    SET dist = dist * 1.609344;
RETURN dist;
END$$
DELIMITER ;

Vous trouverez également la même fonction dans différentes langues sur le site;

1
user2288580