Module: GeoHash
- Defined in:
- lib/geohash.rb
Constant Summary collapse
- VERSION =
'1.0.0'- BASE32 =
'0123456789bcdefghjkmnpqrstuvwxyz'- NEIGHBORS =
{ right: { even: 'bc01fg45238967deuvhjyznpkmstqrwx', odd: 'p0r21436x8zb9dcf5h7kjnmqesgutwvy', }, left: { even: '238967debc01fg45kmstqrwxuvhjyznp', odd: '14365h7k9dcfesgujnmqp0r2twvyx8zb', }, top: { even: 'p0r21436x8zb9dcf5h7kjnmqesgutwvy', odd: 'bc01fg45238967deuvhjyznpkmstqrwx', }, bottom: { even: '14365h7k9dcfesgujnmqp0r2twvyx8zb', odd: '238967debc01fg45kmstqrwxuvhjyznp', } }
- BORDERS =
{ right: { even: 'bcfguvyz', odd: 'prxz' }, left: { even: '0145hjnp', odd: '028b' }, top: { even: 'prxz', odd: 'bcfguvyz' }, bottom: { even: '028b', odd: '0145hjnp' }, }
- @@neighbors_cache =
{}
- @@adjacent_cache =
{ right: {}, left: {}, top: {}, bottom: {} }
Class Method Summary collapse
-
.adjacent(geohash, dir) ⇒ String
Calculate adjacent geohashes.
-
.decode(geohash) ⇒ [[Float]]
Decode geohash into bounding box of latitudes and longitudes.
-
.encode(latitude, longitude, precision = 12) ⇒ String
Encode latitude and longitude into geohash.
-
.neighbors(geohash) ⇒ [String]
Calculate neighbors geohash.
-
.walk(base, path) ⇒ [String]
Walk down.
Class Method Details
.adjacent(geohash, dir) ⇒ String
Calculate adjacent geohashes
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/geohash.rb', line 136 def adjacent(geohash, dir) return @@adjacent_cache[dir][geohash] if @@adjacent_cache[dir][geohash] head, last = geohash[0..-2], geohash[-1] type = [:even, :odd][geohash.length % 2] head = adjacent(head, dir) if BORDERS[dir][type].include?(last) # NOTICE: # do not use append `<<` instead of `+` # head possibly be cached so that mustn't be mutated, # just create new String instance with it head = head + BASE32[NEIGHBORS[dir][type].index(last)] @@adjacent_cache[dir][geohash] = head end |
.decode(geohash) ⇒ [[Float]]
Decode geohash into bounding box of latitudes and longitudes
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/geohash.rb', line 53 def decode(geohash) bounds = [[-90.0, +90.0], [-180.0, +180.0]] geohash.downcase.each_char.with_index do |c, i| d = BASE32.index c 5.times do |j| bit = (d & (1 << (4 - j))) >> (4 - j) k = (~i & 1) ^ (j & 1) bounds[k][bit ^ 1] = (bounds[k][0] + bounds[k][1]) / 2 end end bounds.transpose end |
.encode(latitude, longitude, precision = 12) ⇒ String
Encode latitude and longitude into geohash
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/geohash.rb', line 78 def encode(latitude, longitude, precision = 12) mids = [latitude, longitude] bounds = [[-90.0, +90.0], [-180.0, +180.0]] geohash = [] precision.times do |i| d = 0 5.times do |j| k = (~i & 1) ^ (j & 1) mid = (bounds[k][0] + bounds[k][1]) / 2 bit = mids[k] > mid ? 1 : 0 bounds[k][bit ^ 1] = mid d |= bit << (4 - j) end geohash << BASE32[d] end geohash.join end |
.neighbors(geohash) ⇒ [String]
Calculate neighbors geohash
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/geohash.rb', line 108 def neighbors(geohash) return @@neighbors_cache[geohash] if @@neighbors_cache[geohash] # walk path: # # 8 1 - 2 # | | | # 7 B 3 # | | # 6 - 5 - 4 # @@neighbors_cache[geohash] = walk geohash, [ :top, :right, :bottom, :bottom, :left, :left, :top, :top ] end |
.walk(base, path) ⇒ [String]
Walk down
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/geohash.rb', line 161 def walk(base, path) hashes = [] h = base path.each do |dir| hashes << (h = adjacent(h, dir)) end hashes end |