[BACK]Return to igc_tool.pl CVS log [TXT][DIR] Up to [tkperl]

Annotation of igc_tool.pl, Revision 1.1

1.0       philip      1: #! /usr/bin/perl -w
                      2: use Tk;
                      3: use Tk::widgets qw/Dialog ErrorDialog ROText/;
                      4: use Time::Local qw/timegm_nocheck timelocal/;
                      5: use strict;
                      6:
                      7: my $mw = MainWindow->new;
                      8: $mw->CmdLine;
                      9: $mw->title("IGC log tool");
                     10: $mw->configure(-menu => my $menubar = $mw->Menu);
                     11:
                     12: my $file = $menubar->cascade(qw/-label File -underline 0 -menuitems/ =>
                     13:     [
1.1     ! philip     14:      [command    => 'Open IGC', -command => [\&load_igc]],
        !            15:      [command    => 'Open DAT', -command => [\&load_dat]],
1.0       philip     16:      [command    => 'Exit', -command => [\&exit]],
                     17:     ]);
                     18:
                     19: my $igc = $menubar->cascade(qw/-label Log -underline 0 -menuitems/ =>
                     20:     [
1.1     ! philip     21:      [command    => 'Open IGC', -command => [\&load_igc]],
1.0       philip     22:      [command    => 'Barograph', -command => [\&baro]],
                     23:      [command    => 'Track map', -command => [\&map]],
                     24:      [command    => 'Generate Mapfile', -command => [\&generate_tab]],
                     25:      [command    => 'Split log', -command => [\&logsplit]],
                     26:     ]);
                     27:
1.1     ! philip     28: my $turnpoints = $menubar->cascade(qw/-label Turnpoints -underline 0 -menuitems/ =>
        !            29:     [
        !            30:      [command    => 'Open DAT', -command => [\&load_dat]],
        !            31:      [command    => 'View list', -command => [\&tpdump]],
        !            32:      [command    => 'View task', -command => [\&taskdump]],
        !            33:      [command    => 'Turn/Task', -command => [\&tplist]],
        !            34:     ]);
        !            35:
1.0       philip     36: my $help = $menubar->cascade(qw/-label Help -underline 0 -menuitems/ =>
                     37:     [
                     38:       [command => 'About'],
                     39:       [command => 'Usage'],
                     40:       [command => 'Barograph'],
                     41:       [command => 'Track map'],
                     42:       [command => 'Split log'],
                     43:     ]);
                     44:
                     45: my $DIALOG_ABOUT = $mw->Dialog(
                     46:     -title          => 'About IGC tool',
                     47:     -bitmap         => 'info',
                     48:     -default_button => 'OK',
                     49:     -buttons        => ['OK'],
                     50:     -text           => "IGC log tool\nWindows version\nPhilip Plane\n" .
                     51:                       "6 March 2006\n\nPerl Version $]" .
                     52:                        "\nTk Version $Tk::VERSION",
                     53: );
                     54:
                     55: $help->cget(-menu)->entryconfigure('About',
                     56:     -command => [$DIALOG_ABOUT => 'Show'],
                     57: );
                     58:
                     59: my $DIALOG_USAGE = $mw->Dialog(
                     60:     -title          => 'Using IGC tool',
                     61:     -bitmap         => 'info',
                     62:     -default_button => 'OK',
                     63:     -buttons        => ['OK'],
                     64:     -text           => "To use the IGC tool, first open an IGC log file " .
                     65:                       "from the File menu. The text of the log will " .
                     66:                        "be displayed in the main window. " .
                     67:                        "When a file has been loaded the actions in the Log " .
                     68:                        "menu can be applied to the log.",
                     69: );
                     70:
                     71: $help->cget(-menu)->entryconfigure('Usage',
                     72:     -command => [$DIALOG_USAGE => 'Show'],
                     73: );
                     74:
                     75: my $DIALOG_BARO = $mw->Dialog(
                     76:     -title          => 'Barograph',
                     77:     -bitmap         => 'info',
                     78:     -default_button => 'OK',
                     79:     -buttons        => ['OK'],
                     80:     -text           => "The barograph trace shows height in feet, " .
                     81:                       "and various information from the log. " ,
                     82: );
                     83:
                     84: $help->cget(-menu)->entryconfigure('Barograph',
                     85:     -command => [$DIALOG_BARO => 'Show'],
                     86: );
                     87:
                     88: my $DIALOG_MAP = $mw->Dialog(
                     89:     -title          => 'Track map',
                     90:     -bitmap         => 'info',
                     91:     -default_button => 'OK',
                     92:     -buttons        => ['OK'],
                     93:     -text           => "The track map shows the track from the log file, " .
                     94:                       "any turnpoints in the log file, " .
                     95:                        "and any task in the log file. " .
                     96:                        "Projection is straight xy." .
                     97:                        "Turnpoints are shown as 500 meter circles",
                     98: );
                     99:
                    100: $help->cget(-menu)->entryconfigure('Track map',
                    101:     -command => [$DIALOG_MAP => 'Show'],
                    102: );
                    103:
                    104: my $DIALOG_SPLIT = $mw->Dialog(
                    105:     -title          => 'Split log',
                    106:     -bitmap         => 'info',
                    107:     -default_button => 'OK',
                    108:     -buttons        => ['OK'],
                    109:     -text           => "Some IGC loggers and their software produce logs " .
                    110:                       "that have more than one flight in the log. " .
                    111:                        "The log splitter scans through the log and attempts " .
                    112:                        "to seperate the flights into individual logs. " .
                    113:                        "If the number of logs it finds sounds reasonable, " .
                    114:                        "save the new logs to disk. The log files are named " .
                    115:                        "using the original file name with the eighth character " .
                    116:                        "replaced with a sequence number. ",
                    117: );
                    118:
                    119: $help->cget(-menu)->entryconfigure('Split log',
                    120:     -command => [$DIALOG_SPLIT => 'Show'],
                    121: );
                    122:
                    123: my $text = $mw->Scrolled("ROText")->pack();
                    124:
                    125: # Globals from IGC file
                    126: my $maxalt;
                    127: my $minalt;
                    128: my $maxpres;
                    129: my $minpres;
                    130: my $minlat;
                    131: my $maxlat;
                    132: my $minlon;
                    133: my $maxlon;
                    134: my $mday;
                    135: my $month;
                    136: my $mon;
                    137: my $year;
                    138: my $time;
                    139: my $glider;
                    140: my $cid;
                    141: my $pilot;
                    142: my $recorder;
                    143: my $igcfile;
                    144: my @log;
                    145: my @tp;
                    146: my @task;
                    147: my @track;
                    148:
