Reverse geocoding in Python: from coordinates to an address

Reverse geocoding turns a GPS point into the nearest address. The result is only as useful as its distance: a point in a field is not "near" any address. This tutorial calls the reverse endpoint, reads distance_m and precision, and decides what to do with the answer.

The base URL https://api.addrova.eu is not live yet. Everything below follows the API specification. [À VÉRIFIER : service ouvert, URL de base définitive.]

1. One 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 goes from 1 to 10. Each result carries the label, the components, precision, a confidence and distance_m, the distance in metres from the point you sent. Keep the attribution with the result if you store it.

2. Accept only close results

Decide how far is too far for your use case. A delivery app may want 30 metres, a statistics job 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  # the nearest address is too far to call it "here"
    return best

hit = nearest_address(47.64, 6.86)
print(hit["label"] if hit else "no address within the limit")

3. Many points

For a few points, loop with a short pause rather than all at once, and never log the coordinates: a position can identify a person as surely as an address (the service writes no requested coordinate to its logs, 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)

Things to check