Le géocodage pas à pas

Post en forme de pense-bête qui j’imagine pourra servir à d’autres, tant il a été long pour moi de trouver une solution simple et rapide à mettre en place. On va donc parler de géocodage et même de reverse geocoding tant qu’on y est.

Il arrive souvent qu’après avoir scrapé un site, ou je ne sais quoi encore, on se retrouve avec des adresses postales du type 6 rue de Lyon, St-Servan, Gironde que l’on aimerait bien visualiser sur une carte. Mais pour ça, la plupart des outils de cartographie demande des coordonnées GPS et pas simplement une adresse. Alors quand il y en a une ça va mais quand on arrive à plusieurs centaines voir plusieurs milliers, ça pose problème.

On va voir ici deux façons de faire. Une, très simple à mettre en place mais qui s’appuie sur l’API un tantinet restrictive de Google Maps et une seconde où l’on va construire un script Python pour arriver à nos fins (et en s’appuyant sur le bon travail de Adrien Van Hamme). L’avantage de ces deux méthodes c’est qu’on ne va pas rentrer une à une chaque adresse mais que l’on va servir d’une base de données contenue dans un fichier CSV.

Quelques petites remarques pour commencer :

  • Pour bien tout suivre il va falloir télécharger Python évidemment.
  • Vous allez aussi avoir besoin de Node.js qui va nous permettre de bosser avec du javascript sur notre machine.
  • Préparez votre fichier CSV d’adresses en n’hésitant pas à les détailler en y ajoutant en plus le noms des départements, régions et France (ou le pays concerné). Cela aidera grandement les API à ne pas faire trop d’erreurs. L’adresse entière doit être contenue, si possible, dans une seule et même colonne pour que tout soit pris en compte et c’est plus pratique. Enfin, optez pour le point-virgule comme délimiteur, ce sera utile pour la seconde méthode !
  • Il vaut mieux être familier des panneaux de commandes car tout va se passer dedans ou presque.

Méthode 1 : géocoder avec l’API de Google Maps

On va débuter par la méthode qui demande le moins de compétence mais qui est par conséquent celle qui nous laisse le moins de marge de manœuvre.  Pour cela on va se servir d’un petit module développé par Noah Veltman, que vous pouvez retrouver sur la page Github du projet. Je vais simplement reprendre le points essentiels.

Première chose à faire, allez récupérer votre clé pour utiliser l’API de Google Maps. Tout est très bien expliqué par ici.

Puis on ouvre un panneau de commande et on vient installer le module :

npm install -g csvgeocode

Et voila ! Enfin presque maintenant il faut l’utiliser, on rentre donc cette nouvelle commande :

csvgeocode chemin/d'entrée/fichier.csv chemin/desortie/fichier.csv --url "https://maps.googleapis.com/maps/api/geocode/json?address={{LE_NOM_DE_VOTRE_COLONNE_ADRESSE}}&key=VOTRE_CLE_API" --verbose

Petite astuce si vous galérez à trouver le chemin de votre fichier csv, faites le simplement glisser dans un autre panneau de commande, cela vous donnera son chemin, ne reste plus qu’à le recopier.

N’oubliez pas de renseigner le nom de votre colonne d’adresse et enfin votre clé Google. Personnellement je rajoute une option –verbose qui permet de voir en temps réel le géocodage des adresses. Ça permet de voir si il y a des erreurs dans notre fichier et couper le programme si besoin. Et puis comme ça on voit que le programme tourne, c’est moins frustrant que d’attendre simplement le retour à la fin du processus !

Une méthode rapide, (plus ou moins) efficace mais limitée au bon vouloir de l’API qui autorise seulement 2500 requêtes par jour pour les comptes gratuits. Cela suffira donc pour un petit travail sur quelques centaines d’adresses mais pas plus.

Méthode 2 : géocoder avec du Python et Nominatim

