2013-07-16 10 views
8

Ho il seguente modello.Come filtrare un modello django con coordinate di latitudine e longitudine che rientrano in un determinato raggio

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 

Se il mio attuale latitudine & longitudine è:

current_lat = 43.648 
current_long = 79.404 

ho fatto qualche ricerca e sono imbattuto nel Haversine Equation che calcola la distanza tra due coordinate di posizione. Qui di seguito è l'equazione che ho trovato:

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 

Vorrei restituire tutti gli oggetti di localizzazione che rientrano in un raggio di 10 km, come posso filtrare in modo tale che sarà solo restituire tutti gli oggetti di localizzazione che rientra in questo raggio di 10 km?

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

C'è qualche cosa che posso implementare l'equazione Haversine nel filtraggio in modo che restituisca solo gli oggetti di localizzazione che ricadono in un raggio di 10 km?

Sto cercando una risposta ben dettagliata. Apprezzo l'aiuto.

+1

si dovrebbe provare e utilizzare geodjango https://docs.djangoproject.com/en/dev/ref/contrib/gis/ – user710907

+0

Sicuramente guardare in geodjango, ho una soluzione per questo problema b it richiede geodjango: https://gist.github.com/omouse/5623772 –

+0

@omouse ringrazia per avermi guidato nella giusta direzione, nella tua soluzione hai punto, ma qui in questo modello, è diviso in due campi: longitudine e latitudine. Potresti mettere la tua risposta per questo caso qui sotto nella sezione di risposta. – noahandthewhale

risposta

7

Ma si può sempre fare proposte dall'approccio Brian meglio filtrando i risultati dal passo precedente (che hoepfully dovrebbe essere un sottoinsieme più piccolo) e per ognuno di essi controlla che siano nel raggio.

L'utente è in punto nero. L'approssimazione quadrata data da Brian restituisce il verde ma anche i punti arancioni. Il divario in distanza può essere significativo nel peggiore dei casi l'utente deve andare sqrt (2) volte più del previsto (oltre il 40% della distanza). Quindi per tutti i punti arancione e verde vale la pena controllare se la loro distanza dal punto nero (ad esempio euclideo se questo è veramente breve distanza, ad esempio la navigazione in città) non è maggiore del raggio presunto.

enter image description here

UPDATE:

Se si desidera utilizzare Haversine distanza o (meglio) di cui GeoDjango Hava un'occhiata a questo frammento di confronto tra due punti di vista Django si occupano di ricerca nelle vicinanze:

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

+0

grazie per la tua risposta, ho davvero apprezzato la tua opinione su come affrontare questo! :) – noahandthewhale

+0

l'essenza è rotto. –

+1

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

8

È possibile eseguire query di intervallo con filter.

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

Purtroppo, questa restituisce i risultati sotto forma di un quadrato geometrica (invece di un cerchio)

Problemi correlati