Géocodage inverse en Python : des coordonnées à une adresse

Le géocodage inverse transforme un point GPS en adresse la plus proche. Le résultat ne vaut que par sa distance : un point en plein champ n’est « près » d’aucune adresse. Ce tutoriel appelle le point d’accès inverse, lit distance_m et precision, et décide quoi faire de la réponse.

L’URL de base https://api.addrova.eu n’est pas encore en ligne. Tout ce qui suit suit la spécification de l’API. [À VÉRIFIER : service ouvert, URL de base définitive.]

1. Un point

import os
import requests

resp = requests.get(
    "https://api.addrova.eu/v1/reverse",
    headers={"X-API-Key": os.environ["ADDROVA_API_KEY"]},
    params={"lat": 47.64, "lon": 6.86, "limit": 1},
    timeout=10,
)
resp.raise_for_status()
data = resp.json()
for r in data["results"]:
    print(r["label"], r.get("distance_m"), r["precision"])
print([a["text"] for a in data["attribution"]])

limit va de 1 à 10. Chaque résultat porte le libellé, les composants, precision, une confiance et distance_m, la distance en mètres au point envoyé. Conservez l’attribution avec le résultat si vous le stockez.

2. N’accepter que les résultats proches

Décidez à partir de quelle distance c’est trop loin pour votre cas. Une application de livraison voudra 30 mètres, un traitement statistique 500.

import os
import requests

def nearest_address(lat: float, lon: float, max_distance_m: float = 50.0):
    resp = requests.get(
        "https://api.addrova.eu/v1/reverse",
        headers={"X-API-Key": os.environ["ADDROVA_API_KEY"]},
        params={"lat": lat, "lon": lon, "limit": 1},
        timeout=10,
    )
    resp.raise_for_status()
    results = resp.json()["results"]
    if not results:
        return None
    best = results[0]
    distance = best.get("distance_m")
    if distance is not None and distance > max_distance_m:
        return None  # l'adresse la plus proche est trop loin pour dire « ici »
    return best

hit = nearest_address(47.64, 6.86)
print(hit["label"] if hit else "aucune adresse dans la limite")

3. Plusieurs points

Pour quelques points, bouclez avec une courte pause plutôt que tout d’un coup, et ne journalisez jamais les coordonnées : une position identifie une personne aussi sûrement qu’une adresse (le service n’écrit aucune coordonnée demandée dans ses journaux, ZL-10).

import os
import time
import requests

points = [(47.64, 6.86), (48.8566, 2.3522)]
rows = []
for lat, lon in points:
    resp = requests.get(
        "https://api.addrova.eu/v1/reverse",
        headers={"X-API-Key": os.environ["ADDROVA_API_KEY"]},
        params={"lat": lat, "lon": lon, "limit": 1},
        timeout=10,
    )
    resp.raise_for_status()
    results = resp.json()["results"]
    rows.append((lat, lon, results[0]["label"] if results else None))
    time.sleep(0.05)
print(rows)

À vérifier

  • Précision : une réponse locality ou centroid est un lieu, pas une porte : voir les niveaux de précision.
  • Distance : lisez toujours distance_m avant d’afficher une adresse comme « l’adresse » d’un point.
  • Comparer les fournisseurs : voir quoi comparer en géocodage inverse.