Last active
January 11, 2017 06:29
-
-
Save vijayparikh/9e6e8d8329bd8b44ebe1edc13dea6c4e to your computer and use it in GitHub Desktop.
Ruby class to calculate distance in between too lat,long coordinates using the Great Circle algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module GPS | |
class Distance | |
RAD_PER_DEG = Math::PI / 180 | |
GREAT_CIRCLE_RADIUS_MILES = 3956 | |
GREAT_CIRCLE_RADIUS_KILOMETERS = 6371 # some algorithms use 6367 | |
GREAT_CIRCLE_RADIUS_FEET = GREAT_CIRCLE_RADIUS_MILES * 5280 | |
GREAT_CIRCLE_RADIUS_METERS = GREAT_CIRCLE_RADIUS_KILOMETERS * 1000 | |
GREAT_CIRCLE_RADIUS_NAUTICAL_MILES = GREAT_CIRCLE_RADIUS_MILES / 1.15078 | |
attr_accessor :great_circle_distance | |
attr_accessor :point1 | |
attr_accessor :point2 | |
def initialize(great_circle_distance = 0) | |
@great_circle_distance = great_circle_distance | |
@point1 = [0,0] | |
@point2 = [0,0] | |
end | |
def to_miles | |
calculate | |
@great_circle_distance * GREAT_CIRCLE_RADIUS_MILES | |
end | |
alias_method :to_mi, :to_miles | |
def to_kilometers | |
calculate | |
@great_circle_distance * GREAT_CIRCLE_RADIUS_KILOMETERS | |
end | |
alias_method :to_km, :to_kilometers | |
def to_meters | |
calculate | |
@great_circle_distance * GREAT_CIRCLE_RADIUS_METERS | |
end | |
alias_method :to_m, :to_meters | |
def to_feet | |
calculate | |
@great_circle_distance * GREAT_CIRCLE_RADIUS_FEET | |
end | |
alias_method :to_ft, :to_feet | |
def to_nautical_miles | |
calculate | |
@great_circle_distance * GREAT_CIRCLE_RADIUS_NAUTICAL_MILES | |
end | |
alias_method :to_nm, :to_nautical_miles | |
private | |
# Radians per degree | |
def rpd(num) | |
num * RAD_PER_DEG | |
end | |
def calculate | |
# Accept two arrays of points in addition to four coordinates | |
if point1.is_a?(Array) && point2.is_a?(Array) | |
lat2, lon2 = point2 | |
lat1, lon1 = point1 | |
elsif | |
raise ArgumentError | |
end | |
dlon = lon2 - lon1 | |
dlat = lat2 - lat1 | |
a = (Math.sin(rpd(dlat)/2))**2 + Math.cos(rpd(lat1)) * Math.cos((rpd(lat2))) * (Math.sin(rpd(dlon)/2))**2 | |
@great_circle_distance = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a)) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment