There are multiple ways to use Python to retrieve the name of a country based on its latitude and longitude:
Table of contents
Using urllib3 and nominatim
One possible solution is to use urllib3 to send a URL request to https://nominatim.openstreetmap.org/ and specify the latitude and longitude
import urllib3
import json
http = urllib3.PoolManager(1, headers={'user-agent': 'my-test-app'})
long = '2.2137'
lat = '46.2276'
url = 'https://nominatim.openstreetmap.org/reverse.php?lat={}&lon={}&zoom=18&format=jsonv2'.format(lat,long)
resp = http.request('GET', url)
json.loads(resp.data.decode())
Output
{'place_id': 159350547,
'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright',
'osm_type': 'way',
'osm_id': 218437442,
'lat': '46.2263436',
'lon': '2.2162551',
'place_rank': 26,
'category': 'highway',
'type': 'residential',
'importance': 0.10000999999999993,
'addresstype': 'road',
'name': None,
'display_name': 'Le Bois du Puy, La Celle-sous-Gouzon, Aubusson, Creuse, Nouvelle-Aquitaine, France métropolitaine, 23230, France',
'address': {'hamlet': 'Le Bois du Puy',
'village': 'La Celle-sous-Gouzon',
'municipality': 'Aubusson',
'county': 'Creuse',
'ISO3166-2-lvl6': 'FR-23',
'state': 'Nouvelle-Aquitaine',
'ISO3166-2-lvl4': 'FR-NAQ',
'region': 'France métropolitaine',
'postcode': '23230',
'country': 'France',
'country_code': 'fr'},
'boundingbox': ['46.2253794', '46.2269819', '2.2162122', '2.2180207']}
To extract the name of a country, a possible solution is to do:
res = json.loads(resp.data.decode())
res['address']['country']
which returns here
'France'
Please ensure to read the policies of Nominatim carefully before using it. It is noteworthy that:
The following uses are strictly forbidden and will get you banned:
Auto-complete search This is not yet supported by Nominatim and you must not implement such a service on the client side using the API.
Systematic queries This includes reverse queries in a grid, searching for complete lists of postcodes, towns etc. and downloading all POIs in an area. If you need complete sets of data, get it from the OSM planet or an extract.
Scraping of details The details page is there for debugging only and may not be downloaded automatically.
To obtain the names of countries for a sizeable dataset that contains latitude and longitude information, kindly visit planet.openstreetmap.org.
Using Geopy
Geopy is a Python library that allows developers to obtain coordinates for various locations using popular geocoding web services. This includes finding the coordinates for addresses, cities, countries, and landmarks. The library uses third-party geocoders and data sources to make this process simple for Python developers.
To install Geopy library
pip install geopy
Example on how to use geopy to retrieve country name from longitude and latitude
from geopy.geocoders import Nominatim
from geopy.geocoders import Photon
geolocator = Photon(user_agent="measurements")
long = '2.2137'
lat = '46.2276'
coord = f"{lat}, {long}"
location = geolocator.reverse(coord, exactly_one=True)
print(location)
Output
Étang du Puy, 23230, France
Using Google API
One alternative solution is to utilize the "Geocoding API" from Google. However, it's important to note that using this API requires payment (more information is available on the pricing page). To use the Google API, you'll need to visit google cloud and generate an API key first (check out this video for a tutorial on how to do this). Once you have your Google API key, navigate to the library and search for the Geocoding API. Enable the API once you've found it.
You can create a Python code to retrieve the country based on a specific latitude and longitude:
from urllib.request import urlopen
import json
def get_country(lat, lon):
key='*****************'
url = "https://maps.googleapis.com/maps/api/geocode/json?"
url += "latlng=%s,%s&sensor=false&key=%s" % (lat, lon, key)
v = urlopen(url).read()
j = json.loads(v)
print(j)
components = j['results'][0]['address_components']
country = town = None
for c in components:
if "country" in c['types']:
country = c['long_name']
if "postal_town" in c['types']:
town = c['long_name']
return town, country
print( get_country(2.2137, 46.2276) )
replace key='*****' with your google unique API key.
References
Links | Site |
---|---|
geopy 2.3.0 | pypi.org |
Nominatim | operations.osmfoundation.org |
openstreetmap | planet.openstreetmap |
Nominatim Map | nominatim.openstreetmap.org |
openstreetmap Map | www.openstreetmap.org |
countries.csv | githubusercontent.com/ |