reverse geocoding with python geocoder
Solution 1
The problem is that you forgot to add quotes around your option reverse
:
g = geocoder.google(['lat','lon'], method='reverse')
I consider that a mistake in their documentation. You could send a message to the author to inform him/her of this, he/she might want to update their docs.
Furthermore, you'll want to call it with the actual parameters lat
and lon
, not the strings. Otherwise you'll get an error.
So,
g = geocoder.google([lat, lon], method='reverse') # lat and lon you've extracted already, but maybe you'll still need to cast them to float.
Update: if you're running into reverse lookups that give g.ok == False
, then the problem is related to the throttling of your requests by the API provider (in the examples above, this is Google). For example, the Google Maps API specifies fair use and should not be polled overly fast. This information is clear when you call g.debug()
. Among the output will be:
## Provider's Attributes
* status: OVER_QUERY_LIMIT
* error_message: You have exceeded your rate-limit for this API.
To throttle your requests, you could do the following:
import geocoder
import unicodecsv
import logging
import time
import csv
pcode=[]
with open('locs2.csv', 'rb') as f:
reader = csv.DictReader(f)
for line in reader:
lat = float(line['lat'])
lon = float(line['lon'])
g = geocoder.google([lat,lon], method='reverse')
attempts = 1 # number of lookups
while not(g.ok) and attempts < 4:
logging.warning('Geocoding ERROR: {}'.format(g.debug()))
time.sleep(2) # 2 seconds are specified in the API. If you still get errors, it's because you've reached the daily quota.
g = geocoder.google([lat,lon], method='reverse')
attempts += 1
if attempts > 3:
logging.warning('Daily quota of google lookups exceeded.')
break
pcode.extend(g.postal)
logging.info('Geocoding SUCCESS: ({},{},{})'.format(lat,lon,pcode))
Some of the providers, such as Mapquest, don't impose throttling at the moment.
One bug present in geocoder version 0.9.1 is that lat
and lon
should both differ from 0.0
. The lookup will generate a TypeError
if you have coordinates like that (along the equator or the Greenwhich meridian).
Solution 2
Geocoder has come a long way, the recent version is 1.6.1 which has hopefully fixed a few bugs you are mentioning.
Check out the latest documentation for Reverse Geocoding in Python Geocoder.
import geocoder
g = geocoder.google([45.15, -75.14], method='reverse')
g.city
g.state
g.country
g.postal
Here are the list of providers that support reverse geocoding:
Andy K
Often Rubber Duck-ing You can find me in the SQL chat room
Updated on June 04, 2022Comments
-
Andy K almost 2 years
I'm trying my hands on reverse geocoding with python and the module geocoder
I built this script
#!/Users/admin/anaconda/bin/python import geocoder import unicodecsv import logging with open('locs2.csv', 'rb') as f: reader = unicodecsv.DictReader(f, encoding='iso-8859-1') for line in reader: lat = line['lat'] lon = line['lon'] g = geocoder.google(['lat','lon'], method=reverse) if g.ok: g.postal logging.info('Geocoding SUCCESS: ' + address) else: logging.warning('Geocoding ERROR: ' + address)
According to the doc here, we can do reverse. However, when I'm running the script , I have this error
NameError: name 'reverse' is not defined
Why?
TIA
This is a sample from my file
lat, lon 48.7082,2.2797 48.7577,2.2188 47.8333,2.2500 48.9833,1.7333 47.9333,1.9181 46.2735,4.2586
**Edit **: I've amended the script a bit (see below) and I have this error
WARNING:root:Geocoding ERROR:
the amended script
#!/Users/admin/anaconda/bin/python import geocoder import unicodecsv import logging pcode=[] lat=[] lon=[] with open('locs2.csv', 'rb') as f: reader = unicodecsv.DictReader(f, encoding='iso-8859-1') for line in reader: lat = line['lat'] lon = line['lon'] g = geocoder.google([lat,lon], method='reverse') if g.ok: pcode.extend(g.postal) logging.info('Geocoding SUCCESS: '+ str(lat)+','+str(lon)+','+str(pcode)) else: logging.warning('Geocoding ERROR: ' + str(lat)+','+str(lon)) fields= 'lat', 'lon', 'pcode' rows=zip(lat,lon,pcode) with open('/Users/admin/python/myfile.csv', 'wb') as outfile: w = unicodecsv.writer(outfile, encoding='iso-8859-1') w.writerow(fields) for i in rows: w.writerow(i)
-
Andy K over 9 yearsHi Oliver, thanks for your help. I've amended a bit my script and I've got a new error. Does it ring any bell with you? TIA
-
Oliver W. over 9 years@AndyK The "error" you're getting is merely a warning generated by your call to the logging module:
logging.warning('Geocoding ERROR:')
. That means that the expressiong.ok
evaluates toFalse
for some particular reverse lookup. Without your source data, we cannot say why that is happening. You could uselogging.warning('Geocoding ERROR: ({}, {})'.format(lat, lon))
to know for which coordinates it fails. -
Andy K over 9 yearsOliver, I just realized. Damn , I feel terriby unfamiliar with Python yet !!! This is my source file. dropbox.com/s/srb8skg7lysnj95/locs2.csv?dl=0 Would you mind helping me a bit, please?
-
Andy K over 9 yearsI've amended my script again (see the post). I can see that I got geocoding error for the 9th line with
45.8167,5.9167
. Bizarre thing is the successes are not shown... -
Oliver W. over 9 yearsA reverse lookup on those coordinates works for me:
g.ok
evaluates toTrue
. We should move this discussion to chat if you want to debug it. -
Oliver W. over 9 yearsSorry, I was away for a moment, please join me here
-
Andy K over 9 yearsWait. it seems I need to login -_-
-
Andy K over 9 yearsHi Oliver, almost there. The sucesses are not displayed at my end.
-
Andy K over 9 yearsPlease find the errors ` I've got these errors
Debug ## Connection * URL: [Reverse](https://maps.googleapis.com/maps/api/geocode/json) * Status: ERROR - URL Connection * Status Code: 404 * Parameter [latlng]: 44.8325,-0.6338 * Parameter [sensor]: false ## JSON Attributes * status: ERROR - URL Connection * provider: reverse * location: [44.8325, -0.6338] * error: ERROR - URL Connection
-
Andy K over 9 yearsOne more thing: Please have in mind I need the post code. I'm reverse geocoding only for that reason otherwise, this exercise would be pointless for me.
-
Oliver W. over 9 yearsLet us continue this discussion in chat.
-
Andy K over 9 yearsHi Oliver, quick update: After many attempts with that reverse geocoding , I was able with the help of the author of the reverse geocoding package to get all the reverse geocoding I was looking for. He created the package for reverse geocoding for mapquest, which does not have throttling.I'm updating a bit the script to reflect that.