#!/usr/bin/perl
#
# 数値地図(標高)からUSGS海岸線データを
# Nowral
# 98.12.12
#
@filename = @ARGV;
foreach $oldargv (@filename) {
open(ARGVIN, "<$oldargv");
$newargv = $oldargv . '.dat';
open(ARGVOUT, ">$newargv");
select(ARGVOUT);
&MacPerl'SetFileInfo('JEDT', 'TEXT', $newargv);
$_ = <ARGVIN>; #ヘッダー行
/^[\s\d]{23}(\d{3})(\d{3})(\d{7})(\d{7})(\d{7})(\d{7})/;
$nr = $1;
$lat2 = &dms2deg($3);
$lon0 = &dms2deg($4);
$lat0 = &dms2deg($5);
$lon2 = &dms2deg($6);
$dlat = ($lat2-$lat0) / $nr;
$dlon = ($lon2-$lon0) / $nr;
#ビット列作り
#$slb[$y] < j番目の走査線 全データ格納
#2 壁 1 陸 0 海
$slb[0] = "2" x ($nr+2);
$y = 1;
while (<ARGVIN>) {
if(/\d+/) { #空行飛ばし
s/\d{4}(\d{5})//; #先頭の図番号を削除
for(; $y < $1; ++$y) { $slb[$y] = "2","0" x $nr,"2"; } #海行省略
s/[\n\r]//g;
s/([\-\d]\d{4})/0+($1>-9999)/eg; #境界 <>等高線
$slb[$y] = "2" . $_ . "2";
++$y;
}
}
$slb[$y] = "2" x ($nr+2);
#foreach (@slb) {print $_,"\n";}
#方向テーブル
#北から時計回り
# 0
# |
# 3- @ -1
# |
# 2
@dx = ( 0, 1, 0,-1);
@dy = (-1, 0, 1, 0);
#plaquetteテーブル
# +-+-+
# |3|0|
# +-@-+
# |2|1|
# +-+-+
@px = ( 1, 1, 0, 0);
@py = ( 0, 1, 1, 0);
#発端
$sc = 0;
#上辺
$x = 0;
$y = 0;
$pb = substr($slb[$y+$py[1]],$x+$px[1],1);
for($x = 1 ; $x<$nr; ++$x) {
$nb = substr($slb[$y+$py[1]],$x+$px[1],1);
if($pb==1 && $nb==0) {
$spx[$sc] = $x;
$spy[$sc] = $y;
$spd[$sc] = 2;
++$sc;
}
$pb = $nb;
}
#右辺
$x = $nr;
$y = 0;
$pb = substr($slb[$y+$py[2]],$x+$px[2],1);
for($y = 1 ; $y<$nr; ++$y) {
$nb = substr($slb[$y+$py[2]],$x+$px[2],1);
if($pb==1 && $nb==0) {
$spx[$sc] = $x;
$spy[$sc] = $y;
$spd[$sc] = 3;
++$sc;
}
$pb = $nb;
}
#下辺
$x = $nr;
$y = $nr;
$pb = substr($slb[$y+$py[3]],$x+$px[3],1);
for($x=$nr-1 ; $x>0; --$x) {
$nb = substr($slb[$y+$py[3]],$x+$px[3],1);
if($pb==1 && $nb==0) {
$spx[$sc] = $x;
$spy[$sc] = $y;
$spd[$sc] = 0;
++$sc;
}
$pb = $nb;
}
#左辺
$x = 0;
$y = $nr;
$pb = substr($slb[$y+$py[0]],$x+$px[0],1);
for($y=$nr-1 ; $y>0; --$y) {
$nb = substr($slb[$y+$py[0]],$x+$px[0],1);
if($pb==1 && $nb==0) {
$spx[$sc] = $x;
$spy[$sc] = $y;
$spd[$sc] = 1;
++$sc;
}
$pb = $nb;
}
#内側、閉曲線
for($y=1 ; $y<$nr; ++$y) {
$x = 0;
$pb = substr($slb[$y+$py[1]],$x+$px[1],1);
for($x=1 ; $x<$nr; ++$x) {
$nb = substr($slb[$y+$py[1]],$x+$px[1],1);
if($pb==1 && $nb==0) {
$spx[$sc] = $x;
$spy[$sc] = $y;
$spd[$sc] = 2;
++$sc;
}
$pb = $nb;
}
}
#探索
$lcl = -1; #海岸線長 length of coast line
spl:foreach $sc (0..$#spx) { #出発点ループ
$x = $spx[$sc];
$y = $spy[$sc];
if($x == 0 && $y == 0) { next spl; }
++$lcl;
$clx[$lcl] = 0;
$cly[$lcl] = 0;
++$lcl;
$clx[$lcl] = $x;
$cly[$lcl] = $y;
$pd = $spd[$sc];
$lcl0 = $lcl;
qcl:while(1) { #探索ループ
$nd = ($pd+3) % 4;
$rb = substr($slb[$y+$py[$nd]],$x+$px[$nd],1);
if($rb == 2) { last qcl; } #壁にぶつかって終わり
if($rb == 0) {
$nd++;
$nd %= 4;
$rb = substr($slb[$y+$py[$nd]],$x+$px[$nd],1);
if($rb == 0) {
$nd++;
$nd %= 4;
}
}
if($nd != $pd) {
++$lcl;
$clx[$lcl] = $x;
$cly[$lcl] = $y;
$pd = $nd;
if($x==$spx[$sc] && $y==$spy[$sc]) { #曲線が閉じて終わり
$x = $clx[$lcl0+1];
$y = $cly[$lcl0+1];
last qcl;
}
}
$x += $dx[$pd];
$y += $dy[$pd];
foreach $i ($sc+1..$#spx) {
if($x==$spx[$i] && $y==$spy[$i]) {
$spx[$i] = 0;
$spy[$i] = 0;
}
}
}
++$lcl;
$clx[$lcl] = $x;
$cly[$lcl] = $y;
#近道
#中点処理
$wc = 0;
$x2 = $clx[$lcl0];
$y2 = $cly[$lcl0];
$x3 = $clx[$lcl0+1];
$y3 = $cly[$lcl0+1];
$d23 = sqrt(($x2-$x3)**2 + ($y2-$y3)**2);
$tx3 = $x2;
$ty3 = $y2;
foreach $i ($lcl0+2 .. $lcl) {
$x1 = $x2;
$y1 = $y2;
$x2 = $x3;
$y2 = $y3;
$x3 = $clx[$i];
$y3 = $cly[$i];
$d12 = $d23;
$d23 = sqrt(($x2-$x3)**2 + ($y2-$y3)**2);
# print $d12,",",$d23,"\n";
$tx1 = $tx3;
$ty1 = $ty3;
if($d12==1 || $d23==1) {
$tx2 = ($x2 + $x1) / 2;
$ty2 = ($y2 + $y1) / 2;
$tx3 = ($x2 + $x3) / 2;
$ty3 = ($y2 + $y3) / 2;
}
else {
$tx2 = $x2 + ($x1 - $x2) / $d12 / 2;
$ty2 = $y2 + ($y1 - $y2) / $d12 / 2;
$tx3 = $x2 + ($x3 - $x2) / $d23 / 2;
$ty3 = $y2 + ($y3 - $y2) / $d23 / 2;
}
if($tx2 != $tx1 || $ty2 != $ty1) {
$wx[$wc] = $tx1;
$wy[$wc] = $ty1;
++$wc;
}
$wx[$wc] = $tx2;
$wy[$wc] = $ty2;
++$wc;
}
$wx[$wc] = $tx3;
$wy[$wc] = $ty3;
++$wc;
$wx[$wc] = $clx[$lcl];
$wy[$wc] = $cly[$lcl];
foreach $i (0..$wc) {
$clx[$lcl0 + $i] = $wx[$i];
$cly[$lcl0 + $i] = $wy[$i];
}
$lcl = $lcl0 + $wc;
#省略
$wc = $lcl0 - 1;
$px = $clx[$lcl0];
$py = $cly[$lcl0];
$pa = 0;
foreach $i ($lcl0+1..$lcl) {
$nx = $clx[$i];
$ny = $cly[$i];
if($nx != $px) {$na = ($ny - $py) / ($nx - $px); }
else { $na = $nr + 1; }
if($pa != $na) {
++$wc;
$clx[$wc] = $px;
$cly[$wc] = $py;
$pa = $na;
}
$px = $nx;
$py = $ny;
}
++$wc;
$clx[$wc] = $px;
$cly[$wc] = $py;
$lcl = $wc;
}
#出力 decode
foreach $i (0..$lcl) {
$x = $clx[$i];
$y = $cly[$i];
if($x==0 && $y==0) {
print "# -b\n";
}
else {
$lon = $lon0 + $x*$dlon;
$lat = $lat0 + $y*$dlat;
printf "%.5f\t%.5f\n",$lon,$lat;
# print $x,",",$y,"\n";
}
}
}
&MacPerl'Quit(2);
die "The Unhappy End";
sub dms2deg {
local($_) = @_;
s|(\d\d\d)(\d\d)(\d\d)|$1 + $2/60 + $3/3600|e;
$_;
}