Module: DX::Grid

Defined in:
lib/dx/grid.rb,
lib/dx/grid/version.rb

Constant Summary collapse

VERSION =
"1.0.0"

Class Method Summary collapse

Class Method Details

.decode(grid) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/dx/grid.rb', line 49

def self.decode(grid)
  grid = grid.to_s
  validate_grid!(grid)

  lon = -180
  lat = -90
  
  ord0 = grid[0].upcase.ord - 'A'.ord
  ord1 = grid[1].upcase.ord - 'A'.ord
  ord2 = grid[2].to_i
  ord3 = grid[3].to_i
  
  lon += (360.0 / 18.0) * ord0 + (360.0 / 18.0 / 10.0) * ord2
  lat += (180.0 / 18.0) * ord1 + (180.0 / 18.0 / 10.0) * ord3
  
  if grid.length == 4
    lon += (360.0 / 18.0 / 10.0 / 2.0)
    lat += (180.0 / 18.0 / 10.0 / 2.0)
  else
    ord4 = grid[4].downcase.ord - 'a'.ord
    ord5 = grid[5].downcase.ord - 'a'.ord
    
    lon += (360.0 / 18.0 / 10.0 / 24.0) * (ord4 + 0.5)
    lat += (180.0 / 18.0 / 10.0 / 24.0) * (ord5 + 0.5)
  end
  
  return [lat, lon]
end

.encode(coord, options = {}) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/dx/grid.rb', line 5

def self.encode(coord, options={})
  length = options[:length] || 4
  validate_grid_length!(length)
  validate_coord!(coord)

  lat, lon = coord[0], coord[1]
  grid = ''

  # Normalize from (-90, -180) to (0, 0)
  lon = lon + 180.0
  lat = lat + 90.0

  # Map lon from 0 to 17 (A to R)
  lon_index = (lon / 20.0).to_i
  lat_index = (lat / 10.0).to_i

  # Convert to characters
  grid += "#{('A'.ord + lon_index).chr}#{('A'.ord + lat_index).chr}"

  lon -= lon_index * 20.0 # 20 degrees lon per grid
  lat -= lat_index * 10.0 # 10 degrees lat per grid

  # Map from 0 to 9
  lon_index = (lon / 2.0).to_i
  lat_index = lat.to_i

  grid += "#{lon_index}#{lat_index}"

  # Do the long grid if desired
  if length == 6
    lon -= lon_index * 2.0 # Now 2 degrees lon per grid remaining
    lat -= lat_index       # Now 1 degree lon per grid remaining

    # Map from 0 to 23 (a to x)
    lon_index = (lon / (2.0 / 24.0)).to_i
    lat_index = (lat / (1.0 / 24.0)).to_i

    # Convert to characters
    grid += "#{('a'.ord + lon_index).chr}#{('a'.ord + lat_index).chr}"
  end

  grid
end

.valid?(str) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
81
82
83
84
85
86
87
88
# File 'lib/dx/grid.rb', line 78

def self.valid?(str)
  str = str.to_s

  if str.length == 4
    return str.match(/[A-R]{2}[0-9]{2}/i)
  elsif str.length == 6
    return str.match(/[A-R]{2}[0-9]{2}[A-X]{2}/i)
  end

  false
end