geohash 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
data/History.txt CHANGED
@@ -2,4 +2,9 @@
2
2
 
3
3
  * Released by David Troy (C) Under the MIT License
4
4
 
5
+ === 1.0.1 / 2008-06-11
6
+
7
+ * Added decode_bbox functionality for decoding a geohash into a bounding box
8
+ * Cleaned up test environment
9
+
5
10
 
data/README.txt CHANGED
@@ -15,6 +15,7 @@ removing characters from the end of the code to reduce its size (and gradually l
15
15
  See these resources online:
16
16
  http://geohash.org
17
17
  http://en.wikipedia.org/wiki/Geohash
18
+ http://openlocation.org/geohash/geohash-js (javascript implementation and demo)
18
19
 
19
20
  == FEATURES/PROBLEMS:
20
21
 
@@ -29,7 +30,6 @@ GeoHash is very easy to use (and fast) because it's written in C with Ruby bindi
29
30
 
30
31
  require 'rubygems'
31
32
  require 'geohash'
32
- include GeoHash
33
33
 
34
34
  GeoHash.decode('f77')
35
35
  => [63.98438, -73.82813]
@@ -37,6 +37,10 @@ GeoHash is very easy to use (and fast) because it's written in C with Ruby bindi
37
37
  GeoHash.encode(39.51, -76.24)
38
38
  => "dr1bc0edrj"
39
39
 
40
+ # Decode a geohash to a bounding box
41
+ decode_bbox('dqcw4')
42
+ => [39.0234375, -76.552734375], [39.0673828125, -76.5087890625]]
43
+
40
44
  You can encode or decode to an arbitrary level of precision:
41
45
 
42
46
  # Encode latitude and longitude to a geohash with precision digits
data/bin/geohash CHANGED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env ruby
data/geohash_native.c CHANGED
@@ -26,21 +26,22 @@
26
26
  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
27
 
28
28
  #include "ruby.h"
29
+ #include <ctype.h>
29
30
 
30
31
  static VALUE rb_mGeoHash;
31
32
 
32
33
  #define BASE32 "0123456789bcdefghjkmnpqrstuvwxyz"
33
34
 
