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.

Asked By: Minura Punchihewa

||

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'
Answered By: Corralien
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.