Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a record with the lowest distance from a point using geodjango?

I am using geodjango and have a collection of points in my database. To get a queryset of points within a certain area I use this:

queryset = Spot.objects.filter(point__distance_lte=(origin, distance_m))

My question is how can I return only one point(the point with the lowest distance)from the point I have passed it?

EDIT

I should mention that I am passing in coordinates and wanting to create a Point object with them. Then pass that point in as the origin and filter against that. For example I have tried:

from spots.models import *
from django.contrib.gis.geos import *

origin = Point(28.011030, -26.029430)
distance_m = 1000

queryset = Spot.objects.filter(point__distance_lte=(origin, distance_m))
for q in queryset:
    print q.distance

This snippet of code gives me this error:

Traceback (most recent call last):
  File "<console>", line 2, in <module>
AttributeError: 'Spot' object has no attribute 'distance'

Interestingly enough if I do the following:

origin = Spot.objects.get(name='Montecasino').point
distance_m = 1000

for city in Spot.objects.distance(origin):
    print(city.name, city.distance)

(u'Design Quarter Parking', Distance(m=677.347841801))
(u'Montecasino', Distance(m=0.0))
(u'Fourways', Distance(m=1080.67723755))
like image 667
darren Avatar asked Jul 19 '12 08:07

darren


1 Answers

Finally a solution gathered from clues from GeoDjango distance filter with distance value stored within model - query which lead me to this post. From this information I was able to gather that you MUST SPECIFY the measure parameter in your distance query. You will see in the below snippet, I import measure as D. Then use it in the query. If you don't specify it you will get this error:

ValueError: Tuple required for `distance_lte` lookup type.

To take just the point with the lowest distance I used order_by('distance')[:1][0]

from spots.models import *
from django.contrib.gis.geos import *
from django.contrib.gis.measure import D

distance_m = 20000
origin = Point(28.011030, -26.029430)

closest_spot = Spot.objects.filter(point__distance_lte=(origin, D(m=distance_m))).distance(origin).order_by('distance')[:1][0]
like image 52
darren Avatar answered Sep 18 '22 23:09

darren