1.1     ! philip    149: my $mindiff;
        !           150: my $maxdiff;
        !           151:
        !           152: my $lbtask;
        !           153: my $lbturn;
        !           154: my @landings;
        !           155:
        !           156: my $initialdir = "/";
        !           157:
1.0       philip    158: sub load_igc {
                    159:     my $types = [
                    160:                 ['IGC Files','.igc'],
                    161:                 ['IGC Files','.IGC'],
                    162:                 ];
                    163:
1.1     ! philip    164:     my $igc = $mw->getOpenFile(-initialdir=>$initialdir,
1.0       philip    165:                               -filetypes=>$types);
                    166:     if ( defined $igc ){
                    167:        my @igc = split /\//,$igc;
                    168:        $igcfile = pop @igc;
                    169:         open IGC, $igc or die "Can't open $igc : $!\n";
                    170:         my @log = <IGC>;
                    171:         close IGC;
                    172:         $text->delete("1.0",'end');
                    173:        @tp = ();
                    174:        @task = ();
                    175:        @track = ();
1.1     ! philip    176:         @landings = ();
1.0       philip    177:        $maxalt = 0;
                    178:        $minalt = 99999;
                    179:        $maxpres = 0;
                    180:        $minpres = 99999;
                    181:        $minlat = 90;
                    182:        $maxlat = -90;
                    183:        $minlon = 180;
                    184:        $maxlon = 0;
1.1     ! philip    185:         $mindiff = 9999;
        !           186:         $maxdiff = 0;
1.0       philip    187:        my $oh = 0;
                    188:         while ( $_ = shift @log ){
                    189:            s/\r//;
                    190:          SWITCH: {
                    191:              if ( /^HFDTE/ ){
                    192:                  my $date = substr($_,5);
                    193:                  $mday = substr($date,0,2);
                    194:                  $month = substr($date,2,2);
                    195:                  $year = substr($date,-2,2);
                    196:                  $mon = $month - 1;
                    197:                  last SWITCH;
                    198:              }
                    199:              if ( /^H.GID/ ){
                    200:                  $glider = substr($_,5);
                    201:                  last SWITCH;
                    202:              }
                    203:              if ( /^H.CID/ ){
                    204:                  $cid = substr($_,5);
                    205:                  last SWITCH;
                    206:              }
                    207:              if ( /^H.PLT/ ){
                    208:                  $pilot = substr($_,5);
                    209:                  last SWITCH;
                    210:              }
                    211:              if ( /^H.FTY/ ){
                    212:                  $recorder = substr($_,5);
                    213:                  chop $recorder;
                    214:                  last SWITCH;
                    215:              }
                    216:              if ( /^L\D{4}?(\d{5}?)(\d{7}?[NS])(\d{8}?[WE])(\d{6})(.{8}?)(.*)/ ){
                    217:                  # [ lat, lon, id, name, type ]
                    218:                  # turnpoints
                    219:                  my $lat = latitude($2);
                    220:                  my $lon = longitude($3);
                    221:                  push @tp, [ $lat, $lon, $1, $6, $5 ];
                    222:                  last SWITCH;
                    223:              }
                    224:              if ( /^C(\d{7}?[NS])(\d{8}?[WE])(.*)/ ){
                    225:                  # [ lat, lon, name ]
                    226:                  # task
                    227:                  my $lat = latitude($1);
                    228:                  my $lon = longitude($2);
                    229:                  if ( $lat == 0 ){
                    230:                    last SWITCH;
                    231:                  }
                    232:                  push @task, [ $lat, $lon, $3 ];
                    233:                  last SWITCH;
                    234:              }
1.1     ! philip    235:              if ( /^B(\d{6})(\d{7}[NS])(\d{8}?[WE])A(\d{5})(\d{5})/ ){
        !           236:                   $time = $1;
1.0       philip    237:                  my $lat = latitude($2);
                    238:                  my $lon = longitude($3);
                    239:                  my $alt = $4;
                    240:                  my $pres = $5;
1.1     ! philip    241:                   # keep track of the difference between GPS altitude
        !           242:                   # and pressure altitude
        !           243:                   my $diff = $pres - $alt;
        !           244:                   if ( $diff < 0 ){
        !           245:                     $diff = 0 - $diff;
        !           246:                   }
        !           247:                   if ( $diff > $maxdiff ){
        !           248:                     $maxdiff = $diff;
        !           249:                   }
        !           250:                   if ( $diff < $mindiff ){
        !           251:                     $mindiff = $diff;
        !           252:                   }
1.0       philip    253:
                    254:                  # $time is HHMMSS
                    255:                  $time =~ /(\d{2})(\d{2})(\d{2})/;
                    256:                  my $hour = $1;
                    257:                  my $min = $2;
                    258:                  my $sec = $3;
                    259:                  if ( $hour < $oh ) {
                    260:                    $mday++;
                    261:                  }
                    262:                  $oh = $hour;
                    263:                  my $gt = timegm_nocheck($sec,$min,$hour,$mday,$mon,$year);
                    264:
                    265:                  if ( $lat > $maxlat ) {
                    266:                      $maxlat = $lat;
                    267:                  }
                    268:                  if ( $lat < $minlat ) {
                    269:                      $minlat = $lat;
                    270:                  }
                    271:                  if ( $lon > $maxlon ) {
                    272:                      $maxlon = $lon;
                    273:                  }
                    274:                  if ( $lon < $minlon ) {
                    275:                      $minlon = $lon;
                    276:                  }
                    277:
                    278:                  if ( $alt < $minalt ){
                    279:                      $minalt = $alt;
                    280:                  }
                    281:                  if ( $alt > $maxalt ){
                    282:                      $maxalt = $alt;
                    283:                  }
                    284:                  if ( $pres < $minpres ){
                    285:                      $minpres = $pres;
                    286:                  }
                    287:                  if ( $pres > $maxpres ){
                    288:                      $maxpres = $pres;
                    289:                  }
1.1     ! philip    290:
1.0       philip    291:                  push @track, [ $gt, $lat, $lon, $alt, $pres ];
                    292:                  last SWITCH;
                    293:              }
                    294:          }
                    295:            $text->insert('end',$_);
                    296:        }
                    297:     }
                    298: }
                    299:
                    300: sub baro {
                    301:     my $maxrec = scalar @track;
                    302:     if ( $maxrec > 0 ) {
                    303:        my $bwin = $mw->Toplevel();
                    304:        $bwin->title($igcfile . " Barograph");
                    305:        my $bg = $bwin->Scrolled('Canvas', -width => 850, -height => 500, -scrollregion => [-10,-10,1000,1000])->pack();
                    306:        my $id;
                    307:        my $date = sprintf("%02d/%02d/20%02d",$mday,$month,$year);
                    308:        if ( not defined $glider ) {
                    309:            $glider = $cid;
                    310:        }
                    311:         #clean up pilot name, remove extra whitespace
                    312:        if ( defined $pilot ){
                    313:            chop $pilot;
                    314:           while ( $pilot =~ m/  / ){
                    315:            $pilot =~ s/  / /;
                    316:           }
                    317:         }
                    318:         if ( defined $glider ){
                    319:         chop $glider;
                    320:         }
                    321:        my $gps = sprintf("GPS Low point: %5d ft High point: %5d ft",
                    322:            feet($minalt),feet($maxalt));
                    323:        my $pres = sprintf("Alt Low point: %5d ft High point: %5d ft",
                    324:            feet($minpres),feet($maxpres));
                    325:
                    326:        my @t = localtime($track[0][0]);
                    327:        my $start = sprintf("Log started at %02d:%02d:%02d",$t[2],$t[1],$t[0]);
                    328:        my @f = localtime($track[$maxrec - 1][0]);
                    329:        my $finish = sprintf("Log ended at %02d:%02d:%02d",$f[2],$f[1],$f[0]);
                    330:        my $duration = sprintf("Log duration %s",
                    331:             sec2time($track[$maxrec - 1][0] - $track[0][0]));
1.1     ! philip    332:         my $diff = sprintf("GPS/Pressure difference: max %4d ft / min %4d ft",
        !           333:             feet($maxdiff),feet($mindiff));
1.0       philip    334:
                    335:        $id = $bg->createText(10,10, -text => $pilot, -anchor => "w");
                    336:        $id = $bg->createText(410,10, -text => $recorder, -anchor => "w");
                    337:        $id = $bg->createText(10,25, -text => $glider, -anchor => "w");
                    338:        $id = $bg->createText(10,40, -text => $pres,-fill => "red", -anchor => "w");
                    339:        $id = $bg->createText(10,55, -text => $gps, -fill => "blue", -anchor => "w");
                    340:        $id = $bg->createText(10,70, -text => $date, -anchor => "w");
1.1     ! philip    341:         $id = $bg->createText(410,70, -text => $diff, -anchor => "w");
        !           342:         $id = $bg->createText(10,85, -text => $start, -anchor => "w");
1.0       philip    343:        $id = $bg->createText(10,100, -text => $finish, -anchor => "w");
                    344:        $id = $bg->createText(10,115, -text => $duration, -anchor => "w");
                    345:
                    346:        my $width = 800;
                    347:        my $height = 450;
                    348:
                    349:         my $hscale = ($track[$maxrec-1][0] - $track[0][0])/($width - 50);
                    350:        my $vscale = 25;
                    351:        if ($maxalt < 2000){
                    352:            $vscale = 10;
                    353:        }
                    354:        elsif ($maxalt < 4000){
                    355:            $vscale = 15;
                    356:        }
                    357:
                    358:        my $m = $maxalt / 305;
                    359:
                    360:         # Draw lines at 1000ft (305m)
                    361:        for(my $mil = 0;$mil < $m;$mil++){
                    362:            my $ml = 400 - (($mil * 305)/$vscale);
                    363:            $id = $bg->createLine(40,$ml,$width ,$ml, -dash => [6,4]);
                    364:            $id = $bg->createText(35,$ml, -text => sprintf("%5d", 1000 * $mil), -anchor => "e");
                    365:        }
                    366:
                    367:        my $or = 400 - ( $track[0][4] / $vscale);
                    368:        my $ob = 400 - ( $track[0][3] / $vscale);
                    369:        my $ox = 30;
                    370:         # munch through the track array [ $gt, $lat, $lon, $alt, $pres ]
                    371:         my $osec = $track[0][0];
                    372:         my $olat = $track[0][1];
                    373:         my $olon = $track[0][2];
                    374:         my $oalt = $track[0][3];
                    375:         my $opres = $track[0][4];
                    376:         my $launch = 0;
1.1     ! philip    377:         my $land = 0;
1.0       philip    378:        for (my $i = 0; $i < $maxrec; $i++) {
                    379:             my $t_sec = $track[$i][0];
                    380:             $t_sec = $t_sec - $track[0][0];
                    381:             my $x = 50 + int($t_sec / $hscale);
                    382:            my $pres = $track[$i][4];
                    383:            my $alt = $track[$i][3];
1.1     ! philip    384:             # figure out the takeoff/landing
1.0       philip    385:             my $dlat = abs($track[$i][1] - $olat);
                    386:            my $dlng = abs($track[$i][2] - $olon);
                    387:            my $dist = sqrt(($dlat*$dlat) + ($dlng*$dlng));
                    388:             my $speed = 0;
                    389:             my $dsec = $t_sec - $osec;
                    390:            $osec = $t_sec;
                    391:            if ( ($dsec > 0) and ($dist > 0)){
                    392:              $speed = $dist / $dsec;
                    393:            }
                    394:            if ( ($speed > 0.000100) and ($oalt < $alt)){
                    395:                $launch++;
1.1     ! philip    396:                 $land = 0;
1.0       philip    397:            }
                    398:             if ( $launch == 3 ) {
                    399:                $id = $bg->createLine($x,400,$x,150, -fill => "black");
                    400:                 $id = $bg->createText($x,140, -text => "takeoff");
                    401:                 $launch++;
                    402:             }
1.1     ! philip    403:            if ( ($speed < 0.0000001) and ($oalt == $alt) and ($launch > 0)){
        !           404:                 $land++;
        !           405:             }
        !           406:             if ( $land == 3 ){
        !           407:                $land = 0;
1.0       philip    408:                $launch = 0;
                    409:                $id = $bg->createLine($x,400,$x,150,-fill => "black");
                    410:                 $id = $bg->createText($x,140, -text => "land");
1.1     ! philip    411:                 push @landings,$track[$i][0];
1.0       philip    412:            }
1.1     ! philip    413:
1.0       philip    414:            my $y = 400 - ( $pres/$vscale);
                    415:            $id = $bg->createLine($x,$y,$ox,$or, -fill => "red");
                    416:            $or = $y;
                    417:            $y = 400 - ($alt/$vscale);
                    418:            $id = $bg->createLine($x,$y,$ox,$ob, -fill => "blue");
                    419:            $ob = $y;
                    420:            $ox = $x;
                    421:             $olat = $track[$i][1];
                    422:             $olon = $track[$i][2];
                    423:             $opres = $pres;
                    424:             $oalt = $alt;
                    425:        }
                    426:         # add the timeticks
                    427:         my @start = localtime($track[0][0]);
                    428:         my @finish = localtime($track[$maxrec-1][0]);
                    429:         for ( my $h = $start[2]+1;
                    430:               $h <= $finish[2];
                    431:               $h++ ){
                    432:           @t = @start;
                    433:           $t[2] = $h;
                    434:           $t[0] = 0;
                    435:           $t[1] = 0;
                    436:           my $t = timelocal(@t);
                    437:           my $x = 50 + int(($t - $track[0][0]) / $hscale);
                    438:          $id = $bg->createText($x,410, -text => sprintf("%02d:00",$h));
                    439:           $id = $bg->createLine($x,400,$x,350, -dash => [3,2],
                    440:                                                -fill => "black");
                    441:         }
                    442:     }
                    443: }
                    444:
                    445: sub map {
                    446:     my $maxrec = scalar @track;
                    447:     if ( $maxrec > 0 ) {
                    448:         my $zone;
                    449:        my $ox;
                    450:        my $oy;
                    451:
                    452:        #use max vertical to set scale as most tracks are taller than wider.
                    453:         my $scale = $maxlat - $minlat;
                    454:
                    455:        my $bwin = $mw->Toplevel();
                    456:        $bwin->title($igcfile . " Flight Track");
                    457:        my $bg = $bwin->Scrolled('Canvas', -width => 850, -height => 600, -scrollregion => [-500,-500,1500,1500])->pack();
                    458:
                    459:        my $width = 1000;
                    460:        my $height = 1000;
                    461:
                    462:        $scale = $height / $scale;
                    463:
                    464:
                    465:        # 500 meter radius circle
                    466:        my $r = .004 * $scale;
                    467:
                    468:        #show the turnpoints
                    469:        my $maxtp = scalar @tp;
                    470:        for (my $t = 0; $t < $maxtp; $t++) {
                    471:             my $y = $height - (($tp[$t][0] - $minlat) * $scale);
                    472:             my $x = ($tp[$t][1] - $minlon) * $scale;
                    473:            my $id = $bg->createText($x, $y + 10 + $r, -text => $tp[$t][3]);
                    474:            $id = $bg->createOval($x - $r, $y - $r, $x + $r, $y + $r);
                    475:        }
                    476:        #show the task
                    477:        my $maxtask = scalar @task;
                    478:        if ( $maxtask > 0 ){
                    479:             $oy = $height - (($task[0][0] - $minlat) * $scale);
                    480:             $ox = ($task[0][1] - $minlon) * $scale;
                    481:        }
                    482:        for (my $t = 0; $t < $maxtask; $t++) {
                    483:             my $y = $height - (($task[$t][0] - $minlat) * $scale);
                    484:             my $x = ($task[$t][1] - $minlon) * $scale;
                    485:            my $id = $bg->createText($x, $y + 10 + $r, -text => $task[$t][2]);
                    486:            $id = $bg->createOval($x - $r, $y - $r, $x + $r, $y + $r, -outline => "green");
                    487:            $id = $bg->createLine($x,$y,$ox,$oy, -dash => [6,4], -fill => "green");
                    488:            $ox = $x;
                    489:            $oy = $y;
                    490:        }
                    491:
                    492:         #prime the pump
                    493:         $oy = $height - (($track[0][1] - $minlat) * $scale);
                    494:         $ox = ($track[0][2] - $minlon) * $scale;
                    495:
                    496:        #show the track
                    497:        for (my $i = 0; $i < $maxrec; $i++) {
                    498:             my $y = $height - (($track[$i][1] - $minlat) * $scale);
                    499:             my $x = ($track[$i][2] - $minlon) * $scale;
                    500:            my $id = $bg->createLine($ox,$oy,$x,$y, -fill => "blue");
                    501:            $ox = $x;
                    502:            $oy = $y;
                    503:        }
                    504:     }
                    505: }
                    506:
                    507: sub generate_tab {
                    508:  my $header = "sTrackDescr\tiTrkID\tiColor\tsTimestamp\tfLat\tfLong\tfAlt\tfEasting\tfNorthing\n";
                    509: #IGClog        123             3:21    44.500000       170.200000      123.0
1.1     ! philip    510:  my $tab = $mw->getSaveFile(-initialdir=>$initialdir,
1.0       philip    511:                            -initialfile=>'tracklog.txt');
                    512:  if ( defined $tab ){
                    513:   open TXT, "> " . $tab or die "Couldn't open file $tab: $!\n";
                    514:   print TXT $header;
                    515:   my $maxrec = scalar @track;
                    516:   for (my $i = 0; $i < $maxrec; $i++) {
                    517:    my @now = localtime($track[$i][0]);
                    518:    print TXT "IGCLog\t001\t\t";
                    519:    printf TXT ("%02d:%02d:%02d\t",$now[2], $now[1], $now[0]);
                    520:    printf TXT ("%6f\t%6f\n",$track[$i][1], $track[$i][2]);
                    521:   }
                    522:   close TXT;
                    523:  }
                    524: }
