Forum: Ruby decimal degrees location value to sexagesimal string value conversion

Ee0293412faca21e4ebf3326ed9d5f8c?d=identicon&s=25 Kad Kerforn (kadoudal)
on 2009-05-27 14:52
(Received via mailing list)
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
01a2902971a74c66542c1114e09dd95d?d=identicon&s=25 Ryan Francis (ryan_p_francis)
on 2013-09-10 03:47
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
3df767279ce7d81db0a5bb30f5136863?d=identicon&s=25 Matthew Kerwin (mattyk)
on 2013-09-10 04:25
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
01a2902971a74c66542c1114e09dd95d?d=identicon&s=25 Ryan Francis (ryan_p_francis)
on 2013-09-10 07:31
Matthew Kerwin 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.
5a837592409354297424994e8d62f722?d=identicon&s=25 Ryan Davis (Guest)
on 2013-09-10 08:14
(Received via mailing list)
On Sep 9, 2013, at 19:25 , Matthew Kerwin <lists@ruby-forum.com> 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
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.