cookedcsv.pl to HTML.

index -|- end

Generated: Sat Oct 24 16:35:13 2020 from cookedcsv.pl 2020/07/18 13.2 KB. text copy

#!/usr/bin/perl -w
# NAME: cookedcsv.pl
# AIM: For the 'playback' fLight paths 3D display, read a 'cooked' CSV, and calculate the bounding box
# 18/07/2020 - Review in Dell03
# 30/06/2016 - Initial cut
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use Math::Trig;
use Cwd;
my $os = $^O;
my $perl_dir = '/home/geoff/bin';
my $PATH_SEP = '/';
my $temp_dir = '/tmp';
if ($os =~ /win/i) {
    $perl_dir = 'C:\GTools\perl';
    $temp_dir = $perl_dir;
    $PATH_SEP = "\\";
}
unshift(@INC, $perl_dir);
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n";
require 'fg_wsg84.pl'  or die "Unable to load 'fg_wsg84.pl' Check paths in \@INC...\n";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.6 2020-07-18";
###my $VERS = "0.0.5 2016-06-30";
my $load_log = 0;
my $in_file = '';
my $verbosity = 0;
my $out_file = '';
my $curr_zoom = 12;
my $url_base = "http://a.tile.openstreetmap.org";
my $xg_out = $temp_dir.$PATH_SEP."tempslip.xg";
my $smudge_facter = 20; # percentage to INCREASE BBOX by
my $add_theo_xg = 0;
my $min_ias = 10;

# ### DEBUG ###
my $debug_on = 1;
my $def_file = 'D:\FG\next\playbacks\LFPO-LFPG-cooked.csv';
###my $def_file = 'D:\FG\d-and-c\tracks\VNLK-02-cooked.csv';
###my $def_file = 'D:\FG\d-and-c\tracks\6-27-2016-1-cooked.csv';

my $UL_lat = 27.761329874505222;
my $UL_lon = 86.66015625;
my $LR_lat = 27.683528083787767;
my $LR_lon = 86.748046875;

my $t_ctr_lat = 27.722428979146493;
my $t_ctr_lon = 86.7041015625;

sub get_theo_xg() {
    my $xg = "# Theo lon lat UL $UL_lon $UL_lat LR $LR_lon $LR_lat\n";
    $xg .= "color red\n";
    $xg .= "$UL_lon $UL_lat\n";
    $xg .= "$LR_lon $LR_lat\n";
    $xg .= "NEXT\n";
    $xg .= "color green\n";
    $xg .= "$t_ctr_lon $t_ctr_lat\n";
    $xg .= "NEXT\n";
    $xg .= "anno $t_ctr_lon $t_ctr_lat Tile Ctr\n";
    return $xg;
}

### program variables
my @warnings = ();
my $cwd = cwd();

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    show_warnings($val);
    close_log($outfile,$load_log);
    exit($val);
}


sub prtw($) {
   my ($tx) = shift;
   $tx =~ s/\n$//;
   prt("$tx\n");
   push(@warnings,$tx);
}

###########################################################

sub getTileNumber($$$) {
    my ($lat,$lon,$zoom) = @_;
    my $z2 = 2 ** $zoom;
    my $xtile = int( ($lon+180)/360 * $z2 ) ;
    my $ytile = int( (1 - log(tan(deg2rad($lat)) + sec(deg2rad($lat)))/pi)/2 * $z2 ) ;
    return ($xtile, $ytile);
}

sub getLonLat {
   my ($xtile, $ytile, $zoom) = @_;
   my $n = 2 ** $zoom;
   my $lon_deg = $xtile / $n * 360.0 - 180.0;
   my $lat_deg = rad2deg(atan(sinh(pi * (1 - 2 * $ytile / $n))));
   return ($lon_deg, $lat_deg);
}


##########################################################
sub get_double_stg($) {
    my $d = shift;
    my $cd = sprintf("%4.10f",$d);
    return $cd;
}
sub get_double($) {
    my $d = shift;
    return get_double_stg($d);
}

##########################################################
sub get_minmax_ref() {
    my @a = (200,200,-200,-200);
    return \@a;
}
sub set_minmax_ref($$$) {
    my ($rmm,$lat,$lon) = @_;
    ${$rmm}[0] = $lon if ($lon < ${$rmm}[0]);
    ${$rmm}[1] = $lat if ($lat < ${$rmm}[1]);
    ${$rmm}[2] = $lon if ($lon > ${$rmm}[2]);
    ${$rmm}[3] = $lat if ($lat > ${$rmm}[3]);
}

