reverse geocoding with python geocoder

15,039

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

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:

Share:
15,039
Andy K
Author by

Andy K

Often Rubber Duck-ing You can find me in the SQL chat room

Updated on June 04, 2022

Comments

  • Andy K
    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
    Andy K over 9 years
    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
  • Oliver W.
    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 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.
  • Andy K
    Andy K over 9 years
    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?
  • Andy K
    Andy K over 9 years
    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...
  • Oliver W.
    Oliver W. over 9 years
    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.
  • Oliver W.
    Oliver W. over 9 years
    Sorry, I was away for a moment, please join me here
  • Andy K
    Andy K over 9 years
    Wait. it seems I need to login -_-
  • Andy K
    Andy K over 9 years
    Hi Oliver, almost there. The sucesses are not displayed at my end.
  • Andy K
    Andy K over 9 years
    Please 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
    Andy K over 9 years
    One 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.
    Oliver W. over 9 years
  • Andy K
    Andy K over 9 years
    Hi 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.