Skip to content

Commit 5d8cb31

Browse files
committed
Imported Upstream version 0.7
1 parent a67f1ff commit 5d8cb31

10 files changed

+693
-26
lines changed

PKG-INFO

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
Metadata-Version: 1.0
22
Name: python-geohash
3-
Version: 0.2
4-
Summary: UNKNOWN
5-
Home-page: UNKNOWN
6-
Author: UNKNOWN
3+
Version: 0.7
4+
Summary: Fast, accurate python geohashing library
5+
Home-page: http://code.google.com/p/python-geohash/
6+
Author: Hiroaki Kawai
77
Author-email: UNKNOWN
88
License: UNKNOWN
99
Description: UNKNOWN

README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
* python-geohash
22
python-geohash is a fast, accurate python geohashing library.
33

4+
python-geohash 0.3 can create C extension. If you want to use python-geohash
5+
without C extension, simply copy geohash.py into your system. geohash.py will
6+
work fine without C extension.
7+
48
** LICENSE
59
Code is licensed under Apache License 2.0, MIT Licence and NEW BSD License.
610
You can choose one of the licences above.

geohash.py

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
"""
33
Copyright (C) 2009 Hiroaki Kawai <[email protected]>
44
"""
5+
try:
6+
import _geohash
7+
except ImportError,e:
8+
_geohash = None
9+
510
__all__ = ['encode','decode','decode_exactly','bbox', 'neighbors', 'expand']
611

712
_base32 = '0123456789bcdefghjkmnpqrstuvwxyz'
@@ -32,36 +37,49 @@ def _encode_i2c(lat,lon,lat_length,lon_length):
3237
a = lat
3338
b = lon
3439

40+
boost = (0,1,4,5,16,17,20,21)
3541
ret = ''
36-
while precision>0:
37-
c = ((a&4)<<2) + ((b&2)<<2) + ((a&2)<<1) + ((b&1)<<1) + (a&1)
38-
ret += _base32[c]
42+
for i in range(precision):
43+
ret+=_base32[(boost[a&7]+(boost[b&3]<<1))&0x1F]
3944
t = a>>3
4045
a = b>>2
4146
b = t
42-
precision-=1
4347

4448
return ret[::-1]
4549

4650
def encode(latitude, longitude, precision=12):
47-
if latitude > 90.0 or latitude < -90.0:
51+
if latitude >= 90.0 or latitude < -90.0:
4852
raise Exception("invalid latitude.")
4953
while longitude < -180.0:
5054
longitude += 360.0
5155
while longitude >= 180.0:
5256
longitude -= 360.0
5357

54-
lat = (latitude+90.0)/180.0
55-
lon = (longitude+180.0)/360.0
58+
if _geohash:
59+
basecode=_geohash.encode(latitude,longitude)
60+
if len(basecode)>precision:
61+
return basecode[0:precision]
62+
return basecode+'0'*(precision-len(basecode))
63+
64+
lat = latitude/180.0
65+
lon = longitude/360.0
5666

57-
lat_length=lon_length=precision*5/2
58-
if precision%2==1:
67+
xprecision=precision+1
68+
lat_length=lon_length=xprecision*5/2
69+
if xprecision%2==1:
5970
lon_length+=1
6071

61-
lat = int((1<<lat_length)*lat)
62-
lon = int((1<<lon_length)*lon)
72+
if lat>0:
73+
lat = int((1<<lat_length)*lat)+(1<<(lat_length-1))
74+
else:
75+
lat = (1<<lat_length-1)-int((1<<lat_length)*(-lat))
76+
77+
if lon>0:
78+
lon = int((1<<lon_length)*lon)+(1<<(lon_length-1))
79+
else:
80+
lon = (1<<lon_length-1)-int((1<<lon_length)*(-lon))
6381

64-
return _encode_i2c(lat,lon,lat_length,lon_length)
82+
return _encode_i2c(lat,lon,lat_length,lon_length)[:precision]
6583

6684
def _decode_c2i(hashcode):
6785
lon = 0
@@ -97,15 +115,28 @@ def _decode_c2i(hashcode):
97115
return (lat,lon,lat_length,lon_length)
98116

99117
def decode(hashcode, delta=False):
118+
'''
119+
decode a hashcode and get center coordinate, and distance between center and outer border
120+
'''
121+
if _geohash:
122+
(lat,lon,lat_bits,lon_bits) = _geohash.decode(hashcode)
123+
latitude_delta = 180.0/(2<<lat_bits)
124+
longitude_delta = 360.0/(2<<lon_bits)
125+
latitude = lat + latitude_delta
126+
longitude = lon + longitude_delta
127+
if delta:
128+
return latitude,longitude,latitude_delta,longitude_delta
129+
return latitude,longitude
130+
100131
(lat,lon,lat_length,lon_length) = _decode_c2i(hashcode)
101132

