class Reality::Geo::Coord

Keeps information about coordinates point. All services that are based on particular point in space (Weather, Time) depend on it. Many Entity types can have coordinates, they can be accessed as coord method which returns this class.

Example:

“`ruby Reality::Entity('Mississippi').coord # => #<Reality::Geo::Coord(33°0′0″N,90°0′0″W)> “`

Usage examples:

“`ruby coord = Reality::Geo::Coord.new(50.45, 30.52) # => #<Reality::Geo::Coord(50°27′0″N,30°31′24″E)> coord.sunrise # => 2016-03-31 03:35:22 UTC coord.distance_to(Reality::Entity('London')) # => #<Reality::Measure(2,135 km)> “`

Uses Geokit for some operations like distance_to, close_to? etc.

Constants

DIRS

Attributes

lat[R]
latitude[R]
lng[R]
longitude[R]

Public Class Methods

from_dms(lat, lng) click to toggle source
# File lib/reality/geo.rb, line 38
def from_dms(lat, lng)
  new(decimal_from_dms(lat), decimal_from_dms(lng))
end
new(lat, lng) click to toggle source

@param latitude @param longitude

# File lib/reality/geo.rb, line 69
def initialize(lat, lng)
  @lat, @lng = Rational(lat), Rational(lng)
end

Private Class Methods

decimal_from_dms(dms) click to toggle source
# File lib/reality/geo.rb, line 55
def decimal_from_dms(dms)
  sign = if dms.last.is_a?(String)
    parse_direction(dms.pop)
  else
    dms.first.to_i <=> 0
  end
  
  d, m, s = *dms
  sign * (d.abs.to_i + Rational(m.to_i) / 60 + Rational(s.to_f) / 3600)
end
parse_direction(dir) click to toggle source
# File lib/reality/geo.rb, line 51
def parse_direction(dir)
  DIRS[dir] or fail("Undefined coordinates direction: #{dir.inspect}")
end

Public Instance Methods

==(other) click to toggle source
# File lib/reality/geo.rb, line 144
def ==(other)
  other.is_a?(self.class) && lat == other.lat && lng == self.lng
end
close_to?(point, radius) click to toggle source

@param point - Coordinates, e.g “50.45,30.52”, [50.45, 30.52], Coord or Entity instance @param radius - km, e.g. 10

@return [true, false]

# File lib/reality/geo.rb, line 104
def close_to?(point, radius)
  area = Geokit::Bounds.from_point_and_radius(to_s, radius.to_f)
  area.contains?(normalize_point(point).to_s)
end
direction_to(point) click to toggle source

@param point - Coordinates, e.g “50.45,30.52”, [50.45, 30.52], Coord or Entity instance

@return [Reality::Measure]

# File lib/reality/geo.rb, line 85
def direction_to(point)
  destination_coords = normalize_point(point).to_s
  res = Geokit::LatLng.heading_between(to_s, destination_coords)
  Reality::Measure(res, '°')
end
distance_to(point) click to toggle source

@param point - Coordinates, e.g “50.45,30.52”, [50.45, 30.52], Coord or Entity instance

@return [Reality::Measure]

# File lib/reality/geo.rb, line 76
def distance_to(point)
  destination_coords = normalize_point(point).to_s
  res = Geokit::LatLng.distance_between(to_s, destination_coords, formula: :sphere)
  Reality::Measure(res, 'km')
end
endpoint(direction, distance) click to toggle source

@param direction - angle from the North by clock, e.g. '90' means 'to the east' @param distance - km, e.g. 100

@return [Reality::Geo::Coord]

# File lib/reality/geo.rb, line 95
def endpoint(direction, distance)
  res = Geokit::LatLng.endpoint(to_s, direction.to_f, distance.to_f)
  Coord.new res.lat, res.lng
end
inspect() click to toggle source
# File lib/reality/geo.rb, line 148
def inspect
  "#<%s(%i°%i′%.0f″%s,%i°%i′%.0f″%s)>" % [self.class, *lat_dms, *lng_dms]
end
lat_dms(direction = true) click to toggle source

Latitude in “degrees minutes seconds” format

@return [Array]

# File lib/reality/geo.rb, line 112
def lat_dms(direction = true)
  seconds = (lat.abs % 1.0) * 3600.0
  d, m, s = lat.to_i, (seconds / 60).to_i, (seconds % 60)
  if direction
    [d.abs, m, s, d >= 0 ? 'N' : 'S']
  else
    [d, m, s]
  end
end
latlng()
Alias for: to_s
lng_dms(direction = true) click to toggle source

Longitude in “degrees minutes seconds” format

@return [Array]

# File lib/reality/geo.rb, line 125
def lng_dms(direction = true)
  seconds = (lng.abs % 1.0) * 3600.0
  d, m, s = lng.to_i, (seconds / 60).to_i, (seconds % 60)
  if direction
    [d.abs, m, s, d >= 0 ? 'E' : 'W']
  else
    [d, m, s]
  end
end
sunrise(date = Date.today) click to toggle source
# File lib/reality/geo.rb, line 152
def sunrise(date = Date.today)
  SunTimes.new.rise(date, lat.to_f, lng.to_f)
end
sunset(date = Date.today) click to toggle source
# File lib/reality/geo.rb, line 156
def sunset(date = Date.today)
  SunTimes.new.set(date, lat.to_f, lng.to_f)
end
to_h() click to toggle source
# File lib/reality/geo.rb, line 140
def to_h
  {lat: lat.to_f, lng: lng.to_f}
end
to_s() click to toggle source
# File lib/reality/geo.rb, line 135
def to_s
  "#{lat.to_f},#{lng.to_f}"
end
Also aliased as: latlng

Private Instance Methods

normalize_point(point) click to toggle source
# File lib/reality/geo.rb, line 177
def normalize_point(point)
  return point if point.is_a?(Coord)
  point.coord if point.respond_to?(:coord)
end