Introduction
GeoPandas est une bibliothèque Python très utile pour travailler avec des données géospatiales. Elle s’appuie notamment sur Shapely pour les opérations géométriques. Elle fournit un cadre intuitif pour manipuler et analyser des données géographiques directement en Python, avec des formats comme les shapefiles, GeoJSON ou encore certaines bases de données spatiales.
Un problème courant en analyse géospatiale consiste à déterminer le contexte géographique d’un point. En pratique, cela revient souvent à répondre à une question simple mais fondamentale : étant donné une paire de coordonnées latitude/longitude, à quel pays appartient ce point ?
Dans ce guide, nous allons parcourir un workflow complet et pratique pour répondre à cette question. Nous commencerons par charger les frontières des pays depuis Natural Earth, puis nous verrons comment interroger efficacement des points individuels. Nous mettrons également en évidence certains pièges fréquents, comme les résultats dupliqués liés aux géométries multi-parties, et nous verrons comment les éviter. Enfin, nous comparerons une approche simple avec une solution vectorisée plus optimisée, adaptée aux grands jeux de données.
Table of contents
Télécharger le jeu de données Natural Earth
Nous allons utiliser le jeu de données Natural Earth à résolution 110m, qui fournit les frontières des pays à l’échelle globale.
Natural Earth Data est un jeu de données du domaine public qui fournit des données géographiques à différentes échelles, notamment les frontières des pays, les routes, les villes, etc. Les données Natural Earth peuvent être téléchargées gratuitement depuis leur site.
Téléchargement :
https://www.naturalearthdata.com/downloads/110m-cultural-vectors/
Téléchargez le fichier :
1 | ne_110m_admin_0_countries.shp |
Décompressez-le ensuite et placez-le dans votre répertoire de travail.
Installer GeoPandas
Avant de récupérer les noms des pays, assurons-nous d’abord que GeoPandas est installé. Vous pouvez par exemple l’installer avec pip :
1 | pip install geopandas |
Charger le jeu de données
Utilisons GeoPandas pour explorer le jeu de données culturel Natural Earth 110m :
1 2 3 4 5 6 7 8 9 10 | import geopandas as gpd from shapely.geometry import Point # Charger le shapefile gdf = gpd.read_file("110m_cultural/ne_110m_admin_0_countries.shp") # Conserver uniquement les colonnes utiles gdf = gdf[['NAME', 'geometry']] print(gdf.head()) |

Important :
Les données Natural Earth sont déjà en coordonnées géographiques (EPSG:4326), ce qui correspond au système latitude/longitude.
Retrouver le nom d’un pays à partir d’une latitude et d’une longitude
Définir un point géographique
Pour retrouver le nom du pays correspondant à un point spécifique, nous devons d’abord définir ce point à partir de sa latitude et de sa longitude. Supposons que l’on souhaite savoir dans quel pays se trouve le point suivant.
Avec GeoPandas, on peut utiliser la classe Point de Shapely :
1 2 3 4 | target_lon = 2.2137 target_lat = 46.227 point = Point(target_lon, target_lat) |
Méthode 1 — Approche simple avec une boucle et contains
1 2 3 4 5 6 7 8 9 10 | found_country = None for _, row in gdf.iterrows(): geom = row.geometry if geom.contains(point): found_country = row['NAME'] break print(found_country) |
Sortie :
1 | France
|
Note : pourquoi des doublons peuvent apparaître, par exemple "France" affiché deux fois.
Exemple :
1 2 3 4 5 6 7 8 9 | for index, row in gdf.iterrows(): if 'MultiPolygon' in row['geometry'].geom_type: for polygon in row['geometry'].geoms: if polygon.contains(point): print(row['NAME']) if 'Polygon' in row['geometry'].geom_type: polygon = row['geometry'] if polygon.contains(point): print(row['NAME']) |
Certains pays comme la France sont stockés sous forme de géométries MultiPolygon :
- France métropolitaine ;
- territoires d’outre-mer, par exemple la Guyane française ou certaines îles.
Si vous parcourez manuellement chaque sous-géométrie, vous pouvez obtenir plusieurs correspondances, ce qui peut produire des résultats dupliqués.
Méthode 2 — Approche recommandée avec une jointure spatiale vectorisée
C’est la méthode la plus propre et la plus adaptée aux grands jeux de données.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # Créer un GeoDataFrame pour le point point_gdf = gpd.GeoDataFrame( geometry=[Point(target_lon, target_lat)], crs="EPSG:4326" ) # Vérifier que les systèmes de coordonnées sont cohérents gdf = gdf.to_crs(point_gdf.crs) # Jointure spatiale result = gpd.sjoin(point_gdf, gdf, predicate="within") print(result['NAME'].iloc[0]) |
Sortie :
1 | France
|
Pourquoi cette méthode est préférable :
- pas de boucle explicite ;
- utilisation d’un index spatial, de type R-tree ;
- évite les sorties dupliquées ;
- beaucoup plus rapide pour les grands jeux de données.
Cette approche est particulièrement importante si vous :
- traitez de grands jeux de données ;
- exécutez des pipelines de géolocalisation par lots ;
- travaillez avec des grilles H3.
Gérer les cas particuliers aux frontières
Parfois, un point se trouve exactement sur une frontière. Dans ce cas, contains() peut retourner False.
Vous pouvez alors utiliser :
1 | result = gpd.sjoin(point_gdf, gdf, predicate="intersects") |
Méthode 3 — Plusieurs points à la fois
1 2 3 4 5 6 7 8 9 10 11 | points = gpd.GeoDataFrame( geometry=[ Point(2.21, 46.22), # France Point(-95.71, 37.09), # États-Unis ], crs="EPSG:4326" ) result = gpd.sjoin(points, gdf, predicate="within") print(result[['geometry', 'NAME']]) |
Sortie :
1 2 3 | geometry NAME 0 POINT (2.21 46.22) France 1 POINT (-95.71 37.09) United States of America |
Visualisation, optionnelle mais recommandée
1 2 3 4 5 6 7 8 | import folium m = folium.Map(location=[46.2, 2.2], zoom_start=5) folium.GeoJson(gdf).add_to(m) folium.Marker([target_lat, target_lon]).add_to(m) m |

Cette visualisation est très utile pour :
- déboguer ;
- valider les jointures spatiales ;
- effectuer des contrôles qualité rapides.
Résumé
| Méthode | Avantages | Inconvénients |
|---|---|---|
Boucle + contains |
Simple | Lent |
Boucle + break |
Évite certains doublons | Toujours lent |
Jointure spatiale sjoin |
Rapide, scalable, propre | Nécessite un GeoDataFrame |
Autres méthodes
Voir aussi cet article associé :
Références
| Lien | Description |
|---|---|
| https://www.naturalearthdata.com/downloads/110m-cultural-vectors/ | Jeu de données Natural Earth |
| https://geopandas.org/en/stable/docs/reference/api/geopandas.sjoin.html | Jointure spatiale GeoPandas |
| https://shapely.readthedocs.io/en/stable/manual.html | Opérations géométriques avec Shapely |
| https://proj.org | Systèmes de référence de coordonnées |
| https://rtree.readthedocs.io | Backend d’indexation spatiale |
| https://en.wikipedia.org/wiki/Point_in_polygon | Concept point-dans-polygone |
Conseil final pour les utilisateurs avancés
Pour des pipelines haute performance, par exemple avec des données VIIRS ou des grilles H3, vous pouvez envisager de :
- préconstruire des index spatiaux ;
- utiliser des jointures vectorisées sur des lots de points ;
- combiner GeoPandas avec l’indexation H3 pour effectuer un préfiltrage spatial grossier.
Cela peut améliorer les performances de plusieurs ordres de grandeur sur des jeux de données à grande échelle.
