ruby で緯度経度の”度”を”度分秒”に変換する

ruby_map_service.001

数年ぶりに地図系のサービス開発をしているのですが、まだまだ学びが足りないことを実感させられます。

緯度経度を扱う時に、度のとき(10進数)と度分秒のとき(60進数)の時の2パタンがあるという事を初めて知りました。
いま使ってるサービスのAPIで、緯度経度から住所をひきたいので、たとえばユーザのLocationが”度”で取得されている場合は”度分秒”に変換してからAPIをたたかなければいけない とかそういう事になります。

例えば田町駅(JR)は緯度経度が
35.645798 , 139.747656
で、 これを度分秒表記にすると
35度38分44.8728秒, 139度44分51.5616秒
となる。

この変換の計算をrubyでやってみる事にした。

ちなみに、さすがにこの世の中のどこかにライブラリとか転がってるんじゃないかなぁ と思うんですが、勉強も兼ねて自分で中身の計算をやってみる(車輪の再発明をしてしまう)事で理解を深めようの会。

度と、度分秒の対応関係

度と、度分秒 と言っているけれども10進数と60進数と考えるとわかりやすいのかもしれません。
(すごいどうでもいい話なんですが中学のときに左手で2進数の計算を指を折りながらやる方法習って以来、未だに手が覚えてるのに驚き)

こう考えるとわかりやすい。

度分秒→度

X度Y分Z秒 を 10進数の度に変換するときは、以下のように計算する
(度) = X+(Y/60)+(Z/3600)
※3600というのはもちろん 60×60 の数値

度→度分秒

こっちの場合はそれぞれの項目を以下の様に分解して計算する
例:35.645798 の場合
・度 → 整数部分をそのまま取り出す(35)
・分 → 小数点以下に60をかけたものの、整数部分となる(38)
・秒 → 分の計算の小数点以下を取り出して60をかけたもの(44.8728)

### Rubyで計算してみる

度(Float)を与えて、 度分秒を表示するものとしてみる。
※最終的に桁数を揃えられるけど一応BigDecimalを使ってちっちゃい誤差とかがでないようにしてみる。
(ceilつかわないから意味ない・・?)

require 'bigdecimal'

def sexagesimal_scale(num)
  degree = BigDecimal(num.to_i.to_s)
  atdp = num - degree
  minutes = BigDecimal((atdp * 60).to_i.to_s)
  seconds = (atdp * 60 - minutes) * 60
  puts "#{degree.to_i}度#{minutes.to_i}分#{seconds.to_f}秒"
end

sexagesimal_scale(35.645798) => 35度38分44.8728秒

BigDecimalは引数はFloatダメでStirngであたえないと初期化してくれないんですね。
あと、3とかも 0.3E1 とかの表記になっているので、度分秒で表示する際は
適宜 to_iやto_fでExponentをとっぱらって表示しなくてはならないのが少し手間。

というわけで度と度分秒の変換についてでした。
終わり

 

2016-04-03 | Posted in RubyNo Comments » 


関連記事

Comment





Comment



*