34
- void refine_interval(double *interval, char cd, char mask) {
35
+ static void refine_interval(double *interval, char cd, char mask) {
35
36
  if (cd&mask)
36
37
  interval[0] = (interval[0] + interval[1])/2;
37
- else
38
+ else
38
39
  interval[1] = (interval[0] + interval[1])/2;
39
40
  }
40
41
 
41
- float *decode_geohash(char *geohash, double *point) {
42
+ static void decode_geohash_bbox(char *geohash, double *lat, double *lon) {
42
43
  int i, j, hashlen, is_even=1;
43
- double lat[2], lon[2], lat_err, lon_err;
44
+ double lat_err, lon_err;
44
45
  char c, cd, mask;
45
46
  char bits[] = {16,8,4,2,1};
46
47
 
@@ -64,46 +65,51 @@ float *decode_geohash(char *geohash, double *point) {
64
65
  is_even = !is_even;
65
66
  }
66
67
  }
68
+ }
69
+
70
+ static void decode_geohash(char *geohash, double *point) {
71
+ double lat[2], lon[2];
72
+
73
+ decode_geohash_bbox(geohash, lat, lon);
67
74
 
68
75
  point[0] = (lat[0] + lat[1]) / 2;
69
76
  point[1] = (lon[0] + lon[1]) / 2;
70
-
71
- return 0;
72
77
  }
73
78
 
74
- void *encode_geohash(double latitude, double longitude, int precision, char *geohash) {
79
+ static void encode_geohash(double latitude, double longitude, int precision, char *geohash) {
75
80
  int is_even=1, i=0;
76
81
  double lat[2], lon[2], mid;
77
- char bits[] = {16,8,4,2,1}, bit=0, ch=0;
82
+ char bits[] = {16,8,4,2,1};
83
+ int bit=0, ch=0;
78
84
 
79
85
  lat[0] = -90.0; lat[1] = 90.0;
80
86
  lon[0] = -180.0; lon[1] = 180.0;
81
87
 
82
88
  while (i < precision) {
83
- if (is_even) {
89
+ if (is_even) {
84
90
  mid = (lon[0] + lon[1]) / 2;
85
- if (longitude > mid) {
91
+ if (longitude > mid) {
86
92
  ch |= bits[bit];
87
93
  lon[0] = mid;
88
- } else
94
+ } else
89
95
  lon[1] = mid;
90
- } else {
96
+ } else {
91
97
  mid = (lat[0] + lat[1]) / 2;
92
- if (latitude > mid) {
98
+ if (latitude > mid) {
93
99
  ch |= bits[bit];
94
100
  lat[0] = mid;
95
- } else
101
+ } else
96
102
  lat[1] = mid;
97
- }
98
-
103
+ }
104
+
99
105
  is_even = !is_even;
100
- if (bit < 4)
106
+ if (bit < 4)
101
107
  bit++;
102
- else {
108
+ else {
103
109
  geohash[i++] = BASE32[ch];
104
110
  bit = 0;
105
111
  ch = 0;
106
- }
112
+ }
107
113
  }
108
114
  geohash[i] = 0;
109
115
  }
@@ -124,27 +130,50 @@ static VALUE encode(VALUE self, VALUE lat, VALUE lon, VALUE precision)
124
130
  encode_geohash(RFLOAT(lat)->value, RFLOAT(lon)->value, digits, str);
125
131
 
126
132
  geohash = rb_str_new2(str);
127
- return geohash;
133
+ return geohash;
128
134
  }
129
135
 
136
+ static VALUE decode_bbox(VALUE self, VALUE str)
137
+ {
138
+ VALUE ary, ret;
139
+ double lat[2], lon[2];
140
+ Check_Type(str, T_STRING);
141
+
142
+ decode_geohash_bbox(RSTRING(str)->ptr, lat, lon);
143
+
144
+ ret = rb_ary_new2(2); /* [[lat[0], lon[0]], [lat[1], lon[1]]] */
145
+
146
+ ary = rb_ary_new2(2); /* [lat[0], lon[0]] */
147
+ rb_ary_store(ary, 0, rb_float_new(lat[0]));
148
+ rb_ary_store(ary, 1, rb_float_new(lon[0]));
149
+ rb_ary_store(ret, 0, ary);
150
+
151
+ ary = rb_ary_new2(2); /* [lat[1], lon[1]] */
152
+ rb_ary_store(ary, 0, rb_float_new(lat[1]));
153
+ rb_ary_store(ary, 1, rb_float_new(lon[1]));
154
+ rb_ary_store(ret, 1, ary);
155
+
156
+ return ret;
157
+ }
130
158
 
131
159
  static VALUE decode(VALUE self, VALUE str)
132
160
  {
133
161
  VALUE ary;
134
162
  double point[2];
135
- Check_Type(str, T_STRING);
136
-
163
+ Check_Type(str, T_STRING);
164
+
137
165
  decode_geohash(RSTRING(str)->ptr, point);
138
-
139
- ary = rb_ary_new2(2);
166
+
167
+ ary = rb_ary_new2(2);
140
168
  rb_ary_store(ary, 0, rb_float_new(point[0]));
141
169
  rb_ary_store(ary, 1, rb_float_new(point[1]));
142
- return ary;
170
+ return ary;
143
171
  }
144
172
 
145
173
  void Init_geohash_native()
146
174
  {
147
175
  rb_mGeoHash = rb_define_module("GeoHash");
176
+ rb_define_method(rb_mGeoHash, "decode_bbox_base", decode_bbox, 1);
148
177
  rb_define_method(rb_mGeoHash, "decode_base", decode, 1);
149
178
  rb_define_method(rb_mGeoHash, "encode_base", encode, 3);
150
179
  }
data/lib/geohash.rb CHANGED
@@ -9,16 +9,21 @@ end
9
9
 
10
10
  module GeoHash
11
11
 
12
- VERSION = '1.0.0'
12
+ VERSION = '1.0.1'
13
13
 
14
14
  # Encode latitude and longitude to a geohash with precision digits
15
15
  def encode(lat, lon, precision=10)
16
16
  encode_base(lat, lon, precision)
17
17
  end
18
-
18
+
19
19
  # Decode a geohash to a latitude and longitude with decimals digits
20
20
  def decode(geohash, decimals=5)
21
21
  lat, lon = decode_base(geohash)
22
22
  [lat.decimals(decimals), lon.decimals(decimals)]
23
23
  end
24
+
25
+ # Decode a geohash to a bounding box
26
+ def decode_bbox(geohash)
27
+ decode_bbox_base(geohash)
28
+ end
24
29
  end
data/test/test_geohash.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'rubygems'
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/.."
2
3
  require "#{File.dirname(__FILE__)}/../lib/geohash"
3
4
  require 'test/unit'
4
5
 
@@ -21,6 +22,34 @@ class GeoHashTest < Test::Unit::TestCase
21
22
  assert_equal "6gkzmg1u", encode(-25.427, -49.315, 8)
22
23
  assert_equal "ezs42", encode(42.60498046875, -5.60302734375, 5)
23
24
  end
25
+
26
+ def check_decoding(gh)
27
+ exact = decode(gh, 20)
28
+ bbox = decode_bbox(gh)
29
+
30
+ # check that the bbox is centered on the decoded point
31
+ bbox_center = [(bbox[0][0] + bbox[1][0]) / 2, (bbox[0][1] + bbox[1][1]) / 2]
32
+ assert_equal exact, bbox_center
33
+
34
+ # check that the bounding box is the expected size
35
+ bits = gh.size * 5
36
+ lon_bits = (bits.to_f/2).ceil
37
+ lat_bits = (bits.to_f/2).floor
38
+ correct_size = [180.0/2**lat_bits, 360.0/2**lon_bits]
39
+ bbox_size = [bbox[1][0] - bbox[0][0], bbox[1][1] - bbox[0][1]]
40
+ assert_equal bbox_size, correct_size
41
+ end
42
+
43
+ def test_decoding_bbox
44
+ s = "dqcw4bnrs6s7"
45
+ (s.length-1).downto(0) do |l|
46
+ check_decoding(s[0..l])
47
+ end
48
+ end
49
+
50
+ def test_specific_bbox
51
+ assert_equal [[39.0234375, -76.552734375], [39.0673828125, -76.5087890625]], decode_bbox('dqcw4')
52
+ end
24
53
 
25
54
  # require 'benchmark'
26
55
  # def test_multiple
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geohash
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Troy
@@ -30,7 +30,7 @@ cert_chain:
30
30
  K80lsu167t5ZwbXh+Day+g==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2008-04-24 00:00:00 -04:00
33
+ date: 2008-06-11 00:00:00 -04:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -40,9 +40,9 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: 1.5.1
43
+ version: 1.5.3
44
44
  version:
45
- description: "GeoHash Gem for Ruby (c) 2008 David Troy dave@roundhousetech.com Geohash is a latitude/longitude encoding system invented by Gustavo Niemeyer when writing the web service at geohash.org, and put into the public domain. Geohashes offer properties like arbitrary precision, similar prefixes for nearby positions, and the possibility of gradually removing characters from the end of the code to reduce its size (and gradually lose precision). See these resources online: http://geohash.org http://en.wikipedia.org/wiki/Geohash"
45
+ description: "GeoHash Gem for Ruby (c) 2008 David Troy dave@roundhousetech.com Geohash is a latitude/longitude encoding system invented by Gustavo Niemeyer when writing the web service at geohash.org, and put into the public domain. Geohashes offer properties like arbitrary precision, similar prefixes for nearby positions, and the possibility of gradually removing characters from the end of the code to reduce its size (and gradually lose precision). See these resources online: http://geohash.org http://en.wikipedia.org/wiki/Geohash http://openlocation.org/geohash/geohash-js (javascript implementation and demo)"
46
46
  email:
47
47
  - dave@roundhousetech.com
48
48
  executables:
metadata.gz.sig CHANGED
Binary file