Skip to content

Commit

Permalink
Add location_by to compute offsets.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Nov 8, 2018
1 parent f283f7d commit ebfa929
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions lib/geospatial/location.rb
Expand Up @@ -28,7 +28,8 @@ class Location
# WGS 84 semi-minor axis constant in meters
WGS84_B = 6356752.3

EARTH_RADIUS = (WGS84_A + WGS84_B) / 2.0
# Earth Radius
R = (WGS84_A + WGS84_B) / 2.0

# WGS 84 eccentricity
WGS84_E = 8.1819190842622e-2
Expand Down Expand Up @@ -82,6 +83,10 @@ def to_a
[@longitude, @latitude]
end

def to_ary
to_a
end

def to_s
"#{self.class}[#{self.longitude.to_f}, #{self.latitude.to_f}]"
end
Expand All @@ -92,7 +97,7 @@ def to_s
attr :latitude # -90 -> 90 (equivalent to y)

# http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates
def bounding_box(distance, radius = EARTH_RADIUS)
def bounding_box(distance, radius = R)
raise ArgumentError.new("Invalid distance or radius") if distance < 0 or radius < 0

# angular distance in radians on a great circle
Expand Down Expand Up @@ -153,7 +158,7 @@ def distance_from(other)

a = Math::sin(dlat/2) ** 2 + Math::cos(rlat1) * Math::cos(rlat2) * Math::sin(dlon/2) ** 2
c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1-a))
d = EARTH_RADIUS * c
d = R * c

return d
end
Expand All @@ -170,6 +175,17 @@ def bearing_from(other)
) * R2D
end

def location_by(bearing, distance)
lon1 = self.longitude * D2R
lat1 = self.latitude * D2R

lat2 = Math::asin(Math::sin(lat1)*Math::cos(distance/R) + Math::cos(lat1)*Math::sin(distance/R)*Math::cos(bearing * D2R))

lon2 = lon1 + Math::atan2(Math::sin(bearing * D2R)*Math::sin(distance/R)*Math::cos(lat1), Math::cos(distance/R)-Math::sin(lat1)*Math::sin(lat2))

return self.class.new(lon2 * R2D, lat2 * R2D)
end

def - other
Distance.new(self.distance_from(other))
end
Expand Down

0 comments on commit ebfa929

Please sign in to comment.