Reverse Geocoding in Python. How to Convert Raw Latitude/Longitude... | by Abdishakur | Towards Data Science

Many datasets have only coordinates — latitude and longitude — and do not have any association with identifiable features like addresses, street names, building names or postcodes that we humans recognise. Reverse Geocoding is an essential component in many location data science applications. The process of converting the raw coordinates to insightful location data features is called Reverse Geocoding.
Reverse geocoding is the process of back (reverse) coding of a point location (latitude, longitude) to a readable address or place name. — Wikipedia
In this tutorial, we will cover how to perform reverse geocoding using Python. We use Pandas and Geopy libraries to deliver reverse geocoding. In the next section, we cover the basics and convert a single point coordinates to an address with postcode and building name.
Let us import our libraries first.
%load_ext autotimeimport pandas as pdimport geopandas as gpdimport geopyfrom geopy.geocoders import Nominatimfrom geopy.extra.rate_limiter import RateLimiterimport matplotlib.pyplot as pltimport plotly_express as pximport tqdmfrom tqdm._tqdm_notebook import tqdm_notebook
We now can construct our Geocoder. We first need to specify the Geocoding service. You can access different services including 'google', 'bing', 'yahoo'and 'openmapquest' . Some of these services charge small free after a specific limit, but in our example, we will use the free Geocoding service of Openstreetmap.
locator = Nominatim(user_agent=”myGeocoder”)coordinates = “53.480837, -2.244914”location = locator.reverse(coordinates)location.raw
Once you provide the coordinates with the Geocoding service of our choice, the result is a dictionary of different features you can access. If you print out the raw element of the location you will see several exciting features derived from the coordinates.
{‘address’: {‘building’: ‘Eagle Insurance Buildings’, ‘city’: ‘Manchester’, ‘country’: ‘United Kingdom’, ‘country_code’: ‘gb’, ‘county’: ‘Greater Manchester’, ‘house_number’: ‘68’, ‘postcode’: ‘M2 4JG’, ‘road’: ‘Cross Street’, ‘state’: ‘England’, ‘state_district’: ‘North West England’, ‘suburb’: ‘City Centre’}, ‘boundingbox’: [‘53.480856’, ‘53.4810634’, ‘-2.2451761’, ‘-2.2449576’], ‘display_name’: ‘Eagle Insurance Buildings, 68, Cross Street, City Centre, Manchester, Greater Manchester, North West England, England, M2 4JG, United Kingdom’,‘lat’: ‘53.4809597’, ‘licence’: ‘Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', ‘lon’: ‘-2.24506682746292’, ‘osm_id’: 37139875, ‘osm_type’: ‘way’, ‘place_id’: 86197794}
Here you have a building, postcode, address, country, road name and a bunch of other insightful attributes that were not available with the raw coordinates. If you are only interested in printing out the address only, you can use dictionary keys, or you can directly do like this.
print(location.address)
And it will print out the address part of the output. In the next section, we will see how we can use reverse Geocoding in Pandas DataFrame.
It is often a subset or complete dataset we want to get addresses from latitude and longitude — Reverse Geocoding — rather than individual coordinates. In this section, we explore how we can do that with Pandas and Geopy.
First, we read the data from URL in Pandas. The data is stored in Dropbox and we can easily use with Pandas if we have a link. You just need to make sure that the last characters of the URL are set to “dl=1”.
url = “https://www.dropbox.com/s/15gisj8hx218rn1/street-pole-sample.csv?dl=1"df = pd.read_csv(url)df.head()
The data has X and Y columns where the coordinates are stored with other features, as shown below in this table.
We can also explore the data and show this in a map using Plotly Express. With just one line of code, you can show a map with a base map.
import plotly_express as pxpx.scatter_mapbox(df, lat=”Y”, lon=”X”, zoom=15)
The map shows a subset of Phillidelphia street poles. Now, we need to construct the coordinates column from X and Y columns. We can achieve this by merely mapping these two columns (X & Y) as strings and then concatenate with a comma between them.
df[“geom”] = df[“Y”].map(str) + ‘,’ + df[‘X’].map(str)df[“geom”][0]
Here is how the first row of the geomcolumn we created above.
'39.9427660880249,-75.17009743393821'
We create a service provider locator this time pass timeout to be 10 minutes since we have many rows. That will prevent timeout errors that you might encounter during the process.
locator = Nominatim(user_agent=”myGeocoder”, timeout=10)rgeocode = RateLimiter(locator.reverse, min_delay_seconds=0.001)
Now, we can reverse geocode by using applying the reverse geocoding rgeocode we created above. To get a nice progress bar, we are using here tqdm library.
tqdm.pandas()df[‘address’] = df[‘geom’].progress_apply(rgeocode)df.head()
It might take a while depending on the number of rows in the dataset. But once the process finishes, you will have an additional feature in the dataset where each point has an address as shown below.
The data has now much more insightful attributes associated with each point, including address, postcode, buildings, etc....
It took 1 minute and 45 seconds to perform reverse geocoding with only 150 points. The computation time is probably not a good option as an increase in data points will require a lot of processing time. If you have a large dataset, you might try to decrease the delay seconds.
In this article, we have explored how you can reverse geocode coordinates to addresses. You can access the notebook for this tutorial in this Google Colab Notebook.