2007/2/24 土曜日

GPSデータからグラフ作り:3)経度・緯度で指定した2地点間の距離を求める

Filed under: 開発メモ — matoyan @ 16:16:50

PHPでGPXファイルを取得することができたので、その取得した経度・緯度座標のリストから、距離を求める必要があります。



Webで検索したところ、正式っぽい数式が国土地理院のページにありました。

2点の平面直角座標x,yから測地線長および方向角を求める計算



・・・が、さっぱり理解できない。

仕方がないので他のページも調べてみると、Javascriptのプログラムまでついているページがありました。球面三角法という計算手法を使うようです。

緯度と経度による距離計算



内容を理解し切れてないのですが、ソースコードを参考(そのままコピー・・・)して使わせていただきました。

PHP向けに作り直したコードを乗せておきます。

PHP:
  1. function cal_len($na, $ta, $nb, $tb){
  2.     $na=pi()*$na/180;
  3.     $nb=pi()*$nb/180;
  4.     $ta=pi()*$ta/180;
  5.     $tb=pi()*$tb/180;
  6.     $na=$na-((11.55/60)*pi()/180)*sin(2*$na);
  7.     $nb=$nb-((11.55/60)*pi()/180)*sin(2*$nb);
  8.     $c=cos($na)*cos($nb)*cos($ta-$tb)+sin($na)*sin($nb);
  9.     $s=sqrt(1-$c*$c);
  10.     $t=$s/$c;
  11.     $z=atan($t);
  12.     $z=6378.137*$z; // 地球の半径を6378.137kmで計算
  13.     return $z;
  14. }



これを使って、やっとルートのグラフを生成するプログラムができました!

↓グラフはこんな感じです。




あとは、GPSに標高データが入っていないときでもグラフが作れるように、座標から標高データを取得する方法です。できるのかな・・・。

GPSデータからグラフ作り:3)経度・緯度で指定した2地点間の距離を求める

Filed under: 開発メモ — matoyan @ 16:16:02

PHPでGPXファイルを取得することができたので、その取得した経度・緯度座標のリストから、距離を求める必要があります。



Webで検索したところ、正式っぽい数式が国土地理院のページにありました。

2点の平面直角座標x,yから測地線長および方向角を求める計算



・・・が、さっぱり理解できない。

仕方がないので他のページも調べてみると、Javascriptのプログラムまでついているページがありました。球面三角法という計算手法を使うようです。

緯度と経度による距離計算



内容を理解し切れてないのですが、ソースコードを参考(そのままコピー・・・)して使わせていただきました。

PHP向けに作り直したコードを乗せておきます。

PHP:
  1. function cal_len($na, $ta, $nb, $tb){
  2.     $na=pi()*$na/180;
  3.     $nb=pi()*$nb/180;
  4.     $ta=pi()*$ta/180;
  5.     $tb=pi()*$tb/180;
  6.     $na=$na-((11.55/60)*pi()/180)*sin(2*$na);
  7.     $nb=$nb-((11.55/60)*pi()/180)*sin(2*$nb);
  8.     $c=cos($na)*cos($nb)*cos($ta-$tb)+sin($na)*sin($nb);
  9.     $s=sqrt(1-$c*$c);
  10.     $t=$s/$c;
  11.     $z=atan($t);
  12.     $z=6378.137*$z; // 地球の半径を6378.137kmで計算
  13.     return $z;
  14. }



これを使って、やっとルートのグラフを生成するプログラムができました!

↓グラフはこんな感じです。




あとは、GPSに標高データが入っていないときでもグラフが作れるように、座標から標高データを取得する方法です。できるのかな・・・。

GPSデータからグラフ作り:2)GPXのファイル読み込み

Filed under: 開発メモ — matoyan @ 0:25:24

グラフを描く環境ができたので、次はPHPでGPXのファイルを読み込んで各地点の経度・緯度座標と標高を求める方法を検討しました。


XMLファイルの解析はPHPに解析用のライブラリが用意されているので、解析するのは非常に簡単です。


---------------------------------------

$fname="sample2.xml";

$data=implode("",file($fname));

$xml_parser = xml_parser_create('UTF-8');

xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);

xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);

xml_parse_into_struct($xml_parser, $data, $values, $idx);

