#!/usr/local/bin/perl # #deloldlog.pl delete old GPS log #同じところを通ってるログの古いものを消す require 'glc-sub.pl'; $DEBUG = 0; # ログを出したいときは0以外に設定. $TRK_MODE = 0; # #更新履歴 #2007/08/26 作成開始 #2007/08/30 とりあえず、誤差を認めない分で。 #2007/08/31 とりあえず完成?いろいろ穴がありそう。データ圧縮効果もいまいち。 # しかも、時間かかりすぎ。 #2007/09/01 とりあえず完成。 #2007/09/05 経度順に並べ替えてチェックするバージョンでいちおう完成。 # 30,000ポイントでも実用的な処理速度になった。 #2007/09/23 いちおう完成だけど1割ぐらいしかデータが減らないので、食わせるデータを見直すとか。 #2009/01/18 一から書き直し。というか、発想を変えて10″メッシュですべての格子が通過するなら削除。 #2009/01/22 いちおう完成 #2009/01/22 4次元配列化して2″メッシュでも実用的な処理速度に。 #2009/01/23 配列の分割方法を最適化。西経・南緯にも対応。 #2009/01/28 トラックごとののみの削除から各トラックの先頭・後尾も削除対象に変更 #2009/02/01 ↑の機能を選択制に #カシミール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= は固定にしておく #$time0=localtime(time()); #$t0=time(); $t0=time(); $time0=localtime($t0); print STDERR "$time0\n"; #分割単位。1°をどんだけ割るか。 $DIV = 1200; # #緯度に90を、経度に180を足して、南緯、西経に対応。 $SHIFT_LAT = 90; $SHIFT_LONG =180; #4次元配列の大きさの最適化 $LAT_DIV =180*$DIV; $LONG_DIV=360*$DIV; for($DIV_X = int(sqrt($LONG_DIV)) ; $LONG_DIV % $DIV_X ; $DIV_X--){;} for($DIV_Y = int(sqrt($LAT_DIV )) ; $LAT_DIV % $DIV_Y ; $DIV_Y--){;} @tbl = (); #@tbl=(POT,NO,LAT,LONG,TIME,ADTP); #ハッシュとかほかに方法あるやろ $POT = 0; $NO = 1; $LAT = 2; $LONG = 3; $TIME = 4; $ADDR = 5; #address $DEL_F= 6; @arry = (); # 1周目。配列にセット。 $input_pnt = 0; $output_pnt = 0; $input_trk = 0; $output_trk = 0; #ヘッダー $head = <>; print $head; #1行目 $i = 0; $first = <>; chop $first; &set_tbl($i,$first); $x1=$tbl[$i][$LONG]; $y1=$tbl[$i][$LAT ]; $a1=$tbl[$i][$ADDR]; #2行目以降 while (<>){ #1点ログを読んで、 chop ; $i++; &set_tbl($i,$_); $x2=$tbl[$i][$LONG]; $y2=$tbl[$i][$LAT ]; $a2=$tbl[$i][$ADDR]; if($a1 == $a2){ #トラックの切れ目じゃなかったら &set_line($x1,$y1,$x2,$y2); }else{ #トラックの切れ目だったら $input_trk++; &set_point($x1,$y1); } $x1=$x2; $y1=$y2; $a1=$a2; #ファイル全部読みこみ終わるまで繰り返し } #最終ポイントの処理 $input_trk++; $i++; &set_point($x1,$y1); $input_pnt = $i; print STDERR "input data $input_pnt point(s), $input_trk track(s)\n"; ########## &print_map(135,34,136,35) if($DEBUG); #2週目。チェック $x1=$tbl[0][$LONG]; $y1=$tbl[0][$LAT ]; $a1=$tbl[0][$ADDR]; $track_start=0; for($i=1;$i<$input_pnt;$i++){ $x2=$tbl[$i][$LONG]; $y2=$tbl[$i][$LAT ]; $a2=$tbl[$i][$ADDR]; if($a1 == $a2){ #トラックの切れ目じゃなかったら $tbl[$i-1][$DEL_F] = &chk_line($x1,$y1,$x2,$y2); #print "$tbl[$i-1][$POT]\t$i-1\t$tbl[$i-1][$DEL_F]\n"; }else{ #トラックの切れ目だったら $tbl[$i-1][$DEL_F] = &chk_point($x1,$y1); #print "$tbl[$i-1][$POT]\t$i-1\t$tbl[$i-1][$DEL_F]\n"; $track_start = $i; } $x1 = $x2; $y1 = $y2; $a1 = $a2; } #最終ポイント $tbl[$i-1][$DEL_F] = &chk_point($x1,$y1); #print "$tbl[$i-1][$POT]\t$i-1\t$tbl[$i-1][$DEL_F]\n"; #print "$tbl[$i][$POT]\t$i\t$tbl[$i][$DEL_F]\n"; #全部出力 # for($i=0;$i<=$input_pnt;$i++){ # print "$tbl[$i][$POT]\t$tbl[$i][$DEL_F]\n"; # } # exit; @arry = (); #おまじない #3週目。出力。 $i = 0; @print_buf = (); $prt_mode = 0; $output_trk = 1; if($TRK_MODE){ $pot = $tbl[$i][$POT]; $pot =~ s/adr=\d*/adr=$output_trk/; push(@print_buf,$pot."\n"); if(!$tbl[$i][$DEL_F]){ $prt_mode = 1; } for($i=1;$i<$input_pnt;$i++){ if($tbl[$i-1][$ADDR] != $tbl[$i][$ADDR]){ if($prt_mode){ print @print_buf; $output_pnt += @print_buf; $output_trk++; } @print_buf = (); $prt_mode = 0; } $pot = $tbl[$i][$POT]; $pot =~ s/adr=\d*/adr=$output_trk/; push(@print_buf,$pot."\n"); if(!$tbl[$i][$DEL_F]){ $prt_mode = 1; } } #最終トラック if($prt_mode){ print @print_buf; $output_pnt += @print_buf; # $output_trk++; } @print_buf = (); $prt_mode = 0; }else{ if(!$tbl[$i][$DEL_F]){#削除しない print "$tbl[$i][$POT]\n"; $output_pnt++; $prt_mode = 1; } for($i=1;$i<$input_pnt;$i++){ if($tbl[$i-1][$ADDR] == $tbl[$i][$ADDR]){ #トラックの切れ目じゃなかったら if($tbl[$i][$DEL_F]){ #削除したい if(!$tbl[$i-1][$DEL_F]){#削除できない print "$tbl[$i][$POT]\n"; $output_pnt++; $prt_mode = 1; }elsif($prt_mode){ #削除できないかも push(@print_buf,$tbl[$i][$POT]."\n"); $prt_mode = 1; } #削除 }else{#削除しない print @print_buf; $output_pnt += @print_buf; @print_buf = (); print "$tbl[$i][$POT]\n"; $output_pnt++; $prt_mode = 1; } }else{ #トラックの切れ目だったら if(!$tbl[$i][$DEL_F]){#削除しない print @print_buf; $output_pnt += @print_buf; print "$tbl[$i][$POT]\n"; $output_pnt++; $prt_mode = 1; } $output_trk++ if($prt_mode); @print_buf = (); $prt_mode = 0; } } } ########## &print_map(135,34,136,35) if($DEBUG); print STDERR "output data $output_pnt point(s), $output_trk track(s)\n"; $t1=time(); $time1=localtime($t1); print STDERR "$time1\n"; $t=$t1-$t0; print STDERR "elapsed time $t\n"; exit; sub set_tbl{ my($i,$pot) = @_; $tbl[$i][$POT] = $pot; my($ido ,$kei ,$address ,$altitude ,$col ,$pda ,$pti) = &get_variables($pot); $tbl[$i][$NO] = $i; $tbl[$i][$LAT] = int((&dmspot2deg($ido)+$SHIFT_LAT )*$DIV); #lat -> y $tbl[$i][$LONG] = int((&dmspot2deg($kei)+$SHIFT_LONG)*$DIV); #long-> x $tbl[$i][$TIME] = &pdapti2time($pda ,$pti); #time $tbl[$i][$ADDR] = $address; } sub set_line{ my ($x1, $y1, $x2, $y2) = @_; if(abs($x2-$x1)>abs($y2-$y1)){ if($x1<$x2){ for($xi=$x1;$xi<$x2;$xi++){ $yi=int($y1+($xi-$x1)/($x2-$x1)*($y2-$y1)); &set_point($xi,$yi); } }else{ for($xi=$x1;$xi>$x2;$xi--){ $yi=int($y1+($xi-$x1)/($x2-$x1)*($y2-$y1)); &set_point($xi,$yi); } } }else{ if($y1<$y2){ for($yi=$y1;$yi<$y2;$yi++){ $xi=int($x1+($yi-$y1)/($y2-$y1)*($x2-$x1)); &set_point($xi,$yi); } }else{ for($yi=$y1;$yi>$y2;$yi--){ $xi=int($x1+($yi-$y1)/($y2-$y1)*($x2-$x1)); &set_point($xi,$yi); } } } return 1; } sub set_point{ my ($x, $y) = @_; my($chk) = &set_array($x,$y,1); print "$x , $y , $chk\n" if($DEBUG); return $chk; } sub chk_line{ my ($x1, $y1, $x2, $y2) = @_; my($chk) = 1; if(abs($x2-$x1)>abs($y2-$y1)){ if($x1<$x2){ for($xi=$x1;$xi<$x2;$xi++){ $yi=int($y1+($xi-$x1)/($x2-$x1)*($y2-$y1)); $chk *= &chk_point($xi,$yi); } }else{ for($xi=$x1;$xi>$x2;$xi--){ $yi=int($y1+($xi-$x1)/($x2-$x1)*($y2-$y1)); $chk *= &chk_point($xi,$yi); } } }else{ if($y1<$y2){ for($yi=$y1;$yi<$y2;$yi++){ $xi=int($x1+($yi-$y1)/($y2-$y1)*($x2-$x1)); $chk *= &chk_point($xi,$yi); } }else{ for($yi=$y1;$yi>$y2;$yi--){ $xi=int($x1+($yi-$y1)/($y2-$y1)*($x2-$x1)); $chk *= &chk_point($xi,$yi); } } } return $chk; } sub chk_point{ my ($x, $y) = @_; $chk = &set_array($x ,$y, -1); print "$x , $y , $chk \n" if($DEBUG); $chk = $chk ? 1 : 0; return $chk; } sub set_array{ my ($x, $y ,$i) = @_; my($ix) = int($x / $DIV_X); my($iy) = int($y / $DIV_Y); my($jx) = $x - $ix*$DIV_X; my($jy) = $y - $iy*$DIV_Y; $arry[$ix][$iy][$jx][$jy] += $i; print "$x , $y ,$ix ,$iy ,$jx ,$jy $arry[$ix][$iy][$jx][$jy] \n" if($DEBUG); return $arry[$ix][$iy][$jx][$jy]; } sub print_map{ my ($x1, $y1, $x2, $y2) = @_; my($xs,$xl,$ys,$yl); my($x,$y); my($ix,$iy,$jx,$jy); $x1 = int($x1*$DIV_X); $y1 = int($y1*$DIV_Y); $x2 = int($x2*$DIV_X); $y2 = int($y2*$DIV_Y); if($x1<$x2){$xs = $x1;$xl = $x2;}else{$xs = $x2;$xl = $x1;} if($y1<$y2){$ys = $y1;$yl = $y2;}else{$ys = $y2;$yl = $y1;} for($y=$yl; $y>$ys ; $y--){ for ($x=$xs; $x<$xl ; $x++){ $ix = int($x / $DIV_X); $iy = int($y / $DIV_Y); $jx = $x - $ix*$DIV_X; $jy = $y - $iy*$DIV_Y; printf "%03d,",$arry[$ix][$iy][$jx][$jy]; } print "\n"; } print "-----\n"; } # end of file