102133
lat = (lat<<1) + 1
103134
lon = (lon<<1) + 1
104135
lat_length += 1
105136
lon_length += 1
106137

107-
latitude = 180.0*lat/(1<<lat_length) - 90.0
108-
longitude = 360.0*lon/(1<<lon_length) - 180.0
138+
latitude = 180.0*(lat-(1<<(lat_length-1)))/(1<<lat_length)
139+
longitude = 360.0*(lon-(1<<(lon_length-1)))/(1<<lon_length)
109140
if delta:
110141
latitude_delta = 180.0/(1<<lat_length)
111142
longitude_delta = 360.0/(1<<lon_length)
@@ -119,16 +150,36 @@ def decode_exactly(hashcode):
119150
## hashcode operations below
120151

121152
def bbox(hashcode):
122-
(lat,lon,lat_length,lon_length) = _decode_c2i(hashcode)
153+
'''
154+
decode a hashcode and get north, south, east and west border.
155+
'''
156+
if _geohash:
157+
(lat,lon,lat_bits,lon_bits) = _geohash.decode(hashcode)
158+
latitude_delta = 180.0/(1<<lat_bits)
159+
longitude_delta = 360.0/(1<<lon_bits)
160+
return {'s':lat,'w':lon,'n':lat+latitude_delta,'e':lon+longitude_delta}
123161

162+
(lat,lon,lat_length,lon_length) = _decode_c2i(hashcode)
124163
ret={}
125-
ret['n'] = 180.0*(lat+1)/(1<<lat_length) - 90.0
126-
ret['s'] = 180.0*lat/(1<<lat_length) - 90.0
127-
ret['e'] = 360.0*(lon+1)/(1<<lon_length) - 180.0
128-
ret['w'] = 360.0*lon/(1<<lon_length) - 180.0
164+
if lat_length:
165+
ret['n'] = 180.0*(lat+1-(1<<(lat_length-1)))/(1<<lat_length)
166+
ret['s'] = 180.0*(lat-(1<<(lat_length-1)))/(1<<lat_length)
167+
else: # can't calculate the half with bit shifts (negative shift)
168+
ret['n'] = 90.0
169+
ret['s'] = -90.0
170+
171+
if lon_length:
172+
ret['e'] = 360.0*(lon+1-(1<<(lon_length-1)))/(1<<lon_length)
173+
ret['w'] = 360.0*(lon-(1<<(lon_length-1)))/(1<<lon_length)
174+
else: # can't calculate the half with bit shifts (negative shift)
175+
ret['e'] = 180.0
176+
ret['w'] = -180.0
177+
129178
return ret
130179

131180
def neighbors(hashcode):
181+
if _geohash and len(hashcode)<25:
182+
return _geohash.neighbors(hashcode)
132183
(lat,lon,lat_length,lon_length) = _decode_c2i(hashcode)
133184
ret = []
134185
tlat = lat

setup.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
from distutils.core import setup
1+
from distutils.core import setup, Extension
2+
3+
c1=Extension('_geohash',
4+
sources=['src/geohash.cpp',],
5+
define_macros = [('PYTHON_MODULE',1),])
6+
27
setup(name='python-geohash',
3-
version='0.2',
4-
py_modules=['geohash','quadtree','jpgrid','jpiarea']
8+
version='0.7',
9+
description='Fast, accurate python geohashing library',
10+
author='Hiroaki Kawai',
11+
url='http://code.google.com/p/python-geohash/',
12+
py_modules=['geohash','quadtree','jpgrid','jpiarea'],
13+
ext_modules = [c1]
514
)

src/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CC = gcc
2+
CXX = g++
3+
CFLAGS = -O3
4+
CXXFLAGS =
5+
TARGET = sample
6+
OBJS = geohash_sample.o geohash.o
7+
8+
all: $(TARGET)
9+
$(TARGET): $(OBJS)
10+
$(CXX) -o $@ $(OBJS)
11+
clean:
12+
-rm -f $(TARGET) $(OBJS)
13+
.c.o:
14+
$(CC) $(CFLAGS) -c $<
15+
.cpp.o:
16+
$(CXX) $(CXXFLAGS) -c $<

0 commit comments

Comments
 (0)