Módulo de Python para almacenar y consultar coordenadas geográficas.

¿Hay un módulo de Python en el que pueda crear objetos con una coordenada de ubicación geográfica (latitud y longitud) y consultar todos los objetos en busca de objetos que se encuentren a una distancia de 5 km (es decir, un radio) de una coordenada determinada?

He estado tratando de almacenar la latitud y la longitud como claves en los diccionarios (ya que están indexados por clave) y uso algunos algoritmos de búsqueda de distancia para consultarlos. Pero esto se siente como un horrible hack.

Esencialmente, algo como PostGIS para PostgreSQL, pero todo dentro de la memoria de mi aplicación Python.

Sí, prueba 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 

Después puedes consultar tus listas de puntos:

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

Sé que esto no es exactamente lo que quisiste decir, pero podrías usar GeoDjango con una base de datos SQLite en memoria. Es un conjunto completo de herramientas GIS expuestas como una aplicación web, lo que lo convierte en una razor suiza para el desarrollo rápido de aplicaciones GIS, especialmente para pequeñas consultas ad hoc.

El enfoque habitual en GIS es crear un búfer alrededor del punto de interés y consultar la intersección. Como sugiere @RyanDalton, si planea hacer muchas cosas de geolocalización, use Shapely, la API de GIS para Python. Es bueno saber acerca de Shapely incluso si aún desea un índice espacial (ver más abajo). Aquí es cómo crear buffers en 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) 

Puede indexar sus puntos usted mismo (digamos por longitud, por ejemplo) si no tiene muchos. De lo contrario, también puede usar el paquete Rtree, verifique el enlace llamado Uso de Rtree como una base de datos espacial cheapo !

La idea de su diccionario no suena tan mal, aunque también tendrá que verificar los puntos que se encuentran debajo de las claves del diccionario “vecino”.

Si no puede encontrar la herramienta adecuada y, al igual que los algoritmos de encoding, podría implementar un árbol de partición de espacio binario, que afaik es una forma menos compleja de lograr algo similar.

Puede usar SQLite, que tiene una extensión Rtree para realizar exactamente ese tipo de almacenamiento y consulta. Este enfoque es útil si sus datos son más grandes que la memoria que desea utilizar o si desea guardar y manipular los datos entre las ejecuciones del progtwig. El código real de almacenamiento y consulta está en C, lo que significa que debe comstackrse, pero el beneficio es un rendimiento extra sobre las soluciones puras de Python como Geopy. Pysqlite o APSW funcionarán para el acceso a SQLite. (Divulgación: Soy el autor de APSW).

¿Has mirado a Shapely ? Tiene algunos métodos para consultar objetos dentro de una distancia. Echa un vistazo a los predicados espaciales binarios . Puede que sea lo que buscas.

Tengo un problema similar y parece que el uso de cKDTree de SciPy para búsquedas rápidas de puntos más cercanos junto con GeoPy para el cálculo de la distancia geográfica funciona bien.

 In [1]: import numpy as np In [2]: from scipy.spatial import cKDTree In [3]: from geopy import Point, distance In [4]: points = np.random.sample((100000, 2)) * 180 - 90 # make 100k random lat-long points In [5]: index = cKDTree(points) In [6]: %time lat_long_dist, inds = index.query(points[234], 20) CPU times: user 118 µs, sys: 164 µs, total: 282 µs Wall time: 248 µs In [7]: points_geopy = [Point(*p) for p in points] In [8]: %time geo_dists = [distance.great_circle(points_geopy[234], points_geopy[i]) for i in inds] CPU times: user 244 µs, sys: 218 µs, total: 462 µs Wall time: 468 µs In [9]: geo_dists Out[9]: [Distance(0.0), Distance(29.661520907955524), ... Distance(156.5471729956897), Distance(144.7528417712309)] 

Se necesita un poco de trabajo adicional para obtener todos los puntos dentro de un radio.

Probé el STRtree de Shapely, pero obtuve un rendimiento mucho peor (lo instalé con pip install shapely[vectorized] ).