Created
September 14, 2015 21:13
-
-
Save prithwi/3553bcc22bdd34f4b599 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Author: Prithwish Chakrabory <[email protected]> | |
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example run: