Comment retrouver le nom d’un pays à partir d’une latitude et d’une longitude avec GeoPandas et Natural Earth ?

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.

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())

Comment retrouver le nom d’un pays à partir d’une latitude et d’une longitude avec GeoPandas et Natural Earth ?
Comment retrouver le nom d’un pays à partir d’une latitude et d’une longitude avec GeoPandas et Natural Earth ?

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

Comment retrouver le nom d’un pays à partir d’une latitude et d’une longitude avec GeoPandas et Natural Earth ?
Comment retrouver le nom d’un pays à partir d’une latitude et d’une longitude avec GeoPandas et Natural Earth ?

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é :

https://en.moonbooks.org/Articles/How-to-retrieve-country-name-for-a-given-latitude-and-longitude-using-python-/

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.

Image

of