2011-06-14 1 views
0

J'ai une table avec les utilisateurs et je dois trouver les utilisateurs les plus proches en fonction de latitude, à long. J'ai aussi besoin de la distance. Je me bats avec la formule et les alternatives de haversine pendant deux jours, mais je fais face à quelques erreurs.Problèmes pour trouver la distance à d'autres utilisateurs Sql Server 2005 - Haversine

Disons par exemple que j'utilise lat, long pour Kuala Lumpur, en Malaisie (à peu près 3,2, 102).

Utilisation: Pythagoras

SELECT top 10 *, 
    SQRT(SQUARE(ABS(latitude - 3.2)) + SQUARE(ABS(longitude - 102))) AS distance 
FROM lfuser 
ORDER BY distance 

Il me donne des résultats "corrects" (utilisateurs près de ce point). Mais je ne peux pas obtenir la distance (en KM) de cela et je sais que ce n'est pas tout à fait correct. Donc, j'ai essayé d'utiliser la haversine:

SELECT TOP 10 *, 
    ROUND(2 * ASIN(SQRT(POWER(SIN(((3.2/180) * PI() 
     - (latitude/180) * PI())/2) ,2) + COS((3.2/180) * PI()) 
     * COS((latitude/180) * PI()) * POWER(SIN(((102/180) * PI() 
     - (longitude/180) * PI())/2), 2))) * 6367, 4) AS distance 
FROM lfuser 
ORDER BY distance 

La chose étrange est que cela me donne des utilisateurs ailleurs. En fait, le premier résultat est un utilisateur au Ghana avec lat = 5,55 et long = -0,20.

Ce me rend fou ... Je pourrais bien sûr calculer une distance approximative en multipliant les pythagore résultat avec 110 kms mais je voudrais le résultat plus correct.

J'espère que quelqu'un peut remarquer ce qui est faux.

S'il vous plaît ne pas poster des liens vers les différentes implémentations de formule de Haversine etc. J'ai regardé les deux jours maintenant.

Répondre

2

Dans le passé, je l'avais utilisé Haversine in SQL 2005 donc j'ai essayé de convertir ma procédure d'adaptation pour votre cas. Permettez-moi de savoir si beau travail

Je suppose aussi le bon Kuala Lumpur Longitude et Latitude sont 3.139003, 101.686855

declare @myLatitude decimal(12,6), @myLongitude decimal(12,6), @EarthRadius decimal(12,6) 
select @myLatitude = 3.139003, @myLongitude = 101.686855, @EarthRadius = 6378.137 

SELECT top 10 *, 
    (@EarthRadius * ACOS((SIN(PI() * @myLatitude /180) 
    * SIN(PI() * Latitude/180)) 
    + (COS(PI() * @myLatitude /180) 
    * COS(PI() * Latitude/180) 
    * COS(PI() * Longitude/180 - PI() * @myLongitude /180)))) 
    as distance 
FROM lfuser 
ORDER BY distance 

Hope it helps

+0

Salut Luka, Il semble bien fonctionner. Merci beaucoup. – Jesper

0

Juste une réponse rapide pour le moment. Si vous utilisez SQL Server 2008, vous devez utiliser les types géographiques (point dans votre cas) pour stocker l'emplacement. Il existe des méthodes intégrées pour gérer la distance entre les points. Début here et here

Vous voudrez peut-être poser cette question sur: gis.stackexchange.com qui se spécialise dans ce domaine.

+0

Oui, mais malheureusement, cela est SqlServer 2005 – Jesper

+0

@Jesper - il est probablement Il vaut la peine d'ajouter cette information de version dans votre question - c'est tout à fait pertinent, vous ne pensez pas? –