2012-07-19 29 views
5

Używam geodjango i kolekcję punktów w mojej bazie danych. Aby uzyskać queryset punktów w danym obszarze używam to:Jak zwrócić rekord z najniższą odległością od punktu za pomocą geodjango?

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

Moje pytanie brzmi: w jaki sposób można zwrócić tylko jeden punkt (punkt z najmniejszej odległości) z punktu I minęło go?

EDIT

należy wspomnieć, że jestem przekazując współrzędnych i chcąc stworzyć Point obiekt z nimi. Następnie podaj ten punkt jako źródło i filtruj. Na przykład próbowałem:

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 

Ten fragment kodu daje mi ten błąd:

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

Co ciekawe, jeśli I wykonaj następujące czynności:

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)) 

Odpowiedz

4

Wreszcie rozwiązanie zebrane z wskazówek od GeoDjango distance filter with distance value stored within model - query, które doprowadziły mnie do tego post. Na podstawie tych informacji udało mi się ustalić, że: MUSISZ OKREŚLIĆ parametr pomiaru w zapytaniu odległościowym. W poniższym fragmencie zostanie zaimportowana miara jako D. Następnie użyj go w zapytaniu. Jeśli nie podasz go dostaniesz ten błąd:

ValueError: Tuple required for `distance_lte` lookup type. 

wziąć tylko punkt o najmniejszej odległości użyłem 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] 
+0

czy możesz wyjaśnić, dlaczego masz' [: 1] [0] 'na końcu – Sevenearths

+1

Proszę przejść przez to przed debugowaniem: [https://docs.djangoproject.com/en/1.6/ref/contrib/gis/db-api/# tabele zgodności] właśnie spędził kilka godzin bezsensownie debugując punkt__distance_lte, gdy nie jest obsługiwany przez Mysql – PKaura

0
queryset = Spot.objects.distance(origin).filter(distance__lte=distance_m) 
point = queryset.order_by('distance')[:1][0] 

https://docs.djangoproject.com/en/dev/ref/contrib/gis/geoquerysets/#distance

+2

Próbuję Twojej sugestii Wystąpił błąd. 'FieldError: Nie można określić słowa kluczowego" odległość "w polu. Dostępne opcje: autor, created_on, id, name, point, slug, updated_on' Na moim modelu nie ma pola odległości. – darren

+0

@darren może się zdarzyć, gdy zapomnisz użytkownika 'objects = GeoManager()' Pochodzi od 'from django.contrib.gis.db.models.manager importuj GeoManager' w ustawieniach i BAZ DANYCH pamiętaj o użyciu' 'ENGINE': ' django.contrib.gis.db.backends.postgis ', ' – andi

0

szukałem na przykład o tym, jak rozwiązać wyniki względem lokalizacji z geodjango, więc mój przypadek użycia był bardzo zbliżony do tego. Chociaż przyjęte rozwiązanie zadziałało, wydajność była bardzo zła dla dużego zbioru danych (ponad 140000 wierszy).

Krótka historia: funkcja distance_lte musi obliczać odległość do początku każdego wiersza tabeli i nie może korzystać z indeksów geograficznych. Wydaje się, że funkcja dwithin mogą korzystać z takich indeksów i nie trzeba rzeczywiście obliczyć odległość do pochodzenia dla każdego wiersza przed przed ograniczeniem jest zrobione, więc jest to sposób bardziej efektywny:

origin = Point(28.011030, -26.029430) 
closest_spot = Spot.objects.filter(point__dwithin=(origin, 1)) \ 
    .distance(origin).order_by('distance')[:1][0] 

Funkcja dwithin działa z danymi geograficznymi w stopniach ("1" w zapytaniu).

Powiązane problemy