In Django, I have been trying to get a search field to geocode a location and spit out a list from my db sorted by distance. So far everything works except when I search for a location that Google returns multiple results form such as "ann arbor, MI". I get the ValueError "Didn't find exactly one placemark! (Found 2.)" Here is my views.py
from django.shortcuts import render_to_response
from models import CampSite
from geopy import geocoders
from django.contrib.gis.geos import *
from django.contrib.gis.measure import D
from campsites.forms import SearchForm
from django.http import HttpResponseRedirect
def results(request):
query = request.GET['q']
g = geocoders.Google(resource='maps')
location, (lat, lon) = g.geocode(query)
pnt = fromstr("POINT(%s %s)" % (lon, lat))
distance_from_point = {'mi':'2000'}
results = CampSite.objects.filter(lonlat__distance_lte=(pnt,D(**distance_from_point))).distance(pnt).order_by('distance')
return render_to_response('results.html',{'location': location, 'lat': lat, 'lon': lon, 'results':results})
The common solution I found online was to change
location, (lat, lon) = g.geocode(query)
to
location, (lat, lon) = g.geocode(query, exactly_one=False)
However, this produced the new ValueError "String or unicode input unrecognized as WKT EWKT, and HEXEWKB."
This is my first django project I'm doing outside of tutorials, so thankyou for being gentile.
In Python, the interpreter is your best friend.
>>> g.geocode('ann arbor, MI', exactly_one=False)
[(u'Ann Arbor, MI, USA', (42.2808256, -83.743037799999996)),
(u'Ann Arbor, MI, USA', (42.307649300000001, -83.8473015))]
If you try your code snippet, you will realize that when used with exactly_one=False, the method returns a list of tuples, not a single tuple - so your code need to be refactored accordingly.
results = []
geocodes = g.geocode(query, exactly_one=False)
for geocode in geocodes:
location, (lat, lon) = geocode
pnt = fromstr("POINT(%s %s)" % (lon, lat))
distance_from_point = {'mi':'2000'}
results.append(
CampSite.objects.filter(
lonlat__distance_lte=(
pnt,
D(**distance_from_point)
)
).distance(pnt).order_by('distance')
)
The above is untested, but the after the loop you should end up with a list of results. Then you should decide what to do:
geocodes[0]
, results[0]
)zip(geocodes, results)
in the template)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