使用geohash完成地理距離計算
geohash的原理是使用二分法,把當前的經度和緯度和最大最小的經度緯度進行無限二分,在一邊則為0,否則為1,這樣就可以定位
到地球上的每一個點了。然後把經度放在偶數位,緯度放在奇數位,組成一個01010101串。如果想變得更容易傳輸,可以用某種
方式進行hash,例如base32
,base64
等。
下面是一個簡單的實現。to_geohash
實現經度和緯度轉換成010101串,similarity
比較兩個01010串的前面有多少個相同的字元。
不過,to_geohash
有更高效的位運算實現,但是可讀性不好,不容易懂,就不放出來了。
def to_geohash(longitude, latitude, length=30): '''longitude 經度(在地圖上豎著的線),latitude緯度(在地圖上橫著的線)''' minLat, maxLat = -90.0, 90.0 minLng, maxLng = -180.0, 180.0 result = 0 for i in range(length): if i % 2 == 0:# 偶數,設定longitude mid = (minLng + maxLng) / 2 if longitude < mid: result <<= 1# push 0 maxLng = mid else: result = result << 1 | 1# push 1 minLng = mid else: mid = (minLat + maxLat) / 2 if latitude < mid: result <<= 1 maxLat = mid else: result = result << 1 | 1 minLat = mid return str(bin(result))[2:] def similarity(a, b): """比較a和b兩個字串前length位有多少位相同""" result = 0 length = max(len(a), len(b)) a = a.ljust(length, '0') b = b.ljust(length, '0') for i in range(length): if a[i] == b[i]: result += 1 else: break return result