1.1     ! philip    525:
1.0       philip    526: sub logsplit {
                    527:     my $maxrec = scalar @log;
                    528:     my $osec = 0;
                    529:     my $igccore;
                    530:     my $igccount = 0;
                    531:     my @logs =();
                    532:
                    533:     for (my $i = 0; $i < $maxrec; $i++) {
                    534:        if ( $log[$i] =~ /^B(\d{6})(\d{7}[NS])(\d{8}?[WE]).{1}(\d{5})(\d{5})/ ){
                    535:            my $alt = $4;
                    536:            my $time = $1;
                    537:            $time =~ /(\d{2})(\d{2})(\d{2})/;
                    538:            my $sec = ($1 *3600) + ($2 * 60) + $3;
                    539:            # if the current second is less than the previous, time
                    540:            # has gone backwards. This indicates you've crossed the
                    541:            # boundry of a new day.
                    542:            if ( $sec < $osec ) {
                    543:                $osec -= 86400;
                    544:            }
                    545:            # if the gap in the log is more than sixty seconds assume that
                    546:            # it's a new flight
                    547:            if (( $sec - $osec ) > 60){
                    548:                 $logs[$igccount++] = $igccore;
                    549:                $igccore = "";
                    550:            }
                    551:            $osec = $sec;
                    552:        }
                    553:        $igccore .= $log[$i];
                    554:     }
                    555:     $logs[$igccount] = $igccore;
                    556:     my $split = $mw->Dialog(
                    557:     -title          => 'Split IGC log file',
                    558:     -bitmap         => 'question',
                    559:     -default_button => 'OK',
                    560:     -buttons        => ['OK','Cancel'],
                    561:     -text           => "Found $igccount logs.\nWant to create seperate log files for them?\n",
                    562:     )->Show();
                    563:     if ($split eq 'OK'){
                    564:         for (my $i = 1; $i <= $igccount; $i++) {
                    565:            substr($igcfile,7,1) = $i;
1.1     ! philip    566:            my $frag = $mw->getSaveFile(-initialdir=>$initialdir,
1.0       philip    567:                            -initialfile=>$igcfile);
                    568:            if ( defined $frag ){
                    569:             open TEMP, ">" . $frag or die "Couldn't open $frag: $!\n";
                    570:             print TEMP $logs[0], $logs[$i];
                    571:             close TEMP;
                    572:            }
                    573:         }
                    574:     }
                    575: }
                    576:
