#!/usr/bin/perl -w # NAME: cntnavtypes.pl # AIM: *** VERY SPECIFIC *** Count x-plane navaids in earth_nav_dat use strict; use warnings; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) 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 ...\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.2 2014-01-13"; my $load_log = 0; my $in_file = 'D:\FG\xplane\1000\earth_nav.dat'; my $verbosity = 0; my $out_file = $temp_dir.$PATH_SEP."earth_nav.csv"; my $out_file2 = $temp_dir.$PATH_SEP."clean-nav.csv"; # ### DEBUG ### my $debug_on = 0; my $def_file = 'def_file'; ### 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); } my %navtypes = ( 2 => 'NDB', 3 => 'VOR', 4 => 'ILS', 5 => 'LOC', 6 => 'GS', 7 => 'OM', 8 => 'MM', 9 => 'IM', 12 => 'V-DME', 13 => 'O-DME' ); # sort by type sub mycmp_ascend_n0 { return -1 if (${$a}[0] < ${$b}[0]); return 1 if (${$a}[0] > ${$b}[0]); return 0; } # sort by ID text sub mycmp_ascend_t7 { return -1 if (${$a}[7] lt ${$b}[7]); return 1 if (${$a}[7] gt ${$b}[7]); return 0; } # sort by freq number sub mycmp_ascend_n4 { return -1 if (${$a}[4] < ${$b}[4]); return 1 if (${$a}[4] > ${$b}[4]); return 0; } # 0 1 2 3 4 5 6 7 8 # typ latitude longitude elev freq rng brng id name # 2 38.08777778 -077.32491667 0 396 50 0.0 APH A P HILL NDB sub party_with_navaids($) { my $rn = shift; ###my @navs = sort mycmp_ascend_n4 @{$rn}; my $max = scalar @{$rn}; prt("Partying with $max navaids... outing where freq and id are equal...\n"); my ($typ,$lat,$lon,$alt,$frq,$rng,$brg,$id,$name); my ($i,$ra,$j,$ra2,$fnd,$i2); my ($typ2,$lat2,$lon2,$alt2,$frq2,$rng2,$brg2,$id2,$name2); my ($ret,$az1,$az2,$dist,$km,$rak); my ($nlen,$nlen2); my %done = (); my @nnavs = (); my %had = (); for ($i = 0; $i < $max; $i++) { $ra = ${$rn}[$i]; $typ = ${$ra}[0]; $lat = ${$ra}[1]; $lon = ${$ra}[2]; $alt = ${$ra}[3]; $frq = ${$ra}[4]; $rng = ${$ra}[5]; $brg = ${$ra}[6]; $id = ${$ra}[7]; $name = ${$ra}[8]; if ($id eq '----') { push(@nnavs,$ra); # push this ONE to keep next; } if ($frq == 0) { push(@nnavs,$ra); # push this ONE to keep next; } next if (defined $done{$i}); if (($typ == 4)||($typ == 5)||($typ == 6)) { push(@nnavs,$ra); # push this ONE to keep next; } $done{$i} = 1; $fnd = 0; $rak = $ra; %had = (); $had{$typ} = 1; # had this type for ($j = $i + 1; $j < $max; $j++) { next if (defined $done{$j}); $ra2 = ${$rn}[$j]; $typ2 = ${$ra2}[0]; $lat2 = ${$ra2}[1]; $lon2 = ${$ra2}[2]; $alt2 = ${$ra2}[3]; $frq2 = ${$ra2}[4]; $rng2 = ${$ra2}[5]; $brg2 = ${$ra2}[6]; $id2 = ${$ra2}[7]; $name2 = ${$ra2}[8]; next if ($id2 eq '----'); next if ($frq2 == 0); next if (($typ2 == 4)||($typ2 == 5)||($typ2 == 6)); if ( ($id eq $id2) && ($frq == $frq2) ) { $ret = fg_geo_inverse_wgs_84($lat, $lon, $lat2, $lon2, \$az1, \$az2, \$dist); $km = $dist / 1000; if ($km < 10) { $km = (int(($km+0.005) * 100) / 100); if ($fnd == 0) { $nlen = length($name); prt("\n1:$i: $typ,$lat,$lon,$alt,$frq,$rng,$brg,$id,$name,$km\n"); } $fnd++; $i2 = $fnd + 1; $nlen2 = length($name2); prt("$i2:$j: $typ2,$lat2,$lon2,$alt2,$frq2,$rng2,$brg2,$id2,$name2,$km\n"); $done{$j} = 1; $had{$typ2} = 1; if ($typ == $typ2) { if ($nlen2 > $nlen) { $nlen = $nlen2; $rak = $ra2; } } elsif ($typ == 3) { if ($typ2 == 12) { $rak = $ra2; } elsif ($typ2 == 13) { if (!defined $had{12}) { $rak = $ra2; } } else { prtw("WARNING: Type $typ and $typ2 duplication NOT checked. *FIX ME*\n"); } } elsif (($typ == 12)&&($typ2 == 13)) { # have aleady selected the 12, so nothing to do here } else { prtw("WARNING: Type $typ and $typ2 duplication NOT checked. *FIX ME*\n"); } } } } push(@nnavs,$rak); # push the ONE to keep } # ======================================== # output the new records @nnavs = sort mycmp_ascend_n0 @nnavs; $max = scalar @nnavs; prt("Done $i records... kept $max...\n"); my $csv = "type,lat,lon,feet,freq,rng,bear,id,name\n"; for ($i = 0; $i < $max; $i++) { $ra = $nnavs[$i]; $typ = ${$ra}[0]; $lat = ${$ra}[1]; $lon = ${$ra}[2]; $alt = ${$ra}[3]; $frq = ${$ra}[4]; $rng = ${$ra}[5]; $brg = ${$ra}[6]; $id = ${$ra}[7]; $name = ${$ra}[8]; $csv .= "$typ,$lat,$lon,$alt,$frq,$rng,$brg,$id,$name\n"; } if (-f $out_file2) { my $msg = "WARNING: $out_file2 ALREADY exists! Delete or rename to write a new one.\n"; if (open INF, "<$out_file2") { my @lines = ; close INF; $max = scalar @lines; $msg .= "It contains $max lines.\n"; } else { $msg .= "But am unable to open it...\n"; } prtw($msg); } else { write2file($csv,$out_file2); prt("Clean navaids written to $out_file2\n"); } $load_log = 1; } sub process_in_file($) { my ($inf) = @_; if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; prt("Processing $lncnt lines, from [$inf]...\n"); my %types = (); my %navids = (); my %navfreqs = (); my ($i,$line,$inc,$lnn,$len,@arr,$typ,$nc); my ($lat,$lon,$alt,$frq,$rng,$brg,$id,$name); my ($off,$ra); $lnn = 0; my $csv = "type,lat,lon,feet,freq,rng,bear,id,name\n"; my @navaids = (); for ($i = 0; $i < $lncnt; $i++) { $lnn++; $line = $lines[$i]; chomp $line; $line = trim_all($line); $len = length($line); next if ($len < 10); # arbitrary - skip first 'I' and last '99' lines if ($line =~ /\s+Version\s+/i) { prt(substr($line,0,50)."\n"); next; } @arr = split(/\s+/,$line); $nc = scalar @arr; $typ = $arr[0]; if ($nc < 8) { prt("Type: [$typ] - Handle this line [$line] - count = $nc...\n"); pgm_exit(1,"ERROR: FIX ME FIRST!\n"); } $lat = $arr[1]; $lon = $arr[2]; $alt = $arr[3]; $frq = $arr[4]; $rng = $arr[5]; $brg = $arr[6]; $id = $arr[7]; $name = join(' ', splice(@arr,8)); $name =~ s/,/ /g; $csv .= "$typ,$lat,$lon,$alt,$frq,$rng,$brg,$id,$name\n"; $off = scalar @navaids; push(@navaids,[$typ,$lat,$lon,$alt,$frq,$rng,$brg,$id,$name]); if (!defined $types{$typ}) { $types{$typ} = 1; } else { $types{$typ}++; } if (!defined $navids{$id}) { $navids{$id} = 1; } else { $navids{$id}++; } if (!defined $navfreqs{$frq}) { $navfreqs{$frq} = 1; } else { $navfreqs{$frq}++; } } @arr = keys %types; $i = scalar @arr; prt("Types $i "); $len = 0; foreach $typ (@arr) { $lnn = $types{$typ}; $line = '???'; if (defined $navtypes{$typ}) { $line = $navtypes{$typ}; #$line .= ' ' while (length($line) < 5); } # prt("$typ=$lnn "); prt("$typ $line=$lnn, "); $len += $lnn; } prt(" Total $len navaids\n"); @arr = sort keys %navids; $lnn = 0; # count of ids repeated $typ = 0; # most used $line = ''; foreach $id (@arr) { next if ($id eq '----'); $len = $navids{$id}; if ($len > 1) { $lnn++; if ($len > $typ) { $typ = $len; $line = $id; } } } prt("There are $lnn ID repeated, first most used $line with count of $typ\n"); @arr = sort keys %navfreqs; $lnn = 0; # count of freq repeated $typ = 0; # most used $line = ''; foreach $frq (@arr) { next if ($frq == 0); $len = $navfreqs{$frq}; if ($len > 1) { $lnn++; if ($len > $typ) { $typ = $len; $line = $frq; } } } prt("There are $lnn freq repeated, first most used $line with count of $typ\n"); party_with_navaids(\@navaids); if (! -f $out_file) { write2file($csv,$out_file); prt("Nav csv wirtten to $out_file\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); } 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"); } } 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 (-o) = Write output to this file.\n"); } sub get_nav_spec() { my $txt = <