Karttaskriptejä

FEWikistä
Siirry navigaatioon Siirry hakuun

BMP muuntaminen PNG:ksi:

time convert kartta.bmp -scale 35% +dither -depth 8 -quality 75 \
  -quantize RGB -colors 32 kartta.png

Muunnos kestää noin 5 minuuttia per BMP, jos BMP on noin 12 Mt kokoinen. Voidaan ajaa looppina näin:

for i in *.bmp ; do 
 time convert ${i} -scale 35% +dither -depth 8 -quality 75 \
 -quantize RGB -colors 32 ${i%.bmp}.png
done

convert.sh skripti, jolla muunnetaan ja korjataan gmb2bmpc ohjelman luomien MAP-tiedostojen datumi KKJ;stä WGS84:ään. Samalla asetetaan PNG kuvien uusi koko, sekä syntetisoidaan lisää kalibrointipisteitä. Vaatii kaverikseen alempana olevan kkj2wgs84.php php-skriptin.



#! /bin/bash

# v0.2 Harald 7 Aug 09
#       Calculate moving map values too. Place MOP in the middle

# A shellscript to convert .map files with only the NW and SE corners as
# calibration points into a .map file with synthesized NE and SW corners
# as additional calibrationpoints;
# © harald@iki dot fi 

conv=${HOME}/maps3/kkj2wgs84.php

if [ ! -f "$conv" ] ; then
        echo "missing $conv"
        exit 1
fi

export LC_ALL=C

todec(){
        # Expect a lat or lon in "deg, min.dec, N", output "deg.dec" instead
        oldifs="$IFS" ; IFS=" "
        echo $1 | awk -F , '{print $1" "$2" "$3" "$4}' | while read deg min hemi ; do
                #echo "deg|min.dec|hemi: [$deg|$min|$hemi]" >&2
                degdec=$deg$(/bin/echo -e "scale=10\n$min * 1/60" | bc)
                case $hemi in
                        N|E) echo "$degdec" ;;
                        S|W) echo -"$degdec" ;;
                esac
        done
        IFS="$oldifs"
}

towgs(){
        lat=$1
        lon=$2
        wgs=$(/bin/echo "$lat:$lon" | php ${HOME}/maps3/kkj2wgs84.php)
}

