Skip to content

Instantly share code, notes, and snippets.

@prithwi
Created September 14, 2015 21:13
Show Gist options
  • Save prithwi/3553bcc22bdd34f4b599 to your computer and use it in GitHub Desktop.
Save prithwi/3553bcc22bdd34f4b599 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Prithwish Chakrabory <prithwi@vt.edu>
# LICENSE: MIT
# date: 2015-09-01
"""
Code to find country from lat-lon using shapefile
Shapefile used: http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip
Can use any shapefile as long as geometry defined by lon, lat
"""
import geopandas
import shapely
# import pandas as pd
class ShapeException(Exception):
pass
class ShapeGeo(object):
"""class to get the shapefile backed reverse_geocoder"""
def __init__(self, shapefile, index_col=None):
"""Initialized the class with shapefile
:shapefile: shapefile location
:index_col: file to index_on
"""
self._shapefile = shapefile
self._index_col = index_col
self._geo_df = self.read_shapefile(shapefile, index_col)
@property
def geo_df(self):
return self._geo_df
@staticmethod
def read_shapefile(shapefile, index_col=None):
"""reads the shapefile
Function intentionally left as staticmethod
:returns: geopandas dataframe
"""
geo_df = geopandas.GeoDataFrame.from_file(shapefile)
if index_col:
geo_df.set_index(index_col, inplace=True)
return geo_df
def reverse_geo(self, lat, lon, level=0):
"""reverse geocoder using shapefile
:lat: latitude
:lon: longitude
:level: level of reverse geocoding required.
0: Country
1: State
2: City
:returns: geo as tuple
"""
if level != 0:
raise NotImplementedError("Only country implemented")
point = shapely.geometry.Point(lon, lat)
filtered = self.geo_df[self.geo_df.geometry.contains(point)]
try:
if len(filtered) > 1:
raise Warning("More than one match")
res = (filtered.iloc[0]['NAME'],)
except Exception as e:
raise ShapeException('{}:{} caused {}'.format(lat, lon, e)
)
return res
@prithwi
Copy link
Author

prithwi commented Sep 14, 2015

Example run:

>> from shapeGeocoder import ShapeGeo

>> shapefile = 'TM_WORLD_BORDERS_SIMPL-0.3.shp'
>> geo = ShapeGeo(shapefile)

>> # Reverse Geocoding 
>> br_ll = br_ll = [-15.7833, -47.8667]          # Brazil lat lon
>> print geo.reverse_geo(*br_ll)
(u'Brazil',)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment