Class: Map::LatLonService

Inherits:
Object
  • Object
show all
Defined in:
lib/map/lat_lon_service.rb

Overview

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Latitude/longitude spherical geodesy tools © Chris Veness 2002-2016 */ /* MIT Licence */ /* www.movable-type.co.uk/scripts/latlong.html */ /* www.movable-type.co.uk/scripts/geodesy/docs/module-latlon-spherical.html */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Código portado de biblioteca LatLon do JS

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lat_or_coordinate, lon = nil) ⇒ LatLonService

Returns a new instance of LatLonService.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/map/lat_lon_service.rb', line 16

def initialize(lat_or_coordinate, lon = nil)
  if lon
    @lat = lat_or_coordinate.to_f
    @lon = lon.to_f
  elsif lat_or_coordinate.is_a?(Array)
    @lat = lat_or_coordinate.first.to_f
    @lon = lat_or_coordinate.second.to_f
  elsif lat_or_coordinate.is_a?(Hash)
    lat = HashWithIndifferentAccess.new(lat_or_coordinate)
    @lat = lat[:latitude].to_f
    @lon = lat[:longitude].to_f
  else
    raise 'Parâmetros inválidos'
  end

  Float.include Map::Float
end

Instance Attribute Details

#latObject (readonly)

Returns the value of attribute lat.



14
15
16
# File 'lib/map/lat_lon_service.rb', line 14

def lat
  @lat
end

#lonObject (readonly)

Returns the value of attribute lon.



14
15
16
# File 'lib/map/lat_lon_service.rb', line 14

def lon
  @lon
end

Instance Method Details

#bearing_to(point) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/map/lat_lon_service.rb', line 34

def bearing_to(point)
  raise 'Point não é do tipo LatLon' unless point.is_a?(Map::LatLonService)

  _φ1 = self.lat.to_radians
  _φ2 = point.lat.to_radians
  _Δλ = (point.lon - self.lon).to_radians

  y = Math.sin(_Δλ) * Math.cos(_φ2)
  x = Math.cos(_φ1) * Math.sin(_φ2) - Math.sin(_φ1) * Math.cos(_φ2) * Math.cos(_Δλ)
  θ = Math.atan2(y, x)

  (θ.to_degrees + 360) % 360
end

#destination_point(distance, bearing) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/map/lat_lon_service.rb', line 48

def destination_point(distance, bearing)
  radius = 6371e3

  # _φ2 = asin( sin_φ1⋅cosδ + cos_φ1⋅sinδ⋅cosθ )
  # _λ2 = _λ1 + atan2( sinθ⋅sinδ⋅cos_φ1, cosδ − sin_φ1⋅sin_φ2 )
  # see http://williams.best.vwh.net/avform.htm#LL

  δ = distance / radius
  θ = bearing.to_f.to_radians

  _φ1 = self.lat.to_radians
  _λ1 = self.lon.to_radians

  _φ2 = Math.asin(Math.sin(_φ1)*Math.cos(δ) + Math.cos(_φ1)*Math.sin(δ)*Math.cos(θ))
  x = Math.cos(δ) - Math.sin(_φ1) * Math.sin(_φ2)
  y = Math.sin(θ) * Math.sin(δ) * Math.cos(_φ1)
  _λ2 = _λ1 + Math.atan2(y, x)

  self.class.new(_φ2.to_degrees, (_λ2.to_degrees + 540) % 360-180)
end

#distance_to(point) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/map/lat_lon_service.rb', line 69

def distance_to(point)
  radius = 6371e3

  _φ1 = self.lat.to_radians
  _λ1 = self.lon.to_radians

  _φ2 = point.lat.to_radians
  _λ2 = point.lon.to_radians

  _Δφ = _φ2 - _φ1
  _Δλ = _λ2 - _λ1

  a = Math.sin(_Δφ/2) * Math.sin(_Δφ/2) + Math.cos(_φ1) * Math.cos(_φ2) * Math.sin(_Δλ/2) * Math.sin(_Δλ/2)
  c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))

  radius * c
end

#to_hashObject



87
88
89
90
91
92
# File 'lib/map/lat_lon_service.rb', line 87

def to_hash
  {
    latitude: self.lat,
    longitude: self.lon
  }
end