GeocoderDotUS error handling.

152 views
Skip to first unread message

Eric Sepich

unread,
Jun 1, 2012, 2:17:16 AM6/1/12
to ge...@googlegroups.com
import csv
from geopy import geocoders
import time

g = geocoders.GeoNames()

spamReader = csv.reader(open('locations.csv', 'rb'), delimiter='\t', quotechar='|')

f = open("output.txt",'w')

for row in spamReader:
    a = ', '.join(row)
    print(a)
    #exactly_one = False
    time.sleep(1)
    
    try:
        place, (lat, lng) = g.geocode(a)
        
    except (ValueError, geocoders.geonames.GeoNames):
        b = str(place) + "," + "[" + str(lat) + "," + str(lng) + "]" + "\n"
        print b
        f.write(b)


This is the traceback:

40 Brown St Rockhampton QLD
Traceback (most recent call last):
  File "C:\Users\Penguin\workspace\geocode-nojansdatabase\src\yahoo.py", line 18, in <module>
    place, (lat, lng) = g.geocode(a)
TypeError: 'NoneType' object is not iterable


What is the suggested method for handling this? I suppose there must have to be some error handling I just have not been able to get any examples yet. I am studying the objects. Does anyone know how to do this?

Mike Tigas

unread,
Jun 8, 2012, 6:46:27 PM6/8/12
to geopy
Looks like you're not using GeocoderDotUS
(geopy.geocoders.GeocoderDotUS), but the GeoNames geocoder in this
code. As a warning: GeoNames <http://www.geonames.org/> actually
doesn't appear to handle street address geocoding, but rather
"landmarks" and "place names". I'd recommend trying one of the other
geocoder backends.

In any case, what's happening in your code is that `g.geocode(a)` is
resulting in None, but you're trying to expand that None into `place,
(lat, lng)`, which results in TypeError. (In the normal case, it won't
throw an exception and `g.geocode(a)` will return something like
`(u'Eiffel Tower, A8, FR', (48.858323471538, 2.29451715946198))`,
which gets unpacked into the `place, (lat, lng)` bits properly.)


If you want to continue looping over your data, you can add an extra
`except` clause for the TypeError that happens in this case. (All the
following examples are variations of the try/except block in your
code.)

try:
place, (lat, lng) = g.geocode(a)
except TypeError:
# generally happens when 0 results
print "Error: no results for %s" % a
except ValueError:
# multiple results
print "Error: more than one result for %s" % a
else:
# success: exactly one result
b = "%s,[%s,%s]" % (place, lat, lng)
print b
f.write(b + "\n")


Alternatively you can store the result as a separate variable first
and then you won't be trying to unpack a single None into the place,
lat, and lng variables.

try:
result = g.geocode(a)
except ValueError:
# multiple results
result = None
print "Error: multiple results for '%s'" % a
if result:
# Unpack result into place, (lat, lng)
place, (lat, lng) = result
b = "%s,[%s,%s]" % (place, lat, lng)
print b
f.write(b + "\n")



If you need to elegantly handle situations where the geocoder returns
multiple results, you can select the first one (generally the closest
match) by doing this with your code:

try:
results = g.geocode(a, exactly_one=False)
except Exception, e:
results = None
print "Error: %s when geocoding '%s'" % (e, a)
if results:
# Use first (or only) result and unpack that into place, (lat,
lng)
# (alternatively you can loop over the "results" list and write
some heuristic (i.e. "this location is in the right city/state/
country") to choose the one you want)
place, (lat, lng) = result[0]
b = "%s,[%s,%s]" % (place, lat, lng)
print b
f.write(b + "\n")


Hope this helps.


--
Mike Tigas
Web Developer
http://mike.tig.as/
Reply all
Reply to author
Forward
0 new messages