Class: Geo::Itudes

Inherits:
Object
  • Object
show all
Defined in:
lib/itudes.rb,
lib/itudes/version.rb

Overview

Convenience class to operate w/ multitudes.

Constant Summary collapse

RADIUS =

Earth radius in different measurement units (needed to calc distance between two points on the Earth.)

{
  :km => 6_371, # km
  :mi => 3_959  # mi
}
VERSION =
"0.0.1"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(v1, v2 = nil) ⇒ Itudes

Constructs the Geo::Itudes instance. If there are two parameters, they may be either strings or floats (or string and float.) If there is the only param, it may be one of the following:

- {Itudes} — produces a dup copy of it, 
- {String} — tries to parse string (see String#to_itude)
- {Array} — tries to parse elements

Parameters:

  • v1

    either latitude or one of possible multitudes representations

  • v2 (defaults to: nil)

    longitude (if given)



51
52
53
54
55
56
57
58
59
60
# File 'lib/itudes.rb', line 51

def initialize v1, v2 = nil
  @latitude, @longitude = (v2.nil? ?
      case v1
        when Itudes  then [v1.latitude, v1.longitude]
        when String then v1.split(',').map(&:to_itude)
        when Array  then v1.map { |m| Itudes.tudify m }
      end :
      [Itudes.tudify(v1), Itudes.tudify(v2)]).map(&:to_f)
  kilometers!
end

Instance Attribute Details

#latitudeObject (readonly)

Returns the value of attribute latitude.



33
34
35
# File 'lib/itudes.rb', line 33

def latitude
  @latitude
end

#longitudeObject (readonly)

Returns the value of attribute longitude.



33
34
35
# File 'lib/itudes.rb', line 33

def longitude
  @longitude
end

#unitsObject (readonly)

Returns the value of attribute units.



33
34
35
# File 'lib/itudes.rb', line 33

def units
  @units
end

Class Method Details

.distance(start, finish) ⇒ Object

Calculates distance between two points on the Earth. Convenient method.



120
121
122
# File 'lib/itudes.rb', line 120

def self.distance start, finish
  Itudes.new(start) - Itudes.new(finish)
end

Instance Method Details

#-Float

Calculates distance between two points on the Earth.

Parameters:

  • other

    the place on the Earth to calculate distance to

Returns:

  • (Float)

    the distance between two places on the Earth



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/itudes.rb', line 117

def distance other
  o = Itudes.new other
  raise ArgumentError.new "operand must be lat-/longitudable" if (o.latitude.nil? || o.longitude.nil?)

  dlat = Itudes.radians(o.latitude - @latitude)
  dlon = Itudes.radians(o.longitude - @longitude)
  lat1 = Itudes.radians(@latitude)
  lat2 = Itudes.radians(o.latitude);

  a = Math::sin(dlat/2)**2 + Math::sin(dlon/2)**2 * Math::cos(lat1) * Math::cos(lat2)
  (RADIUS[@units] * 2.0 * Math::atan2(Math.sqrt(a), Math.sqrt(1-a))).abs
end

#==(other) ⇒ Boolean

Compares against another instance.

Returns:

  • (Boolean)

    true if other value represents the same multitudes values, false otherwise



74
75
76
77
# File 'lib/itudes.rb', line 74

def == other
  other = Itudes.new other
  (@latitude == other.latitude) && (@longitude == other.longitude)
end

#distance(other) ⇒ Float

Calculates distance between two points on the Earth.

Parameters:

  • other

    the place on the Earth to calculate distance to

Returns:

  • (Float)

    the distance between two places on the Earth



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/itudes.rb', line 105

def distance other
  o = Itudes.new other
  raise ArgumentError.new "operand must be lat-/longitudable" if (o.latitude.nil? || o.longitude.nil?)

  dlat = Itudes.radians(o.latitude - @latitude)
  dlon = Itudes.radians(o.longitude - @longitude)
  lat1 = Itudes.radians(@latitude)
  lat2 = Itudes.radians(o.latitude);

  a = Math::sin(dlat/2)**2 + Math::sin(dlon/2)**2 * Math::cos(lat1) * Math::cos(lat2)
  (RADIUS[@units] * 2.0 * Math::atan2(Math.sqrt(a), Math.sqrt(1-a))).abs
end

#kilometers!Object

Sets the internal measurement to kilometers (see #distance)



67
68
69
70
# File 'lib/itudes.rb', line 67

def kilometers!
  @units = :km
  self
end

#miles!Object

Sets the internal measurement to miles (see #distance)



62
63
64
65
# File 'lib/itudes.rb', line 62

def miles!
  @units = :mi
  self
end

#round(slice = 0.5) ⇒ Itudes

Calculates the nearest [lat,long] location, basing in the value of

parameter. E. g. for [53.121231231, -18.4353465] will return [53.0, -18.5].
It might be useful if we need to round multitudes to present them.

Parameters:

  • slice (Number) (defaults to: 0.5)

    the “modulo” to calculate nearest “rounded” value

Returns:

  • (Itudes)

    the rounded value



93
94
95
# File 'lib/itudes.rb', line 93

def round slice = 0.5
  Itudes.new @latitude - @latitude.modulo(slice), @longitude - @longitude.modulo(slice)
end

#to_aArray

Array representation of multitudes.

Returns:

  • (Array)
    @latitude, @longitude


85
86
87
# File 'lib/itudes.rb', line 85

def to_a
  [@latitude, @longitude]
end

#to_sString

String representation of multitudes.

Returns:

  • (String)

    in the form “53.121231231, -18.43534656”



80
81
82
# File 'lib/itudes.rb', line 80

def to_s
  "#{@latitude},#{@longitude}"
end

#valid?Boolean

Checks if the multitudes behind represent the correct place on the Earth.

Returns:

  • (Boolean)

    true if the multitudes are OK



98
99
100
101
# File 'lib/itudes.rb', line 98

def valid?
  !@latitude.nil? && !@longitude.nil? && !(@latitude.zero? && @longitude.zero?) && \
      @latitude > -90 && @latitude < 90 && @longitude > -90 && @longitude < 90
end