Trying to wrap my head around django forms and the django way of doing things. I want to create a basic web form that allows a user to input an address and have that address geocoded and saved to a database.
I created a Location model:
class Location(models.Model):
address = models.CharField(max_length=200)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100, null=True)
postal_code = models.CharField(max_length=100, null=True)
country = models.CharField(max_length=100)
latitude = models.DecimalField(max_digits=18, decimal_places=10, null=True)
longitude = models.DecimalField(max_digits=18, decimal_places=10, null=True)
And defined a form:
class LocationForm(forms.ModelForm):
class Meta:
model = models.Location
exclude = ('latitude','longitude')
In my view I'm using form.save()
to save the form. This works and saves an address to the database.
I created a module to geocode an address. I'm not sure what the django way of doing things is, but I guess in my view, before I save the form, I need to geocode the address and set the lat and long. How do I set the latitude and longitude before saving?
Geocoding is the process of converting addresses (like a street address) into geographic coordinates (latitude and longitude), which you can use to place markers on a map, or position the map. The focus of this document is to clarify considerations involved when geocoding addresses.
One way to find your geolocation is to simply perform a lookup online. Melissa's Geocoder Lookup tool returns latitude, longitude, county, census tract and block data based on an address or ZIP Code. Simply enter the address or ZIP Code into the easy-to-use Lookups interface and submit.
You can override the model's save method. I geocode the data before saving. This is using googleapi, but it can be modified accordingly.
import urllib
def save(self):
location = "%s, %s, %s, %s" % (self.address, self.city, self.state, self.zip)
if not self.latitude or not self.longitude:
latlng = self.geocode(location)
latlng = latlng.split(',')
self.latitude = latlng[0]
self.longitude = latlng[1]
super(Marker, self).save()
def geocode(self, location):
output = "csv"
location = urllib.quote_plus(location)
request = "http://maps.google.com/maps/geo?q=%s&output=%s&key=%s" % (location, output, settings.GOOGLE_API_KEY)
data = urllib.urlopen(request).read()
dlist = data.split(',')
if dlist[0] == '200':
return "%s,%s" % (dlist[2], dlist[3])
else:
return ','
Update for Google Maps API v3:
import json
import urllib.parse
from decimal import Decimal
def save(self):
if not self.lat or not self.lng:
self.lat, self.lng = self.geocode(self.address)
super(Location, self).save()
def geocode(self, address):
address = urllib.parse.quote_plus(address)
maps_api_url = "?".join([
"http://maps.googleapis.com/maps/api/geocode/json",
urllib.parse.urlencode({"address": address, "sensor": False})
])
response = urllib.urlopen(maps_api_url)
data = json.loads(response.read().decode('utf8'))
if data['status'] == 'OK':
lat = data['results'][0]['geometry']['location']['lat']
lng = data['results'][0]['geometry']['location']['lng']
return Decimal(lat), Decimal(lng)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With