Skip to content

Recherche Géolocalisée – Tutoriel

Soyez sociable ! Partagez :
  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS

Dans le cadre de mon travail, il m’a été demandé de faire une recherche géolocalisée. L’objectif est de connaitre le nombre d’individus d’une base de données présents dans un périmètre défini autour d’un point donné.

Comment faire une recherche géolocalisée

Comment faire une recherche géolocalisée

Pour  réussir sa géolocalisation, je vous invite à suivre ce tutoriel qui vous permettra d’aboutir à une recherche géolocalisée optimisée.

Ajouter les champs longitudes et latitudes

Pour commencer, nous allons ajouter 2 champs à notre table dans notre base de données :

ALTER TABLE cutomers
ADD lon DOUBLIE;

ALTER TABLE cutomers
ADD lat DOUBLIE;

Vous l’aurez compris, “lon” correspond à la longitude et “lat” à la latitude.

Géolocalisation d’un utilisateur

Pour géolocaliser un utilisateur, nous allons utiliser l’API de google maps qui va nous autoriser à récupérer les coordonnées GPS d’un point du globe.

Nous commencerons par écrire un fonction get_geolocation() prenant en paramètre une requête :

def get_geolocation(query)
  # query : address formatée : address+cp+town+country (WARGING : /[^[:alnum:]])

  loc = Net::HTTP.get('maps.googleapis.com', "/maps/api/geocode/json?address=#{query}&sensor=false")

  # La fonction get fait la même chose qu'un Curl pour PHP

  # Ensuite on decode le JSON récupéré
  # VOus avez la possibilité de récupérer du XML en remplaçant JSON par XML dans la requête
  reponse = ActiveSupport::JSON.decode(loc)

  # Je retourn un hash des coordonnées GPS (lng, lat)
  reponse["results"][0]["geometry"]["location"]

  end

Pour faire simple, on va récupérer le contenu de la page généré par google maps. Pour plus d’information, vous pouvez vous rendre sur la page de documentation.

Une fois cette fonction codée, il ne vous reste plus qu’un injecter les informations dans votre base de données.

c = Customer.last

# je prépare la query /!\ PAS D'ESPACE ou de CARACTERES SPECIAUX
query = c.address_1 + "+" + c.zipcode + "+" + c.town + "+" + c.country

coord = get_geolocation(query)

c.lon = coord["lng"]
c.lat = coord["lat]

c.save

Vous pouvez, si vous le désirez, faire des tâches de géolocalisation pour tous vos utilisateurs.

Recherche par proximité

L’une des fonctions recherchées avec la géolocalisation, est la recherche par proximité. L’objectif est de trouver tous les utilisateurs présent autour d’un point dans un périmètre donné.

Je ne vais vous donner que la requête SQL ainsi, vous pourrez l’adapter selon votre technologie.

SELECT customers.*
  , SIN((RADIANS(":lon") - RADIANS(lat)) / 2) *
    SIN((RADIANS(":lon") - RADIANS(lat)) / 2) +
    COS(RADIANS(lat)) * COS(RADIANS(":lon")) *
    SIN((RADIANS(":lat") - RADIANS(lon)) / 2) *
    SIN((RADIANS(":lat") - RADIANS(lon)) / 2) AS distance 
FROM `customers` 
WHERE ((`customers`.`lon` BETWEEN ":lat" - ":distance_en_degre"
                                     AND ":lat" + ":distance_en_degre" 
AND `customers`.`lat` BETWEEN ":lon" - ":distance_en_degre" 
                               AND ":lon" + ":distance_en_degre")) 
AND (SIN((RADIANS(":lon") - RADIANS(lat)) / 2) *
        SIN((RADIANS(":lon") - RADIANS(lat)) / 2) +
        COS(RADIANS(lat)) * COS(RADIANS(":lon")) *
        SIN((RADIANS(":lat") - RADIANS(lon)) / 2) *
        SIN((RADIANS(":lat") - RADIANS(lon)) / 2) <= ":distance")

Pour vous expliquer le fonctionnement de cette requête :

  • On filtre sur la distance entre le point recherché et le “customer”
  • Les 2 premiers filtres permettent de faire un premier zonage en carré pour éliminer ceux qui sont vraiment éloignés du point (optimisation de la requête)
  • Le troisième filtre permet de tracer un cercle autour du point demandé et de ne récupérer que les “customers” s’y trouvant

Conclusion

Si vous avez bien suivi ce tutoriel, vous devriez être apte à faire une recherche géolocalisée sur votre application. Si toutefois vous rencontrez un problème, n’hésitez pas à m’en faire part dans ces commentaires.

Pour information, je suis développeur Ruby On Rails, le code que vous voyez est donc dans cette technologie.

A bientôt !

Soyez Sociable ! Partagez !
Published inTutoriel
banner