xml_parser_free($xml_parser);

---------------------------------------


とするだけで、XMLの解析が完了します。

ちょっと理解しにくいのですが、$valuesと$idxにデータが分けて入ってます。

GPSの最初のデータにアクセスする場合、

緯度: $values[$idx['trkpt'][0]]['attributes']['lat']

経度: $values[$idx['trkpt'][0]]['attributes']['lon']

標高: $values[$idx['ele'][0]]['value']

時刻: $values[$idx['ele'][0]]['time']

にデータが入ってます。


これでGPSのデータを読み込むことができました。

ちなみに元のGPXファイルがこちら

プログラムで解析した結果はこちら(ソースコードを見ると改行された表示が見えます)


⇒ 次は経度・緯度で指定した2地点間の距離を求める方法です。

2007/2/23 金曜日

GPSデータからグラフ作り:1)折れ線グラフを書く

Filed under: 開発メモ — matoyan @ 0:38:12

GPSからグラフを作るために、まずは折れ線グラフを書いてくれるライブラリを探しました。

自分の使える言語はPerlとPHPぐらいなので、その中からPHPで使えるJpGraphというライブラリを使いました。

「PHPで、 高機能なグラフ生成ライブラリーJpGraphを使いグラフを描いてみました」

というページにインストール方法からサンプルまでがまとまってます。これと公式マニュアルがあれば大体のグラフは描けそうです。



このライブラリを使えば↓のようなグラフが簡単に作成できます。




プログラムは非常に簡単です。

PHP:
  1. <?php
  2. //折れ線グラフ 作成手順サンプル
  3. include ("jpg/jpgraph.php");
  4. include ("jpg/jpgraph_line.php");
  5. $ydata = array(17,21,41,14,30,9); //(各月の最高温度)
  6. $xdata = array("Jan","Feb","Mar","Apr","May","Jun");
  7. $graph = new Graph(300,200,"auto")
  8. $graph->img->SetImgFormat("png");
  9. $graph->SetScale("textlin");
  10. $graph->title->Set("Line Plot Example");
  11. $graph->xaxis->SetTickLabels($xdata);
  12. $graph->xaxis->title->Set("Month");
  13. $graph->yaxis->title->Set("y-title");
  14.  
  15. $lp1 = new LinePlot($ydata); //<font color=red>*2</font>
  16. $lp1->SetLegend("Temperature");
  17. $graph->Add($lp1);
  18. $graph->Stroke();
  19. ?>






★[PHP]: JpGraph

公式HP:アシアル社

http://www.asial.co.jp/jpgraph/

マニュアル(オンライン/ダウンロード)

http://www.asial.co.jp/jpgraph/manual/jpgraph_manual/toc.html

http://www.asial.co.jp/jpgraph/download.php

解説/設定

「PHPで、 高機能なグラフ生成ライブラリーJpGraphを使いグラフを描いてみました」

http://www.linkclub.or.jp/~ma3ki/webutil/jpgraph/howtomake-jpgraph.html



Perlにも同じようなライブラリがあるみたいです。結局使いませんでしたが、おそらく同等の機能が実現できると思います。

★[Perl]: GD::Graph

公式HP:CPAN

http://cpan.uwinnipeg.ca/module/GD

解説/設定

http://www.linkclub.or.jp/~ma3ki/webutil/gdgraph/perlgd-install.html





その他、むかし大学の研究室時代によく使っていたツールも紹介しておきます。複雑な数式とかを使うときにはこちらの方がいいのかもしれません。

★[tool]: gnuplot

公式HP:

http://www.gnuplot.info/

解説/設定

http://t16web.lanl.gov/Kawano/gnuplot/



★[tool]: PGPLOT

公式HP:

http://www.astro.caltech.edu/~tjp/pgplot/

解説/設定:

http://www.fluidlab.naoe.t.u-tokyo.ac.jp/~minnie/pgplot/



⇒ 次はGPXファイルの読み込みです

2007/2/22 木曜日

GPSデータからグラフ作り

Filed under: 開発メモ — matoyan @ 23:34:43

携帯ページの作成は先送りになりますが、次にやりたいことが決まりました。


今のヤマレコで、ルートを表示するためにGPSのデータを登録してもらっていますが、ルートを表示するだけじゃもったいない。