1.1     ! philip    577:
        !           578: sub load_dat {
        !           579:     # @tp
        !           580:     # [ lat, lon, id, name, type ]
        !           581:     # Cambridge turnpoints file
        !           582:     #1,44:29.080S,169:58.660E,1380F,TAH,01-Omarama  ,*EastEnd Rwa
        !           583:     my $types = [
        !           584:                 ['DAT Files','.dat'],
        !           585:                 ['DAT Files','.DAT'],
        !           586:                 ];
        !           587:
        !           588:     my $dat = $mw->getOpenFile(-initialdir=>$initialdir,
        !           589:                               -filetypes=>$types);
        !           590:     if ( defined $dat ){
        !           591:         my $count = 0;
        !           592:         @tp = ();
        !           593:        my @dat = split /\//,$dat;
        !           594:        my $datfile = pop @dat;
        !           595:         open DAT, $dat or die "Can't open $dat : $!\n";
        !           596:         my @log = <DAT>;
        !           597:         close DAT;
        !           598:         while ( $_ = shift @log ){
        !           599:             if ( $_ =~ /^\d/ ){
        !           600:                @dat = split(/\,/,$_);
        !           601:                 if ( $dat[4] =~ /T|S|F/ ){
        !           602:                         if ( $dat[5] eq "" ) {
        !           603:                           $dat[5] = $dat[0];
        !           604:                         }
        !           605:                         $tp[$count][0] = datlat($dat[1]);
        !           606:                         $tp[$count][1] = datlng($dat[2]);
        !           607:                         $tp[$count][2] = $dat[0];
        !           608:                         $tp[$count][3] = $dat[5];
        !           609:                         $tp[$count][4] = $dat[4];
        !           610:                         $count++;
        !           611:                 }
        !           612:             }
        !           613:        }
        !           614:     }
        !           615: }
        !           616:
        !           617: sub datlat{
        !           618:   #44:29.080S
        !           619:   my $lat = shift @_;
        !           620:   $lat =~ /(\d{2})\:(\d{2}\.\d{3})([SN])/;
        !           621:   my $degrees = $1;
        !           622:   my $min = $2;
        !           623:   my $hemi = $3;
        !           624:   $min = $min * 0.0166666667;
        !           625:   $degrees = $degrees + $min;
        !           626:   if ( $hemi eq 'S' ){
        !           627:     $degrees = 0 - $degrees;
        !           628:   }
        !           629:   return $degrees;
        !           630: }
        !           631:
        !           632: sub datlng{
        !           633:   #169:58.660E
        !           634:   my $lng = shift @_;
        !           635:   $lng =~ /(\d{3})\:(\d{2}\.\d{3})([WE])/;
        !           636:   my $degrees = $1;
        !           637:   my $min = $2;
        !           638:   my $hemi = $3;
        !           639:   $min = $min * 0.0166666667;
        !           640:   $degrees = $degrees + $min;
        !           641:   if ( $hemi eq 'W' ){
        !           642:     $degrees = 0 - $degrees;
        !           643:   }
        !           644:   return $degrees;
        !           645: }
        !           646:
        !           647: sub tpdump {
        !           648:   #show the turnpoints
        !           649:   my $maxtp = scalar @tp;
        !           650:   $text->delete("1.0",'end');
        !           651:   for (my $t = 0; $t < $maxtp; $t++) {
        !           652:     my $tmp = sprintf("%6.2f %6.2f %s\n",$tp[$t][0], $tp[$t][1], $tp[$t][3]);
        !           653:     $text->insert('end',$tmp);
        !           654:   }
        !           655: }
        !           656:
        !           657: sub taskdump {
        !           658:   #show task
        !           659:   my $maxrec = scalar @task;
        !           660:   $text->delete("1.0".'end');
        !           661:   for (my $t = 0; $t < $maxrec; $t++) {
        !           662:     my $tmp = sprintf("%6.2f %6.2f %s\n",$task[$t][0], $task[$t][1], $task[$t][2]);
        !           663:     $text->insert('end',$tmp);
        !           664:   }
        !           665: }
        !           666:
        !           667: sub tplist {
        !           668:     my $maxrec = scalar @tp;
        !           669:     if ( $maxrec > 0 ) {
        !           670:        my $bwin = $mw->Toplevel();
        !           671:         $bwin->title("Turnpoints");
        !           672:         $bwin->minsize(175,50);
        !           673:         $bwin->Label(-text=>"Turnpoints")->grid( "x", $bwin->Label(-text=>"Task"));
        !           674:
        !           675:        $lbturn = $bwin->Scrolled("Listbox",
        !           676:                -scrollbars => "e",
        !           677:                 -selectmode => "single")->grid(-row=> 0,
        !           678:                                                -column=> 0,
        !           679:                                                -rowspan=> 2,
        !           680:                                                -sticky=> "nsew");
        !           681:
        !           682:        $bwin->Button(-text=>"Add ->",
        !           683:                    -command=> \&add_to_task
        !           684:                     )->grid(-row=> 0,
        !           685:                             -column=> 1,
        !           686:                             -sticky=> "sew");
        !           687:
        !           688:        $lbtask = $bwin->Scrolled("Listbox",
        !           689:                -scrollbars => "e",
        !           690:                 -selectmode => "single")->grid(-row=> 0,
        !           691:                                                -column=> 2,
        !           692:                                                -rowspan=> 2,
        !           693:                                                -sticky=> "nsew");
        !           694:
        !           695:        $bwin->Button(-text=>"Del <-",
        !           696:                     -command=> \&del_from_task
        !           697:                     )->grid(-row=> 1,
        !           698:                             -column=> 1,
        !           699:                             -sticky=> "new");
        !           700:         #populate the turnpoint list
        !           701:         $lbturn->delete("1.0",'end');
        !           702:        for (my $t = 0; $t < $maxrec; $t++) {
        !           703:          $lbturn->insert('end',$tp[$t][3]);
        !           704:        }
        !           705:         # populate the task
        !           706:         $maxrec = scalar @task;
        !           707:         $lbtask->delete("1.0",'end');
        !           708:        for (my $t = 0; $t < $maxrec; $t++) {
        !           709:          $lbtask->insert('end',$task[$t][2]);
        !           710:        }
        !           711:
        !           712:     }
        !           713: }
        !           714:
        !           715: sub add_to_task {
        !           716:        my @selection = $lbturn->curselection();
        !           717:         foreach ( @selection ){
        !           718:                my $turnpoint = $lbturn->get($_);
        !           719:                 $lbtask->insert('end',$turnpoint);
        !           720:         }
        !           721: }
        !           722:
        !           723: sub del_from_task {
        !           724:        my @selection = $lbtask->curselection();
        !           725:         foreach ( @selection ){
        !           726:                $lbtask->delete($_);
        !           727:         }
        !           728: }
