Module: Asari::Geography

Defined in:
lib/asari/geography.rb

Overview

Public: This module contains helper methods that serialize and deserialize latitudes and longitudes to store on Cloudsearch. For more information, see:

docs.aws.amazon.com/cloudsearch/latest/developerguide/geosearch.html

Constant Summary collapse

EARTH_RADIUS =
6367444
METERS_PER_DEGREE_OF_LATITUDE =
111133

Class Method Summary collapse

Class Method Details

.coordinate_box(options) ⇒ Object

Public: Calculates a range of integers to search within from a point and a distance in meters. This is used to search a certain distance from a point in Cloudsearch.

options - the options hash requires:
  meters: an Integer
  lat: a Float
  lng: a Float

Examples:

Asari::GeographyConversion.coordinate_box(lat: 25062714160, lng: 1112993466, miles: 5)
#=> {:lat=>25062714160, :lng=>1112993466}

Returns: a Hash containing :lat and :lng keys with Range values



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/asari/geography.rb', line 69

def coordinate_box(options)
  latitude = options[:lat]
  longitude = options[:lng]

  earth_radius_at_latitude = EARTH_RADIUS * Math.cos(latitude * ( Math::PI / 180 ))

  change_in_latitude = ( options[:meters].to_f / EARTH_RADIUS ) * ( 180 / Math::PI )
  change_in_longitude = ( options[:meters].to_f / earth_radius_at_latitude ) * ( 180 / Math::PI )

  bottom = latitude_to_int(latitude - change_in_latitude)
  top = latitude_to_int(latitude + change_in_latitude)
  if((latitude - change_in_latitude).abs < (latitude + change_in_latitude).abs)
    left = longitude_to_int(longitude - change_in_longitude, latitude - change_in_latitude)
    right = longitude_to_int(longitude + change_in_longitude, latitude - change_in_latitude)
  else
    left = longitude_to_int(longitude - change_in_longitude, latitude + change_in_latitude)
    right = longitude_to_int(longitude + change_in_longitude, latitude + change_in_latitude)
  end

  { lat: (bottom.round..top.round), lng: (left.round..right.round) }
end

.degrees_to_int(options) ⇒ Object

Public: Converts coordinates to unsigned integers that store up to two place values.

options - the options hash requires:
  lat: a Float
  lng: a Float

Examples:

Asari::GeographyConversion.degrees_to_int(45.52, 122.6819)
#=> {:lat=>25062714160, :lng=>1112993466}

Returns: a Hash containing :lat and :lng keys with Integer values



27
28
29
30
31
# File 'lib/asari/geography.rb', line 27

def degrees_to_int(options)
  latitude = latitude_to_int(options[:lat])
  longitude = longitude_to_int(options[:lng], options[:lat])
  { lat: latitude, lng: longitude }
end

.int_to_degrees(options) ⇒ Object

Public: Converts unsigned integers created with ‘degrees_to_int` back to the standard Geographic Coordinate System.

options - the options hash requires:
  lat: an Integer
  lng: an Integer

Examples:

Asari::GeographyConversion.int_to_degrees(lat: 25062714160, lng: 1112993466)
#=> {:lat=>45.52, :lng=>-122.682}

Returns: a Hash containing :lat and :lng keys with Float values



47
48
49
50
51
# File 'lib/asari/geography.rb', line 47

def int_to_degrees(options)
  latitude = latitude_to_degrees(options[:lat])
  longitude = longitude_to_degrees(options[:lng], latitude)
  { lat: latitude, lng: longitude }
end