We've recently begun validating user-submitted addresses via Google Maps. As it turns out, this is very easy to do. All that's necessary is an HTTP call to this URL:
http://maps.google.com/maps/geo
We are using Django and Python. Below is a simple function to handle the geocoding. We have additional code to call this via AJAX via jQuery, as well as internal code to enforce our validation requirements.
The code not seen in this function comes from the Django settings file, and it only contains the arguments required by Google. Documentation for that is on
Google's page describing use.
Here are the arguments we send (aside from, obviously, the address itself, which is urlencoded and sent as argument 'q'):
key: our Google Maps key
sensor: false
output: json
oe: utf8
Output:
Google Geocoding responds with a lot of useful information. The address object is 'Placemark.' For ambiguous addresses, it may return multiple placemarks. For our purposes, this counts as an invalid address. It also returns an
accuracy number, from zero through nine. This is helpful in determining whether your user entered an address specific enough for your purposes. In our case, we can accept four, a fairly low score, since we are just estimating driving distance. But if you're planning to send something by mail, a higher score (at least eight) is required.
If there's interest, I may provide some JavaScript code, or maybe even a fully-functional example page in a later post. Our primary application requires a login to use, and is not available to the public.
def get_address_info(**kwargs):
#expects to receive address fields, bumps
#them up against Google, and returns the
#validation status
geocode_options = settings.GEOCODE_OPTIONS
address_string = ' '.join([
kwargs['street_line1'],
kwargs['street_line2'],
kwargs['city'],
kwargs['state'],
kwargs['postal_code'],
kwargs['country']]
).encode('utf-8')
geocode_options['q'] = address_string
try:
output = urlopen("%s?%s" % (settings.GEOCODE_URL, urlencode(geocode_options)))
except Exception, ex:
return False
geocode = simplejson.loads(output.read())
result = {
'latitude': '',
'longitude': '',
'accuracy': 0,
'address': '',
'multiple': False,
}
#if Google returned something juicy
if 'Placemark' in geocode:
if len(geocode['Placemark']) > 1:
result['multiple'] = True
result['accuracy'] = geocode['Placemark'][0]['AddressDetails']['Accuracy']
try:
result['address'] = geocode['Placemark'][0]['address']
except Exception, ex:
log.debug("Exception adding address to result dict: %s" % (ex,))
if (len(geocode['Placemark']) == 1 and result['accuracy'] >= 8):
result['latitude'] = geocode['Placemark'][0]['Point']['coordinates'][0]
result['longitude'] = geocode['Placemark'][0]['Point']['coordinates'][1]
return result