2013-07-16 10 views
8

Mam następujący model.Jak filtrować model django z współrzędnymi długości i szerokości geograficznej, które mieszczą się w określonym promieniu

class Location(models.Model): 
    name = models.CharField(max_length = 128, blank = True) 
    address =models.CharField(max_length = 200, blank= True) 
    latitude = models.DecimalField(max_digits=6, decimal_places=3) 
    longitude = models.DecimalField(max_digits=6, decimal_places=3) 

    def __unicode__(self): 
     return self.name 

Jeśli moja obecna szerokość geograficzna jest &:

current_lat = 43.648 
current_long = 79.404 

Zrobiłem rozeznanie i natrafiliśmy na Haversine Equation który oblicza odległość między dwoma lokalizacji współrzędnych. Poniżej przedstawiono równanie znalazłem:

import math 

def distance(origin, destination): 
    lat1, lon1 = origin 
    lat2, lon2 = destination 
    radius = 6371 # km 

    dlat = math.radians(lat2-lat1) 
    dlon = math.radians(lon2-lon1) 
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \ 
     * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2) 
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)) 
    d = radius * c 

    return d 

Chciałbym zwrócić wszystkie obiekty, miejsca, które mieszczą się w promieniu 10 km, w jaki sposób można filtrować je w taki sposób, że powróci tylko wszystkie obiekty miejscu, które mieszczą się w promieniu 10 km?

LocationsNearMe = Location.objects.filter(#This is where I am stuck) 

Czy mimo to mogę wdrożyć równanie Haversine do filtrowania, tak że zwraca tylko obiekty lokalizacji, które mieszczą się w promieniu 10 km?

Szukam dobrze szczegółowej odpowiedzi. Doceń pomoc.

+1

powinieneś spróbować użyć geodjango https://docs.djangoproject.com/en/dev/ref/contrib/gis/ – user710907

+0

Zdecydowanie zajrzyj do geodjango, mam rozwiązanie tego problemu b ut it wymaga geodjango: https://gist.github.com/omouse/5623772 –

+0

@omouse dzięki za prowadzenie we właściwym kierunku, w twoim rozwiązaniu masz punkt, ale tutaj w tym modelu jest on podzielony na dwa pola: długość geograficzna i szerokość geograficzna. Czy mógłbyś umieścić odpowiedź na ten przypadek poniżej w sekcji odpowiedzi. – noahandthewhale

Odpowiedz

7

Ale zawsze możesz proponowany przez podejściu Brian lepiej poprzez filtrowanie wyników z poprzedniego etapu (który hoepfully powinien być mniejszym podzbiorem) i dla każdego z nich sprawdź, czy znajdują się one w promieniu.

Twój użytkownik jest w czarnym punkcie. Przybliżenie kwadratu podane przez Briana zwraca kolor zielony, ale także pomarańczowy. Różnica w odległości może być znacząca w najgorszym przypadku użytkownik musi przejść sqrt (2) razy dalej niż się spodziewano (dodatkowe 40% odległości). Tak więc dla wszystkich punktów pomarańczowych i zielonych warto sprawdzić, czy odległość od punktu czarnego (np. Euklidesowa, jeśli są to naprawdę krótkie odległości np. Nawigacja w mieście) nie jest większa niż założony promień.

enter image description here

UPDATE:

Jeśli chcesz użyć Haversine odległość lub (lepiej) wspomniano spojrzeć na tym fragmencie porównując dwie django widoki czynienia z pobliskiego poszukiwaniu GeoDjango Hava:

https://gist.github.com/andilabs/4232b463e5ad2f19c155

+0

dzięki za odpowiedź, naprawdę doceniam twój wgląd w to, jak sobie z tym poradzić! :) – noahandthewhale

+0

Istota jest zepsuta. –

+1

Oto nowy link http://andilabs.github.io/django/devops/tools/postgres/postgis/2015/01/31/postgis-geodjango-english.html –

8

Możesz wykonywać zapytania zakresów, korzystając z filter.

LocationsNearMe = Location.objects.filter(latitude__gte=(the minimal lat from distance()), 
              latitude__lte=(the minimal lat from distance()), 
              (repeat for longitude)) 

Niestety, ten zwraca wyniki w postaci geometrycznej kwadrat (zamiast koła)

Powiązane problemy