読者です 読者をやめる 読者になる 読者になる

gpxログをひとまとめにするスクリプト

GPSつきPDAである、mioP560を購入して、Windows Mobile 上で、GPX Loggerを走らせている。
GPX Logger とは、GPS情報を取得して、その時点での時刻・緯度・経度・高度情報を得ることができる。
上記の情報から、速度を割り出すことができる。

それらを自動化するためのシステムを以前作ったが、このGPSファイル情報が、
50プロットごとぐらいで、プチプチとファイルが分割されてしまい、それをひとつに統合させるのが、
手作業では超大変だった。
でも、今回の科教協の旅行のような比較的大きな時間旅行していると、
そのためのファイル処理に要するには膨大な時間が要請された。

そこで、複数のGPX情報を、自動的にファイル更新時刻を元に、ひとつのファイルに統合するための
スクリプトを作った。
これで、今後も適当にこのスクリプトを流すだけで自動的になる。
PHPで実装した.PHP5にしたかったが、なんと、自分のサーバはPHP4.4だった。
こんどバージョンアップをしておこう。

<?php  /* vim: set fdm=marker: */
// PHP Version 4.4
// This program is based on GPL. except member function of getFileListFromDirectory
// @see 

$string = "<trk lat=\"36.319285\" lon=\"136.31583\">";
preg_match('/^<((|\/)trkpt|ele|time).*$/i', $string, $matches);
//print_r($matches);


    $x = new Marger();
    $x->run($argv[1]);

    /** GPXデータが複数に分割されているので、それを
     * ディレクトリの中の最終更新日データから、
     * 順番に必要なデータ項目のみを抽出して、
     * ひとつのGPXデータとして出力する。
     * Usage: $marger {directory} > {outputfile}
     * @auther ymlab
     */
    class Marger { /**{{{*/
	/** ファイルリスト*/
	var $mFileList = array();
	/** 結合されたGPXデータ */
	var $strGPX;
        /** 特定のディレクトリの中から、GPXファイルを抽出して、
         * そのファイルリストを返す
         * @param $path 調査するディレクトリ
         * @return $filelist エポックタイムでソートされたGPXファイルリスト
         */
	function getFileListFromDirectory($path) {/**{{{*/
	   $filelist = array();
	   $filetimeStamp = array();
	   //print $path;
	   $drc = dir( $path );
	   while ( $fl = $drc->read()) {
	       $lfl = $path."/".$fl;
	       $din = pathinfo($lfl);
	       if ( is_dir( $lfl) && $fl != ".." && $fl != "." )  {
		   //print "☆".$din["basename"]."\n";
	       } else if ( $fl != ".." && $fl != "." ) {
		   //拡張子でフィルタ. GPX か xmlにしておく.
		   $extension = strtolower( strrchr( $fl, "." ) );
		   if ( $extension == ".gpx" ||
		       $extension == ".xml" ) {
			 array_push( $filelist, $lfl );
			 array_push( $filetimeStamp, filemtime( $lfl ) );
		    }
	       } else {}
	   }
	   $drc->close();
	   // filelist に対応するエポック秒がfiletimeStampに入れてあるので、
	   // filetimeStampをキーにしてソートする。[連想配列を使えというのはなし]
	   array_multisort($filetimeStamp, SORT_ASC, $filelist);
	   return $filelist;
	}
	/**}}}*/

	/** マージする.
	 * @return retStr マージされたデータ
	 */
	function marge() { /** {{{*/
	    $retStr = <<<EM
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="GPX Logger"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.topografix.com/GPX/1/1"
    xsi:schemaLocation="http://www.topografix.com/GPX/1/1
    http://www.topografix.com/GPX/1/1/gpx.xsd">
<trk>
    <name><![CDATA[$this->mFileList[0]]]></name>
    <extensions></extensions>
<trkseg>
EM;
	    for ( $iCounter = 0; $iCounter < count($this->mFileList); $iCounter++){
		//ファイルを読み込んでいく。
		$temp = file( $this->mFileList[$iCounter] );
		foreach ( $temp as $line_num => $line ) {
		    if ( preg_match('/^<((|\/)trkpt|ele|time).*$/i', $line, $matches )) {
			//ヒットした
			$retStr .= $line;
		    } 
		}
	    }
	    $retStr .= "</trkseg>\n</trk>\n</gpx>\n";
	    return $retStr;
	}
	/**}}}*/

	/** ここからスタートする*/	
	function run( $path ) { /** {{{*/
	    //エポック秒でソートされたファイルリストを取得。
	    $this->mFileList = $this->getFileListFromDirectory($path);
	    $this->strGPX = $this->marge();

	    print $this->strGPX;
	}
	/**}}}*/

    }
    /**}}}*/

?>