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.
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/
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.
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
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.
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;
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;