Géocodage d’adresse avec Python : GeoPy et Pandas

Le géocodage consiste en la localisation géographique d’adresse. Le géocodage d’adresse avec Python présente l’avantage de réaliser des tâches de fond automatisées par la machine. Cette transformation géographique permet de traiter des centaines de milliers d’adresses stockées dans des bases de données et des tableurs. Pour cela, on utilise des bibliothèques Python tel GeoPy qui prend en charge des services de géocodage comme Nominatim.

Bibliothèques Python pour le géocodage d’adresse

Présentation de GeoPy

GeoPy est une bibliothèque Python open-source qui possède de nombreuses fonctionnalités :

  • Géocoder des adresses;
  • Trouver des distances entre deux points géographiques;
  • Calculer des itinéraires;
  • Et, effectuer d’autres opérations liées à la géolocalisation basés sur différents fournisseurs de services de géocodage comme OpenStreetMap Nominatim, Google Maps, Bing Maps.

La documentation officielle de GeoPy est disponible en ligne pour plus de détails sur ses fonctionnalités.

Installation de GeoPy

Pour utiliser GeoPy, vous devez l’installer au préalable en exécutant la commande suivante dans votre terminal ou invite de commande :

pip install geopy

Utilisation de GeoPy : Exemple de Géocodage d’une adresse

Dans cette section, on utilise GeoPy pour géolocaliser une adresse. Le géocodeur Nominatim fourni par la bibliothèque permet d’obtenir les coordonnées géographiques (longitude et latitude) du Mont-Saint-Michel en Normandie. – Certains irrésistibles diront que ce monument historique est localisé en Bretagne à marée haute 😉 -.

Localisation du Mont-Saint-michel
import geopy
from geopy.geocoders import Nominatim

# Création d'un objet géocodeur Nominatim
geolocator = Nominatim(user_agent="my_geocoder")

# Géocodage d'une adresse
location = geolocator.geocode("Mont-Saint-Michel, Normandie, France")

# Affichage des informations de localisation
print("Adresse:", location.address,"Latitude:", location.latitude, "Longitude:", location.longitude)

L’exécution du script ci-dessus donne une erreur SSL lors de l’appel du service web de géocodage de Nominatim. On installe les modules certifi et SSL pour pallier ce problème.

import geopy,certifi,ssl
from geopy.geocoders import Nominatim

ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx

# Création d'un objet géocodeur Nominatim
geolocator = Nominatim(user_agent="my_geocoder")

# Géocodage d'une adresse
location = geolocator.geocode("Mont-Saint-Michel, Normandie, France")

# Affichage des informations de localisation
print("Adresse:", location.address,"Latitude:", location.latitude, "Longitude:", location.longitude)
#output
Adresse: Mont Saint-Michel, Grand Degré, Le Mont-Saint-Michel, Avranches, Manche, Normandie, France métropolitaine, 50170, France Latitude: 48.6359541 Longitude: -1.511459954959514

Note : Si on remplace Normandie par Bretagne, effectivement, on ne trouve pas la bonne adresse du Mont-Saint-Michel… 😕

Pandas pour l’analyse des données en Python

Présentation de la librairie Python Pandas

Pandas est une bibliothèque open-source pour l’analyse de données en Python. Elle facilite la manipulation des données grâce principalement à deux types de structure : les Series et les DataFrame.

  1. Series : Structure unidimensionnelle identique à un tableau ou une colonne dans une feuille de calcul. Les Series sont également utilisées pour représenter une seule colonne d’un DataFrame.
  2. DataFrame : Structure de données tabulaire bidimensionnelle comparable à une table attributaire. Les colonnes peuvent être de types différents et définies comme index.

Ainsi, Pandas gère le filtrage, le regroupement, le tri, la fusion et d’autres opérations performantes sur les données. Par extension, d’autres bibliothèques de Python comme NumPy, Matplotlib et Scikit-learn lui sont associées pour des traitements et des analyses de données exhaustives.

La documentation de Pandas présente l’ensemble de ses fonctionnalités avec des exemples d’utilisation.

Exemple d’utilisation de Pandas

Voici un exemple simple d’utilisation de la librairie Pandas avec la création d’un DataFrame :

import pandas as pd

# Création d'un DataFrame
data = {'Ville': ['Paris', 'Marseille', 'Lyon'],
        'Longitude': [2.2107, 5.2212, 4.4956],
        'Latitude': [48.5124, 43.1747, 45.4528]}

df = pd.DataFrame(data)

# Affichage du Tableau
print(df)
#output
       Ville  Longitude  Latitude
0      Paris     2.2107   48.5124
1  Marseille     5.2212   43.1747
2       Lyon     4.4956   45.4528

Code Python pour le géocodage d’adresse

Dans cette section, le code Python a pour objectif de géocoder des adresses depuis un tableur csv. Il peut se décomposer en trois étapes :

  1. Lecture des données du tableur csv;
  2. Géocodage des adresses avec Nominatim;
  3. Export du DataFrame avec les adresses géolocalisées dans un tableur csv.

Pour l’exemple, on s’appuie sur le tableur des églises brésiliennes issu des recherches de Victor Araújo (2023).

Lecture d’un fichier csv en Python avec Pandas

