You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
geo-dht/geohash32.py

91 lines
2.6 KiB
Python

class Geohash(object):
def __init__(self):
pass
base_32 = "0123456789bcdefghjkmnpqrstuvwxyz"
# base_32 = "0123456789abcdefghijklmnopqrstuv"
def divideRangeByValue(self, value, range123):
mid = self.middle(range123)
if value >= mid:
range123[0] = mid
return 1
else:
range123[1] = mid
return 0
def divideRangeByBit(self, bit, range):
mid = self.middle(range)
if bit > 0:
range[0] = mid
else:
range[1] = mid
def middle(self, range):
return (range[0] + range[1]) / 2
def encodeBinary(self, lat, lon, prec):
latRange = [-90.0, 90.0]
lonRange = [-180.0, 180.0]
isEven = True
binaryhash = ""
while binaryhash.__len__() < prec:
if isEven:
res = self.divideRangeByValue(lon, lonRange)
binaryhash += str(res)
else:
res = self.divideRangeByValue(lat, latRange)
binaryhash += str(res)
isEven = not isEven
return binaryhash
def encodeGeohash(self, latitide, longitide, precision):
latRange = [-90.0, 90.0]
lonRange = [-180.0, 180.0]
isEven = True
bit = 0
base32CharIndex = 0
geohash = ""
while geohash.__len__() < precision:
if isEven:
base32CharIndex = (base32CharIndex << 1) | self.divideRangeByValue(longitide, lonRange)
else:
base32CharIndex = (base32CharIndex << 1) | self.divideRangeByValue(latitide, latRange)
if isEven:
isEven = False
else:
isEven = True
if bit < 4:
bit = bit + 1
else:
geohash += self.base_32[base32CharIndex]
bit = 0
base32CharIndex = 0
return geohash
def decodeGeohash(self, geohash):
latRange = [-90.0, 90.0]
lonRange = [-180.0, 180.0]
isEvenBit = True
index = 0
for char in geohash:
base32CharIndex = self.base_32[index]
jIndex = 4
for i in range(4):
if isEvenBit:
self.divideRangeByBit((base32CharIndex >> jIndex) & 1, lonRange)
isEvenBit = False
else:
self.divideRangeByBit((base32CharIndex >> jIndex) & 1, latRange)
isEvenBit = True
jIndex = jIndex - 1
return [self.middle(latRange), self.middle(lonRange)]