Reverse Geo Location

For the drawn polygons I want to add a location label to get an idea where it is without the need of a map.

Nominatim

The standard solution is Nominatim and this would solve my problem easily, i.e. https://nominatim.openstreetmap.org/ui/reverse.html?lat=48.68330&lon=9.00311&zoom=17 (no link to not cause traffic). The query only returns one street and I am actually interested in the crossing of two streets.

The Usage policy of Nominatim could be okish for my idea, but I wanted to explore alternatives.

Stadia Maps

So I looked into what Stadia Maps could do, because I use them for maps already. Using their openapi based reference and a bit of Python code solves my problem (same geo coordinate as above):

import httpx

r = httpx.get(
    "https://api-eu.stadiamaps.com/geocoding/v1/reverse",
    params={
        "point.lat": "48.68330",
        "point.lon": "9.00311",
        "boundary.circle.radius": 1,  # 1 km radius
        "layers": "street",
        "sources": "openstreetmap",
        "api_key": "your-api-key-goes-here",
    },
)

for index, street in enumerate(r.json()["features"]):
    print(
        {
            k: v
            for k, v in street.get("properties").items()
            if k in ["distance", "label", "gid"]
        }
    )
    if index == 4:
        # stop after max 5 streets
        break

This results in:

{'distance': 0.019, 'gid': 'openstreetmap:street:polyline:31083747', 'label': 'Calwer Straße, Böblingen, BW, Germany'}
{'distance': 0.094, 'gid': 'openstreetmap:street:polyline:27779973', 'label': 'Berliner Straße, Böblingen, BW, Germany'}
{'distance': 0.12, 'gid': 'openstreetmap:street:polyline:31083808', 'label': 'Herrenberger Straße, Böblingen, BW, Germany'}
{'distance': 0.167, 'gid': 'openstreetmap:street:polyline:6513917', 'label': 'Karl-Benz-Straße, Böblingen, BW, Germany'}
{'distance': 0.203, 'gid': 'openstreetmap:street:polyline:6508508', 'label': 'Kurze Straße, Böblingen, BW, Germany'}

Which is not perfect, because the crossing is actually between "Calwer Straße" and "Herrenberger Straße". I see where this comes from: The crossing between "Berliner Straße" and "Herrenberger Straße" is not that far away. But overall this is good enough for me, as I only need a hint for a human where the crossing roughly is.

The Stadia Maps reverse api endpoint is in beta and currently free to use, but looking at their pricing table, reverse geo location seems to be not included in the free tier once it is out of beta.

OpenCage

The next possible solution is OpenCage Geocoding API. They have a good demo page too that shows everything I needed. The code to get the nearest street via OpenCage:

r = httpx.get(
    "https://api.opencagedata.com/geocode/v1/json",
    params={
        "q": "48.68330,9.00311",
        "language": "en",
        "key": "your-api-keys-goes-here",
        "pretty": 1,
    },
)

result = r.json()["results"][0]
print(result.get("formatted"))

This results in:

Calwer Straße, 71034 Böblingen, Germany
Like Nominatim this api returns only one street but still a good alternative when Stadia Maps is not free anymore.

Conclusion

I may use both apis (Stadia Maps and OpenCage) in the beginning and wait what happens when the Stadia Maps reverse geolocation feature is out of beta.

There are other alternatives and getlon.lat gives a pretty good overview. For me having three (including Nominatim) solutions seems enough for now.