Andy K
Andy K

Reputation: 5075

reverse geocoding with python geocoder

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

Answers (2)

user1116928
user1116928

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

Oliver W.
Oliver W.

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

Upvotes: 3

Related Questions