2

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) 

2 Answers 2

4

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:

Sign up to request clarification or add additional context in comments.

Comments

3

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 latand 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).

12 Comments

Hi 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
@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 expression g.ok evaluates to False for some particular reverse lookup. Without your source data, we cannot say why that is happening. You could use logging.warning('Geocoding ERROR: ({}, {})'.format(lat, lon)) to know for which coordinates it fails.
Oliver, 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?
I'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...
A reverse lookup on those coordinates works for me: g.ok evaluates to True. We should move this discussion to chat if you want to debug it.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.