Created
November 17, 2011 06:48
-
-
Save seanlin/1372541 to your computer and use it in GitHub Desktop.
Automatic geocoding in Django model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Helper file to geocode address using Google Geocoder | |
import urllib, urllib2, simplejson | |
from django.utils.encoding import smart_str | |
def get_lat_lng(location): | |
# Reference: http://djangosnippets.org/snippets/293/ | |
location = urllib.quote_plus(smart_str(location)) | |
url = 'http://maps.googleapis.com/maps/api/geocode/json?address=%s&sensor=false' % location | |
response = urllib2.urlopen(url).read() | |
result = simplejson.loads(response) | |
if result['status'] == 'OK': | |
lat = str(result['results'][0]['geometry']['location']['lat']) | |
lng = str(result['results'][0]['geometry']['location']['lng']) | |
return '%s,%s' % (lat, lng) | |
else: | |
return '' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Sample Model File | |
from django.db import models | |
from helpers import get_lat_lng ## Calling helper file | |
class Address(models.Model): | |
address_1 = models.CharField(max_length=250) | |
address_2 = models.CharField(max_length=250, null=True, blank=True) | |
city = models.CharField(max_length=250) | |
zipcode = models.CharField(max_length=20) | |
state = models.CharField(max_length=250, null=True, blank=True) | |
country = CountryField() | |
latlng = models.CharField(blank=True, max_length=100) | |
## Geocode using full address | |
def _get_full_address(self): | |
return u'%s %s %s %s %s %s' % (self.address_1, self.address_2, self.city, self.state, self.country, self.zipcode) | |
full_address = property(_get_full_address) | |
## Geocode by just using zipcode and country name (faster and more reliable) | |
def _get_geo_address(self): | |
return u'%s %s' % (self.country.name, self.zipcode) | |
geo_address = property(_get_geo_address) | |
def save(self, *args, **kwargs): | |
if not self.latlng: | |
if self.zipcode and self.country: | |
location = self.geo_address | |
self.latlng = get_lat_lng(location) | |
else: | |
location = '+'.join(filter(None, (self.address_1, self.address_2, self.city, self.state, self.country))) | |
self.latlng = get_lat_lng(location) | |
super(Address, self).save(*args, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment