今の仕事は携帯サイトの開発。
そのため、いろいろと携帯の仕様を調べたりすることがある。
その中で面白そうだなと思ったのが位置情報通知サービス。
銀行の携帯サイトなんかでは、位置情報を送ると最寄りのATMが調べられたりして結構便利な機能だったりする。
この位置情報を使ってなんかできないかなぁ~って事で思いついたのが、自分の位置情報から最寄り駅の時刻表を携帯に表示させてみようという試み。(いつ完成するかは未定だけど・・・)
で、早速位置情報を取得して画面に表示してみると、案外と簡単に緯度経度情報が取得できた。
駅の位置情報は地図を調べれば解るので2点間の距離を算出すれば最寄り駅がどこかもわかるはず。
しかし、困った...
2点の緯度経度からどうやったら距離が算出できるのだろうか。
ググッてみてもいくつかの計算式が出てるが、その通り計算しても変な結果が帰ってくることが多い。
理論的には2点の緯度と経度それぞれの差から縦の距離と横の距離を算出して、三平方の定理で直線距離が出てくるはずだ。
でも、地球は丸いので平面の理論だけでは距離が正しくない...ややこしいぞ。
通勤中や昼休みに考えること3日、なんとなく計算方法ができあがり、あってそうな距離が帰ってきた。
で、実際に位置情報を取得して特定の場所との距離を計算すると、地図上で測った距離と近似した値になったのでOKそう。(三角関数なんて学生の時以来じゃないか??)
しかし、通勤中など移動しながら何度か計測していると突然位置が大きく移動したりすることがある。
よくよく調べてみると、簡易位置情報はその時繋がっている基地局の緯度経度が得られるようで、ハンドオーバーした瞬間大きく移動したことになっている。
逆に、その時の緯度経度で地図を調べると基地局がどこにあるかわかる。
我が家で繋がっているのはベランダから見える高台のマンションにある基地局のようだ (^^)
で、計算式は完成したのでデータベースに登録した駅の位置情報と現在地の距離を計算し近い順にリストを取得できればOK。
でも、データベースからリストを取得して、距離を計算し並べ替えるのは結構面倒。
データベースからリストを取得する段階で近い順に並んでリストが得られればプログラムも簡単になるはず。
って事は、データベースに距離を計算する関数を用意しておけば楽チン!
で完成した関数(PostgreSQL版)がこれ。
create function
distant(double precision, double precision, double precision, double precision)
returns
double precision
as
'select asin(sqrt(power((sin(radians(abs($1 - $3) * 0.5)) * 2), 2) + power((sin(radians(abs($2 - $4) * 0.5)) * 2), 2)) * 0.5) * 12756274;'
language sql
(始点の緯度、始点の経度、終点の緯度、終点の経度)を渡すと距離がm(メートル)で返ってきます。
多分計算式はあってるはず...多分ね
使ってみたい方はご自由にお使い下さい。
但し、自己責任でお願いします (^^;
もし間違いやもっと計算が簡単にできるよって情報をお持ちの方はコメントをお願いします。
コメントを残す