Previously I posted how to use the geopy python library to call the Google geocode API. But somewhere along the way my version of geopy was not working (maybe because the API changed). Instead of figuring out that problem, I just wrote my own function to call the Google API directly. No need to worry about installing geopy.
Part of the reason I blog is so I have notes for myself – I’m pretty sure I’ve rewritten this several times for different quick geocoding projects, but I couldn’t find them this morning when I needed to do it again. So here is a blog post for my own future reference.
Here is the function, it takes as input the full string address. Also I was getting back some null responses by rapid fire calling the API (with only 27 addresses), so I set the function to delay for five seconds and that seemed to fix that problem.
import urllib, json, time
def GoogGeoAPI(address,api="",delay=5):
base = r"https://maps.googleapis.com/maps/api/geocode/json?"
addP = "address=" + address.replace(" ","+")
GeoUrl = base + addP + "&key=" + api
response = urllib.urlopen(GeoUrl)
jsonRaw = response.read()
jsonData = json.loads(jsonRaw)
if jsonData['status'] == 'OK':
resu = jsonData['results'][0]
finList = [resu['formatted_address'],resu['geometry']['location']['lat'],resu['geometry']['location']['lng']]
else:
finList = [None,None,None]
time.sleep(delay) #in seconds
return finList
And here is an example use of the function. It returns the formatted address, the latitude and the longitude.
#Example Use
test = r"1600 Amphitheatre Parkway, Mountain View, CA"
geoR = GoogGeoAPI(address=test)
print geoR
This works for a few addresses without an API key. Even with an API key though the limit I believe is 2,500 – so don’t use this to geocode a large list. Also if you have some special characters in your address field this will take more work. For example if you have an &
for an intersection I bet this url call will fail. But that should not be too hard to deal with. Also note the terms of service for using the API (which I don’t understand – so don’t ask me!)
I should eventually wrap up all of this google API python code into an extension for SPSS. Don’t hold your breath though for me getting the time to do that.
Here is an update for Python 3+ (the urllib library changed a bit). Also shows how to extract out the postal code.
#Update For Python 3+
#Also includes example parsing out the postal code
import urllib.request, urllib.parse
import json, time
key = r'???!!!your key here!!!!????'
def GoogGeoAPI(address,api="",delay=3):
base = r"https://maps.googleapis.com/maps/api/geocode/json?"
addP = "address=" + urllib.parse.quote_plus(address)
GeoUrl = base + addP + "&key=" + api
response = urllib.request.urlopen(GeoUrl)
jsonRaw = response.read()
jsonData = json.loads(jsonRaw)
if jsonData['status'] == 'OK':
resu = jsonData['results'][0]
post_code = -1
for i in resu['address_components']:
if i['types'][0] == 'postal_code':
post_code = i['long_name'] #not sure if everything always has a long name?
finList = [resu['formatted_address'],resu['geometry']['location']['lat'],resu['geometry']['location']['lng'],post_code]
else:
finList = [None,None,None,None]
time.sleep(delay) #in seconds
return finList
test = r"1600 Amphitheatre Parkway, Mountain View, CA"
geoR = GoogGeoAPI(address=test,api=key,delay=0)
print(geoR)
Jessy
/ May 30, 2017Hi Andrew,
How can I make the same code return me the address when lat,long is passed?
apwheele
/ May 30, 2017That is called reverse geocoding. I give an example of extracting neighborhoods from the Google reverse geocoding api here, https://andrewpwheeler.wordpress.com/2016/05/03/neighborhoods-in-albany-according-to-google/. You would need to edit it slightly to get the nearest address, but that should be a good start.
marco
/ March 28, 2019Hi Andrew,
I would need to get the address details from postal codes, using Python.
Do you know how can I adapt geopy for that?
Or maybe directly using google API?
thanks, marco
apwheele
/ March 29, 2019I updated with an example showing how to dig out the post code (also updated for Python 3+, as urllib changed a bit).
marco
/ March 29, 2019many thanks!