Extract District from Coordinates Using Python
Question:
I have a collection of longitudes and latitudes, and I want to be able to extract the district of each of these coordinates using Python.
As of right now, I have developed the following function using the geopy
library,
from geopy.geocoders import Nominatim
from geopy.point import Point
MAX_RETRIES = 5
def get_district(lat, longi):
geolocator = Nominatim(user_agent="http")
point = Point(lat, longi)
retries = 0
while retries < MAX_RETRIES:
retries += 1
try:
location = geolocator.reverse(point)
district = location.raw['address']['state_district']
return district
except:
print('Request failed.')
print('Retrying..')
time.sleep(2)
print('Max retries exceeded.')
return None
This works fine for a single point, but I have a number of them (approximately 10,000) and this only works for one coordinate at a time. There is no option to make bulk requests for several points.
Furthermore, this API becomes quite unreliable when making multiple such requests.
Is there a better way to achieve this using Python? I am open to any approach. Even if there is a file of sorts that I can find with a mapping of the coordinates against the districts, it works for me.
Note: At the moment, I am looking at coordinates in Sri Lanka.
Answers:
You can use Geopandas. First you have to download the shapefiles of Sri Lanka (DDL) then extract the files of the second level (district, adm2). Finally,
# pip install geopandas
import geopandas as gpd
from shapely.geometry import Point
# you also need .shx file
gdf = gpd.read_file('lka_admbnda_adm2_slsd_20220816.shp')
def get_district(lat, longi):
point = Point(longi, lat) # swap longi and lat here
return gdf.loc[gdf.contains(point), 'ADM2_EN'].squeeze()
Usage:
>>> get_district(6.927079, 79.861244)
'Colombo'
>>> get_district(9.661498, 80.025547)
'Jaffna'
I have a collection of longitudes and latitudes, and I want to be able to extract the district of each of these coordinates using Python.
As of right now, I have developed the following function using the geopy
library,
from geopy.geocoders import Nominatim
from geopy.point import Point
MAX_RETRIES = 5
def get_district(lat, longi):
geolocator = Nominatim(user_agent="http")
point = Point(lat, longi)
retries = 0
while retries < MAX_RETRIES:
retries += 1
try:
location = geolocator.reverse(point)
district = location.raw['address']['state_district']
return district
except:
print('Request failed.')
print('Retrying..')
time.sleep(2)
print('Max retries exceeded.')
return None
This works fine for a single point, but I have a number of them (approximately 10,000) and this only works for one coordinate at a time. There is no option to make bulk requests for several points.
Furthermore, this API becomes quite unreliable when making multiple such requests.
Is there a better way to achieve this using Python? I am open to any approach. Even if there is a file of sorts that I can find with a mapping of the coordinates against the districts, it works for me.
Note: At the moment, I am looking at coordinates in Sri Lanka.
You can use Geopandas. First you have to download the shapefiles of Sri Lanka (DDL) then extract the files of the second level (district, adm2). Finally,
# pip install geopandas
import geopandas as gpd
from shapely.geometry import Point
# you also need .shx file
gdf = gpd.read_file('lka_admbnda_adm2_slsd_20220816.shp')
def get_district(lat, longi):
point = Point(longi, lat) # swap longi and lat here
return gdf.loc[gdf.contains(point), 'ADM2_EN'].squeeze()
Usage:
>>> get_district(6.927079, 79.861244)
'Colombo'
>>> get_district(9.661498, 80.025547)
'Jaffna'