Pandas offre la possibilité de lire un fichier csv avec la méthode read_csv qui associe de nombreux paramètres. Ici, on indique :

  • L’emplacement du fichier csv;
  • usecols : permet de sélectionner les colonnes à retourner dans le DataFrame;
  • header : 0 indique la prise en charge d’une ligne d’en-tête dans le fichier;
  • nrows : retourne un nombre de lignes limité du tableur csv.

Puis, on concatène les colonnes logradouro et municipio pour créer la serie adresse.

import pandas as pd,geopy,certifi,ssl
from geopy.geocoders import Nominatim

ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx

geolocator = Nominatim(user_agent="geocodage")

#Remplacer le chemin du fichier
df = pd.read_csv(rf'D:\temp\df_igrejas_nomes.csv', 
                 usecols= ['numero','logradouro','cep','municipio'],header=0,nrows=10)
adresse = df['logradouro'] +' '+ df['municipio']

print(adresse)
#output
0       CARLOS DE NOBREGA TEIXEIRA RIO GRANDE DA SERRA
1                                          QS BRASILIA
2                              SANTA GERTRUDES GOIANIA
3                          JOAO XXIII QD 03 RIO BRANCO
4                ALTO DA VILA PRAIANA LAURO DE FREITAS
5                                DA PISTA NOVA VALENCA
6                                       14 PARAUAPEBAS
7    https://cran.r-project.org/web/packages/ggdag/...
8                  CAPITAO NATANAEL AGUIAR PORTO VELHO
9                                     TOCANTINS PALMAS
dtype: object

Géocodage des adresses en Python avec GeoPy et Nominatim

Comme pour la section sur GeoPy, on utilise le service de géocodage Nominatim. Dans une boucle, on liste les adresses pour lesquelles on retourne les longitudes et les latitudes. Puis, on ajoute les résultats dans des listes avec la méthode append. Enfin, ces listes sont intégrées dans un DataFrame déclaré ici output. On note que l’exception retourne les adresses non géolocalisées. Ces dernières pourraient également être stockées dans un tableau.

import pandas as pd,geopy,certifi,ssl
from geopy.geocoders import Nominatim

ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx

geolocator = Nominatim(user_agent="geocodage")

df = pd.read_csv(rf'D:\temp\df_igrejas_nomes.csv', 
                 usecols= ['numero','logradouro','cep','municipio'],header=0,nrows=10)
adresse = df['logradouro'] +' '+ df['municipio']
adresse_list = []
longitude_list = []
latitude_list = []
for x in adresse:
    try: 
        longitude = geolocator.geocode(x).longitude
        latitude = geolocator.geocode(x).latitude
        adresse_list.append(x)
        longitude_list.append(longitude)
        latitude_list.append(latitude)
    except:
        print('Adresse non localisée : '+x)
output = pd.DataFrame({'adresse':adresse_list,'longitude':longitude_list,'latitude':latitude_list})
print(output)
Géocodage d'adresse avec Python

Export des adresses géocodées dans un tableur csv

La méthode to_csv de Pandas génère l’export des données du DataFrame dans un tableur csv sur le disque. Et, comme pour read_csv, de nombreux paramètres existent. Ici, on indique :

  • index : False, aucune colonne n’est définie comme index;
  • sep : indique le séparateur entre les colonnes du tableur;
  • encoding : définition de l’encodage des caractères.
import pandas as pd,geopy,certifi,ssl
from geopy.geocoders import Nominatim

ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx

geolocator = Nominatim(user_agent="geocodage")

df = pd.read_csv(rf'D:\temp\df_igrejas_nomes.csv', 
                 usecols= ['numero','logradouro','cep','municipio'],header=0,nrows=10)
adresse = df['logradouro'] +' '+ df['municipio']
adresse_list = []
longitude_list = []
latitude_list = []
for x in adresse:
    try: 
        longitude = geolocator.geocode(x).longitude
        latitude = geolocator.geocode(x).latitude
        adresse_list.append(x)
        longitude_list.append(longitude)
        latitude_list.append(latitude)
    except:
        print('Adresse non localisée : '+x)
output = pd.DataFrame({'adresse':adresse_list,'longitude':longitude_list,'latitude':latitude_list})
#print(output)
output.to_csv(rf'D:\temp\df_igrejas_nomes_loc.csv',index=False,sep=';',encoding='utf-8')
#fichier csv
adresse;longitude;latitude
CARLOS DE NOBREGA TEIXEIRA RIO GRANDE DA SERRA;-46.4069098;-23.7692356
QS BRASILIA;-48.01154835195575;-15.88353925
SANTA GERTRUDES GOIANIA;-49.2808133;-16.6803343
JOAO XXIII QD 03 RIO BRANCO;-67.8187623;-9.9587369
ALTO DA VILA PRAIANA LAURO DE FREITAS;-38.312636;-12.8980526
14 PARAUAPEBAS;-49.8903283;-6.0696846
CAPITAO NATANAEL AGUIAR PORTO VELHO;-63.8637977;-8.7568735
TOCANTINS PALMAS;-48.3336423;-10.1837852

En conclusion, après exécution du code Python, on obtient le fichier csv avec les adresses géocodées.

Partager l'article
Taggé , .Mettre en favori le Permaliens.

A propos Florian Delahaye

Passionné de Géomatique

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *