Estimated Time
10 mins
Skill Level
Intermediate
Exercises
na
Content Sections
Course Provider
Provided by HolyPython.com
Geocoding is the application when you type 5th Ave. New York, NY, 10010 and you get coordinates like this: (40.740200, -73.990586).
Geocoding process maps open addresses to coordinates consisted of longitude and latitude and vice versa.
Since the new millenia started and especially after the first Iphone 2g came out, gps applications have exponentially surged. Today it’s crazy to think that people used to carry big printed foldable maps in the glow compartments of their cars and routinely stop to look up roads and cities and figure out where they are headed.
Today, there are so many applications for geocoding and it’s making people’s lives better every single day. We are also witnessing different technologies being blended for an even better optimized service such as Voice Input technology in Google maps.
As a developer you might have a specific task at hand or you might just want to learn geo-coding basics thinking you’ll probably need it sometime anyway.
Let’s take a look at how this technology can be implemented in Python.
Used Where?
- Maps
- Location apps
- Activity tracking
- Emergency tracking
- Food delivery
- e-commerce
- Games
- Social Media
- Photo geo-tagging
How to install geopy
Geopy is a Python library that makes geocoding operations very accessible and practical. You can check if you have geopy in your libraries by using this code in Python:
help("modules")
If you can’t see geopy in your library selection, it might be time to have it installed. You can do so simply by opening the Anaconda Command Prompt and typing the command below:
pip install geopy
Supported Geocoders (Full list)
Geopy supports majority of the major geocoders straight out of the box.
Geocoders are a bit like APIs but for coding and they offer more services than a simple API. But you can make database calls using their APIs to retrieve data for your app, website, commercial or individual use. They usually differ in pricing, accuracy, coverage, technology, daily limits and compatibility.
Here is the full list of supported geocoders:
Specifying Parameters Once
Geopy Is Not a Service
Async Mode
Accessing Geocoders
Default Options Object
Usage with Pandas
AlgoliaPlaces
ArcGIS
AzureMaps
Baidu
BaiduV3
BANFrance
Bing
DataBC
GeocodeEarth
GeocodeFarm
Geolake
GeoNames
GoogleV3
HERE
IGNFrance
MapBox
MapQuest
MapTiler
OpenCage
OpenMapQuest
Nominatim
Pelias
Photon
PickPoint
LiveAddress
TomTom
What3Words
Yandex
Using geopy
Geocoders usually use a technique called address interpolation. This technique allows matching street, avenue, door number (street geographic information) type of parameters with geographic coordinate space that’s included in the map.
GPS is another obviously common geocoding process technique and there might be other specialized methods as well.
OpenStreetMap (OSM) is a collaborative project that offers a great geodata and map of Earth while Nominatim is a cool geocoder that makes use of OSM geodata and it can do both geocoding and reverse geocoding. Now we will explore Nominatim with Python’s geopy library.
from geopy.geocoders import Nominatim
Normally, geocoders accept a properly written address with street name and zip code. But, let’s test Nominatim and OpenStreetMap a little.
Ben & Jerry’s is a very successful ice cream brand in the Northeastern United States. What would happen if we just pass “Ben & Jerry’s” as the address to Nominatim using geopy?
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="name")
address = "Ben & Jerry's, VT"
location = geolocator.geocode(address)
print(location.address)
Ben & Jerry's, Newbury Street, Back Bay, Boston, Suffolk County, Massachusetts, 02116, United States of America
Interestingly it returns a Ben & Jerry’s franchise in Boston, MA. Let’s try “Ben & Jerry’s. VT” and “Ben & Jerry’s NY” consecutively.
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="name")
address1 = "Ben & Jerry's, VT"
address2 = "Ben & Jerry's, NY"
location = geolocator.geocode(address1)
print(location.address)
location = geolocator.geocode(address2)
print(location.address)
Ben & Jerry's, Cherry Street, Church Street Marketplace, Burlington, Chittenden County, Vermont, 05401, United States of America
Ben & Jerry's, Lomb Memorial Drive, Genesee Junction, Henrietta Town, Monroe County, New York, 14624-4721, United States of America
We get 2 seemingly random stores again. The one in Burlington seems pretty cool on Google Maps.
So, this is good enough on Nominatim’s part. Without even completing the address we are getting accurate results. Let’s try some other places from the world and see if non-US data is as accurate:
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="name")
address1 = "Moulin Rouge"
address2 = "Noma"
location = geolocator.geocode(address1)
print(location.address)
location = geolocator.geocode(address2)
print(location.address)
Le Moulin Rouge, Boulevard de Clichy, Quartier des Grandes-Carrières, Paris, Île-de-France, France métropolitaine, 75018, France
Noma, Refshalevej, Margretheholm, Christianshavn, København, Københavns Kommune, Region Hovedstaden, 1440, Danmark
Okay, pretty impressive. It even recognizes Denmark’s award winning Michelin Restaurant and shows up the address for only typing Noma. Let’s try to run “latitude”, “longitude” and “raw” properties for Noma as well.
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="name")
address = "Noma"
location = geolocator.geocode(address)
print((location.latitude, location.longitude))
(55.6829314, 12.6104818)
print(location.raw)
{'place_id': 62456056, 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', 'osm_type': 'node', 'osm_id': 5416925514, 'boundingbox': ['55.6828814', '55.6829814', '12.6104318', '12.6105318'], 'lat': '55.6829314', 'lon': '12.6104818', 'display_name': 'Noma, Refshalevej, Margretheholm, Christianshavn, København, Københavns Kommune, Region Hovedstaden, 1440, Danmark', 'class': 'amenity', 'type': 'restaurant', 'importance': 0.46778439681543516, 'icon': 'https://nominatim.openstreetmap.org/images/mapicons/food_restaurant.p.20.png'}
It makes more sense to print this one with Python’s pretty print library:
import pprint
pprint.pprint(location.raw)
{'boundingbox': ['55.6828814', '55.6829814', '12.6104318', '12.6105318'],
'class': 'amenity',
'display_name': 'Noma, Refshalevej, Margretheholm, Christianshavn, København, '
'Københavns Kommune, Region Hovedstaden, 1440, Danmark',
'icon': 'https://nominatim.openstreetmap.org/images/mapicons/food_restaurant.p.20.png',
'importance': 0.46778439681543516,
'lat': '55.6829314',
'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. '
'https://osm.org/copyright',
'lon': '12.6104818',
'osm_id': 5416925514,
'osm_type': 'node',
'place_id': 62456056,
'type': 'restaurant'}
In raw data from geopy we can see bunch of useful information such as type (shown as restaurant here), latitude, longitude, class (shown as amenity) and importance.
Distance calculations with Geopy
You can also calculate the distance between two locations or points using geopy.distance module.
Let’s see the distance between a Department Store with Tesla Supercharger near Orly Airport and Paris’ finest ice-cream shop Berthillon. Geopy has been very successful at reverse geocoding place names to coordinates, let’s see if it can identify exact locations with little information again such as name.
from geopy import distance
import geopy
location1 = geolocator.geocode("Belle Épine, Thiais")
location2 = geolocator.geocode("Berthillon")
a=(location1.latitude, location1.longitude)
b=(location2.latitude, location2.longitude)
print(distance.distance(a, b).miles)
“Belle Epine” wasn’t being picked up by Geopy by itself so adding the district’s name was a good idea. It’s probably always a good idea to be as explicit as possible with addresses anyways.
6.630156139356959
The distance can be expressed in many differeny measurement units other than miles. Let’s take a look at what help() function returns on geopy.distance.distance:
help(geopy.distance.distance)
| feet
|
| ft
|
| kilometers
|
| km
|
| m
|
| meters
|
| mi
|
| miles
|
| nautical
|
| nm
Great, there are tons of options! Let’s try km, since miles won’t make a lot of sense in France.
from geopy import distance
import geopy
location1 = geolocator.geocode("Belle Épine, Thiais")
location2 = geolocator.geocode("Berthillon")
a=(location1.latitude, location1.longitude)
b=(location2.latitude, location2.longitude)
print(distance.distance(a, b).km)
10.670202001937287