Decimal degrees location value to sexagesimal string value conversion


#1

Is there any way to get it somewhere ? don’t want to re-re-code such
useful utility ?
I am using Geokit::Geoloc output lat / lng as decimal degrees , but
need to display the sexagesimal position

thanks for your suggestions

erwin


#2

In case other people run into this problem like I did today…here is
some ruby code to do the job when provided with decimal longitude and
latitude numbers.

For example, a latitude of 41.886256 and -87.644723 will spit out: 41˚
53’ 10" N, 87˚ 38’ 41" E

Call method with: YourClass.sexagesimal_coordinates(41.886256,
-87.644723)

def self.sexagesimal_coordinates(latitude, longitude)
planes = [“latitude”, “longitude”]
formatted_coordinates = planes.map do |plane|
if plane == “latitude”
coordinate = latitude.to_f
coordinate_direction = coordinate > 0 ? “N” : “S”
else
coordinate = longitude.to_f
coordinate_direction = coordinate > 0 ? “W” : “E”
end
coordinate = coordinate.abs
coordinate_whole = coordinate.to_i
coordinate_decimal = coordinate - coordinate_whole
minutes = coordinate_decimal * 60
minutes_whole = minutes.to_i
minutes_decimal = minutes - minutes_whole
seconds = (minutes_decimal * 60).to_i
coordinate_formatted = “#{coordinate_whole}\u{02DA}
#{minutes_whole}’ #{seconds}” #{coordinate_direction}"
end
return formatted_coordinates.join(", ")
end


#3

Matthew K. wrote in post #1121063:

Ryan Francis wrote in post #1121060:

In case other people run into this problem like I did today…here is
some ruby code to do the job when provided with decimal longitude and
latitude numbers.

For example, a latitude of 41.886256 and -87.644723 will spit out: 41˚
53’ 10" N, 87˚ 38’ 41" E

Call method with: YourClass.sexagesimal_coordinates(41.886256,
-87.644723)

Ooh, another mental gymnastics puzzle! Here’s a refactor of the same
code, using shorter variable names (and fewer of them). Also no more
strings-as-identifiers. Oh and I rounded the seconds instead of
truncating them, so I get 41° 53’ 11" N.

def self.sexagesimal_coordinates(latitude, longitude)
planes = [[latitude,‘N’,‘S’], [longitude,‘E’,‘W’]]
planes.map do |coord, dir_pos, dir_neg|
coord = coord.to_f
dir = coord > 0 ? dir_pos : dir_neg
deg, rem = coord.abs.divmod 1
min, rem = (rem * 60).divmod 1
sec = (rem * 60).round
“#{deg}\u{02DA} #{min}’ #{sec}” #{dir}"
end.join ', ’
end

Ah, brilliant! Thanks for the refactor and good find with rounding the
seconds instead of truncating. I’ve never used divmod before, but it
certainly is the method for the job. Thanks again, Matthew.


#4

On Sep 9, 2013, at 19:25 , Matthew K. removed_email_address@domain.invalid wrote:

 deg, rem = coord.abs.divmod 1
 min, rem = (rem * 60).divmod 1
 sec = (rem * 60).round
 "#{deg}\u{02DA} #{min}' #{sec}\" #{dir}"

end.join ', ’
end

def to_degrees_min_sec d
time = []
[ 3600, 60, 1 ].inject((d*3600).abs.to_i) { |n,u| time << n / u; n % u
}
time
end

def direction n, pos, neg
n > 0 ? pos : neg
end

def sexagesimal_coordinates latitude, longitude
dNS = direction latitude, “N”, “S”
dEW = direction longitude, “E”, “W”

dN, mN, sN = to_degrees_min_sec latitude
dW, mW, sW = to_degrees_min_sec longitude

“#{dN}\u{02DA} #{mN}’ #{sN}” #{dNS}, #{dW}\u{02DA} #{mW}’ #{sW}"
#{dEW}"
end


#5

Ryan Francis wrote in post #1121060:

In case other people run into this problem like I did today…here is
some ruby code to do the job when provided with decimal longitude and
latitude numbers.

For example, a latitude of 41.886256 and -87.644723 will spit out: 41˚
53’ 10" N, 87˚ 38’ 41" E

Call method with: YourClass.sexagesimal_coordinates(41.886256,
-87.644723)

Ooh, another mental gymnastics puzzle! Here’s a refactor of the same
code, using shorter variable names (and fewer of them). Also no more
strings-as-identifiers. Oh and I rounded the seconds instead of
truncating them, so I get 41° 53’ 11" N.

def self.sexagesimal_coordinates(latitude, longitude)
planes = [[latitude,‘N’,‘S’], [longitude,‘E’,‘W’]]
planes.map do |coord, dir_pos, dir_neg|
coord = coord.to_f
dir = coord > 0 ? dir_pos : dir_neg
deg, rem = coord.abs.divmod 1
min, rem = (rem * 60).divmod 1
sec = (rem * 60).round
“#{deg}\u{02DA} #{min}’ #{sec}” #{dir}"
end.join ', ’
end