class SoraGeocoding::Geohash

generate Geohash

Constants

BASE32
REFINED_RANGE

Public Class Methods

new(lat, lon) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 13
def initialize(lat, lon)
  @lat = lat.to_s
  @lon = lon.to_s
end

Public Instance Methods

encode() click to toggle source
# File lib/sora_geocoding/geohash.rb, line 18
def encode
  calc_geohash(
    convert_byte(@lat, REFINED_RANGE[0][0], REFINED_RANGE[0][1], range(@lat)),
    convert_byte(@lon, REFINED_RANGE[1][0], REFINED_RANGE[1][1], range(@lon))
  )
end

Private Instance Methods

calc_bit(val, mid) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 65
def calc_bit(val, mid)
  val.to_f > mid ? 1 : 0
end
calc_geohash(lat, lon) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 69
def calc_geohash(lat, lon)
  bytes = split_bits(lat, lon)
  bytes[-1] = bytes[-1].ljust(5, '0')
  bytes.map { |v| BASE32[convert_to_decimal(v), 1] }.join
end
calc_mid(min, max) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 61
def calc_mid(min, max)
  (min + max).to_f / 2
end
calc_range(size) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 36
def calc_range(size)
  10**size
end
calc_size(val) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 40
def calc_size(val)
  val.to_s.split('.')[-1].size * -1
end
convert_byte(val, min, max, range) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 44
def convert_byte(val, min, max, range)
  bits = []
  while (min - max).abs > range
    mid = calc_mid(min, max)
    bit = calc_bit(val, mid)

    if bit.zero?
      max = mid
    else
      min = mid
    end

    bits.push bit
  end
  bits.join
end
convert_to_decimal(val) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 84
def convert_to_decimal(val)
  "0b#{val}".to_i(0)
end
integrate_bits(odd_bit, even_bit) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 75
def integrate_bits(odd_bit, even_bit)
  even_bit.chars.zip(odd_bit.chars).flatten.join
end
max_range(range) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 32
def max_range(range)
  [range, calc_range(-6)].max
end
range(val) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 26
def range(val)
  size = calc_size(val)
  range = calc_range(size)
  max_range(range)
end
split_bits(odd_bit, even_bit) click to toggle source
# File lib/sora_geocoding/geohash.rb, line 79
def split_bits(odd_bit, even_bit)
  bytes = integrate_bits(odd_bit, even_bit)
  bytes.chars.each_slice(5).map(&:join)
end