1.0       philip    729:
                    730: sub feet{
                    731:     my $meters = shift @_;
                    732:     my $feet = $meters * 3.2808399;
                    733:     return int($feet);
                    734: }
                    735:
                    736: sub duration{
                    737:     # expects 2 parameters, start time and finish time
                    738:     my $start = shift @_;
                    739:     my $end = shift @_;
                    740:     my $ss = seconds($start);
                    741:     my $se = seconds($end);
                    742:     # if we finished before we started, we crossed the day boundry
                    743:     if ( $se < $ss ) {
                    744:       $se += 60 * 60 * 24;
                    745:     }
                    746:     return $se - $ss;
                    747: }
                    748:
                    749: sub seconds{
                    750:     my $time = shift @_;
                    751:     my $hours = substr($time,0,2);
                    752:     my $minutes = substr($time,2,2);
                    753:     my $seconds = substr($time,4,2);
                    754:     return $seconds + ($minutes * 60) + ($hours * 60 * 60);
                    755: }
                    756:
                    757: sub sec2time{
                    758:     my $sec = shift @_;
                    759:     my $hours = int($sec / 3600);
                    760:     $sec = $sec % 3600;
                    761:     my $minutes = int($sec / 60);
                    762:     $sec = $sec % 60;
                    763:     return sprintf("%02d:%02d:%02d",$hours,$minutes,$sec);
                    764: }
                    765:
                    766: sub latitude{
                    767:   my $lat = shift @_;
                    768:   my $degrees = substr($lat,0,2);
                    769:   my $min = '0.' . substr($lat,2,5);
                    770:   $min = $min * 1.66666667;
                    771:   $degrees = $degrees + $min;
                    772:   my $hemi = substr($lat,-1);
                    773:   if ( $hemi eq 'S' ){
                    774:     $degrees = 0 - $degrees;
                    775:   }
                    776:   return $degrees;
                    777: }
                    778:
                    779: sub longitude{
                    780:   my $lon = shift @_;
                    781:   my $degrees = substr($lon,0,3);
                    782:   my $min = '0.' . substr($lon,3,5);
                    783:   $min = $min * 1.66666667;
                    784:   $degrees = $degrees + $min;
                    785:   my $hemi = substr($lon,-1);
                    786:   if ( $hemi eq 'W' ){
                    787:     $degrees = 0 - $degrees;
                    788:   }
                    789:   return $degrees;
                    790: }
                    791:
                    792: MainLoop;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>