geohex 1.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.
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2009-11-19
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/geohex.rb
6
+ spec/geohex_spec.rb
@@ -0,0 +1,69 @@
1
+ = geohex
2
+
3
+ * http://geohex.rubyforge.org/
4
+
5
+ ## GEOHEX DESCRIPTION
6
+ GeoHex Gem for Ruby (c) 2009 Haruyuki Seki
7
+ http://twitter.com/hal_sk_e (en)
8
+ http://twitter.com/hal_sk (ja)
9
+
10
+ * The GeoHex is a latitude/longitude encoding system invented by sa2da.
11
+ * GeoHex divides geometry regions into hexagonal grid and set an unique identifier to each grid. It supports only Japan region so far.
12
+ * The coding idea is opened under the Creative Commons Attribution 2.1 Japan Lisence.
13
+ * GeoHex Documentation: http://github.com/geohex/geohex-docs
14
+ * GeoHex Original Wiki(Japanese): http://geogames.net/labs/geohex
15
+ * GeoHex Demo: http://geogames.net/hex/
16
+ * Various GeoHex Libraries: http://github.com/geohex/
17
+
18
+ ## GEOHEX GEM DESCRIPTION
19
+
20
+ This GeoHex Ruby gem can convert latitude/longitude to GeoHex code each others.
21
+ * Encode from latitude/longitude to GeoHex code to an arbitrary level of precision
22
+ * Decode from GeoHex code to latitude/longitude and level of precision
23
+
24
+ ## INSTALL
25
+
26
+ sudo gem install geohex
27
+
28
+ ## QUICK START
29
+
30
+ require 'geohex'
31
+ GeoHex.encode(35.647401,139.716911,1)
32
+ => '132KpuG'
33
+ GeoHex.decode('0dMV')
34
+ => [24.338279000000004,124.1577708779443,7]
35
+
36
+ ## FEATURES
37
+
38
+ require 'geohex'
39
+ geohex = GeoHex.new(35.647401,139.716911,1)
40
+ geohex.code
41
+ => '132KpuG'
42
+ geohex = GeoHex.decode('0dMV')
43
+ geohex.lat
44
+ => 24.338279000000004
45
+
46
+ ## LICENSE
47
+
48
+ (The MIT License)
49
+
50
+ Copyright (c) 2008 David Troy, Roundhouse Technologies LLC
51
+
52
+ Permission is hereby granted, free of charge, to any person obtaining
53
+ a copy of this software and associated documentation files (the
54
+ 'Software'), to deal in the Software without restriction, including
55
+ without limitation the rights to use, copy, modify, merge, publish,
56
+ distribute, sublicense, and/or sell copies of the Software, and to
57
+ permit persons to whom the Software is furnished to do so, subject to
58
+ the following conditions:
59
+
60
+ The above copyright notice and this permission notice shall be
61
+ included in all copies or substantial portions of the Software.
62
+
63
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
64
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
65
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
66
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
67
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
68
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
69
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.spec 'geohex' do
7
+ developer('hal_sk', 'hal.marsellus@gmail.com')
8
+
9
+ # self.rubyforge_name = 'geohexx' # if different than 'geohex'
10
+ end
11
+
12
+ # vim: syntax=ruby
@@ -0,0 +1,142 @@
1
+ #
2
+ # ported from perl libraries http://svn.coderepos.org/share/lang/perl/Geo-Hex/trunk/lib/Geo/Hex.pm
3
+ # author Haruyuki Seki
4
+ #
5
+ class GeoHex
6
+ VERSION = '1.0.0'
7
+
8
+ H_KEY = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX'
9
+
10
+ MIN_X_LON = 122930.0 #与那国島
11
+ MIN_X_LAT = 24448.0
12
+ MIN_Y_LON = 141470.0 ##南硫黄島
13
+ MIN_Y_LAT = 24228.0
14
+ H_GRID = 1000
15
+ H_SIZE = 0.5
16
+
17
+ attr_accessor :code, :lat, :lon, :level
18
+
19
+ def initialize(*params)
20
+ if params.first.is_a?(Float)
21
+ @lat,@lon = params[0],params[1]
22
+ @level= params[2]||7
23
+ @code = GeoHex.encode(@lat,@lon,@level)
24
+ else
25
+ @code = params.first
26
+ @lat,@lon,@level=GeoHex.decode(@code)
27
+ 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
+
37
+ lon_grid = lon * H_GRID
38
+ lat_grid = lat * H_GRID
39
+ unit_x = 6.0 * level * H_SIZE
40
+ unit_y = 2.8 * level * H_SIZE
41
+ h_k = (( (1.4 / 3) * H_GRID).round.to_f / H_GRID)
42
+
43
+ base_x = ( (MIN_X_LON + MIN_X_LAT / h_k ) / unit_x).floor.to_f
44
+ base_y = ( (MIN_Y_LAT - h_k * MIN_Y_LON) / unit_y).floor.to_f
45
+ h_pos_x = ( lon_grid + lat_grid / h_k ) / unit_x - base_x
46
+ h_pos_y = ( lat_grid - h_k * lon_grid) / unit_y - base_y
47
+ h_x_0 = h_pos_x.floor
48
+ h_y_0 = h_pos_y.floor
49
+ h_x_q = ((h_pos_x - h_x_0) * 100).floor.to_f / 100
50
+ h_y_q = ((h_pos_y - h_y_0) * 100).floor.to_f / 100
51
+ h_x = h_pos_x.round
52
+ h_y = h_pos_y.round
53
+
54
+
55
+ if ( h_y_q > -h_x_q + 1 )
56
+
57
+ if ( h_y_q < (2 * h_x_q ) and h_y_q > (0.5 * h_x_q ) )
58
+ h_x = h_x_0 + 1
59
+ h_y = h_y_0 + 1
60
+ end
61
+ elsif ( h_y_q < -h_x_q + 1 )
62
+ if( (h_y_q > (2 * h_x_q ) - 1 ) && ( h_y_q < ( 0.5 * h_x_q ) + 0.5 ) )
63
+ h_x = h_x_0
64
+ h_y = h_y_0
65
+ end
66
+ end
67
+ return self.__hyhx2geohex( h_y, h_x, level )
68
+ end
69
+
70
+ # geohex to latlon
71
+ def self.decode(code)
72
+ h_y, h_x, level, unit_x, unit_y, h_k, base_x, base_y = self.__geohex2hyhx( code )
73
+
74
+ h_lat = ( h_k * ( h_x + base_x ) * unit_x + ( h_y + base_y ) * unit_y ) / 2
75
+ h_lon = ( h_lat - ( h_y + base_y ) * unit_y ) / h_k
76
+ lat = h_lat / H_GRID
77
+ lon = h_lon / H_GRID
78
+
79
+ return lat, lon, level
80
+ end
81
+
82
+
83
+
84
+ private
85
+ def self.__hyhx2geohex(h_y,h_x,level)
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
96
+
97
+ if ( level < 7 )
98
+ code = H_KEY[ level % 60 ,1] + H_KEY[ h_x_100 ,1] + H_KEY[ h_y_100,1 ] +
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 ]
104
+ end
105
+ return code
106
+ 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
+
126
+ return h_y, h_x, level, unit_x, unit_y, h_k, base_x, base_y
127
+ end
128
+
129
+ def self.__geohex2level(hexcode)
130
+ code = hexcode.split(//)
131
+ c_length = code.size
132
+
133
+ if ( c_length > 4 )
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
141
+ end
142
+ end
@@ -0,0 +1,65 @@
1
+ require "#{File.dirname(__FILE__)}/../lib/geohex.rb"
2
+
3
+ describe GeoHex do
4
+ before(:all) do
5
+ @correct_ll2hex = eval('{' + File.open("#{File.dirname(__FILE__)}/testdata_ll2hex.txt").read + '}')
6
+ @correct_hex2ll = eval('{' + File.open("#{File.dirname(__FILE__)}/testdata_hex2ll.txt").read + '}')
7
+ end
8
+
9
+ it "should throw error if parameters is not valid" do
10
+ lambda { GeoHex.encode() }.should raise_error(ArgumentError) # no parameters
11
+ lambda { GeoHex.encode(-91,100,1) }.should raise_error(ArgumentError) # invalid latitude
12
+ lambda { GeoHex.encode(91,100,1) }.should raise_error(ArgumentError) # invalid latitude
13
+ lambda { GeoHex.encode(90,181,1) }.should raise_error(ArgumentError) # invalid longitude
14
+ lambda { GeoHex.encode(-90,-181,1) }.should raise_error(ArgumentError) # invalid longitude
15
+ lambda { GeoHex.encode(0,180,0) }.should raise_error(ArgumentError) # invalid level
16
+ lambda { GeoHex.encode(0,-180,61) }.should raise_error(ArgumentError) # invalid level
17
+ end
18
+ 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
+ # correct answers (you can obtain this test variables from jsver_test.html )
24
+ @correct_ll2hex.each_pair do |k,v|
25
+ GeoHex.encode(v[0],v[1],v[2]).should == k
26
+ end
27
+
28
+ end
29
+ 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
+ # correct answers (you can obtain this test variables from jsver_test.html )
36
+ @correct_hex2ll.each_pair do |k,v|
37
+ GeoHex.decode(k).should == v
38
+ end
39
+
40
+ end
41
+
42
+ it "should return instance from coordinates " do
43
+ GeoHex.new(35.647401,139.716911,1).code.should == '132KpuG'
44
+ GeoHex.new(35.647401,139.716911,60).code.should == '032Lq'
45
+ end
46
+
47
+ it "should raise error if instancing with nil data " do
48
+ lambda { GeoHex.new }.should raise_error(ArgumentError)
49
+ 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
+
61
+ end
62
+ end
63
+
64
+
65
+
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geohex
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - hal_sk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-20 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.3.3
24
+ version:
25
+ description: |-
26
+ This GeoHex Ruby gem can convert latitude/longitude to GeoHex code each others.
27
+ * Encode from latitude/longitude to GeoHex code to an arbitrary level of precision
28
+ * Decode from GeoHex code to latitude/longitude and level of precision
29
+ email:
30
+ - hal.marsellus@gmail.com
31
+ executables: []
32
+
33
+ extensions: []
34
+
35
+ extra_rdoc_files:
36
+ - History.txt
37
+ - Manifest.txt
38
+ - README.txt
39
+ files:
40
+ - History.txt
41
+ - Manifest.txt
42
+ - README.txt
43
+ - Rakefile
44
+ - lib/geohex.rb
45
+ - spec/geohex_spec.rb
46
+ has_rdoc: true
47
+ homepage: http://geohex.rubyforge.org/
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --main
53
+ - README.txt
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: geohex
71
+ rubygems_version: 1.3.5
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: This GeoHex Ruby gem can convert latitude/longitude to GeoHex code each others
75
+ test_files: []
76
+