16

Esiste un modulo Python in cui posso creare oggetti con coordinate geografiche (latitudine e longitudine) e interrogare tutti gli oggetti per quelli che si trovano entro una distanza di 5 km (cioè raggio) di una determinata coordinata?Modulo Python per la memorizzazione e l'interrogazione delle coordinate geografiche

Ho cercato di memorizzare la latitudine e la longitudine come chiavi nei dizionari (dato che sono indicizzati per chiave) e utilizzare alcuni algoritmi di ricerca della distanza per interrogarli. Ma questo sembra un orribile hack.

Essenzialmente qualcosa come PostGIS per PostgreSQL, ma tutto nella memoria dell'app Python.

risposta

16

Sì, prova geopy.

import geopy 
import geopy.distance 

pt1 = geopy.Point(48.853, 2.349) 
pt2 = geopy.Point(52.516, 13.378) 

dist = geopy.distance.distance(pt1, pt2).km 
# 878.25 

seguito è possibile interrogare le vostre liste di punti:

[pt for pt in points if geopy.distance.distance(orig, pt).km < 5.] 
+0

Grazie per la risposta. Avevo saltato su goepy perché pensavo che fosse interamente per geocoding. Con l'esempio di query, non passerebbe in loop su ogni oggetto in 'punti'? Il che non è abbastanza efficiente come l'indicizzazione dei punti PostGIS - forse l'approccio al database sarebbe più efficiente. –

+0

@ Jonathan - hai ragione, iterà su tutta la lista di punti. Non conosco alcuna possibilità di indicizzazione all'interno di geopy. Forse trovi qualcosa. – eumiro

5

So che questo non è esattamente quello che volevi dire, ma si potrebbe utilizzare GeoDjango con un database SQLite in memoria. È un set completo di strumenti GIS esposti come applicazione Web, che lo rende un coltello dell'esercito svizzero per applicazioni GIS in rapido sviluppo, in particolare per piccole query ad hoc.

1

L'idea del dizionario non sembra così male, anche se sarà necessario controllare i punti che rientrano anche nei tasti del dizionario "vicini".

Se non riesci a trovare lo strumento giusto e ad esempio gli algoritmi di codifica, potresti implementare un albero di partizione dello spazio binario che afaik è un modo meno hacky per ottenere una cosa simile.

2

L'approccio normale in GIS è creare un buffer attorno al punto di interesse e interrogare l'intersezione. Come suggerisce @RyanDalton, se hai intenzione di fare molte cose di geolocalizzazione, usa Shapely, l'API GIS per Python. È bene sapere su Shapely anche se vuoi ancora un indice spaziale (vedi sotto). Ecco come creare buffer in Shapely:

distance = 3 
center = Point(1, 1) 
pts = [Point(1.1, 1.2),Point(1.2,1.2)] 
center_buf = a.buffer(distance) 
#filters the points list according to whether they are contained in the list 
contained = filter(center_buf.contains,pts) 

È indice possibile i punti da soli (diciamo dalla longitudine, per esempio), se non si dispone di molti. Altrimenti puoi anche usare il pacchetto Rtree, controlla il link chiamato Using Rtree as a cheapo spatial database!

1

È possibile utilizzare SQLite che ha un'estensione Rtree per fare esattamente questo tipo di archiviazione e interrogazione. Questo approccio è utile se i dati sono più grandi della memoria che si desidera utilizzare o se si desidera salvare e manipolare i dati tra le esecuzioni del programma. Lo storage e il codice di query effettivi sono in C, il che significa che deve essere compilato, ma il vantaggio è prestazioni extra rispetto a soluzioni Python come geopy. O pysqlite o APSW funzioneranno per l'accesso SQLite. (Disclosure: I am the APSW author.)