updated error handling in address_to_district and changed GeocodeError to have numeric error codes
git-svn-id: https://polipoly.googlecode.com/svn/trunk@10 1885ebd5-0a40-0410-88a4-770918bee656
This commit is contained in:
parent
79740a73ab
commit
9f77360de1
@ -15,51 +15,85 @@ The CGI script takes two parameters:
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import cgi
|
import cgi
|
||||||
from polipoly import AddressToDistrictService
|
import re
|
||||||
|
from polipoly import AddressToDistrictService, GeocodingError
|
||||||
|
|
||||||
GMAPS_API_KEY = 'define-me'
|
GMAPS_API_KEY = 'define-me'
|
||||||
PATH_TO_CDFILES = ''
|
PATH_TO_CDFILES = 'cd99_110'
|
||||||
|
|
||||||
# run as a module
|
class ApiException(Exception):
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
|
# these codes are in the 300s to fit the sunlight API
|
||||||
|
STATUS_CODES = {
|
||||||
|
300: 'Google returned a server error when attempting to geocode',
|
||||||
|
301: 'Empty address string',
|
||||||
|
302: 'Unknown address',
|
||||||
|
303: 'Prohibited address',
|
||||||
|
304: 'Unknown geocoding error',
|
||||||
|
305: 'Address refers to a PO Box',
|
||||||
|
306: 'Address does not fall within a congressional district',
|
||||||
|
320: 'Too many requests to geocoding service'}
|
||||||
|
|
||||||
|
def __init__(self, code):
|
||||||
|
self.code = code
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '%d: %s' % (self.code, self.STATUS_CODES[self.code])
|
||||||
|
|
||||||
|
def main():
|
||||||
# get address field and output type
|
# get address field and output type
|
||||||
fields = cgi.FieldStorage()
|
fields = cgi.FieldStorage()
|
||||||
addr = fields.getvalue('address')
|
addr = fields.getvalue('address') or ''
|
||||||
output = fields.getvalue('output')
|
output = fields.getvalue('output')
|
||||||
|
|
||||||
|
# discard blank addresses as error 301
|
||||||
|
if re.match('^\s*$', addr):
|
||||||
|
raise ApiException(301)
|
||||||
|
|
||||||
|
# discard PO Box addresses as error 305
|
||||||
|
pobox = re.compile('[Pp]\.?[Oo]\.?\s*(?:box|Box|BOX)')
|
||||||
|
if pobox.search(addr):
|
||||||
|
raise ApiException(305)
|
||||||
|
|
||||||
# plaintext error if no address is provided
|
# create service and get a district
|
||||||
if addr is None:
|
service = AddressToDistrictService(GMAPS_API_KEY, PATH_TO_CDFILES)
|
||||||
print 'Content-type: text/plain\n'
|
try:
|
||||||
print 'error: must provide address parameter'
|
lat, lng, districts = service.address_to_district(addr)
|
||||||
|
except GeocodingError, ge:
|
||||||
|
# convert GeocodingError to API error code (300-303 and 320)
|
||||||
|
err_dict = {500: 300, 601: 301, 602: 302, 603: 303, 620: 320}
|
||||||
|
raise ApiException(err_dict.get(ge.code,304))
|
||||||
|
|
||||||
|
# 306: address did not fall within congressional district
|
||||||
|
if len(districts) == 0:
|
||||||
|
raise ApiException(306)
|
||||||
|
|
||||||
|
# XML output
|
||||||
|
if output == 'xml':
|
||||||
|
dist_str = '\n'.join([' <district state="%s">%s</district>' % dist
|
||||||
|
for dist in districts])
|
||||||
|
print 'Content-type: text/xml\n'
|
||||||
|
print '''<results>
|
||||||
|
<address>%s</address>
|
||||||
|
<latitude>%s</latitude>
|
||||||
|
<longitude>%s</longitude>
|
||||||
|
<districts>
|
||||||
|
%s
|
||||||
|
</districts>
|
||||||
|
</results>''' % (addr, lat, lng, dist_str)
|
||||||
|
|
||||||
|
# JSON output (default)
|
||||||
else:
|
else:
|
||||||
# create service and find out districts
|
dist_str = ','.join(['{"state":"%s", "district":"%s"}' % dist
|
||||||
service = AddressToDistrictService(GMAPS_API_KEY, PATH_TO_CDFILES)
|
for dist in districts])
|
||||||
lat, lng, districts = service.address_to_district(addr)
|
print 'Content-type: application/json\n'
|
||||||
|
print '''{"address":"%s", "latitude":"%s", "longitude":"%s",
|
||||||
# JSON output (default)
|
|
||||||
if output is None or output == 'json':
|
|
||||||
print 'Content-type: application/json\n'
|
|
||||||
dist_str = ','.join(['{"state":"%s", "district":"%s"}' % dist
|
|
||||||
for dist in districts])
|
|
||||||
print '''{"address":"%s", "latitude":"%s", "longitude":"%s",
|
|
||||||
"districts": [ %s ] }''' % (addr, lat, lng, dist_str)
|
"districts": [ %s ] }''' % (addr, lat, lng, dist_str)
|
||||||
|
|
||||||
# XML output
|
|
||||||
elif output == 'xml':
|
|
||||||
print 'Content-type: text/xml\n'
|
|
||||||
dist_str = '\n'.join([' <district state="%s">%s</district>' % dist
|
|
||||||
for dist in districts])
|
|
||||||
print '''<results>
|
|
||||||
<address>%s</address>
|
|
||||||
<latitude>%s</latitude>
|
|
||||||
<longitude>%s</longitude>
|
|
||||||
<districts>
|
|
||||||
%s
|
|
||||||
</districts>
|
|
||||||
</results>''' % (addr, lat, lng, dist_str)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print 'Content-type: text/plain\n'
|
|
||||||
print 'error: invalid output parameter specified'
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except ApiException,e:
|
||||||
|
print 'Content-type: text/plain\n'
|
||||||
|
print e
|
||||||
|
16
polipoly.py
16
polipoly.py
@ -74,19 +74,19 @@ class GeocodingError(Exception):
|
|||||||
See http://www.google.com/apis/maps/documentation/reference.html#GGeoStatusCode
|
See http://www.google.com/apis/maps/documentation/reference.html#GGeoStatusCode
|
||||||
"""
|
"""
|
||||||
|
|
||||||
STATUS_CODES = {'500': 'Unknown Geocoding Server Error',
|
STATUS_CODES = {500: 'Unknown Geocoding Server Error',
|
||||||
'601': 'Empty Address',
|
601: 'Empty Address',
|
||||||
'602': 'Unknown Address',
|
602: 'Unknown Address',
|
||||||
'603': 'Prohibited Address',
|
603: 'Prohibited Address',
|
||||||
'610': 'Bad API Key',
|
610: 'Bad API Key',
|
||||||
'620': 'Too Many Requests'}
|
620: 'Too Many Requests'}
|
||||||
|
|
||||||
def __init__(self, code):
|
def __init__(self, code):
|
||||||
Exception.__init__(self)
|
Exception.__init__(self)
|
||||||
self.code = code
|
self.code = int(code)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'GeocodingError: %s - %s' % (self.code,
|
return 'GeocodingError: %d - %s' % (self.code,
|
||||||
self.STATUS_CODES[self.code])
|
self.STATUS_CODES[self.code])
|
||||||
class ShapefileError(Exception):
|
class ShapefileError(Exception):
|
||||||
""" Exception for problems with census shapefiles."""
|
""" Exception for problems with census shapefiles."""
|
||||||
|
Loading…
Reference in New Issue
Block a user