Python 如何在没有GeoDjango的情况下搜索多边形内的点
情况如下:Python 如何在没有GeoDjango的情况下搜索多边形内的点,python,django,geolocation,geodjango,Python,Django,Geolocation,Geodjango,情况如下: 每个供应商都有一些服务区域,用户使用谷歌地图(多边形)定义这些区域 我需要将这些数据存储在数据库中,并在此基础上进行简单(但快速)的查询 查询应类似于:“列出服务区域包含x,y的所有供应商”或“其中多边形(服务区域)x,y在其中?” 此时,我找到了GeoDjango,它看起来是这个问题的一个非常复杂的解决方案。要使用它,我需要一个非常复杂的设置,我找不到任何最近的(好的)教程 我提出了这个解决方案: 将每个多边形作为Json存储到数据库中 应用一种方法来确定某个x,y是否属于任
- 每个供应商都有一些服务区域,用户使用谷歌地图(多边形)定义这些区域李>
- 我需要将这些数据存储在数据库中,并在此基础上进行简单(但快速)的查询李>
- 查询应类似于:“列出服务区域包含x,y的所有供应商”或“其中多边形(服务区域)x,y在其中?”
- 将每个多边形作为Json存储到数据库中
- 应用一种方法来确定某个x,y是否属于任何多边形
此解决方案使您能够在GeoDjango之外存储多边形,以显著加快多边形中的点查询 在我的例子中,我需要找到我的numpy数组的坐标是否位于存储在geodjango db(陆地/水掩蔽)中的多边形中。这需要迭代数组中的每个坐标组合,以测试它是在多边形内部还是外部。由于我的阵列很大,使用geodjango需要很长时间 使用django的GEOSGeometry.contains,我的命令如下所示:
import numpy as np
from django.contrib.gis.geos import Point
my_polygon = model.geometry # get model multipolygon field
lat_lon = zip(latitude.flat, longitude.flat) # zip coordinate arrays to tuple
mask = np.array([my_polygon.contains(Point(l)) for l in lon_lat]) # boolean mask
对于大型阵列,这需要20秒或更长时间。我尝试了在数组上应用geometry.contains()函数的不同方法(例如np.vectorize),但这并没有带来任何改进。然后我意识到是Django包含查找花费了太长的时间。我还将几何体转换为shapely多边形,并测试了shapely的多边形。包含函数-没有差异或更糟
解决方案在于使用isInside方法绕过GeoDjango。首先,我创建了一个函数,用于从Geos Multipolygon创建多边形对象
from Polygon import Polygon
def multipolygon_to_polygon(multipolygon):
"""
Convert a Geos Multipolygon to python Polygon
"""
polygon = multipolygon[0] # select first polygon object
nrings = polygon.num_interior_rings # get number of rings in polygon
poly = Polygon()
poly.addContour(polygon[0].coords) # Add first ring coordinates tuple
# Add subsequent rings
if nrings > 0:
for i in range(nrings):
print("Adding ring %s" % str(i+1))
hole = True
poly.addContour(polygon[i+1].coords, hole)
return poly
把这个应用到我的问题上
my_polygon = model.geometry # get model multipolygon field
polygon = multipolygon_to_polygon(my_polygon) # convert to python Polygon
lat_lon = zip(bands['latitude'].flat, bands['longitude'].flat) # points tuple
land_mask = array([not polygon.isInside(ll[1], ll[0]) for ll in lat_lon])
这使得速度提高了约20倍。希望这对别人有帮助
Python2.7.您不会仅仅为此使用GeoDjango。你可以改用Shapely。但是你同时问了很多问题。问题是如何在数据库中存储数据?或者如何找到一个点是否在多边形中?tx@AntonisChristofides!我添加了更多细节。问题不在于确定点是否在多边形内,但我需要以这样一种方式存储多边形,我可以快速查询其中的几个。现在清楚了吗?看起来Shapely并没有解决这个问题,也许你需要的是PostGIS。这是一个老问题,但添加了这个注释,因为它仍然在这里突出显示。使用geodjango肯定没有您尝试过的基于json的方法那么复杂。空间数据库是专门为查找空间关系而设计的。这是一个地狱很多代码由很多有才华的人。如果你想用JSON复制它,你会非常痛苦。我刚刚发现了Geos准备的几何图形。这使得像.contains这样的操作更快,并且只需要一行简单的代码:my_polygon=my_polygon.prepared,然后再执行.contains操作。这将产生与上述替代解决方案相当的速度。见: