14 votes

Sélectionnez les coordonnées qui se trouvent dans un rayon d'un point central ?

J'ai une base de données de coordonnées dans le schéma :

ID:Latitude:Longitude:nom:desc

J'ai configuré mon application Google Maps pour afficher les marqueurs à l'écran. Cependant, j'ai besoin d'ajouter une autre fonctionnalité permettant à l'utilisateur de visualiser tous les marqueurs qui se trouvent dans le rayon d'un point central.

Comment puis-je écrire une déclaration sql de ce type ?

Select all pointers that fall within a 10 mile radius of X & Y

30voto

Rajeev Shenoy Points 902

Le SQL ci-dessous devrait fonctionner :

SELECT * FROM Table1 a 
WHERE (
          acos(sin(a.Latitude * 0.0175) * sin(YOUR_LATITUDE_X * 0.0175) 
               + cos(a.Latitude * 0.0175) * cos(YOUR_LATITUDE_X * 0.0175) *    
                 cos((YOUR_LONGITUDE_Y * 0.0175) - (a.Longitude * 0.0175))
              ) * 3959 <= YOUR_RADIUS_INMILES
      )

Ceci est basé sur la loi sphérique des cosinus. Pour des informations plus détaillées sur le sujet, consultez cet article. http://www.movable-type.co.uk/scripts/latlong.html

2voto

Steve O'Connor Points 1193

Vous devez probablement faire cela en deux étapes. Sélectionnez les points qui se trouvent dans un carré de 20 miles carrés dont le centre est situé à X,Y. En supposant que vous calculez d'abord les coordonnées haut, gauche et bas, droite du carré, vous pouvez obtenir tous les points à l'intérieur du carré à partir de la base de données :

select * from coordinates where longitude < right and longitude > left and 
latitude < top and latitude > bottom;

La deuxième étape consiste à voir si l'ensemble des points se trouve à l'intérieur du cercle de 10 miles de rayon. À ce stade, je serais tenté d'utiliser Google Maps pour calculer la distance entre les points et le centre de votre carré à l'aide de la fonction google.maps.geometry.spherical.computeDistanceBetween(from:LatLng, to:LatLng, radius?:number) fonction. Vérifiez que la réponse est inférieure à 10 miles. Cette fonction utilise le rayon de la terre par défaut.

0voto

Imran Selim Points 39

Ce SQL donne une réponse plus précise :

SELECT *
 FROM Table1 a
 WHERE 1 = 1
 AND 2 * 3961 * asin(sqrt( power((sin(radians((X - cast(a.latitude as decimal(10,8))) / 2))) , 2) + cast(cos(radians(cast(a.latitude as decimal(18,8)))) * cos(radians(X)) * power((sin(radians((Y - cast(a.long as decimal(18,8))) / 2))) , 2) as decimal(18,10) ))) <= Radius_In_Miles

X = Latitude du centroïde Y = Longitude du centroïde

Je l'ai fait dans Redshift, donc j'ai dû utiliser le cast pour éviter l'erreur de dépassement de valeur numérique.

Référence : http://daynebatten.com/2015/09/latitude-longitude-distance-sql/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X