Module: Geo3x3

Defined in:
lib/geo3x3.rb,
lib/geo3x3/version.rb

Constant Summary collapse

VERSION =
"0.0.4"

Class Method Summary collapse

Class Method Details

.decode(code) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/geo3x3.rb', line 72

def self.decode(code)
  code =
    case code
    when Integer
      code.west_longitude? ? "W#{code}" : "E#{code}"
    when String
      raise ArgumentError if code.empty?
      code
    else
      raise ArgumentError
    end

  unit = 180.0
  lat = 0.0
  lng = 0.0
  level = 1

  code[1..-1].each_char do |c|
    break if c == "0"
    n = c.to_i

    unit /= 3
    n -= 1
    lng += (n % 3) * unit
    lat += (n / 3) * unit
    level += 1
  end

  lat += unit / 2
  lng += unit / 2
  lat = 90 - lat
  lng -= 180 if code.west_longitude?

  {
    lat:   lat,
    lng:   lng,
    level: level,
    unit:  unit
  }
end

.encode(*params) ⇒ Object

Raises:

  • (ArgumentError)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/geo3x3.rb', line 34

def self.encode(*params)
  if params.size == 3 && params.all? {|i| i.kind_of? Numeric}
    lat, lng, level = *params
    lat = lat.to_f
    lng = lng.to_f
  elsif params[0].kind_of? Hash
    lat = params[0][:lat].to_f
    lng = params[0][:lng].to_f
    level = params[0][:level]
  else
    raise ArgumentError
  end
  raise ArgumentError if level < 1

  code = 
    if lng.east_longitude?
      "E"
    else
      lng += 180
      "W"
    end

  lat = 90 - lat

  unit = 180.0 
  (level-1).times do
    unit /= 3
    x = (lng/unit).floor
    y = (lat/unit).floor
    code += ((x + y*3) + 1).to_s

    lng -= x * unit
    lat -= y * unit
  end

  code
end