【发布时间】:2019-08-27 09:49:28
【问题描述】:
我正在查看 GIS SE -Using geohash for proximity searches? 上这个最受好评的接受答案的 pythonic 实现,但我无法为我的 geohash 查询检索任何匹配项。这是我迄今为止尝试过的方法。
要运行此最小可验证完整示例 (MVCE),您需要下载以下文件 - geohash int 和sortedlist python 并通过pip 安装python 排序列表。你还需要在你的机器上安装最新版本的 Cython,以便包装 geohash-int 的 C 功能(注意我只包装了这个 MVCE 所必需的东西)。
geohash_test.py
# GeoHash is my Cython wrapper of geohash-int C package
from geo import GeoHash
from sortedcontainers import SortedList
import numpy as np
def main():
# Bounding coordinates of my grid.
minLat = 27.401436
maxLat = 62.54858
minLo = -180.0
maxLo = 179.95000000000002
latGrid = np.arange(minLat,maxLat,0.05)
lonGrid = np.arange(minLo,maxLo,0.05)
geoHash = GeoHash()
# Create my own data set of points with a resolution of
# 0.05 in the latitude and longitude direction.
gridLon,gridLat = np.meshgrid(lonGrid,latGrid)
grid_points = np.c_[gridLon.ravel(),gridLat.ravel()]
sl = SortedList()
#Store my grid points in the best resolution possible i.e. 52(First step in accepted answer)
for grid_point in grid_points:
lon = grid_point[0]
lat = grid_point[1]
geohash = geoHash.encode(lat,lon,52)
bitsOriginal = geohash["bits"]
sl.add(bitsOriginal)
#Derive the minimum and maximum value for the range query from method below
minValue,maxValue = getMinMaxForQueryGeoHash(geoHash)
# Do the actual range query with a sorted list
it = sl.irange(minValue,maxValue,inclusive=(False,False))
print(len(list(it)))
def getMinMaxForQueryGeoHash(geoHash):
lonTest = 172.76843
latTest = 61.560745
#Query geohash encoded at resolution 26 because my search area
# is around 10 kms.(Step 2 and 3 in accepted answer)
queryGeoHash = geoHash.encode(latTest,lonTest,26)
# Step 4 is getting the neighbors for query geohash
neighbors = geoHash.get_neighbors(queryGeoHash)
bitsList = []
for key,value in neighbors.items():
bitsList.append(value["bits"])
#Step 5 from accepted answer
bitsList.append(queryGeoHash["bits"])
# Step 6 We need 1 to all the neighbors
newList = [x+1 for x in bitsList]
joinedList = bitsList + newList
#Step 7 Left bit shift this to 52
newList2 = [x <<26 for x in joinedList]
#Return min and max value to main method
minValue = min(newList2)
maxValue = max(newList2)
return minValue,maxValue
main()
如果有人把它写成伪代码,这就是我正在做的事情
鉴于我的边界框是一个网格,我通过计算每个纬度和经度的 geohash(这恰好是位深度 52)以可能的最高分辨率存储它
我将 geohash 添加到排序列表中
然后我想通过指定搜索半径为 10 公里的特定查询坐标来进行范围查询
从接受的答案中,您需要查询 geohash 的最小值和最大值
我在getMinMaxForQueryGeoHash方法中计算最小值和最大值
计算位深度为26的查询geohash(这是10公里的半径)
计算查询geohash的邻居并创建18个成员数组
18个成员是C方法返回的8个邻居加上原始查询geohash,剩下的9个是这个数组加1得到的
-
然后将这个数组左移26位,并将最小值和最大值返回给有序列表的irange查询。
位移 = 52(最大分辨率) - 查询 geohash 精度(26) = 26
但该查询返回给我一个NULL。有人可以解释我哪里出错了吗?
【问题讨论】:
标签: python-3.x nearest-neighbor proximity geohashing