Class: Reality::Geo::Coord

Inherits:
Object
  • Object
show all
Defined in:
lib/reality/geo.rb

Overview

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:

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

Usage examples:

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.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lat, lng) ⇒ Coord

@param latitude @param longitude



69
70
71
# File 'lib/reality/geo.rb', line 69

def initialize(lat, lng)
  @lat, @lng = Rational(lat), Rational(lng)
end

Instance Attribute Details

#latObject (readonly) Also known as: latitude

Returns the value of attribute lat.



32
33
34
# File 'lib/reality/geo.rb', line 32

def lat
  @lat
end

#lngObject (readonly) Also known as: longitude

Returns the value of attribute lng.



32
33
34
# File 'lib/reality/geo.rb', line 32

def lng
  @lng
end

Class Method Details

.from_dms(lat, lng) ⇒ Object



38
39
40
# File 'lib/reality/geo.rb', line 38

def from_dms(lat, lng)
  new(decimal_from_dms(lat), decimal_from_dms(lng))
end

Instance Method Details

#==(other) ⇒ Object



144
145
146
# 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) ⇒ true, false

Parameters:

  • point
    • Coordinates, e.g "50.45,30.52", [50.45, 30.52], Coord or Entity instance
  • radius
    • km, e.g. 10

Returns:

  • (true, false)


104
105
106
107
# 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) ⇒ Reality::Measure

Parameters:

  • point
    • Coordinates, e.g "50.45,30.52", [50.45, 30.52], Coord or Entity instance

Returns:



85
86
87
88
89
# 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) ⇒ Reality::Measure

Parameters:

  • point
    • Coordinates, e.g "50.45,30.52", [50.45, 30.52], Coord or Entity instance

Returns:



76
77
78
79
80
# 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) ⇒ Reality::Geo::Coord

Parameters:

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

Returns:



95
96
97
98
# 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

#inspectObject



148
149
150
# 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) ⇒ Array

Latitude in "degrees minutes seconds" format

Returns:

  • (Array)


112
113
114
115
116
117
118
119
120
# 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

Links to popular maps sites with this point marked Maps: openstreetmap, google maps, wikimapia

Returns:

  • (Hash)


164
165
166
167
# File 'lib/reality/geo.rb', line 164

def links
  param = {lat: lat.to_f, lng: lng.to_f, latlng: latlng}
  Hashie::Mash.new(EXTERNAL_LINKS.map{|key, pattern| [key, pattern % param]}.to_h)
end

#lng_dms(direction = true) ⇒ Array

Longitude in "degrees minutes seconds" format

Returns:

  • (Array)


125
126
127
128
129
130
131
132
133
# 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) ⇒ Object



152
153
154
# 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) ⇒ Object



156
157
158
# File 'lib/reality/geo.rb', line 156

def sunset(date = Date.today)
  SunTimes.new.set(date, lat.to_f, lng.to_f)
end

#to_hObject



140
141
142
# File 'lib/reality/geo.rb', line 140

def to_h
  {lat: lat.to_f, lng: lng.to_f}
end

#to_sObject Also known as: latlng



135
136
137
# File 'lib/reality/geo.rb', line 135

def to_s
  "#{lat.to_f},#{lng.to_f}"
end