Module: GeohashInt

Defined in:
lib/geohash_int.rb,
lib/geohash_int/ffi.rb,
lib/geohash_int/version.rb

Overview

The GeohashInt provides methods to encode and decode geographic coordinates using the geohash algorithm, but instead of returning a string, an integer (Fixnum) is returned.

See also:

- https://en.wikipedia.org/wiki/Geohash
- https://github.com/yinqiwen/geohash-int
- https://github.com/yinqiwen/ardb/wiki/Spatial-Index

Defined Under Namespace

Modules: FFI Classes: BoundingBox, Neighbors

Constant Summary collapse

LAT_RANGE =
GeohashInt::FFI::Range.new.tap do |range|
  range[:min] = -90.0
  range[:max] =  90.0
end
LNG_RANGE =

:nodoc:

GeohashInt::FFI::Range.new.tap do |range|
  range[:min] = -180.0
  range[:max] =  180.0
end
NORTH =

:nodoc:

0
EAST =
1
WEST =
2
SOUTH =
3
SOUTH_WEST =
4
SOUTH_EAST =
5
NORTH_WEST =
6
NORTH_EAST =
7
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.decode(value, steps) ⇒ Object

Decodes a previously encoded value. The given steps must be the same as the one given in #encode to generate value.

Returns a BoundingBox where the original coordinate falls (the Geohash algorithm is lossy), where ‘latitude` and `longitude` of that bounding box are its center.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/geohash_int.rb', line 78

def decode(value, steps)
  bits = new_bits(value, steps)
  area = GeohashInt::FFI::Area.new

  # This will always return 0 because the only condition for it
  # returning something else is when area is NULL, but we are
  # not passing NULL.
  GeohashInt::FFI.geohash_fast_decode(LAT_RANGE, LNG_RANGE, bits, area)

  lat_range = area[:latitude]
  lng_range = area[:longitude]

  lat = (lat_range[:max] + lat_range[:min]) / 2
  lng = (lng_range[:max] + lng_range[:min]) / 2

  BoundingBox.new(
    lat, lng,
    lat_range[:min], lat_range[:max],
    lng_range[:min], lng_range[:max],
  )
end

.encode(latitude, longitude, steps) ⇒ Object

Encodes a coordinate by splitting the world map the given number of steps (1..32).

Returns the encoded value as an integer (Fixnum). To correctly decode this value back into a coordinate you must pass the same steps to #decode.

To learn more about the steps argument, read this explanation in the Readme file: github.com/TheoremOne/ruby-geohash_int/blob/master/README.md#explanation



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/geohash_int.rb', line 58

def encode(latitude, longitude, steps)
  bits = GeohashInt::FFI::Bits.new

  result = GeohashInt::FFI.geohash_fast_encode(LAT_RANGE, LNG_RANGE,
                                               latitude, longitude,
                                               steps, bits)
  if result == 0
    bits[:bits]
  else
    raise ArgumentError.new("Incorrect value for latitude (#{latitude}), " \
                            "longitude (#{longitude}) or steps (#{steps})")
  end
end

.get_neighbor(value, direction, steps) ⇒ Object

Gets a neighbor of an encoded value.

  • direction must be one of this module’s constants ( NORTH, EAST, etc. ).

  • steps must be the same as the one used in #encode to generate value.



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/geohash_int.rb', line 104

def get_neighbor(value, direction, steps)
  bits     = new_bits(value, steps)
  neighbor = GeohashInt::FFI::Bits.new

  result = GeohashInt::FFI.geohash_get_neighbor(bits, direction, neighbor)
  if result == 0
    neighbor[:bits]
  else
    raise ArgumentError.new("Incorrect value for direction (#{direction})")
  end
end

.get_neighbors(value, steps) ⇒ Object

Gets all neighbors of an encoded value.

  • steps must be the same as the one used in ‘encode` to generate value.

Returns a Neighbors instance.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/geohash_int.rb', line 121

def get_neighbors(value, steps)
  bits      = new_bits(value, steps)
  neighbors = GeohashInt::FFI::Neighbors.new

  # This function never fails
  GeohashInt::FFI.geohash_get_neighbors(bits, neighbors)

  Neighbors.new(
    neighbors[:north     ][:bits],
    neighbors[:east      ][:bits],
    neighbors[:west      ][:bits],
    neighbors[:south     ][:bits],
    neighbors[:south_west][:bits],
    neighbors[:south_east][:bits],
    neighbors[:north_west][:bits],
    neighbors[:north_east][:bits],
  )
end