You could make a recursive function. Just typing Python-esque pseudo-code:
from geopy.exc import GeocoderTimedOut
def do_geocode(address, attempt=1, max_attempts=5):
try:
return geopy.geocode(address)
except GeocoderTimedOut:
if attempt <= max_attempts:
return do_geocode(address, attempt=attempt+1)
raise
Documentation for geopy.exc.GeocoderTimedOut
.
This will keep retrying the do_geocode
function until it manages to return without a Timeout exception being raised. You might want to limit the number of attempts, or also set a waiting period after a failed attempt. You might also want to think about why a timeout is occurring. Geopy allows you to set the length of time to wait before raising a timeout error, for any of the geocoding methods, with the timeout
keyword argument. The documentation says that "some services are consistently slow", and recommends that this be increased.
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 :
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
Best Answer
User_Agent
is an http request header that is sent with each request.Nominatim requires this value to be set to your application name. The goal is to be able to limit the number of requests per application.
https://operations.osmfoundation.org/policies/nominatim/
Moreover, should you have a lot of queries, Nominatim asks that the
user_agent
also contains your email address (or that you use theemail
parameter)https://nominatim.org/release-docs/develop/api/Search/