どうせならカシミールのGPS関連の機能を他にも入れてしまおうと。


3D処理が必要な鳥瞰図とかは難しい気がしますが、まずは簡単なところでグラフ機能の生成からトライしたいです。


こんな感じでステップ分けしてやろうと思ってます。

・Step1:GPSのデータ(GPXファイル)からグラフ生成

・Step2:ヤマレコのHPから地図上をクリックするだけで、ルートとグラフが両方完成。

本来の趣旨からずれますが、GPSを持っていない人(実は自分も持ってませんが)でも、簡単に同じ機能を実現できればなぁと思ってます。



で、Step1に向けての課題を並べてみると

1)折れ線グラフを書く

2)GPXのファイルを読み込んで、各地点の経度・緯度座標と標高を求める。

3)経度・緯度で指定した2地点間の距離を求める。



Step2までやるなら

4)経度・緯度で指定した各地点の標高データを求める。

手元にデータがないので難しそう・・・。


できる範囲からコツコツやってきます。

2007/2/20 火曜日

Yahoo Maps上にルート作成(5):線画座標と経度・緯度座標の変換

Filed under: 開発メモ — matoyan @ 1:52:48

GPSのGPXファイル(ルート情報)を読み込んで、Yahoo! 地図情報上にルートを作成するプログラムを作成しました。その際のメモを残しておきます。



前回までで、Yahoo地図上にプロットするための経度・緯度の座標データがそろいつつ、線画するためのライブラリも準備できました。



今回は線画用の座標系と経度・緯度の座標系変換です。



jsgraphics (wz_jsgraphics.js)で使う座標系は、divタグで指定したキャンバスの左上位置を座標(x,y)=(0,0)として、下にy軸、右にx軸が伸びる座標系です。

キャンバスの座標系
図1:キャンバスの座標系の例



それに対して、GPS情報で取得した座標データは経度・緯度ベースの情報なので、線を描くには座標系を合わせるための変換処理が必要になります。

地図の座標系
図2:地図の座標系の例



今回はブラウザ上で線画をしたいので、GPS情報の経度・緯度情報を座標系に変換します。

座標変換のためには、まず

1)今表示している地図の経度・緯度ベースの座標範囲

2)地図を表示しているキャンバスのサイズ(ピクセル値)

を求めて、経度・緯度それぞれ1度移動すると縦横に何ピクセル移動するか(すなわち座標系のスケールの違い)を算出しておいて

Yahoo地図の左上(x,y)=(0,0)の経度・緯度をもとに、

3)GPSの各データのピクセル位置を特定します。



言葉で書いても分かりにくいので、例を使って個別に解説します。





1)今表示している地図の経度・緯度ベースの座標範囲



Yahoo!地図情報のリファレンスマニュアルを見ると、キャンバスの左上と右上の座標を取得する関数としてgetBottomLeft関数とgetTopRight関数が用意されています。

var bl = _map.getBottomLeft();

var tr = _map.getTopRight();

とすれば、左下の緯度・経度が(bl.lat, bl.lon)右上の緯度・経度が(tr.lat, tr.lon)に格納されます。





2)地図を表示しているキャンバスのサイズ(ピクセル値)



これはdivタグで指定したwidth, heightの値です。

Windowのサイズから自動的にとる場合は、

if(window.innerWidth) {

w = window.innerWidth;

h = window.innerHeight;

} else {

w=document.body.clientWidth;

h=document.body.clientHeight;

}

とすれば、変数wに幅が、hに高さがピクセル値で得られます。





これで、以下の式を使えば経度・緯度それぞれ1度あたりのピクセル数を算出できます。

var wscale = w / (tr_w.lon-bl_w.lon);

var hscale = h / (tr_w.lat-bl_w.lat);





4)GPSの各データのピクセル位置



GPSの各データがtrkpts[0]["-lat"], trkpts[0]["-lon"]に格納されていた場合、

x[0] = Math.round((trkpts[0]["-lon"] - bl_w.lon)*wscale);

y[0] = Math.round(h-(trkpts[0]["-lat"] - bl_w.lat)*hscale);

とすると、各トラックポイントの座標位置をキャンバス上の座標に変換することができます。



