geohex 1.0.0 → 2.0.0
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/README.txt +9 -1
- data/lib/geohex.rb +195 -120
- data/spec/geohex_spec.rb +34 -39
- metadata +44 -10
data/README.txt
CHANGED
|
@@ -45,9 +45,17 @@ http://twitter.com/hal_sk (ja)
|
|
|
45
45
|
|
|
46
46
|
## LICENSE
|
|
47
47
|
|
|
48
|
+
NOTE:
|
|
49
|
+
The idea of GeoHex is licensed by sa2da.
|
|
50
|
+
You should follow original license of GeoHex.
|
|
51
|
+
(The license is opened by CC-BY-SA license)
|
|
52
|
+
You must attribute this work to sa2da (with link).
|
|
53
|
+
http://geogames.net
|
|
54
|
+
|
|
55
|
+
This ruby code is covered by MIT License.
|
|
48
56
|
(The MIT License)
|
|
49
57
|
|
|
50
|
-
Copyright (c)
|
|
58
|
+
Copyright (c) 2009 Haruyuki SEKI
|
|
51
59
|
|
|
52
60
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
53
61
|
a copy of this software and associated documentation files (the
|
data/lib/geohex.rb
CHANGED
|
@@ -1,142 +1,217 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
#
|
|
2
|
-
# ported from
|
|
3
|
+
# ported from js libraries http://geohex.net
|
|
3
4
|
# author Haruyuki Seki
|
|
4
5
|
#
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
require 'ostruct'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
module GeoHex
|
|
10
|
+
VERSION = '2.0.0'
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
H_SIZE = 0.5
|
|
12
|
+
H_KEY = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
13
|
+
H_BASE = 20037508.34;
|
|
14
|
+
H_DEG = Math::PI*(30.0/180);
|
|
15
|
+
H_K = Math.tan(H_DEG);
|
|
16
|
+
R=20037508.34
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
class Zone
|
|
19
|
+
attr_accessor :code, :lat, :lon, :x, :y
|
|
20
|
+
def initialize(*params)
|
|
21
|
+
raise ArgumentError, "latlng or code is needed" if params.size == 0
|
|
22
|
+
if params.first.is_a?(Float)
|
|
23
|
+
@lat,@lon = params[0],params[1]
|
|
24
|
+
@level= params[2]||7
|
|
25
|
+
@code= GeoHex::Zone.encode(@lat,@lon,@level)
|
|
26
|
+
else
|
|
27
|
+
@code = params.first
|
|
28
|
+
@lat,@lon,@level=GeoHex::Zone.decode(@code)
|
|
29
|
+
end
|
|
27
30
|
end
|
|
28
|
-
#@center_lat =
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# latlon to geohex
|
|
32
|
-
def self.encode(lat,lon,level=7)
|
|
33
|
-
raise ArgumentError, "latitude must be between -90 and 90" if (lat < -90 || lat > 90)
|
|
34
|
-
raise ArgumentError, "longitude must be between -180 and 180" if (lon < -180 || lon > 180)
|
|
35
|
-
raise ArgumentError, "level must be between 1 and 60" if (level < 1 || level > 60)
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
32
|
+
def self.calcHexSize(level)
|
|
33
|
+
H_BASE/(2**level)/3
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def level
|
|
37
|
+
H_KEY.index(code[0,1])
|
|
38
|
+
end
|
|
39
|
+
def hexSize
|
|
40
|
+
self.calcHexSize(self.level)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def hexCoords
|
|
44
|
+
h_lat = self.lat;
|
|
45
|
+
h_lon = self.lon;
|
|
46
|
+
h_xy = GeoHex.loc2xy(h_lon, h_lat);
|
|
47
|
+
h_x = h_xy.x
|
|
48
|
+
h_y = h_xy.y
|
|
49
|
+
h_deg = Math.tan(Math::PI * (60 / 180));
|
|
50
|
+
h_size = self.hexSize
|
|
51
|
+
h_top = xy2loc(h_x, h_y + h_deg * h_size).lat;
|
|
52
|
+
h_btm = xy2loc(h_x, h_y - h_deg * h_size).lat;
|
|
53
|
+
|
|
54
|
+
h_l = xy2loc(h_x - 2 * h_size, h_y).lon;
|
|
55
|
+
h_r = xy2loc(h_x + 2 * h_size, h_y).lon;
|
|
56
|
+
h_cl = xy2loc(h_x - 1 * h_size, h_y).lon;
|
|
57
|
+
h_cr = xy2loc(h_x + 1 * h_size, h_y).lon;
|
|
58
|
+
|
|
59
|
+
[
|
|
60
|
+
{:lat => h_lat, :lon => h_l},
|
|
61
|
+
{:lat => h_top, :lon => h_cl},
|
|
62
|
+
{:lat => h_top, :lon => h_cr},
|
|
63
|
+
{:lat => h_lat, :lon => h_r},
|
|
64
|
+
{:lat => h_btm, :lon => h_cr},
|
|
65
|
+
{:lat => h_btm, :lon => h_cl}
|
|
66
|
+
]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# latlon to geohex
|
|
70
|
+
def self.encode(lat,lon,level=7)
|
|
71
|
+
raise ArgumentError, "latitude must be double" unless (lat.is_a?(Numeric))
|
|
72
|
+
raise ArgumentError, "latitude must be between -85 and 85" if (lat < -85.1 || lat > 85.1)
|
|
73
|
+
raise ArgumentError, "latitude must be between -85 and 85" if (lat < -85.1 || lat > 85.1)
|
|
74
|
+
raise ArgumentError, "longitude must be between -180 and 180" if (lon < -180 || lon > 180)
|
|
75
|
+
raise ArgumentError, "level must be between 0 and 24" if (level < 0 || level > 24)
|
|
54
76
|
|
|
55
|
-
|
|
77
|
+
h_size = self.calcHexSize(level)
|
|
78
|
+
z_xy = loc2xy(lon,lat)
|
|
79
|
+
lon_grid = z_xy.x
|
|
80
|
+
lat_grid = z_xy.y
|
|
81
|
+
unit_x = 6.0* h_size;
|
|
82
|
+
unit_y = 6.0* h_size*H_K;
|
|
83
|
+
h_pos_x = (lon_grid + lat_grid / H_K) / unit_x;
|
|
84
|
+
h_pos_y = (lat_grid - H_K*lon_grid) / unit_y;
|
|
85
|
+
|
|
86
|
+
h_x_0 = h_pos_x.floor;
|
|
87
|
+
h_y_0 = h_pos_y.floor;
|
|
88
|
+
h_x_q = h_pos_x - h_x_0
|
|
89
|
+
h_y_q = h_pos_y - h_y_0
|
|
90
|
+
h_x = h_pos_x.round;
|
|
91
|
+
h_y = h_pos_y.round;
|
|
56
92
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
93
|
+
h_max=(H_BASE/unit_x + H_BASE/unit_y).round;
|
|
94
|
+
|
|
95
|
+
if ( h_y_q > -h_x_q + 1 )
|
|
96
|
+
if ( h_y_q < (2 * h_x_q ) and h_y_q > (0.5 * h_x_q ) )
|
|
97
|
+
h_x = h_x_0 + 1
|
|
98
|
+
h_y = h_y_0 + 1
|
|
99
|
+
end
|
|
100
|
+
elsif ( h_y_q < -h_x_q + 1 )
|
|
101
|
+
if ( (h_y_q > (2 * h_x_q ) - 1 ) && ( h_y_q < ( 0.5 * h_x_q ) + 0.5 ) )
|
|
102
|
+
h_x = h_x_0
|
|
103
|
+
h_y = h_y_0
|
|
104
|
+
end
|
|
60
105
|
end
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
106
|
+
|
|
107
|
+
h_lat = (H_K * h_x * unit_x + h_y * unit_y) / 2;
|
|
108
|
+
h_lon = (h_lat - h_y * unit_y)/H_K;
|
|
109
|
+
|
|
110
|
+
z_loc = xy2loc(h_lon,h_lat)
|
|
111
|
+
z_loc_x = z_loc.lon
|
|
112
|
+
z_loc_y = z_loc.lat
|
|
113
|
+
|
|
114
|
+
if (H_BASE - h_lon <h_size)
|
|
115
|
+
z_loc_x = 180.0;
|
|
116
|
+
h_xy = h_x;
|
|
117
|
+
h_x = h_y;
|
|
118
|
+
h_y = h_xy;
|
|
65
119
|
end
|
|
120
|
+
|
|
121
|
+
h_x_p = (h_x<0) ? 1 : 0;
|
|
122
|
+
h_y_p = (h_y<0) ? 1 : 0;
|
|
123
|
+
h_x_abs = ((h_x).abs * 2 + h_x_p).to_f;
|
|
124
|
+
h_y_abs = ((h_y).abs * 2 + h_y_p).to_f;
|
|
125
|
+
h_x_10000 = ((h_x_abs%777600000)/12960000).floor;
|
|
126
|
+
h_x_1000 = ((h_x_abs%12960000)/216000).floor;
|
|
127
|
+
h_x_100 = ((h_x_abs%216000)/3600).floor;
|
|
128
|
+
h_x_10 = ((h_x_abs%3600)/60).floor;
|
|
129
|
+
h_x_1 = ((h_x_abs%3600)%60).floor;
|
|
130
|
+
h_y_10000 = ((h_y_abs%77600000)/12960000).floor;
|
|
131
|
+
h_y_1000 = ((h_y_abs%12960000)/216000).floor;
|
|
132
|
+
h_y_100 = ((h_y_abs%216000)/3600).floor;
|
|
133
|
+
h_y_10 = ((h_y_abs%3600)/60).floor;
|
|
134
|
+
h_y_1 = ((h_y_abs%3600)%60).floor;
|
|
135
|
+
h_code = H_KEY[level % 60, 1];
|
|
136
|
+
h_code += H_KEY[h_x_10000, 1]+H_KEY[h_y_10000, 1] if(h_max >=12960000/2) ;
|
|
137
|
+
h_code += H_KEY[h_x_1000, 1]+H_KEY[h_y_1000, 1] if(h_max >=216000/2) ;
|
|
138
|
+
h_code += H_KEY[h_x_100, 1]+H_KEY[h_y_100, 1] if(h_max >=3600/2) ;
|
|
139
|
+
h_code += H_KEY[h_x_10, 1]+H_KEY[h_y_10, 1] if(h_max >=60/2) ;
|
|
140
|
+
h_code += H_KEY[h_x_1, 1]+H_KEY[h_y_1, 1];
|
|
141
|
+
|
|
142
|
+
return h_code;
|
|
66
143
|
end
|
|
67
|
-
return self.__hyhx2geohex( h_y, h_x, level )
|
|
68
|
-
end
|
|
69
144
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
145
|
+
# geohex to latlon
|
|
146
|
+
def self.decode(code)
|
|
147
|
+
c_length = code.length;
|
|
148
|
+
level = H_KEY.index(code[0,1]);
|
|
149
|
+
scl = level;
|
|
150
|
+
h_size = self.calcHexSize(level);
|
|
151
|
+
unit_x = 6.0 * h_size;
|
|
152
|
+
unit_y = 6.0 * h_size * H_K;
|
|
153
|
+
h_max = (H_BASE / unit_x + H_BASE / unit_y).round;
|
|
154
|
+
h_x = 0;
|
|
155
|
+
h_y = 0;
|
|
156
|
+
|
|
157
|
+
if (h_max >= 12960000 / 2)
|
|
158
|
+
h_x = H_KEY.index(code[1,1]) * 12960000 +
|
|
159
|
+
H_KEY.index(code[3,1]) * 216000 +
|
|
160
|
+
H_KEY.index(code[5,1]) * 3600 +
|
|
161
|
+
H_KEY.index(code[7,1]) * 60 +
|
|
162
|
+
H_KEY.index(code[9,1]);
|
|
163
|
+
h_y = H_KEY.index(code[2,1]) * 12960000 +
|
|
164
|
+
H_KEY.index(code[4,1]) * 216000 +
|
|
165
|
+
H_KEY.index(code[6,1]) * 3600 +
|
|
166
|
+
H_KEY.index(code[8,1]) * 60 +
|
|
167
|
+
H_KEY.index(code[10,1]);
|
|
168
|
+
elsif (h_max >= 216000 / 2)
|
|
169
|
+
h_x = H_KEY.index(code[1,1]) * 216000 +
|
|
170
|
+
H_KEY.index(code[3,1]) * 3600 +
|
|
171
|
+
H_KEY.index(code[5,1]) * 60 +
|
|
172
|
+
H_KEY.index(code[7,1]);
|
|
173
|
+
h_y = H_KEY.index(code[2,1]) * 216000 +
|
|
174
|
+
H_KEY.index(code[4,1]) * 3600 +
|
|
175
|
+
H_KEY.index(code[6,1]) * 60 +
|
|
176
|
+
H_KEY.index(code[8,1]);
|
|
177
|
+
elsif (h_max >= 3600 / 2)
|
|
178
|
+
h_x = H_KEY.index(code[1,1]) * 3600 +
|
|
179
|
+
H_KEY.index(code[3,1]) * 60 +
|
|
180
|
+
H_KEY.index(code[5,1]);
|
|
181
|
+
h_y = H_KEY.index(code[2,1]) * 3600 +
|
|
182
|
+
H_KEY.index(code[4,1]) * 60 +
|
|
183
|
+
H_KEY.index(code[6,1]);
|
|
184
|
+
elsif (h_max >= 60 / 2)
|
|
185
|
+
h_x = H_KEY.index(code[1,1]) * 60 +
|
|
186
|
+
H_KEY.index(code[3,1]);
|
|
187
|
+
h_y = H_KEY.index(code[2,1]) * 60 +
|
|
188
|
+
H_KEY.index(code[4,1]);
|
|
189
|
+
else
|
|
190
|
+
h_x = H_KEY.index(code[1,1]);
|
|
191
|
+
h_y = H_KEY.index(code[2,1]);
|
|
192
|
+
end
|
|
193
|
+
h_x = (h_x % 2 == 1) ? -(h_x - 1) / 2 : h_x / 2;
|
|
194
|
+
h_y = (h_y % 2 == 1) ? -(h_y - 1) / 2 : h_y / 2;
|
|
83
195
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
h_x = h_x.to_f
|
|
87
|
-
h_y = h_y.to_f
|
|
88
|
-
h_x_100 = ( h_x / 3600).floor
|
|
89
|
-
h_x_10 = ((h_x % 3600) / 60).floor
|
|
90
|
-
h_x_1 = ((h_x % 3600) % 60).floor
|
|
91
|
-
h_y_100 = ( h_y / 3600).floor
|
|
92
|
-
h_y_10 = ((h_y % 3600) / 60).floor
|
|
93
|
-
h_y_1 = ((h_y % 3600) % 60).floor
|
|
94
|
-
|
|
95
|
-
code = nil
|
|
196
|
+
h_lat_y = (H_K * h_x * unit_x + h_y * unit_y) / 2;
|
|
197
|
+
h_lon_x = (h_lat_y - h_y * unit_y) / H_K;
|
|
96
198
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
H_KEY[ h_x_10,1 ] + H_KEY[ h_y_10,1 ] + H_KEY[ h_x_1,1 ] + H_KEY[ h_y_1,1 ]
|
|
100
|
-
elsif ( level == 7 )
|
|
101
|
-
code = H_KEY[ h_x_10,1 ] + H_KEY[ h_y_10,1 ] + H_KEY[ h_x_1,1 ] + H_KEY[ h_y_1,1 ]
|
|
102
|
-
else
|
|
103
|
-
code = H_KEY[ level % 60, 1 ] + H_KEY[ h_x_10,1 ] + H_KEY[ h_y_10,1 ] + H_KEY[ h_x_1,1 ] + H_KEY[ h_y_1,1 ]
|
|
199
|
+
h_loc = xy2loc(h_lon_x, h_lat_y);
|
|
200
|
+
return [h_loc.lat, h_loc.lon, level]
|
|
104
201
|
end
|
|
105
|
-
return code
|
|
106
202
|
end
|
|
107
|
-
|
|
108
|
-
def self.__geohex2hyhx (hexcode)
|
|
109
|
-
|
|
110
|
-
level, c_length, code = __geohex2level( hexcode )
|
|
111
|
-
|
|
112
|
-
unit_x = 6.0 * level * H_SIZE
|
|
113
|
-
unit_y = 2.8 * level * H_SIZE
|
|
114
|
-
h_k = ( ( ( 1.4 / 3 ) * H_GRID ).round.to_f ) / H_GRID
|
|
115
|
-
base_x = ( ( MIN_X_LON + MIN_X_LAT / h_k ) / unit_x ).floor.to_f
|
|
116
|
-
base_y = ( ( MIN_Y_LAT - h_k * MIN_Y_LON ) / unit_y ).floor.to_f
|
|
117
|
-
|
|
118
|
-
if ( c_length > 5 )
|
|
119
|
-
h_x = H_KEY.index(code[0]) * 3600 + H_KEY.index(code[2]) * 60 + H_KEY.index(code[4])
|
|
120
|
-
h_y = H_KEY.index(code[1]) * 3600 + H_KEY.index(code[3]) * 60 + H_KEY.index(code[5])
|
|
121
|
-
else
|
|
122
|
-
h_x = H_KEY.index(code[0]) * 60 + H_KEY.index(code[2])
|
|
123
|
-
h_y = H_KEY.index(code[1]) * 60 + H_KEY.index(code[3])
|
|
124
|
-
end
|
|
125
203
|
|
|
126
|
-
|
|
204
|
+
def loc2xy(_lon,_lat)
|
|
205
|
+
x=_lon*H_BASE/180;
|
|
206
|
+
y= Math.log(Math.tan((90+_lat)*Math::PI/360)) / (Math::PI / 180 );
|
|
207
|
+
y= y * H_BASE / 180;
|
|
208
|
+
return OpenStruct.new("x"=>x, "y"=>y);
|
|
127
209
|
end
|
|
128
|
-
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
level = H_KEY.index( code.shift )
|
|
135
|
-
raise 'Code format is something wrong' if ( level == -1 )
|
|
136
|
-
level = 60 if ( level == 0 )
|
|
137
|
-
else
|
|
138
|
-
level = 7
|
|
139
|
-
end
|
|
140
|
-
return level, c_length, code
|
|
210
|
+
|
|
211
|
+
def xy2loc(_x,_y)
|
|
212
|
+
lon=(_x/H_BASE)*180;
|
|
213
|
+
lat=(_y/H_BASE)*180;
|
|
214
|
+
lat=180.0/Math::PI*(2.0*Math.atan(Math.exp(lat*Math::PI/180))-Math::PI/2);
|
|
215
|
+
return OpenStruct.new("lon" => lon,"lat" => lat);
|
|
141
216
|
end
|
|
142
217
|
end
|
data/spec/geohex_spec.rb
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
1
|
require "#{File.dirname(__FILE__)}/../lib/geohex.rb"
|
|
2
|
+
require "pp"
|
|
3
|
+
include GeoHex
|
|
2
4
|
|
|
3
5
|
describe GeoHex do
|
|
4
6
|
before(:all) do
|
|
5
|
-
@
|
|
6
|
-
@
|
|
7
|
+
@test_ll2hex = []
|
|
8
|
+
@test_hex2ll = []
|
|
9
|
+
File.open("#{File.dirname(__FILE__)}/testdata_ll2hex.txt").read.each_line do |l|
|
|
10
|
+
if l.slice(0,1) != "#"
|
|
11
|
+
d = l.strip.split(',')
|
|
12
|
+
@test_ll2hex << [d[0].to_f, d[1].to_f, d[2].to_i, d[3]]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
File.open("#{File.dirname(__FILE__)}/testdata_hex2ll.txt").read.each_line do |l|
|
|
16
|
+
if l.slice(0,1) != "#"
|
|
17
|
+
d = l.strip.split(',')
|
|
18
|
+
@test_hex2ll << [d[0],d[1].to_f, d[2].to_f,d[3].to_i]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
7
21
|
end
|
|
8
22
|
|
|
9
23
|
it "should throw error if parameters is not valid" do
|
|
10
|
-
lambda { GeoHex.encode() }.should raise_error(ArgumentError) # no parameters
|
|
11
|
-
lambda { GeoHex.encode(-
|
|
12
|
-
lambda { GeoHex.encode(
|
|
13
|
-
lambda { GeoHex.encode(
|
|
14
|
-
lambda { GeoHex.encode(-
|
|
15
|
-
lambda { GeoHex.encode(0,180
|
|
16
|
-
lambda { GeoHex.encode(0,-180,
|
|
24
|
+
lambda { GeoHex::Zone.encode() }.should raise_error(ArgumentError) # no parameters
|
|
25
|
+
lambda { GeoHex::Zone.encode(-86,100,0) }.should raise_error(ArgumentError) # invalid latitude
|
|
26
|
+
lambda { GeoHex::Zone.encode(86,100,0) }.should raise_error(ArgumentError) # invalid latitude
|
|
27
|
+
lambda { GeoHex::Zone.encode(85,181,0) }.should raise_error(ArgumentError) # invalid longitude
|
|
28
|
+
lambda { GeoHex::Zone.encode(-85,-181,0) }.should raise_error(ArgumentError) # invalid longitude
|
|
29
|
+
lambda { GeoHex::Zone.encode(0,180,-1) }.should raise_error(ArgumentError) # invalid level
|
|
30
|
+
lambda { GeoHex::Zone.encode(0,-180,25) }.should raise_error(ArgumentError) # invalid level
|
|
17
31
|
end
|
|
18
32
|
it "should convert coordinates to geohex code" do
|
|
19
|
-
# simple test
|
|
20
|
-
GeoHex.encode(35.647401,139.716911,1).should == '132KpuG'
|
|
21
|
-
GeoHex.encode(24.340565,124.156201,42).should == 'G028k'
|
|
22
|
-
|
|
23
33
|
# correct answers (you can obtain this test variables from jsver_test.html )
|
|
24
|
-
@
|
|
25
|
-
GeoHex.encode(v[0],v[1],v[2]).should ==
|
|
34
|
+
@test_ll2hex.each do |v|
|
|
35
|
+
GeoHex::Zone.encode(v[0],v[1],v[2]).should == v[3]
|
|
26
36
|
end
|
|
27
37
|
|
|
28
38
|
end
|
|
29
39
|
it "should convert geohex to coordinates " do
|
|
30
|
-
# simple test
|
|
31
|
-
GeoHex.decode('132KpuG').should == [35.6478085,139.7173629550321,1]
|
|
32
|
-
GeoHex.decode('70dMV').should == [24.338279000000004,124.1577708779443,7]
|
|
33
|
-
GeoHex.decode('0dMV').should == [24.338279000000004,124.1577708779443,7]
|
|
34
|
-
|
|
35
40
|
# correct answers (you can obtain this test variables from jsver_test.html )
|
|
36
|
-
@
|
|
37
|
-
GeoHex.decode(
|
|
41
|
+
@test_hex2ll.each do |v|
|
|
42
|
+
GeoHex::Zone.decode(v[0]).should == [v[1],v[2],v[3]]
|
|
38
43
|
end
|
|
39
|
-
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
it "should return instance from coordinates " do
|
|
43
|
-
GeoHex.new(35.647401,139.716911,
|
|
44
|
-
GeoHex.new(35.647401,139.716911,60).code.should == '032Lq'
|
|
47
|
+
GeoHex::Zone.new(35.647401,139.716911,12).code.should == 'mbas1eT'
|
|
45
48
|
end
|
|
46
49
|
|
|
47
50
|
it "should raise error if instancing with nil data " do
|
|
48
|
-
lambda { GeoHex.new }.should raise_error(ArgumentError)
|
|
51
|
+
lambda { GeoHex::Zone.new }.should raise_error(ArgumentError)
|
|
49
52
|
end
|
|
50
|
-
it "should return instance from hexcode " do
|
|
51
|
-
geohex = GeoHex.new('132KpuG')
|
|
52
|
-
geohex.lat.should == 35.6478085
|
|
53
|
-
geohex.lon.should == 139.7173629550321
|
|
54
|
-
geohex.level.should == 1
|
|
55
|
-
|
|
56
|
-
geohex = GeoHex.new('0016C')
|
|
57
|
-
geohex.lat.should == 24.305370000000003
|
|
58
|
-
geohex.lon.should == 124.17423982869379
|
|
59
|
-
geohex.level.should == 60
|
|
60
53
|
|
|
54
|
+
it "should return instance from hexcode " do
|
|
55
|
+
geohex = GeoHex::Zone.new('wwhnTzSWp')
|
|
56
|
+
geohex.lat.should == 35.685262361266446
|
|
57
|
+
geohex.lon.should == 139.76695060729983
|
|
58
|
+
geohex.level.should == 22
|
|
61
59
|
end
|
|
62
60
|
end
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
metadata
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: geohex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
4
|
+
hash: 15
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 2
|
|
8
|
+
- 0
|
|
9
|
+
- 0
|
|
10
|
+
version: 2.0.0
|
|
5
11
|
platform: ruby
|
|
6
12
|
authors:
|
|
7
13
|
- hal_sk
|
|
@@ -9,19 +15,41 @@ autorequire:
|
|
|
9
15
|
bindir: bin
|
|
10
16
|
cert_chain: []
|
|
11
17
|
|
|
12
|
-
date:
|
|
18
|
+
date: 2010-10-08 00:00:00 +09:00
|
|
13
19
|
default_executable:
|
|
14
20
|
dependencies:
|
|
15
21
|
- !ruby/object:Gem::Dependency
|
|
16
|
-
name:
|
|
22
|
+
name: rubyforge
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 7
|
|
30
|
+
segments:
|
|
31
|
+
- 2
|
|
32
|
+
- 0
|
|
33
|
+
- 4
|
|
34
|
+
version: 2.0.4
|
|
17
35
|
type: :development
|
|
18
|
-
|
|
19
|
-
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: hoe
|
|
39
|
+
prerelease: false
|
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
20
42
|
requirements:
|
|
21
43
|
- - ">="
|
|
22
44
|
- !ruby/object:Gem::Version
|
|
23
|
-
|
|
24
|
-
|
|
45
|
+
hash: 19
|
|
46
|
+
segments:
|
|
47
|
+
- 2
|
|
48
|
+
- 6
|
|
49
|
+
- 2
|
|
50
|
+
version: 2.6.2
|
|
51
|
+
type: :development
|
|
52
|
+
version_requirements: *id002
|
|
25
53
|
description: |-
|
|
26
54
|
This GeoHex Ruby gem can convert latitude/longitude to GeoHex code each others.
|
|
27
55
|
* Encode from latitude/longitude to GeoHex code to an arbitrary level of precision
|
|
@@ -54,21 +82,27 @@ rdoc_options:
|
|
|
54
82
|
require_paths:
|
|
55
83
|
- lib
|
|
56
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
|
+
none: false
|
|
57
86
|
requirements:
|
|
58
87
|
- - ">="
|
|
59
88
|
- !ruby/object:Gem::Version
|
|
89
|
+
hash: 3
|
|
90
|
+
segments:
|
|
91
|
+
- 0
|
|
60
92
|
version: "0"
|
|
61
|
-
version:
|
|
62
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
|
+
none: false
|
|
63
95
|
requirements:
|
|
64
96
|
- - ">="
|
|
65
97
|
- !ruby/object:Gem::Version
|
|
98
|
+
hash: 3
|
|
99
|
+
segments:
|
|
100
|
+
- 0
|
|
66
101
|
version: "0"
|
|
67
|
-
version:
|
|
68
102
|
requirements: []
|
|
69
103
|
|
|
70
104
|
rubyforge_project: geohex
|
|
71
|
-
rubygems_version: 1.3.
|
|
105
|
+
rubygems_version: 1.3.7
|
|
72
106
|
signing_key:
|
|
73
107
|
specification_version: 3
|
|
74
108
|
summary: This GeoHex Ruby gem can convert latitude/longitude to GeoHex code each others
|