__all__ = ['encode','decode','bbox','neighbors']
_base32 = '0123456789bcdefghjkmnpqrstuvwxyz'
#10进制和32进制转换,32进制去掉了ailo
_decode_map = {}
_encode_map = {}
for i in range(len(_base32)):
_decode_map[_base32[i]] = i
_encode_map[i]=_base32[i]
del i
'''
encode精度
geohash长度 Lat位数 Lng位数 Lat误差 Lng误差 km误差
1 2 3 ±23 ±23 ±2500
2 5 5 ± 2.8 ± 5.6 ±630
3 7 8 ± 0.70 ± 0.7 ±78
4 10 1 0 ± 0.087 ± 0.18 ±20
5 12 1 3 ± 0.022 ± 0.022 ±2.4
6 15 1 5 ± 0.0027 ± 0.0055 ±0.61
7 17 1 8 ±0.00068 ± 0.00068 ±0.076
8 20 2 0 ±0.000086 ±0.000172 ±0.01911
9 22 2 3 ±0.000021 ±0.000021 ±0.00478
10 25 2 5 ±0.00000268 ±0.00000536 ±0.0005971
11 27 2 8 ±0.00000067 ±0.00000067 ±0.0001492
12 30 3 0 ±0.00000008 ±0.00000017 ±0.0000186
'''
# 交线位置给左下
def encode(lon,lat,precision=11):
'''
坐标转编码
'''
lat_range, lon_range = [-90.0, 90.0], [-180.0, 180.0]
geohash=[]
code=[]
j=0
while len(geohash)<precision:
# print(code,lat_range,lon_range,geohash)
j+=1
lat_mid=sum(lat_range)/2
lon_mid=sum(lon_range)/2
#经度
if lon<=lon_mid:
code.append(0)
lon_range[1]=lon_mid
else:
code.append(1)
lon_range[0]=lon_mid
#纬度
if lat<=lat_mid:
code.append(0)
lat_range[1]=lat_mid
else:
code.append(1)
lat_range[0]=lat_mid
##encode
if len(code)>=5:
geohash.append(_encode_map[int(''.join(map(str,code[:5])),2)])
code=code[5:]
return ''.join(geohash)
def decode(geohash):
'''
编码转坐标
'''
lat_range, lon_range = [-90.0, 90.0], [-180.0, 180.0]
is_lon=True
for letter in geohash:
code=str(bin(_decode_map[letter]))[2:].rjust(5,'0')
for bi in code:
if is_lon and bi=='0':
lon_range[1]=sum(lon_range)/2
elif is_lon and bi=='1':
lon_range[0]=sum(lon_range)/2
elif (not is_lon) and bi=='0':
lat_range[1]=sum(lat_range)/2
elif (not is_lon) and bi=='1':
lat_range[0]=sum(lat_range)/2
is_lon=not is_lon
return sum(lat_range)/2,sum(lon_range)/2
def neighbors(geohash,lv):
'''
搜索附近
lv = 大边长 / 小边长 / 3
例如: 在一个9*9平方米的范围生成3*3米的栅格, 9 / 3 / 3 = 1 lv就传1
'''
neighbors=[]
lat_range,lon_range=180,360
x,y=decode(geohash)
num=len(geohash)*5
dx=lat_range/(2**(num//2))
dy=lon_range/(2**(num-num//2))
n = 0
for i in range(1*lv,-2*lv,-1):
for j in range(-1*lv,2*lv):
code = encode(y+j*dy,x+i*dx,num//5)
neighbors.append(code)
# r.set(code,random.randrange(1,3))
# neighbors.remove(geohash)
return neighbors
def bbox(geohash):
lat_range, lon_range = [-90.0, 90.0], [-180.0, 180.0]
is_lon=True
for letter in geohash:
code=str(bin(_decode_map[letter]))[2:].rjust(5,'0')
for bi in code:
if is_lon and bi=='0':
lon_range[1]=sum(lon_range)/2
elif is_lon and bi=='1':
lon_range[0]=sum(lon_range)/2
elif (not is_lon) and bi=='0':
lat_range[1]=sum(lat_range)/2
elif (not is_lon) and bi=='1':
lat_range[0]=sum(lat_range)/2
is_lon=not is_lon
#左上、右下;(lat_max,lon_min),(lat_min,lon_max)
return [(lat_range[1],lon_range[0]),(lat_range[0],lon_range[1])]
geohash地图栅格化搜索附近
猜你喜欢
转载自blog.csdn.net/wuhchengfei616/article/details/106112186
今日推荐
周排行