Python模块,用于存储和查询地理坐标



有没有Python模块,我可以在其中创建具有地理位置坐标(纬度和经度)的对象,并查询所有对象中距离给定坐标5km(即半径)以内的对象?

我一直在尝试将纬度和经度作为关键字存储在字典中(因为它们是按关键字索引的),并使用一些测距算法来查询它们。但这感觉像是一个可怕的黑客。

本质上类似于PostgreSQL的PostGIS,但都在我的Python应用程序的内存中。

是的,请尝试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

之后你可以查询你的积分列表:

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

我知道这不是你的意思,但你可以将GeoDjango与内存中的SQLite数据库一起使用。它是作为Web应用程序公开的一整套GIS工具,这使它成为快速开发GIS应用程序的瑞士军刀,尤其是用于小型临时查询。

GIS中的常用方法是在兴趣点周围创建一个缓冲区并查询交叉点。正如@RyanDalton所建议的,如果你计划做很多地理定位工作,请使用Shapely,Python的GIS API。了解Shapely是件好事,即使你仍然想要一个空间索引(见下文)。以下是如何在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)

如果你没有很多,你可以自己索引你的点(比如说通过经度)。否则你也可以使用Rtree包,查看名为Using Rtree as a cheap空间数据库的链接!

您的字典想法听起来并没有那么糟糕,不过您还需要检查"相邻"字典键下的点。

如果你找不到合适的工具,就像编码算法一样,你可以实现一个二进制空间分区树,afaik是实现类似功能的一种不那么麻烦的方式。

您可以使用具有Rtree扩展的SQLite来执行这种存储和查询。如果您的数据大于您想要使用的内存,或者您想要在程序运行之间保存和操作数据,那么这种方法非常有用。实际的存储和查询代码是用C语言编写的,这意味着必须对其进行编译,但与geopy等纯Python解决方案相比,其优点是具有额外的性能。pysqlite或APSW都适用于SQLite访问。(披露:我是APSW的作者。)

我也有类似的问题,使用SciPy的cKDTree进行快速最近点查找,以及使用GeoPy进行地理距离计算似乎效果不错。

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

为了得到半径内的所有点,需要做一些额外的工作。

我尝试了Shapely的STRtree,但性能差得多(我安装了pip install shapely[vectorized])。

你看过Shapely吗?它有一些方法可以查询一定距离内的对象。看看二进制空间谓词。这可能正是你想要的。

相关内容

  • 没有找到相关文章

最新更新