Created
August 11, 2010 20:52
-
-
Save laurynas/519740 to your computer and use it in GitHub Desktop.
Convert decimal to degrees, minutes, seconds sexagesimal (used for GPS coordinates)
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
class Float | |
# Convert decimal to degrees, minutes, seconds sexagesimal | |
# (used for GPS coordinates) | |
def to_sexagesimal | |
degrees = abs.floor | |
x = (abs - degrees) * 60 | |
minutes = x.floor | |
seconds = (((x - minutes) * 60) * 100).round.to_f / 100 | |
sign = self < 0 ? '-' : '' | |
"#{sign}#{degrees}°#{minutes}'#{seconds}\"" | |
end | |
end |
Try this one instead:
refine Float do
# Convert DD angle to DMS with the degrees zero padded to +padding+ length
def to_dms(padding=3)
degrees = self.abs.floor
minutes = ((self.abs - degrees) * 60).floor
seconds = (self.abs - degrees - minutes.to_f / 60) * 3600
minutes, seconds = minutes + 1, 0 if seconds.round(2) == 60
degrees, minutes = degrees + 1, 0 if minutes == 60
%Q(%s%0#{padding}d°%02d'%05.2f") % [
('-' if self.negative?),
self.abs.truncate,
minutes.abs.truncate,
seconds.abs
]
end
end
refine String do
# Convert DMS angle to DD or +nil+ if the format is not recognized
def to_dd
if self =~ /\A(-)?(\d{1,3})[° ]?(\d{2})[' ]?(\d{2}\.?\d{0,2})"?\z/
("#{$1}1".to_i * ($2.to_f + ($3.to_f/60) + ($4.to_f/3600)))
end
end
end
You can test all possible DMS notations for roundtrip symmetry:
describe "Float#to_dms"
it "must do all possible roundtrip conversions" do
2.times.with_index do |degrees|
60.times.with_index do |minutes|
60.times.with_index do |seconds|
100.times.with_index do |fractions|
subject = %q(%03d°%02d'%02d.%02d") % [degrees, minutes, seconds, fractions]
subject.to_dd.to_dms.must_equal subject
end
end
end
end
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please watch what happens if you feed the float
4.883333333333333
to your method:4°52'60.0"
. Kinda right, but really wrong as well.