[GIS] Max retries exceeded with URL in Nominatim with GeoPy

geopynominatimpythonreverse-geocoding

I'm trying to get a country name by lat lon (reverse encoding) using Python. I got to Nominatim with GeoPy which worked great two times but now I keep getting Max retries exceeded error.

My code:

from geopy.geocoders import Nominatim

def get_countries(lat,lon):
    coordinates = f'{lat} {lon}'
    locator = Nominatim(user_agent='myencoder', timeout=10)
    location = locator.reverse(coordinates,language='en')
    country = location.raw['address']['country_code'].upper()
    return [country,lat,lon]

get_countries(32.782023,35.478867)

In practice I would like to use this function for about 100-200 locations, but I get the error also for this one location. It worked the first time I run the code, but then I'm keep getting:

GeocoderUnavailable: HTTPSConnectionPool(host='nominatim.openstreetmap.org', port=443): Max retries exceeded with url: /reverse?lat=32.782023&lon=35.478867&format=json&accept-language=en&addressdetails=1 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001F7AA229978>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it',))

I've tried changing the user_agent by writing my email or another name as suggested here, I also read the answers here and here, also other solutions. All resulted in this error.

What else can I do? Are there other reliable options using Python to get a country name (preferably with to letters e.g., ES, IT, US, etc.) by lat lon?

Best Answer

If GeoPy usage is not mandatory, one can try to achieve the desired output with the requests package and the The Nominatim.

There will be a request sent like a Reverse geocoding based on the following URL:

https://nominatim.openstreetmap.org/reverse?lat=<value>&lon=<value>&<params>

However, the above link needs several adjustments:

https://nominatim.openstreetmap.org/reverse?lat=<value>&lon=<value>&format=json&accept-language=en&zoom=3

where:

  • format=json : Output format
  • accept-language=en : Language of results
  • zoom=3 : Result limitation for country
import requests

def get_country(lat, lon):
    url = f'https://nominatim.openstreetmap.org/reverse?lat={lat}&lon={lon}&format=json&accept-language=en&zoom=3'
    try:
        result = requests.get(url=url)
        result_json = result.json()
        return result_json['display_name']
    except:
        return None

print(get_country(32.782023,35.478867)) # results in Israel

The output in Browser shall look like this :

result

To get only two letters, one can try the following code:

import requests

def get_country(lat, lon):
    url = f'https://nominatim.openstreetmap.org/reverse?lat={lat}&lon={lon}&format=json&namedetails=1&accept-language=en&zoom=3'
    try:
        result = requests.get(url=url)
        result_json = result.json()
        return result_json['address']['country_code'].upper()
    except:
        return None

print(get_country(32.782023,35.478867)) # results in IL