mapconvert(){

        oldifs="$IFS" # Store the original input file separator
        IFS=""
        # We now make WGS84 points instead
        #header=$(grep -B10 ^Point01 $1 |grep -v ^Point01 | sed -e 's,.ozf2,.png,' -e 's,.bmp,.png,' -e 's,.BMP,.png,' -e 's/Finl
and Hayford/Finnish Nautical,WGS 84,   0.0000,   0.0000,WGS 84/')
        header=$(grep -B10 ^Point01 $1 |grep -v ^Point01 | sed -e 's,.ozf2,.png,' -e 's,.bmp,.png,' -e 's,.BMP,.png,' -e 's/Finni
sh Nautical/WGS 84,WGS 84,   0.0000,   0.0000,WGS 84/')
        header=$(/bin/echo $header | sed -e 's,Finland Hayford,WGS 84,')
        firstline=$(grep ^Point01 $1)
        secondline=$(grep ^Point02 $1)
        footer=$(grep -A100 ^Point05 $1 |grep -v "^ ")


        # Take the image size
        maxx=$(echo $secondline | awk -F , '{print $3}')
        maxy=$(echo $secondline | awk -F , '{print $4}')
        
        # Doublecheck from 'file' info on the .png
        imagemaxx=$(file ${i%.map}.png | awk -F , '{print $2}' | awk -F x '{print $1}')
        imagemaxy=$(file ${i%.map}.png | awk -F , '{print $2}' | awk -F x '{print $2}')
        
        IFS="$oldifs"
        if [ $maxx != $imagemaxx ] ; then 
                echo "warning: $i has map and png size X in disagreement" >&2
                echo -n "Taking png size as maxx " >&2
                echo -n "maxx was [$maxx], " >&2
                export maxx=$imagemaxx
                echo "and it is now [$maxx]" >&2
        fi
        if [ $maxy != $imagemaxy ] ;then 
                echo "warning: $i has map and png size Y in disagreement" >&2
                echo -n "Taking png size as maxy " >&2
                echo -n "maxy was [$maxy], " >&2
                export maxy=$imagemaxy
                echo "and it is now [$maxy]" >&2
        fi
        IFS=""

        # Take Coords from first and secondline
        ynw=$(echo $firstline | awk -F , '{print $7","$8","$9}')
        if [ -z "$ynw" ] ; then
                echo "warning: ynw is empty!" >&2
        fi
        xnw=$(echo $firstline | awk -F , '{print $10","$11","$12}')
        yse=$(echo $secondline | awk -F , '{print $7","$8","$9}')
        xse=$(echo $secondline | awk -F , '{print $10","$11","$12}')

        # Then use kkj2wgs84.php to convert lat & lon from KKJ to WGS84
        # Could be convert to two lines, soon..
        xnw=$(echo $(todec $ynw):$(todec $xnw) | php $conv | awk -F ":" '{print $2}')
        ynw=$(echo $(todec $ynw):$(todec $xnw) | php $conv | awk -F ":" '{print $1}')
        xse=$(echo $(todec $yse):$(todec $xse) | php $conv | awk -F ":" '{print $2}')
        yse=$(echo $(todec $yse):$(todec $xse) | php $conv | awk -F ":" '{print $1}')
        

        #echo $ynw:$xnw >&2 # Correct answer

        # these are obvious, but I state them here for clarity
        # The x coord of the SE corner is the same as the X coord of the NE corner, right?
        xne="$xse"
        # ditto for yne
        yne="$ynw"
        xsw="$xnw"
        ysw="$yse"


        # pre-calculate decimal position for corners with todec()
        ynwd=$(todec "$ynw")
        xnwd=$(todec "$xnw")
        yned=$(todec "$yne")
        xned=$(todec "$xne")
        ysed=$(todec "$yse")
        xsed=$(todec "$xse")
        yswd=$(todec "$ysw")
        xswd=$(todec "$xsw")
        #echo "ynwd: $ynwd ynw: $ynw"

        # Re-write the first Pointline
        newfirst=$(/bin/echo "Point01,xy,00000,00000,in,deg,$ynw,$xnw,grid,,,,N")
        # this is the NE corner;
        newsecond=$(/bin/echo "Point02,xy,$maxx,00000,in, deg,$yne,$xne, grid,,,,N")
        # SW corner
        #newthird=$(echo $secondline | sed -e 's,Point02,Point03,')     
        newthird=$(/bin/echo "Point03,xy,$maxx,$maxy,in,deg,$yse,$xse,grid,,,,N")
        
        # this is the SW corner, x=max, y=min
        fourthline=$(/bin/echo "Point04,xy,00000,$maxy,in, deg,$ysw,$xsw, grid,,,,N")

        # Then create the MMP moving map parameters at the end of the file
        #IFS="$oldifs"
        footer1=$(echo $footer | grep -B100 "^Moving Map"|grep -v "^Moving Map") # strip the old MM stuff out before 

        mmstuff=$(/bin/echo -e "Moving Map Parameters = MM?    These follow if they exist\nMM0,Yes\nMMPNUM,4\nMMPXY,1,0,0\nMMPXY,2,$maxx,0\nMMPXY,3,$maxx,$maxy\nMMPXY,4,0,$maxy\n")
        mmstuff=$(/bin/echo -e "$mmstuff\nMMPLL,1,$xnwd,$ynwd\nMMPLL,2,$xned,$yned\nMMPLL,3,$xsed,$ysed\nMMPLL,4,$xswd,$yswd\n")

        footer2=$(/bin/echo "MOP,Map Open Position,$(echo $maxx/2|bc),$(echo $maxy/2|bc)\nIWH,Map Image Width/Height,$maxx,$maxy")
        #echo -n "Footer1: $footer1"    


        footer=$(/bin/echo -e "$footer1\n$mmstuff\n$footer2")

        echo $header
        echo $newfirst
        echo $newsecond
        echo $newthird 
        echo $fourthline
        echo $footer

        return
}

for i in *.map *.MAP ; do
        if [ -f $i ] ; then
                /bin/echo -n "processing $i "
                cp $i $i.orig
                mapconvert $i |todos > $i.new
                mv $i.new $i
                echo "done"
        fi
done

Skripti on todettu toimivaksi Ubuntu 9.04, netpbm, php-cli vaaditaan nyt ainakin. Edellisessä kutsuttu kkj2wgs84.php skripti:

<?php

# from http://www.viestikallio.fi/tools/kkj-funcs.php?source=1

# From http://www.kolumbus.fi/eino.uikkanen/geodocsgb/ficoords.htm 
# info that dx,dy,dz = (-74  -229 -88)

# 13 Aug 09 Harald

# Input:  KKJ[La]  is Latitude in Radians, north is positive
#         KKJ[Lo]  is Longitude in Radians, east is positive
# Output: WGS[La]  is Latitude in Radians, north is positive
#         WGS[Lo]  is Longitude in Radians, east is positive
#
# Accuracy has some limitations in range of 0.2-1.0 meters
#

# $KKJ is an array

$in_arr=read_data();

# Convert input given as "60, 11.4100,N,  24, 37.0800,E" into deg
//$in_split=split(",", $in_arr[0]);
//print_r($in_split);

$KKJ[La]=deg2rad($in_arr[0]);
$KKJ[Lo]=deg2rad($in_arr[1]);

$wgs=KKJlalo_to_WGSlalo($KKJ);

//echo "input KKJ:  " . $in_arr[0] . ":" . $in_arr[1] . "\n"; // in_arr[1];
//echo rad2deg($wgs[La]). ":" . rad2deg($wgs[Lo]) . "\n";

//echo "output WGS2: " . fmtddd($wgs[La], 1) . ":" . fmtddd($wgs[Lo], 0) . "\n";
//echo "output DMM: " . fmtdmm($wgs[La], 1) . ":" . fmtdmm($wgs[Lo], 0) . "\n";

// OZI output:
echo fmtozi($wgs[La], 1) . ":" . fmtozi($wgs[Lo], 0) . "\n";

# 
function dms2deg($deg,$min,$sec) {
    $sign = 1;
    if ($deg < 0) {
        $sign = -1;
        $deg = -$deg;
    }
    $deg = $deg + $min / 60.0 + $sec / 3600.0;
    return ($deg * $sign);
}

# input is expected to be "60.12345:21.2313123" (lat:lon) in decimal
# Output ??
function KKJlalo_to_WGSlalo($KKJ) {

    $La = rad2deg( $KKJ[La] );
    $Lo = rad2deg( $KKJ[Lo] );
    //$La=$KKJ[La];
    //$Lo=$KKJ[Lo];

    $dLa = deg2rad(  0.124867E+01       +
                     -0.269982E+00 * $La +
                     0.191330E+00 * $Lo +
                     0.356119E-02 * $La * $La +
                     -0.122312E-02 * $La * $Lo +
                     -0.335514E-03 * $Lo * $Lo ) / 3600.0;
    $dLo = deg2rad( -0.286111E+02       +
                    0.114183E+01 * $La +
                    -0.581428E+00 * $Lo +
                    -0.152421E-01 * $La * $La +
                    0.118177E-01 * $La * $Lo +
                    0.826646E-03 * $Lo * $Lo ) / 3600.0;

    $WGS[La] = $KKJ[La] + $dLa;
    $WGS[Lo] = $KKJ[Lo] + $dLo;

    return ($WGS);
}

// fopen("php://stdin", 'r')
// fopen("php://stdout")
// fopen("php://stderr")

function fmtddd($angle,$latitude) {

    $res = "E ";
    $deg = rad2deg($angle) + 0.0000000001;
    if ($latitude) { $res = "N"; }
    if ($deg < 0.0) {
        $deg = -$deg;
        $res = "W ";
        if ($latitude) { $res = "S"; }
    }

    return( sprintf("%s%3.9f ",$res,$deg) );
}

function fmtdms($angle,$latitude) {

    $res = "E ";
    $deg = rad2deg($angle);
    if ($latitude) { $res = "N"; }
    if ($deg < 0.0) {
        $deg = -$deg;
        $res = "W ";
        if ($latitude) { $res = "S"; }
    }
    $deg += 0.0000000001;

    $d = floor($deg);
    $deg = 60.0 * ($deg - $d);

    $m = floor($deg);
    $s = 60.0 * ($deg - $m);

    return( sprintf("%s%3d° %02d'%02.4f\"",$res,$d,$m,$s) );
}

function fmtdmm($angle,$latitude) {

    $res = "E ";
    $deg = rad2deg($angle) + 0.0000000001;
    if ($latitude) { $res = "N"; }
    if ($deg < 0.0) {
        $deg = -$deg;
        $res = "W ";
        if ($latitude) { $res = "S"; }
    }

    $d = floor($deg);
    $m = 60.0 * ($deg - $d);

    return( sprintf("%s%3d�%02.7f'",$res,$d,$m) );
}

function fmtozi($angle,$latitude) {

    $res = "E ";
    $deg = rad2deg($angle) + 0.0000000001;
    if ($latitude) { $res = "N"; }
    if ($deg < 0.0) {
        $deg = -$deg;
        $res = "W ";
        if ($latitude) { $res = "S"; }
    }

    $d = floor($deg);
    $m = 60.0 * ($deg - $d);

    return( sprintf("%3d,%02.7f,%s",$d,$m,$res) );
}

function read_data() {

    $in = fopen("php://stdin", "r");
    //set_timeout();
    $in_string = trim(fgets($in, 255));
    //clear_timeout();
    fclose($in);
    $in_arr=split(":", $in_string, 3);
    return $in_arr;
}
?>

tcsh skripti pnmtotb.txt jolla pilkotaan png-kuvia pienemmiksi paloiksi, ja luodaan .tar tiedostoja TrekBuddy:ä varten:

 #!/bin/tcsh

# http://www.trekbuddy.net/forum/viewtopic.php?t=187

# First of all, kudos to kruch for this great program!

# I have an alternative map cutting solution for the Linux/Mac crowd to contribute back to the effort: the attached "pnmtotb" she
ll script. Its advantages over the "gimp" method are:
# - far faster and more efficient, and higher quality output (esp. better color reduction)
# - does the whole job: produces compressed, color-reduced TB map from image (JPEG, PNG, GIF, TIFF, ...) + .map file
# - non-interactive command: easy to batch-process an entire collection
#
# It uses the "netpbm" package which is standard with many Linux installations, and which I highly recommend for batch image proc
essing. To use:
# 1. install the attached "pnmtotb" shell script somewhere in your command path (the ".txt" extension is just to satisfy the foru
m software)
# 2. edit it to set your desired tile size and number of colors (the values in the script are what I use for my Z550i)
# 3. Let's say you have a JPEG image "fiji.jpg" and the "fiji.map" file for it. In that case run "jpegtopnm fiji.jpg | pnmtotb fi
ji". The resulting "fiji.tar" file is your compressed TB map (ta-dah!)
#
# Some more explanation: the first part of the above command, "jpegtopnm", simply converts the JPEG into netpbm's own "pnm" forma
t, which is what "pnmtotb" takes as input. Netpbm contains such converters for many formats. If you had a TIFF, for instance, the
 command would be "tifftopnm fiji.tif | pnmtotb fiji". The "fiji" argument to pnmtotb is the name of the map; it means that the s
cript loooks for "fiji.map" and produces "fiji.tar". (The image can actually be called something else, just give it to the conver
ter as argument.)
# Enjoy,
#- nic

#
# pnmtotb - convert PNM file to TrailBuddy
# version 1.0
# (c) 2007 Nic Schraudolph
# free for non-commercial use
# Disclaimer: not fit for any purpose. use at your won risk.
#
set w=400    # tile width
set h=400    # tile height
set c=16     # number of colors
#
cat - > tmp$$
&& wc $1.map > /dev/null
&& pnmcolormap $c tmp$$ > cmap$$
&& pnmremap -map=cmap$$ tmp$$ | pamdice -o tmpppm -w $w -h $h
&& rm tmp$$ cmap$$
&& mkdir set
&& ls tmpppm_[0-9]*_[0-9]*.ppm | tr '.' '_' | awk -F'_' '{ \
printf("/opt/local/bin/pnmtopng tmpppm_%s_%s.ppm > set/%s_%d_%d.png\n", \
$2, $3, f, w*$3, h*$2);}' f=$1 w=$w h=$h | sh
&& rm tmpppm_*_*.ppm
&& ls set > $1.set
&& tar cf $1.tar $1.map $1.set set
&& rm -rf $1.set set

Vaatii netpbm paketin asentamista. Kutsutaan esim näin;

for i in *.png ; do
  pngtopnm $i | tcsh pnmtotb.txt ${i%.png}
done

Sillä tehdään trekbuddy kartasto kaikista hakemiston .png ja .map tiedostoista.

makeatlas skripti, jolla luodaan nykyisen hakemiston kaikista .tar tiedostoista tar-pakattu atlas TrekBuddyä varten:

#! /bin/bash

# 13 Aug 09 Harald
#   Take dir with *.tar files and create a Trekbuddy atlas

# Go to the dir containing ready tar-files
cwd=$(pwd)

# Create all dirs
mkdir atlas/Merikortit

# Create subdirs, and populate them with the content from tar-files
for i in *.tar ; do 
    mkdir atlas/Merikortit/${i%.tar}
    cd atlas/Merikortit/${i%.tar}/
    tar xf ${cwd}/$i
    cd $cwd
done
# previous unfinished

# Create temporary tba file, only to be inside the index .tar file
echo "Atlas 1.0" > atlas/Merikortit.tba 

# Now we're ready to create a tar-file (atlas file)
cd atlas/
tar -cf Merikortit.tar --exclude=*.png --exclude=*.tar Merikortit.tba Merikortit
# Remove temporary tba, not to be in the finished file
rm Merikortit.tba

# Place the packed charts inside their directories:
cd $cwd
for i in *.tar ; do
    rm -rf atlas/Merikortit/${i%.tar}/*
    cp $i atlas/Merikortit/${i%.tar}/
done

# Now create a zip-file of the lot:
cd $cwd
zip -r merikortit-atlas.zip atlas