#1度约100km,故0.00001度约1米
#地球一圈40000km,4e8米,2的28次方,故均可切成28位数
#[l, mid)为左,[mid, r]为右
def lng2LngBinary(lng, levelNum = 28):
l, r = -180, 180
if lng < l or lng > r:
print("lng输入值为: {}, 不在合理范围[-180, 180]内".format(lng))
return
lngBinary = []
for _ in range(levelNum):
mid = (l+r)/2
if lng < mid:
lngBinary.append(0)
r = mid
else:
lngBinary.append(1)
l = mid
return lngBinary
def lngBinary2Lng(lngBinary):
l, r = -180, 180
for num in lngBinary:
mid = (l+r)/2
if num == 0:
r = mid
else:
l = mid
lng = (l+r)/2
return lng
def lat2LatBinary(lat, levelNum = 28):
l, r = -90, 90
if lat < l or lat > r:
print("lat输入值为: {}, 不在合理范围[-90, 90]内".format(lat))
return
latBinary = []
for _ in range(levelNum):
mid = (l+r)/2
if lat < mid:
latBinary.append(0)
r = mid
else:
latBinary.append(1)
l = mid
return latBinary
def latBinary2Lat(latBinary):
l, r = -90, 90
for num in latBinary:
mid = (l+r)/2
if num == 0:
r = mid
else:
l = mid
lat = (l+r)/2
return lat
#经纬度编码结合,从地址0开始,经度在偶数,纬度在奇数
def lngLatCombine(lngBinary, latBinary):
lnglat = []
for i in range(max(len(lngBinary), len(latBinary))):
if i < len(lngBinary):
lnglat.append(lngBinary[i])
else:
lnglat.append(0)
if i < len(latBinary):
lnglat.append(latBinary[i])
else:
lnglat.append(0)
return lnglat
def lngLatSplit(lnglat):
lngBinary, latBinary = [], []
for i in range(len(lnglat)):
if i%2 == 0:
lngBinary.append(lnglat[i])
else:
latBinary.append(lnglat[i])
return lngBinary, latBinary
#5位的二进制list转数值
def binary2Num(binary):
num = 0
n = len(binary)
for i in range(n):
num += binary[n-1-i]*pow(2,i)
return num
def num2Binary(num):
binary = []
divisor = 16
while divisor > 0:
binary.append(num//divisor)
num = num%divisor
divisor = divisor//2
return binary
def lnglat2lnglat32(lnglat):
D = {0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9',
10: 'b', 11: 'c', 12: 'd', 13: 'e', 14: 'f', 15: 'g', 16: 'h', 17: 'j', 18: 'k', 19: 'm',
20: 'n', 21: 'p', 22: 'q', 23: 'r', 24: 's', 25: 't', 26: 'u', 27: 'v', 28: 'w', 29: 'x',
30: 'y', 31: 'z'}
lnglat32 = []
for i in range(len(lnglat)//5):
binary = lnglat[5*i:5*(i+1)]
num = binary2Num(binary)
str = D[num]
lnglat32.append(str)
return "".join(lnglat32)
def lnglat322lnglat(lnglat32):
D = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
'b': 10, 'c': 11, 'd': 12, 'e': 13, 'f': 14, 'g': 15, 'h': 16, 'j': 17, 'k': 18, 'm': 19,
'n': 20, 'p': 21, 'q': 22, 'r': 23, 's': 24, 't': 25, 'u': 26, 'v': 27, 'w': 28, 'x': 29,
'y': 30, 'z': 31}
lnglat = []
for str in lnglat32:
num = D[str]
binary = num2Binary(num)
lnglat += binary
return lnglat
#lng, lat的geohash
def lngAndlat2lnglat32(lng, lat):
#1-转化为二进制
lngBinary = lng2LngBinary(lng)
latBinary = lat2LatBinary(lat)
#2-经纬度组合
lnglat = lngLatCombine(lngBinary, latBinary)
#3-转为32进制编码
lnglat32 = lnglat2lnglat32(lnglat)
return lnglat32
#lng, lat的geohash
def lnglat322lngAndlat(lnglat32):
lnglat = lnglat322lnglat(lnglat32)
lngBinary, latBinary = lngLatSplit(lnglat)
lng = lngBinary2Lng(lngBinary)
lat = latBinary2Lat(latBinary)
return lng, lat
if __name__ == '__main__':
#1-初始化经纬度
lng, lat = 116.38955, 39.928167
print("1-lng:{}, lat:{}".format(lng, lat))
#2-转化为二进制
lngBinary = lng2LngBinary(lng)
latBinary = lat2LatBinary(lat)
print("\n2-lngBinary:{}\nlatBinary:{}".format(lngBinary, latBinary))
#2.1-二进制转回来
lng = lngBinary2Lng(lngBinary)
lat = latBinary2Lat(latBinary)
print("\n2.1-lng:{}, lat:{}".format(lng, lat))
#3-经纬度组合
lnglat = lngLatCombine(lngBinary, latBinary)
print("\n3-lnglat:{}".format(lnglat))
#3.1-lnglat拆分为经纬度
lngBinary, latBinary = lngLatSplit(lnglat)
print("\n3.1-lngBinary:{}\nlatBinary:{}".format(lngBinary, latBinary))
#4-转为32进制编码
lnglat32 = lnglat2lnglat32(lnglat)
print("\n4-lnglat32:{}".format(lnglat32))
#4.1-32进制编码拆分为lnglat
lnglat = lnglat322lnglat(lnglat32)
print("\n4.1-lnglat:{}".format(lnglat))
#5
lng, lat = 116.38955, 39.928167
print("\n5-lng:{}, lat:{}".format(lng, lat))
#5.1-encode(整合1-4)
lnglat32 = lngAndlat2lnglat32(lng, lat)
print("\n5.1-lnglat32:{}".format(lnglat32))
#5.2-decode
lng, lat = lnglat322lngAndlat(lnglat32)
print("\n5.2-lng:{}, lat:{}".format(lng, lat))
05-26
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交