sub expand_minmax_ref($$) {
    my ($rmm,$factor) = @_;
    return if ($factor <= 0);
    my $min_lon = ${$rmm}[0];
    my $min_lat = ${$rmm}[1];
    my $max_lon = ${$rmm}[2];
    my $max_lat = ${$rmm}[3];
    my $lon_dif = $max_lon - $min_lon;
    my $lat_dif = $max_lat - $min_lat;
    # do we have positive difference
    return if ( !(($lon_dif > 0)&&($lat_dif > 0)) );
    # calculate the smudge factors - in degrees
    my $lon_sm = (($factor / 100) * $lon_dif) / 2;
    my $lat_sm = (($factor / 100) * $lat_dif) / 2;
    # apply the smudge factors
    $min_lon -= $lon_sm;
    $min_lat -= $lat_sm;
    $max_lon += $lon_sm;
    $max_lat += $lat_sm;
    # update the reference
    set_minmax_ref($rmm,$min_lat,$min_lon);
    set_minmax_ref($rmm,$max_lat,$max_lon);
}

sub get_minmax_ref_xg($$) {
    my ($rmm,$color) = @_;
    my $min_lon = ${$rmm}[0];
    my $min_lat = ${$rmm}[1];
    my $max_lon = ${$rmm}[2];
    my $max_lat = ${$rmm}[3];
    my $xg = "# BBOX: $min_lon,$min_lat,$max_lon,$max_lat\n";
    $xg .= "color $color\n";
    $xg .= "$min_lon $min_lat\n";
    $xg .= "$min_lon $max_lat\n";
    $xg .= "$max_lon $max_lat\n";
    $xg .= "$max_lon $min_lat\n";
    $xg .= "$min_lon $min_lat\n";
    $xg .= "NEXT\n";
    return $xg;
}

###########################################################################
# assumed CSV input, like
# lon,lat,alt,hdg,ias,roll,pitch,slip
# lon,         lat,          alt,hdg,ias,roll,pitch,slip
# 2.3768278670,48.7177639931,287,18,0,-0.019473,4.617867,0.000000
# 2.3768278696,48.7177639904,287,18,3,-0.007387,4.627360,-71.801193
# ...

