Reputation: 5075
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)
Upvotes: 2
Views: 16684
Reputation: 149
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:
Upvotes: 4
Reputation: 13459
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).
Upvotes: 3