Cette seconde méthode est bien plus souple que la première et va nous permettre, en plus, de mettre les mains dans le Python. Je vais ici reprendre les points essentiels du très bon tuto de Adrien Van Hamme qui a également mis à disposition son script, merci à lui.

Après avoir installer Python sur votre machine, on va poursuivre en installant geopy qui va nous permettre d’utiliser différents services de géoloc’, dont Nominatim pour notre cas.

Puis vient l’étape de l’écriture du script dont la majeure partie provient, une nouvelle fois du travail d’Adrien Van Hamme :

#!/usr/bin/env python
# coding: utf8

import csv
from time import sleep
from geopy.geocoders import Nominatim
geocoder = Nominatim()
inputFile = open('/chemin/dossier/entrée/fichier.csv', 'rb') #chemin de votre fichier à géocoder
outputFile = open('/chemin/dossier/sortie/fichierOK.csv', 'w') #chemin de votre fichier de résultats
try:
    outputData = csv.writer(outputFile, delimiter=';', lineterminator='\n') #spécifier le délimiteur de votre fichier de sortie
    outputData.writerow(('adresse', 'lat', 'lng')) #spécifier le nom de vos colonnes pour le fichier de résultats
    inputData = csv.reader(inputFile, delimiter=';') #spécifier le délimiteur de votre fichier à géocoder
    for ligne in inputData:
        adresse = ligne[0] #ligne correspond aux colonnes de votre tableau
        try:
            location = geocoder.geocode(adresse, True, 30)
            outputData.writerow((adresse, location.latitude, location.longitude))
        except Exception as inst:
            print(inst)
        sleep(0.5)
finally:
    inputFile.close()
    outputFile.close()

Finissons par quelques précisions sur ce script. Prenez bien soin de modifier vos chemins d’entrée et de sortie, assurez vous que le script et vos fichiers sont dans le même répertoire. Modifiez si besoin la ligne 15 pour qu’elle colle avec la syntaxe de votre csv (voir plus bas dans la section reverse geocoding). Il ne semble pas vraiment aimer les codes postaux donc laissez les tomber et préférez ville + région.

Vous n’avez plus qu’à exécuter ce script dans votre panneau de commande en tapant son chemin d’accès !

Le reverse geocoding

Comme promis, on va aussi en profiter pour parler reverse geocoding. L’avantage de ce script est qu’il permet en un rien de temps de passer du geocoding classique à du reverse. Pour cela on modifie la fonction location à la ligne 18.

location = geocoder.geocode(adresse, True, 30)

devient

location = geocoder.reverse(adresse, True, 30)

Bien souvent nos latitudes et longitudes sont séparées par une virgule, ce qui va nous forcer à modifier également la ligne de déclaration de la colonne d’adresse à la ligne 16.

adresse = ligne[0]

devient

adresse = ligne[0] + "," + ligne[1]

Vous pouvez aussi appliquer ce cas pendant un géocodage classique si votre adresse complète se trouve dans deux colonnes différentes.

Et enfin à la ligne 18, on lui demande d’écrire nos nouvelles informations dans notre fichier de sortie.

outputData.writerow((adresse, location.latitude, location.longitude))

devient

outputData.writerow((coord, location.address.encode('utf-8')))

Quelques conseils pour régler les problèmes fréquents :

Une réflexion au sujet de « Le géocodage pas à pas »

  1. Dommage de s’appuyer sur l’API de Google… il faudrait lire les condition d’utilisation de celle-ci quant à ce qu’on peut réellement faire avec le résultat du géocodage !

    En alternative il y a l’API de la Base Adresse Nationale… écrite en python (le code est libre et sur github).

    Cette API permet du géocodage à l’unité, du géocodage inverse, de l’autocomplétion d’adresse et du géocodage en masse de fichiers CSV (pas besoin de faire des milliers de requêtes, mais une seul pour des paquets pouvant aller jusque 10 à 15000 lignes).

    Ça se passe ici: http://adresse.data.gouv.fr/tools/

Laisser un commentaire