sub process_in_file($) {
    my ($inf) = @_;
    if (! open INF, "<$inf") {
        pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); 
    }
    my @lines = <INF>;
    close INF;
    my $lncnt = scalar @lines;
    prt("Processing $lncnt lines, from [$inf]...\n");
    my ($line,$inc,$lnn,@arr,$len);
    my ($lon,$lat,$alt,$hdg,$ias,$roll,$pitch,$slip);
    my ($spanx,$spany);
    my $min_lon = 200;
    my $max_lon = -200;
    my $min_lat = 200;
    my $max_lat = -200;
    my $z = $curr_zoom;
    my $rmm = get_minmax_ref();
    my $rmmt = get_minmax_ref();
    $lnn = 0;
    my $xg = "color yellow\n";
    my $skipped_ias = 0;
    my $points_added = 0;
    foreach $line (@lines) {
        chomp $line;
        $lnn++;
        @arr = split(",",$line);
        $len = scalar @arr;
        if ($lnn == 1) {
            prt("$lnn: $line, items $len\n");
            next;
        }
        if ($len < 8) {
            prt("$lnn: BAD length, got $len, expect 8\n");
            next;
        }
        $lon = $arr[0];
        $lat = $arr[1];
        $alt = $arr[2];
        $hdg = $arr[3];
        $ias = $arr[4];
        set_minmax_ref($rmm,$lat,$lon);
        $min_lon = $lon if ($lon < $min_lon);
        $max_lon = $lon if ($lon > $max_lon);
        $min_lat = $lat if ($lat < $min_lat);
        $max_lat = $lat if ($lat > $max_lat);
        if ($min_ias && ($ias >= $min_ias)) {
            $xg .= "$lon $lat ; $alt $hdg $ias\n";
            $points_added++;
        } else {
            $skipped_ias++;
        }
    }
    $xg .= "NEXT\n";
    prt("Processed $lncnt lines, added $points_added route pts, skipped $skipped_ias due ias\n");
    $spanx = $max_lon - $min_lon;
    $spany = $max_lat - $min_lat;
    prt("BBOX: $min_lon,$min_lat,$max_lon,$max_lat\n");
    $xg .= "# BBOX: $min_lon,$min_lat,$max_lon,$max_lat\n";
    $lon = ($min_lon + $max_lon) / 2;
    $lat = ($min_lat + $max_lat) / 2;
    $xg .= "color gray\n";
    $xg .= "$min_lon $min_lat\n";
    $xg .= "$min_lon $max_lat\n";
    $xg .= "$max_lon $max_lat\n";
    $xg .= "$max_lon $min_lat\n";
    $xg .= "$min_lon $min_lat\n";
    $xg .= "NEXT\n";
    $xg .= "# Expand the boundaries by $smudge_facter% in all directions...\n";
    expand_minmax_ref($rmm,$smudge_facter);
    $xg .= get_minmax_ref_xg($rmm,'white');

    prt("Center: lon/lat $lon,$lat, span x,y $spanx,$spany\n");


    my ($x,$y) = getTileNumber($lat,$lon,$z);
    my $dir = "/$z/$x/$y.png";
    prt("PNG: $url_base$dir\n");
    $xg .= "# PNG: $url_base$dir\n";
    my ($x1,$y1) = getTileNumber($lat,$lon,10);
    my $dir2 = "/10/$x1/$y1.png";
    prt("PNG: $url_base$dir2\n");
    #$xg .= "# PNG: $url_base$dir\n";

    my ($tl_lon, $tl_lat) = getLonLat($x+0,$y+0,$z);
    my ($bl_lon, $bl_lat) = getLonLat($x+0,$y+1,$z);
    my ($tr_lon, $tr_lat) = getLonLat($x+1,$y+0,$z);
    my ($br_lon, $br_lat) = getLonLat($x+1,$y+1,$z);
    my $ctr_lat = ($tl_lat + $br_lat) / 2;
    my $ctr_lon = ($tl_lon + $br_lon) / 2;
    my ($cx, $cy) = getTileNumber($ctr_lat,$ctr_lon,$z);
    set_minmax_ref($rmmt,$tl_lat,$tl_lon);
    set_minmax_ref($rmmt,$bl_lat,$bl_lon);
    set_minmax_ref($rmmt,$tr_lat,$tr_lon);
    set_minmax_ref($rmmt,$br_lat,$br_lon);

    prt("Center: lat,lon ".get_double($ctr_lat).",".get_double($ctr_lon));
    prt(" (".get_double(($bl_lat + $tr_lat) / 2).",".get_double(($bl_lon+$tr_lon) / 2));
    prt(" /z/cx/cy.png /$z/$cx/$cy.png\n");
    prt("\n");
    #                                  x    y    z
    prt("TL ".get_double($tl_lat).",".get_double($tl_lon)." y+0,x+0 ".($x+0).",".($y+0)."\n");
    prt("BL ".get_double($bl_lat).",".get_double($bl_lon)." y+1,x+0 ".($x+0).",".($y+1)."\n");
    prt("TR ".get_double($tr_lat).",".get_double($tr_lon)." y+0,x+1 ".($x+1).",".($y+0)."\n");
    prt("BR ".get_double($br_lat).",".get_double($br_lon)." y+1,x+1 ".($x+1).",".($y+1)."\n");
    prt("\n");
    # $xg .= "color blue\n";
    # $xg .= "$bl_lon $bl_lat\n";
    # $xg .= "$tl_lon $tl_lat\n";
    # $xg .= "$tr_lon $tr_lat\n";
    # $xg .= "$br_lon $br_lat\n";
    # $xg .= "$bl_lon $bl_lat\n";
    # $xg .= "NEXT\n";
    $xg .= get_minmax_ref_xg($rmmt,'blue');

    $xg .= get_theo_xg() if ($add_theo_xg);

    rename_2_old_bak($xg_out);
    write2file($xg,$xg_out);
    prt("Written xg to $xg_out\n");

}

#########################################
### MAIN ###
parse_args(@ARGV);
process_in_file($in_file);
pgm_exit(0,"");
########################################

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av);
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    my $verb = VERB2();
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                $verb = VERB2();
                prt("Verbosity = $verbosity\n") if ($verb);
            } elsif ($sarg =~ /^l/) {
                if ($sarg =~ /^ll/) {
                    $load_log = 2;
                } else {
                    $load_log = 1;
                }
                prt("Set to load log at end. ($load_log)\n") if ($verb);
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if ($verb);
            } elsif ($sarg =~ /^s/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $min_ias = $sarg;
                if ($min_ias =~ /^\d+$/) {
                    prt("Set min. IAS to [$min_ias].\n") if ($verb);
                } else {
                    pgm_exit(1,"ERROR: Invalid argument '$arg $sarg'! Only integer allowed\n");
                }
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $in_file = $arg;
            prt("Set input to [$in_file]\n") if ($verb);
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        if (length($in_file) ==  0) {
            $in_file = $def_file;
            prt("Set DEFAULT input to [$in_file]\n");
            $load_log = 1;
            #$min_ias = 10;
        }
    }
    if (length($in_file) ==  0) {
        pgm_exit(1,"ERROR: No input files found in command!\n");
    }
    if (! -f $in_file) {
        pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n");
    }
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] in-file\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
    prt(" --speed <ias> (-s) = Only records that have this IAS. 0 to disable. (def=$min_ias)\n");

}

# eof - cookedcsv.pl

index -|- top

checked by tidy  Valid HTML 4.01 Transitional