上記の内容を踏まえて線を描くと・・・


ルート情報がはみ出ます
★サンプルはこちらのページにあります。




線がはみ出ます・・・。あとドラッグしても線が置き去りになります。



ということで、さらに

・キャンバス外に出たポイントを線画しないように修正

・ドラッグしたときに再線画するように修正

すれば、やっとGPX情報を経路情報として表示できるようになりました!



本当は線画領域の境界を計算して画面ぎりぎりまで線を引くべきなんですが、サボって画面外に出たら線を引かないようにしてます。この部分はそのうち直すかも。



興味のある方は、完成したトレースの表示ページから、ソースコードも確認してみてください。




関連エントリ:

Yahoo Maps上にルート作成(1):GPXファイルの取得

Yahoo Maps上にルート作成(2):GPXファイルの解析

Yahoo Maps上にルート作成(3):測地系の変換

Yahoo Maps上にルート作成(4):Yahoo!Map上に線を描く

・Yahoo Maps上にルート作成(5):線画座標と経度・緯度座標の変換

Yahoo Maps上にルート作成(4):Yahoo!Map上に線を描く

Filed under: 開発メモ — matoyan @ 1:00:51

GPSのGPXファイル(ルート情報)を読み込んで、Yahoo! 地図情報上にルートを作成するプログラムを作成しました。その際のメモを残しておきます。



前回までで、Yahoo地図上にプロットするための座標データがそろいました。



原稿執筆時点では、Yahoo!地図情報のライブラリに線画用のライブラリが存在しないため、GPS情報のルートを書くために別の線画ライブラリを利用します。



Javascriptで線画するために、複数のブラウザで確実に動かすこと(クロスブラウザ対応)も考慮したライブラリを使うことになります。



候補としては

1)jsgraphics (wz_jsgraphics.js)

2)GoogleのExplorerCanvas

3)phpspotで紹介されていた、javascript線画用ライブラリ

などがありました。



機能的には1、2ともに同じ様な感じだった(3は試してない)ですが、2)に関しては新しくキャンバスという画像領域を定義されるのでYahooの地図上に白いキャンバスが重なってしまい、線だけを重ねる方法がわからず断念。

1)のjsgraphicsライブラリを使って線画することにしました。



リンク先のページを見てもらえると分かりますが、jsgraphicsは線を引くだけではなくて、円や長方形などの図形も描けるので、楕円のグラフを書いたりすることもできそうです。



で、この機能を使って線を1本書いてみました。Yahoo地図上に重ねて表示するために、Yahoo地図の領域「map」にキャンバス領域を重ねて表示しています。


JavaScript:
  1. <div id="canvas" style="position:absolute;width:200px; height:200px;">
  2. <div id="map" style="width:200px; height:200px;"></div></div>
  3. <script type="text/javascript">
  4. <!--
  5. var Ymap = new YahooMapsCtrl("mapcanvas1", "36.322500,137.730583", 4); // 地図の表示
  6. var jg_doc;
  7. jg_doc = new jsGraphics("canvas"); // canvas領域に記述することを宣言
  8. jg_doc.setColor("#ff0000"); // 線の色は赤色
  9. jg_doc.setStroke(4); // 線の太さは4px
  10. jg_doc.drawLine(10, 10, 100, 100); //(x,y)=(10,10)から(x,y)=(100,100)まで線を引く
  11. jg_doc.paint(); // 線画命令
  12. // -->
  13. </script>













Web Services by Yahoo! JAPAN

上記では単純な1本線だったのでdrawLine関数を使いましたが、折れ線の場合はdrawPolylineを使うこともできます。drawLineを何回も呼ぶ方法ももちろんアリです。(どちらが線画速度が速いのか分かりませんが)



⇒ 次は線画座標と経度・緯度座標の変換処理です。




関連エントリ:

Yahoo Maps上にルート作成(1):GPXファイルの取得

Yahoo Maps上にルート作成(2):GPXファイルの解析

Yahoo Maps上にルート作成(3):測地系の変換

・Yahoo Maps上にルート作成(4):Yahoo!Map上に線を描く

Yahoo Maps上にルート作成(5):線画座標と経度・緯度座標の変換

次のページ »

HTML convert time: 1.121 sec. Powered by WordPress ME