#!/usr/local/bin/perl # #deloldlog.pl delete old GPS log #同じところを通ってるログの古いものを消す # #ソートルーチンは #http://ash.jp/perl/sort_csv.htm #を使わせていただきました。 require 'glc-sub.pl'; # #更新履歴 #2007/08/26 作成開始 #2007/08/30 とりあえず、誤差を認めない分で。 #2007/08/31 とりあえず完成?いろいろ穴がありそう。データ圧縮効果もいまいち。 # しかも、時間かかりすぎ。 #2007/09/01 とりあえず完成。 #2007/09/05 経度順に並べ替えてチェックするバージョンでいちおう完成。 # 30,000ポイントでも実用的な処理速度になった。 #2007/09/23 # #カシミール3Dのpotファイル専用 #書式は以下 #DAT=WGS84/WGS84/0.000/0.00000000/0/0/0 #ORD=POI/tex=/ido=034'41'24'5/kei=135'33'05'7/adr=1/alt=-5/col=12/pda=22-SEP-05/pti=21:44:54 #ORD=POI/tex=/ido=034'41'26'3/kei=135'33'05'4/adr=1/alt=+9/col=12/pda=22-SEP-05/pti=21:45:23 #ORD=POI/tex=/ido=034'41'25'8/kei=135'33'05'3/adr=2/alt=+9/col=12/pda=22-SEP-05/pti=21:47:20 #ORD=POI/tex=/ido=034'41'25'8/kei=135'33'05'3/adr=2/alt=+11/col=12/pda=22-SEP-05/pti=21:47:24 # 緯度 経度 軌跡番号 高度 表示色 日付 時刻 #日付・時刻はUTC #ORD=POI と tex= は固定にしておく $MAX_LAT_ERROR = 2/60/60; $MAX_LONG_ERROR = 2/60/60; #1sec $INFRA_WEST = -181; $ULTRA_EAST = +181; $PI = 3.14159265358979; @tbl = (); #@tbl=(NO,LAT,LONG,TIME,ADR_PLUS,DEL_FLAG); $NO = 0; $LAT = 1; $LONG = 2; $TIME = 3; $ADR_PLUS = 4; $DEL_FLAG = 5; # ソートのパラメータの設定 # ソートルーチンもなんとかしたい。 $key_num = 2; # キーの数 $key_idx[0] = $LONG; # キーのカラム番号 $key_dir[0] = 0; # 0:昇順 1:降順 $key_idx[1] = $LAT; # キーのカラム番号 $key_dir[1] = 0; # 0:昇順 1:降順 #ヘッダー $head = <>; #データの読み込み $i = 0; $tbl[$i][$NO] = $i; $tbl[$i][$LAT] = 0; # lat $tbl[$i][$LONG] = $INFRA_WEST; # long $tbl[$i][$TIME] = 0; # time $tbl[$i][$ADR_PLUS] = 1; # adr_plus $tbl[$i][$DEL_FLAG] = 1; # del_flag @idxtbl[$i] = $i; $i++; while (<>){ chop ; ($ido[$i] ,$kei[$i] ,$address[$i] ,$altitude[$i] ,$col[$i] ,$pda[$i] ,$pti[$i]) = &get_variables($_); $tbl[$i][$NO] = $i; $tbl[$i][$LAT] = &dmspot2deg($ido[$i]); #lat $tbl[$i][$LONG] = &dmspot2deg($kei[$i]); #long $tbl[$i][$TIME] = &pdapti2time($pda[$i] ,$pti[$i]); #time if($address[$i] > $address[$i-1]){ $tbl[$i][$ADR_PLUS] = 1; }else{ $tbl[$i][$ADR_PLUS] = 0; }# adr_plus $tbl[$i][$DEL_FLAG] = 0; # del_flag @idxtbl[$i] = $i; $i++; } $tbl[$i][$NO] = $i; $tbl[$i][$LAT] = 0; # lat $tbl[$i][$LONG] = $ULTRA_EAST; # long $tbl[$i][$TIME] = 0; # time $tbl[$i][$ADR_PLUS] = 1; # adr_plus $tbl[$i][$DEL_FLAG] = 1; # del_flag @idxtbl[$i] = $i; $data_max = $i; print STDERR "input data $i record(s) , "; # ソート @idxtbl = sort tblsort @idxtbl; #データのチェック for ($i = 1 ; $i < $data_max ; $i++){ $idxi = $idxtbl[$i]; if($tbl[$idxi][$DEL_FLAG]){ next; } for ($j = 1 ; ($tbl[$idxi][$LONG] > ($tbl[$idxtbl[$i+$j]][$LONG] - $MAX_LONG_ERROR)); $j++){ $idxj = $idxtbl[$i+$j]; if (&isnear($tbl[$idxi][$LAT] , $tbl[$idxj][$LAT] , $MAX_LAT_ERROR)){ ; }else{ next; } #とりあえず役者を揃える if (&isnear($tbl[$idxi-1][$LAT] , $tbl[$idxj-1][$LAT] , $MAX_LAT_ERROR) && &isnear($tbl[$idxi-1][$LONG], $tbl[$idxj-1][$LONG], $MAX_LONG_ERROR)){ $near0 = 1; }else{ $near0 = 0; } if (&isnear($tbl[$idxi+1][$LAT] , $tbl[$idxj+1][$LAT] , $MAX_LAT_ERROR) && &isnear($tbl[$idxi+1][$LONG], $tbl[$idxj+1][$LONG], $MAX_LONG_ERROR)){ $near2 = 1; }else{ $near2 = 0; } #前提条件として、入力ファイルは時間順にソートされているものとする。 #時間をみるようにすれば、それもなんとかなるかも。 #あとで、時間順にソートしなおしてから出力。 if($idxi < $idxj){ if(($near0 && $near2) || ($near0 && $tbl[$idxi+1][$ADR_PLUS]) || ($tbl[$idxi][$ADR_PLUS] && $near2)) { $tbl[$idxi][$DEL_FLAG] = 1; $tbl[$idxi][$ADR_PLUS] = 1; $tbl[$idxi+1][$ADR_PLUS] = 1; }elsif($near0){ $tbl[$idxi][$ADR_PLUS] = 1; }elsif($near2){ $tbl[$idxi+1][$ADR_PLUS] = 1; } }else{ if(($near0 && $near2) || ($near0 && $tbl[$idxj+1][$ADR_PLUS]) || ($tbl[$idxj][$ADR_PLUS] && $near2)) { $tbl[$idxj][$DEL_FLAG] = 1; $tbl[$idxj][$ADR_PLUS] = 1; $tbl[$idxj+1][$ADR_PLUS] = 1; }elsif($near0){ $tbl[$idxj][$ADR_PLUS] = 1; }elsif($near2){ $tbl[$idxj+1][$ADR_PLUS] = 1; } } } } #データの書き出し print $head; $i=1;$adr=0;$j=0; for ($i = 0 ; $i<$data_max ; $i++){ if ($tbl[$i][$DEL_FLAG] || ($tbl[$i][$ADR_PLUS] && $tbl[$i+1][$ADR_PLUS])){ ; }else{ $adr += $tbl[$i][$ADR_PLUS]; &print_pot($ido[$i],$kei[$i],$adr,$altitude[$i],$col[$i],$pda[$i],$pti[$i]); $j++; } } print STDERR "output data $j record(s)\n"; exit; #近いかどうかの判断 #&isnear($a,$b,$error) #aとbがerrorの範囲にあるかどうか sub isnear { my($a,$b,$error) = @_; if(($a < $b + $error) && ($a > $b - $error)){ return 1; }else{ return 0; } } 1; #return true sub tblsort { # 比較関数 # $a < $b : -1 # $a > $b : 1 # $a = $b : 0 my ($i, $idx, $stat); $stat = 0; for ($i = 0; $i < $key_num; $i++) { $idx = $key_idx[$i]; if ($tbl[$a][$idx] < $tbl[$b][$idx]) { if ($key_dir[$i]) { # 降順 $stat = 1; } else { # 昇順 $stat = -1; } last; } elsif ($tbl[$a][$idx] > $tbl[$b][$idx]) { if ($key_dir[$i]) { # 降順 $stat = -1; } else { # 昇順 $stat = 1; } last; } } return($stat); }