Generated: Sun Aug 21 11:10:59 2011 from findap02.pl 2010/11/15 58.8 KB.
#!/usr/bin/perl # NAME: findap02.pl # AIM: Read FlightGear apt.dat, and find an airport given the name, # 12/11/2010-11/11/2010 - check out... reduce noise... # 09/11/2010 - Some UI enhancements... Skip NAV version line, ... FIX20101109 # 17/08/2010 - Fix for windows command -latlon=5,10 becomes -latlon 5 10 # 13/02/2010 - Change to using C:\FGCVS\FLightGear\data files... # 18/11/2009 - Added Bucket2.pm, to show bucket details - OOPS, would NOT work # 18/12/2008 - Used tested include 'fg_wsg84.pl' for distance services # 12/12/2008 - Switch to using DISTANCE, rather than DEGREES, for searching # for close NAVAIDS ... Add a -range=nn Kilometers # 19/11/2008 - Added $tryharder, when NO navaid found # updated 20070526 fixes to run from command line # Updated 20070405 to parse inputs, added help, # 20061127 - Use gz (gzip) files directly from $FG_ROOT # geoff mclane - http://geoffmclane.com/mperl/index.htm - 20061127 use strict; use warnings; use Time::HiRes qw( gettimeofday tv_interval ); my $perl_dir = 'C:/GTools/perl'; unshift(@INC, $perl_dir); require 'logfile.pl' or die "Error: Unable to locate logfile.pl ...\n"; require 'fg_wsg84.pl' or die "Unable to load fg_wsg84.pl ...\n"; require "Bucket2.pm" or die "Unable to load Bucket2.pm ...\n"; # ============================================================================= # This NEEDS to be adjusted to YOUR particular default location of these files. my $FGROOT = (exists $ENV{'FG_ROOT'})? $ENV{'FG_ROOT'} : "C:/FGCVS/FlightGear/data"; #my $FGROOT = (exists $ENV{'FG_ROOT'})? $ENV{'FG_ROOT'} : "C:/FG/27/data"; my $APTFILE = "$FGROOT/Airports/apt.dat.gz"; # the airports data file my $NAVFILE = "$FGROOT/Navaids/nav.dat.gz"; # the NAV, NDB, etc. data file ##my $FIXFILE = "$FGROOT/Navaids/fix.dat.gz"; # the FIX data file # ============================================================================= my $VERS="Nov 12, 2010. version 1.0.1"; # log file stuff my ($LF); my $pgmname = $0; if ($pgmname =~ /\w{1}:\\.*/) { my @tmpsp = split(/\\/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $perl_dir."\\temp.$pgmname.txt"; open_log($outfile); my $t0 = [gettimeofday]; # program variables - set during running # different searches -icao=LFPO, -latlon=1,2, or -name="airport name" # KSFO San Francisco Intl (37.6208607739872,-122.381074803838) my $aptdat = $APTFILE; my $navdat = $NAVFILE; my $SRCHICAO = 0; # search using icao id ... takes precedence my $SRCHONLL = 0; # search using lat,lon my $SRCHNAME = 0; # search using name my $SHOWNAVS = 0; # show navaids around airport found my $g_max_name_len = 32; # was 24 my $aptname = "strasbourg"; my $apticao = 'KSFO'; my $g_lat = 37.6; my $g_lon = -122.4; my $maxlatd = 0.5; my $maxlond = 0.5; my $nmaxlatd = 0.1; my $nmaxlond = 0.1; my $max_cnt = 0; # maximum airport count - 0 = no limit my $max_range_km = 5; # range search using KILOMETERS # features my $tryharder = 0; # Expand the search for NAVAID, until at least 1 found my $usekmrange = 0; # search using KILOMETER range - see $max_range_km my $sortbyfreq = 1; # sort NAVAIDS by FREQUENCY my $verbosity = 0; # just info neeeded... my $vor_only = 0; my $loadlog = 0; # variables for range using distance calculation my $PI = 3.1415926535897932384626433832795029; my $D2R = $PI / 180; my $R2D = 180 / $PI; my $ERAD = 6378138.12; my $DIST_FACTOR = $ERAD; # debug tests # =================== my $test_name = 0; # to TEST a NAME search my $def_name = "hong kong"; my $test_ll = 0; # to TEST a LAT,LON search my $def_lat = 37.6; my $def_lon = -122.4; my $test_icao = 0; # to TEST an ICAO search my $def_icao = 'VHHH'; ## 'KHAF'; ## LFPO'; ## 'KSFO'; my $dbg1 = 0; # show airport during finding ... my $dbg_fa02 = 0; # show navaid during finding ... my $dbg3 = 0; # show count after finding my $verb3 = 0; my $dbg_fa04 = 0; # show NAV center search... # =================== my $av_apt_lat = 0; # later will be $tlat / $ac; my $av_apt_lon = 0; # later $tlon / $ac; # apt.dat.gz CODES - see http://x-plane.org/home/robinp/Apt810.htm for DETAILS my $aln = '1'; # airport line my $rln = '10'; # runways/taxiways line my $sealn = '16'; # Seaplane base header data. my $heliln = '17'; # Heliport header data. my $twrln = '14'; # Tower view location. my $rampln = '15'; # Ramp startup position(s) my $bcnln = '18'; # Airport light beacons my $wsln = '19'; # windsock my $minatc = '50'; my $twrfrq = '54'; # like 12210 TWR my $appfrq = '55'; # like 11970 ROTTERDAM APP my $maxatc = '56'; my $lastln = '99'; # end of file # nav.dat.gz CODES my $navNDB = '2'; my $navVOR = '3'; my $navILS = '4'; my $navLOC = '5'; my $navGS = '6'; my $navOM = '7'; my $navMM = '8'; my $navIM = '9'; my $navVDME = '12'; my $navNDME = '13'; my @navset = ($navNDB, $navVOR, $navILS, $navLOC, $navGS, $navOM, $navMM, $navIM, $navVDME, $navNDME); my @navtypes = qw( NDB VOR ILS LOC GS OM NM IM VDME NDME ); my $maxnnlen = 4; # global program variables my $actnav = ''; my @g_aptlist = (); # ALL airports found, for research, if needed my @aptlist2 = (); my @navlist = (); my @navlist2 = (); my @g_navlist3 = (); my $totaptcnt = 0; my $g_acnt = 0; my $outcount = 0; my @tilelist = (); my $in_input_file = 0; #program variables my @warnings = (); my %g_dupe_shown = (); my $nav_file_version = 0; my $got_center_latlon = 0; # 1 if latlon given in command, or ... my $g_total_aps = 0; # push(@g_aptlist, [$diff, $icao, $name, $alat, $alon]); sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub prtw { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } sub show_warnings { my ($dbg) = shift; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS ...\n" ); foreach my $line (@warnings) { prt("$line\n" ); } prt("\n"); } elsif ($dbg) { prt("\nNo warnings issued.\n\n"); } } sub pgm_exit($$) { my ($val,$msg) = @_; show_warnings(0); if (length($msg)) { $msg =~ s/\n$//; prt("$msg\n"); } $loadlog = 1 if ($outcount > 30); close_log($outfile,$loadlog); unlink($outfile); exit($val); } sub get_bucket_info { my ($lon,$lat) = @_; my $b = Bucket2->new(); $b->set_bucket($lon,$lat); return $b->bucket_info(); } sub show_scenery_tiles() { my ($name); my $cnt = scalar @tilelist; if ($cnt) { if (VERB9()) { prt( "Scenery Tile" ); if ($cnt > 1) { prt( "s" ); } prt( ": " ); foreach $name (@tilelist) { prt( "$name " ); } prt( "\n" ); } elsif (VERB5()) { prt( "Scenery Tile Count $cnt\n" ); } } } #====================================================== ### MAIN ### # ========== parse_args(@ARGV); # collect command line arguments ... prt( "$pgmname ... Hello, World ... ".scalar localtime(time())."\n" ) if (VERB9()); load_apt_data(); set_average_apt_latlon(); #my @aptsort = sort mycmp_ascend @aptlist; show_airports_found($max_cnt); #if ($acnt && $SHOWNAVS) { if ($SHOWNAVS) { search_nav(); show_navaids_found(); show_airports_found($max_cnt) if (VERB9()); } show_scenery_tiles(); my $elapsed = tv_interval ( $t0, [gettimeofday]); prt( "Ran for $elapsed seconds ...\n" ); pgm_exit(0,""); ######################################################################## ### ONLY SUBS BELOW HERE sub elim_the_dupes($) { my ($name) = @_; my @arr = split(/\s+/,$name); my %dupes = (); my @narr = (); my ($itm); foreach $itm (@arr) { if (!defined $dupes{$itm}) { $dupes{$itm} = 1; push(@narr,$itm); } } return join(" ",@narr); } sub show_airports_found { my ($mx) = shift; # limit the AIRPORT OUTPUT my $scnt = $g_acnt; my $tile = ''; my ($dist,$az,$adkm,$ahdg,$alat,$alon,$line,$diff,$icao,$name,$msg); $msg = ""; if ($mx && ($mx < $scnt)) { $scnt = $mx; $msg .= "Listing $scnt of $g_acnt aiports "; } else { $msg .= "Listing $scnt aiport(s) "; } if ($SRCHICAO) { $msg .= "with ICAO [$apticao] ..."; } elsif ($SRCHONLL) { $msg .= "around lat,lon [$g_lat,$g_lon], using diff [$maxlatd,$maxlond] ..."; } else { $msg .= "matching [$aptname] ..."; } prt("$msg\n") if (VERB1()); # search the airport list # 0=typ, 1=lat, 2=lon, 3=alt, 4=frq, 5-rng, 6-frq2, 7=nid, 8=name, 9=off, 10=dist, 11=az); #push(@g_navlist3, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az]); @aptlist2 = sort mycmp_decend_ap_dist @aptlist2 if ($got_center_latlon); for (my $i = 0; $i < $scnt; $i++) { $diff = $aptlist2[$i][0]; $icao = $aptlist2[$i][1]; $name = $aptlist2[$i][2]; $name = elim_the_dupes($name); # locations $alat = $aptlist2[$i][3]; $alon = $aptlist2[$i][4]; # from center point $dist = $aptlist2[$i][12]; $az = $aptlist2[$i][13]; $tile = get_bucket_info( $alon, $alat ); $adkm = sprintf( "%0.2f", ($dist / 1000.0)); # get kilometers $ahdg = sprintf( "%0.1f", $az ); # and azimuth while (length($icao) < 4) { $icao .= ' '; } $line = $diff; while (length($line) < 6) { $line = ' '.$line; } # name length = 'Chavenay Villepreux ' - say 24 for unique $name .= " " while (length($name) < 24); # expand to standard $alat = sprintf("%2.9f",$alat); $alon = sprintf("%3.9f",$alon); #$alat = ' '.$alat while (length($alat) < 12); #$alon = ' '.$alon while (length($alon) < 13); #$line .= ' '.$icao.' '.$name.' ('.$alat.','.$alon.") tile=$tile"; $line .= ' '.$icao.' '.$name.' '.$alat.','.$alon; $line .= " ("; $line .= "fg=".get_tile($alon,$alat); # more information on a/p found... $line .= ", ".$adkm."Km on $ahdg"; $line .= ")"; # close # show it prt("$line\n"); # print $outcount++; add_2_tiles($tile); } prt( "[v2] Done $scnt list ...\n" ) if (VERB2()); } sub get_tile { # $alon, $alat my ($lon, $lat) = @_; my $tile = 'e'; if ($lon < 0) { $tile = 'w'; $lon = -$lon; } my $ilon = int($lon / 10) * 10; if ($ilon < 10) { $tile .= "00$ilon"; } elsif ($ilon < 100) { $tile .= "0$ilon"; } else { $tile .= "$ilon" } if ($lat < 0) { $tile .= 's'; $lat = -$lat; } else { $tile .= 'n'; } my $ilat = int($lat / 10) * 10; if ($ilat < 10) { $tile .= "0$ilat"; } elsif ($ilon < 100) { $tile .= "$ilat"; } else { $tile .= "$ilat" } return $tile; } sub add_2_tiles { # $tile my ($tl) = shift; if (@tilelist) { foreach my $t (@tilelist) { if ($t eq $tl) { return 0; } } } push(@tilelist, $tl); return 1; } sub is_valid_nav { my ($t) = shift; if ($t && length($t)) { my $txt = "$t"; my $cnt = 0; foreach my $n (@navset) { if ($n eq $txt) { $actnav = $navtypes[$cnt]; return 1; } $cnt++; } } return 0; } sub set_average_apt_latlon { $g_acnt = scalar @aptlist2; $g_total_aps = scalar @g_aptlist; my $ac = $g_acnt; my $tlat = 0; my $tlon = 0; my ($alat,$alon); prt( "Found $$g_acnt, of $totaptcnt, airports ...getting average...\n" ) if ($dbg3 || VERB9()); if ($ac) { for (my $i = 0; $i < $ac; $i++ ) { $alat = $aptlist2[$i][3]; $alon = $aptlist2[$i][4]; $tlat += $alat; $tlon += $alon; } $av_apt_lat = $tlat / $ac; $av_apt_lon = $tlon / $ac; if ($SRCHICAO) { prt( "Found $g_acnt matching $apticao ...(av. $av_apt_lat,$av_apt_lon)\n" ) if ($dbg3 || VERB9()); } elsif ($SRCHONLL) { prt( "Found $g_acnt matching $g_lat, $g_lon ...(av. $av_apt_lat,$av_apt_lon)\n" ) if ($dbg3 || VERB9()); } else { prt( "Found $g_acnt matching $aptname ... (av. $av_apt_lat,$av_apt_lon)\n" ) if ($dbg3 || VERB9()); } } } # push(@aptlist2, [$diff, $icao, $name, $alat, $alon]); # my $nmaxlatd = 1.5; # my $nmaxlond = 1.5; sub near_an_airport { my ($lt, $ln, $dist, $az) = @_; my ($az1, $az2, $s, $ret); my $ac = scalar @aptlist2; my ($x,$y,$z) = fg_ll2xyz($ln,$lt); # get cart x,y,z my $d2 = $max_range_km * 1000; # get meters my ($alat,$alon,$diff,$icao,$name); for (my $i = 0; $i < $ac; $i++ ) { $diff = $aptlist2[$i][0]; $icao = $aptlist2[$i][1]; $name = $aptlist2[$i][2]; $alat = $aptlist2[$i][3]; $alon = $aptlist2[$i][4]; if ($usekmrange) { my ($xb, $yb, $yz) = fg_ll2xyz($alon, $alat); my $dst = sqrt( fg_coord_dist_sq( $x, $y, $z, $xb, $yb, $yz ) ) * $DIST_FACTOR; if ($dst < $d2) { $s = -1; $az1 = -1; $ret = fg_geo_inverse_wgs_84($alat, $alon, $lt, $ln, \$az1, \$az2, \$s); $$dist = $s; $$az = $az1; return ($i + 1); } } else { my $td = abs($lt - $alat); my $nd = abs($ln - $alon); if (($td < $nmaxlatd)&&($nd < $nmaxlond)) { $s = -1; $az1 = -1; $ret = fg_geo_inverse_wgs_84($alat, $alon, $lt, $ln, \$az1, \$az2, \$s); $$dist = $s; $$az = $az1; return ($i + 1); } } } return 0; } sub not_in_world_range($$) { my ($lt,$ln) = @_; return 1 if ($lt < -90); return 1 if ($lt > 90); return 1 if ($ln < -180); return 1 if ($ln > 180); return 0; } # like sub near_an_airport { sub near_given_point { my ($lt, $ln, $dist, $az) = @_; return 0 if (not_in_world_range($lt,$ln)); my ($az1, $az2, $s, $ret); my ($x,$y,$z) = fg_ll2xyz($ln,$lt); # get cart x,y,z my $d2 = $max_range_km * 1000; # get meters my $ngp_ret = 0; my ($alat,$alon); if ($SRCHONLL) { # for (my $i = 0; $i < $ac; $i++ ) { # $diff = $aptlist2[$i][0]; # $icao = $aptlist2[$i][1]; # $name = $aptlist2[$i][2]; $alat = $g_lat; $alon = $g_lon; if ($usekmrange) { my ($xb, $yb, $yz) = fg_ll2xyz($alon, $alat); my $dst = sqrt( fg_coord_dist_sq( $x, $y, $z, $xb, $yb, $yz ) ) * $DIST_FACTOR; if ($dst < $d2) { $s = -1; $az1 = -1; $ret = fg_geo_inverse_wgs_84($alat, $alon, $lt, $ln, \$az1, \$az2, \$s); ${$dist} = $s; ${$az} = $az1; $ngp_ret = 1; } } else { my $td = abs($lt - $alat); my $nd = abs($ln - $alon); if (($td < $nmaxlatd)&&($nd < $nmaxlond)) { $s = -1; $az1 = -1; $ret = fg_geo_inverse_wgs_84($alat, $alon, $lt, $ln, \$az1, \$az2, \$s); ${$dist} = $s; ${$az} = $az1; $ngp_ret = 1; } } } return $ngp_ret; } sub show_navaids_found { my ($ic, $in, $line, $lcnt, $dnone); my ($diff, $icao, $alat, $alon); my ($typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off); my ($dist, $az, $adkm, $ahdg); my ($apds,$apaz,$dist_hdg,$add); my $msg = ''; my $hdr = "Type Latitude Logitude Alt. Freq. Range Frequency2 ID Name"; #prt( "$actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n"); #push(@navlist2, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off]); my $nearna = scalar @g_navlist3; my $ac = scalar @aptlist2; @navlist2 = sort mycmp_ascend_n4 @navlist2 if ($sortbyfreq); my $nc = scalar @navlist2; my $tot = $nc + $nearna; my $dspcnt = 0; $msg = "For "; $msg .= "$nearna 'near' aids, " if ($nearna); $msg .= "$ac airports, found $tot NAVAIDS, "; if ($usekmrange) { $msg .= "within [$max_range_km] Km ..."; } else { $msg .= "within [$nmaxlatd,$nmaxlond] degrees ..."; } prt("$msg\n"); $lcnt = 0; prt("List $nearna NEAR $g_lat,$g_lon...\n") if ($nearna); #my @navlist3 = sort mycmp_decend_dist @g_navlist3; #my $rnavlist3 = \@navlist3; @g_navlist3 = sort mycmp_decend_dist @g_navlist3; my $rnavlist3 = \@g_navlist3; $dspcnt = 0; for ($ic = 0; $ic < $nearna; $ic++) { $typ = ${$rnavlist3}[$ic][0]; $nlat = ${$rnavlist3}[$ic][1]; $nlon = ${$rnavlist3}[$ic][2]; $nalt = ${$rnavlist3}[$ic][3]; $nfrq = ${$rnavlist3}[$ic][4]; $nrng = ${$rnavlist3}[$ic][5]; $nfrq2 = ${$rnavlist3}[$ic][6]; $nid = ${$rnavlist3}[$ic][7]; $name = ${$rnavlist3}[$ic][8]; $off = ${$rnavlist3}[$ic][9]; $dist = ${$rnavlist3}[$ic][10]; $az = ${$rnavlist3}[$ic][11]; is_valid_nav($typ); if ($vor_only) { if (($actnav =~ /VOR/) || ($actnav =~ /NBD/)) { # these are OK } else { next; } } $dspcnt++; $line = $actnav; $line .= ' ' while (length($line) < $maxnnlen); $line .= ' '; $nalt = ' '.$nalt while (length($nalt) < 5); $nfrq = ' '.$nfrq while (length($nfrq) < 5); $nrng = ' '.$nrng while (length($nrng) < 5); $nfrq2 = ' '.$nfrq2 while (length($nfrq2) < 10); $nid = ' '.$nid while (length($nid) < 4); $nlat = ' '.$nlat while (length($nlat) < 12); $nlon = ' '.$nlon while (length($nlon) < 13); $adkm = sprintf( "%0.2f", ($dist / 1000.0)); # get kilometers $ahdg = sprintf( "%0.1f", $az ); # and azimuth $name = elim_the_dupes($name); $name .= ' ' while (length($name) < $g_max_name_len); $dist_hdg = "(".$adkm."Km on $ahdg, ap$off)"; $line .= "$nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name"; if ($dnone == 0) { #prt( "Type Latitude Logitude Alt. Freq. Range Frequency2 ID Name\n" ); prt( "$hdr\n" ); $dnone++; } if (defined $g_dupe_shown{$line}) { prt( "[v5] DupeNR: Shown [$actnav $nlat,$nlon $name] - SHOWN\n") if (VERB5()); } else { prt( "$line $dist_hdg\n" ); $outcount++; $lcnt++; $g_dupe_shown{$line} = 1; } } prt("Done $dspcnt of $nearna NEAR $g_lat,$g_lon...\n") if ($nearna); $lcnt = 0; # count objects for display... $dspcnt = 0; for ($ic = 0; $ic < $ac; $ic++) { $diff = $aptlist2[$ic][0]; $icao = $aptlist2[$ic][1]; $name = $aptlist2[$ic][2]; $alat = $aptlist2[$ic][3]; $alon = $aptlist2[$ic][4]; $apds = $aptlist2[$ic][12]; $apaz = $aptlist2[$ic][13]; $icao .= ' ' while (length($icao) < 4); $line = $diff; $line = ' '.$line while (length($line) < 6); $line .= ' '.$icao.' '.$name.' ('.$alat.','.$alon.')'; $dnone = 0; for ( $in = 0; $in < $nc; $in++ ) { $typ = $navlist2[$in][0]; $nlat = $navlist2[$in][1]; $nlon = $navlist2[$in][2]; $nalt = $navlist2[$in][3]; $nfrq = $navlist2[$in][4]; $nrng = $navlist2[$in][5]; $nfrq2 = $navlist2[$in][6]; $nid = $navlist2[$in][7]; $name = $navlist2[$in][8]; $off = $navlist2[$in][9]; $dist = $navlist2[$in][10]; $az = $navlist2[$in][11]; if ($off == ($ic + 1)) { # it is FOR this airport is_valid_nav($typ); if ($vor_only) { if (($actnav =~ /VOR/) || ($actnav =~ /NBD/)) { # these are OK } else { next; } } # NDB 50.049000, 008.328667, 490, 399, 25, 0.000, WBD, Wiesbaden NDB (ap=2 nnnKm on 270.1) # Type Latitude Logitude Alt. Freq. Range Frequency2 ID Name # VOR 37.61948300, -122.37389200, 13, 11580, 40, 17.0, SFO, SAN FRANCISCO VOR-DME (ap=1 nnnKm on 1.1) #prt( "$actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n"); $dspcnt++; } } # prt( "$hdr\n" ) if ($dnone); } prt("List for $ac airports... near $g_lat,$g_lon... display $dspcnt...\n") if ($ac); $lcnt = 0; for ($ic = 0; $ic < $ac; $ic++) { $diff = $aptlist2[$ic][0]; $icao = $aptlist2[$ic][1]; $name = $aptlist2[$ic][2]; $alat = $aptlist2[$ic][3]; $alon = $aptlist2[$ic][4]; $apds = $aptlist2[$ic][12]; $apaz = $aptlist2[$ic][13]; $icao .= ' ' while (length($icao) < 4); # start with 'offset' from center point $line = $diff; $line = ' '.$line while (length($line) < 6); $line .= ' '.$icao.' '.$name.' ('.$alat.','.$alon.')'; $dspcnt = 0; # check the LIST of viable items to DISPLAY for ( $in = 0; $in < $nc; $in++ ) { $typ = $navlist2[$in][0]; $off = $navlist2[$in][9]; if ($off == ($ic + 1)) { is_valid_nav($typ); if ($vor_only) { if (($actnav =~ /VOR/) || ($actnav =~ /NBD/)) { $dspcnt++; # these are OK } } else { $dspcnt++; } } } $line .= " ($dspcnt)"; prt("\n") if ($ic && $dspcnt); prt("$line\n"); $outcount++; $dnone = 0; $line = ''; for ( $in = 0; $in < $nc; $in++ ) { $typ = $navlist2[$in][0]; $nlat = $navlist2[$in][1]; $nlon = $navlist2[$in][2]; $nalt = $navlist2[$in][3]; $nfrq = $navlist2[$in][4]; $nrng = $navlist2[$in][5]; $nfrq2 = $navlist2[$in][6]; $nid = $navlist2[$in][7]; $name = $navlist2[$in][8]; $off = $navlist2[$in][9]; $dist = $navlist2[$in][10]; $az = $navlist2[$in][11]; if ($off == ($ic + 1)) { # it is FOR this airport is_valid_nav($typ); if ($vor_only) { if (($actnav =~ /VOR/) || ($actnav =~ /NBD/)) { # these are OK } else { next; } } # NDB 50.049000, 008.328667, 490, 399, 25, 0.000, WBD, Wiesbaden NDB (ap=2 nnnKm on 270.1) # Type Latitude Logitude Alt. Freq. Range Frequency2 ID Name # VOR 37.61948300, -122.37389200, 13, 11580, 40, 17.0, SFO, SAN FRANCISCO VOR-DME (ap=1 nnnKm on 1.1) #prt( "$actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n"); # start line $line = $actnav; $line .= ' ' while (length($line) < $maxnnlen); $line .= ' '; $nalt = ' '.$nalt while (length($nalt) < 5); $nfrq = ' '.$nfrq while (length($nfrq) < 5); $nrng = ' '.$nrng while (length($nrng) < 5); $nfrq2 = ' '.$nfrq2 while (length($nfrq2) < 10); $nid = ' '.$nid while (length($nid) < 4); $nlat = ' '.$nlat while (length($nlat) < 12); $nlon = ' '.$nlon while (length($nlon) < 13); $adkm = sprintf( "%0.2f", ($dist / 1000.0)); # get kilometers $ahdg = sprintf( "%0.1f", $az ); # and azimuth $name = elim_the_dupes($name); $name .= ' ' while (length($name) < $g_max_name_len); $dist_hdg .= "(".$adkm."Km on $ahdg, ap$off)"; $line .= "$nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name"; $add = 0; if (defined $g_dupe_shown{$line}) { if (VERB5()) { $add = 1; } } else { $add = 1; } if ($add && ($dnone == 0)) { #prt( "Type Latitude Logitude Alt. Freq. Range Frequency2 ID Name\n" ); prt( "$hdr\n" ); $dnone = 1; } $outcount++; $lcnt++; if (defined $g_dupe_shown{$line}) { if (VERB5()) { prt( "DupeAID: Shown [$actnav $nlat,$nlon $name] - SHOWN\n"); } } else { prt( "$line $dist_hdg\n" ); $g_dupe_shown{$line} = 1; add_2_tiles( get_bucket_info( $nlon, $nlat ) ); } } } prt( "$hdr\n" ) if ($dnone); } prt( "[v5] Listed $lcnt NAVAIDS ...\n" ) if (VERB5()); } sub load_apt_data { my ($cnt,$msg); prt("[v9] Loading $aptdat file ...\n") if (VERB9()); mydie("ERROR: Can NOT locate $aptdat ...$!...\n") if ( !( -f $aptdat) ); ###open IF, "<$aptdat" or mydie("OOPS, failed to open [$aptdat] ... check name and location ...\n"); open IF, "gzip -d -c $aptdat|" or mydie( "ERROR: CAN NOT OPEN $aptdat...$!...\n" ); my @lines = <IF>; close IF; $cnt = scalar @lines; $msg = ''; if ($SRCHICAO) { $msg .= "Search ICAO [$apticao]..."; } elsif ($SRCHONLL) { $msg .= "Search LAT,LON [$g_lat,$g_lon], w/diff [$maxlatd,$maxlond]..."; } else { $msg .= "Search NAME [$aptname]..."; } $msg .= " got $cnt lines, FOR airports,rwys,txwys... "; prt("$msg\n") if (VERB1()); my ($add,$alat,$alon); # ================ # SEARCH THE LINES # search ICAO, POSITION, NAME... # ================ $add = 0; my ($off,$dist,$az,@arr2,$rwyt,$glat,$glon,$dlat,$dlon,$rlat,$rlon); my ($line,$apt,$diff,$rwycnt,$icao,$name); $off = 0; $dist = 0; $az = 0; $glat = 0; $glon = 0; $apt = ''; $rwycnt = 0; foreach $line (@lines) { $line = trimall($line); ###prt("$line\n"); my @arr = split(/ /,$line); if ($line =~ /^$aln\s+/) { # start with '1' if (length($apt) && ($rwycnt > 0)) { # average position $alat = $glat / $rwycnt; $alon = $glon / $rwycnt; $off = -1; $dist = 999999; $az = 400; #$off = near_given_point( $alat, $alon, \$dist, \$az ); $dlat = abs( $g_lat - $alat ); $dlon = abs( $g_lon - $alon ); $diff = int( ($dlat * 10) + ($dlon * 10) ); @arr2 = split(/ /,$apt); $icao = $arr2[4]; $name = join(' ', splice(@arr2,5)); ##prt("$diff [$apt] (with $rwycnt runways at [$alat, $alon]) ...\n"); ##prt("$diff [$icao] [$name] ...\n"); #push(@g_aptlist, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az]); push(@g_aptlist, [$diff, $icao, $name, $alat, $alon]); $add = 0; if ($SRCHICAO) { $add = 1 if ($icao =~ /$apticao/); } else { if ($SRCHONLL) { # searching by LAT,LON position if (($dlat < $maxlatd) && ($dlon < $maxlond)) { $add = 1; } } else { # searching by airport name $add = 1 if ($name =~ /$aptname/i); } } if ($add) { $off = near_given_point( $alat, $alon, \$dist, \$az ); prt("$icao, $name, $alat, $alon, rwys $rwycnt...\n") if ($dbg1); # 0=typ, 1=lat, 2=lon, 3=alt, 4=frq, 5-rng, 6-frq2, 7=nid, 8=name, 9=off, 10=dist, 11=az); #push(@g_navlist3, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az]); } } $apt = $line; $rwycnt = 0; $glat = 0; $glon = 0; $totaptcnt++; # count another AIRPORT } elsif ($line =~ /^$rln\s+/) { # 10 36.962213 127.031071 14x 131.52 8208 1595.0620 0000.0000 150 321321 1 0 3 0.25 0 0300.0300 # 10 36.969145 127.020106 xxx 221.51 329 0.0 0.0 75 161161 1 0 0 0.25 0 $rlat = $arr[1]; $rlon = $arr[2]; $rwyt = $arr[3]; ###prt( "$line [$rlat, $rlon]\n" ); if ( $rwyt ne "xxx" ) { $glat += $rlat; $glon += $rlon; $rwycnt++; } } elsif ($line =~ /^$lastln\s?/) { # 99, followed by space, count 0 or more ... prt( "Reached END OF FILE ... \n" ) if ($dbg1); last; } } # do any LAST entry $add = 0; $off = -1; $dist = 0; $az = 0; if ($rwycnt > 0) { $alat = $glat / $rwycnt; $alon = $glon / $rwycnt; $off = -1; $dist = 999999; $az = 400; #$off = near_given_point( $alat, $alon, \$dist, \$az ); $dlat = abs( $g_lat - $alat ); $dlon = abs( $g_lon - $alon ); $diff = int( ($dlat * 10) + ($dlon * 10) ); @arr2 = split(/ /,$apt); $icao = $arr2[4]; $name = join(' ', splice(@arr2,5)); ###prt("$diff [$apt] (with $rwycnt runways at [$alat, $alon]) ...\n"); ###prt("$diff [$icao] [$name] ...\n"); ###push(@g_aptlist, [$diff, $icao, $name, $alat, $alon]); ##push(@g_aptlist, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az]); push(@g_aptlist, [$diff, $icao, $name, $alat, $alon]); $totaptcnt++; # count another AIRPORT $add = 0; if ($SRCHICAO) { $add = 1 if ($name =~ /$apticao/); } else { if ($SRCHONLL) { if (($dlat < $maxlatd) && ($dlon < $maxlond)) { $add = 1; } } else { $add = 1 if ($name =~ /$aptname/i); } } if ($add) { $off = near_given_point( $alat, $alon, \$dist, \$az ); prt("$icao, $name, $alat, $alon, rwycnt $rwycnt - LAST\n") if ($dbg1); # push(@aptlist2, [$diff, $icao, $name, $alat, $alon]); # 0=typ, 1=lat, 2=lon, 3=alt, 4=frq, 5-rng, 6-frq2, 7=nid, 8=name, 9=off, 10=dist, 11=az); #push(@g_navlist3, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az]); } } } sub load_nav_file { prt("\n[v9] Loading $navdat file ...\n") if (VERB9()); mydie("ERROR: Can NOT locate [$navdat]!\n") if ( !( -f $navdat) ); open NIF, "gzip -d -c $navdat|" or mydie( "ERROR: CAN NOT OPEN $navdat...$!...\n" ); my @nav_lines = <NIF>; close NIF; return @nav_lines; } sub search_nav { my ($typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off); my ($alat, $alon); my ($dist, $az,$msg); my $cnt = 0; my @nav_lines = load_nav_file(); my $nav_cnt = scalar @nav_lines; my $ac = scalar @aptlist2; $msg = ''; $msg .= "Search FOR [$g_lat,$g_lon]... "; if ($ac == 1) { $alat = $aptlist2[0][3]; $alon = $aptlist2[0][4]; if ($usekmrange) { $msg .= "Use max [$max_range_km] Km from $ac ap at $alat,$alon."; } else { $msg .= "Use dev [$nmaxlatd,$nmaxlond] from $ac ap at $alat,$alon."; } } else { if ($usekmrange) { $msg .= "Use max dist [$max_range_km] Km from $ac apts."; } else { $msg .= "Use dev [$nmaxlatd,$nmaxlond] from $ac apts."; } } $msg .= " in $nav_cnt NAV lines..."; prt("$msg\n") if (VERB1()); my $vcnt = 0; my $navs_found = 0; my (@arr,$nc,$lnn,$len,$dnvers,$line); $lnn = 0; $lnn = 0; $dnvers = 0; $cnt = 0; foreach $line (@nav_lines) { $cnt++; $line = trimall($line); $len = length($line); $lnn++; # 810 Version - data cycle 2009.12, build 20091080, metadata NavXP810 if ($line =~ /\s+Version\s+/i) { if ($line =~ /\s*(\n+)\s+Version\s+/) { $nav_file_version = $1; } $typ = length($line) > 80 ? substr($line,0,80) : $line; prt( "[v2] NAVAID: $typ\n" ) if (VERB2()); $dnvers = 1; last; } } $lnn = 0; $cnt = scalar @nav_lines; prt( "[04] Doing 'center' search... $cnt NAV objects\n") if ($dbg_fa04); $cnt = 0; $vcnt = 0; foreach $line (@nav_lines) { $line = trimall($line); $len = length($line); $lnn++; next if ($line =~ /\s+Version\s+/i); @arr = split(/ /,$line); $nc = scalar @arr; $typ = $arr[0]; # Check for type number in @navset, and set $actnav to name, like VOR, NDB, etc $off = 0; if ( is_valid_nav($typ) ) { $vcnt++; $nlat = $arr[1]; $nlon = $arr[2]; $nalt = $arr[3]; $nfrq = $arr[4]; $nrng = $arr[5]; $nfrq2 = $arr[6]; $nid = $arr[7]; $name = ''; for (my $i = 8; $i < $nc; $i++) { $name .= ' ' if length($name); $name .= $arr[$i]; } $off = near_given_point( $nlat, $nlon, \$dist, \$az ); if ($off) { $off = 2; prt( "[04] $actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n") if ($dbg_fa04); # 0=typ, 1=lat, 2=lon, 3=alt, 4=frq, 5-rng, 6-frq2, 7=nid, 8=name, 9=off, 10=dist, 11=az); push(@g_navlist3, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); $cnt++; } } } prt( "[04] Done 'center' search, $vcnt valid, found $cnt...\n") if ($dbg_fa04); $lnn = 0; $vcnt = 0; foreach $line (@nav_lines) { $line = trimall($line); $len = length($line); $lnn++; my ($tmp); # 810 Version - data cycle 2009.12, build 20091080, metadata NavXP810 if ($line =~ /\s+Version\s+/i) { if ($line =~ /\s*(\n+)\s+Version\s+/) { $nav_file_version = $1; } $typ = length($line) > 80 ? substr($line,0,80) : $line; prt( "[v2] NAVAID: $typ\n" ) if (VERB2() && !$dnvers); next; } ###prt("$line\n"); @arr = split(/ /,$line); # 0 1 (lat) 2 (lon) 3 4 5 6 7 8++ # 2 38.087769 -077.324919 284 396 25 0.000 APH A P Hill NDB # 3 57.103719 009.995578 57 11670 100 1.000 AAL Aalborg VORTAC # 4 39.980911 -075.877814 660 10850 18 281.662 IMQS 40N 29 ILS-cat-I # 4 -09.458922 147.231225 128 11010 18 148.650 IWG AYPY 14L ILS-cat-I # 5 40.034606 -079.023281 2272 10870 18 236.086 ISOZ 2G9 24 LOC # 5 67.018506 -050.682072 165 10955 18 61.600 ISF BGSF 10 LOC # 6 39.977294 -075.860275 655 10850 10 300281.205 --- 40N 29 GS # 6 -09.432703 147.216444 128 11010 10 302148.785 --- AYPY 14L GS # 7 39.960719 -075.750778 660 0 0 281.205 --- 40N 29 OM # 7 -09.376150 147.176867 146 0 0 148.785 JSN AYPY 14L OM # 8 -09.421875 147.208331 91 0 0 148.785 MM AYPY 14L MM # 8 -09.461050 147.232544 146 0 0 328.777 PY AYPY 32R MM # 9 65.609444 -018.052222 32 0 0 22.093 --- BIAR 01 IM # 9 08.425319 004.475597 1126 0 0 49.252 IL DNIL 05 IM # 12 -09.432703 147.216444 11 11010 18 0.000 IWG AYPY 14L DME-ILS # 12 -09.449222 147.226589 11 10950 18 0.000 IBB AYPY 32R DME-ILS $nc = scalar @arr; $typ = $arr[0]; # Check for type number in @navset, and set $actnav to name, like VOR, NDB, etc if ( is_valid_nav($typ) ) { $vcnt++; $nlat = $arr[1]; $nlon = $arr[2]; $nalt = $arr[3]; $nfrq = $arr[4]; $nrng = $arr[5]; $nfrq2 = $arr[6]; $nid = $arr[7]; $name = ''; for (my $i = 8; $i < $nc; $i++) { $name .= ' ' if length($name); $name .= $arr[$i]; } push(@navlist, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name]); # Using $nmaxlatd, $nmaxlond, check airports in @aptlist2; $off = near_an_airport( $nlat, $nlon, \$dist, \$az ); $off = near_given_point( $nlat, $nlon, \$dist, \$az ) if (!$off); if ($off) { prt( "[02] $actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n") if ($dbg_fa02); # 0 1 2 3 4 5 6 7 8 9 10 11 push(@navlist2, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); } #} elsif ($line =~ /^\d+\s+Version\s+-\s+DAFIF\s+/) { # my $ind = index($line,','); # prt( "NAVAID: ".substr($line, 0, (($ind > 0) ? $ind : 50) )."\n" ); # 810 Version - DAFIF ... } elsif (($line eq 'I')||($line eq '99')) { # ignore these } elsif (length($line)) { #$typ = $line; $typ = length($line) > 80 ? substr($line,0,80) : $line; prtw("WARNING: What is this line? [$typ]???\n". "from $navdat file ...\n"); } } $navs_found = scalar @navlist2; if (($navs_found == 0) && $tryharder) { my $def_latd = $nmaxlatd; my $def_lond = $nmaxlond; my $def_dist = $max_range_km; while ($navs_found == 0) { $nmaxlatd += 0.1; $nmaxlond += 0.1; $max_range_km += 0.1; if ($usekmrange) { prt("Expanded to [$max_range_km] Km from $ac airport(s)...\n" ); } else { prt("Expanded to [$nmaxlatd,$nmaxlond] from $ac airport(s)...\n" ); } foreach $line (@nav_lines) { $line = trimall($line); ###prt("$line\n"); @arr = split(/ /,$line); $nc = scalar @arr; $typ = $arr[0]; # Check for type number in @navset, and set $actnav to name, like VOR, NDB, etc if ( is_valid_nav($typ) ) { $nlat = $arr[1]; $nlon = $arr[2]; $nalt = $arr[3]; $nfrq = $arr[4]; $nrng = $arr[5]; $nfrq2 = $arr[6]; $nid = $arr[7]; $name = ''; for (my $i = 8; $i < $nc; $i++) { $name .= ' ' if length($name); $name .= $arr[$i]; } # Using $nmaxlatd, $nmaxlond, check airports in @aptlist2; $off = near_an_airport( $nlat, $nlon, \$dist, \$az ); if ($off) { prt( "[02] $actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n") if ($dbg_fa02); push(@navlist2, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); } } } $navs_found = scalar @navlist2; } prt("Found $navs_found nearby NAVAIDS, "); if ($usekmrange) { prt("using distance $max_range_km Km...\n" ); } else { prt("using difference $nmaxlatd, $nmaxlond...\n" ); } $nmaxlatd = $def_latd; $nmaxlond = $def_lond; $max_range_km = $def_dist; } prt("[v5] Done - Found $navs_found nearby NAVAIDS, of $vcnt searched...\n" ) if (VERB5()); } # put least first sub mycmp_ascend_n4 { if (${$a}[4] < ${$b}[4]) { return -1; } if (${$a}[4] > ${$b}[4]) { return 1; } return 0; } # put least first sub mycmp_ascend { if (${$a}[0] < ${$b}[0]) { prt( "-[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3; return -1; } if (${$a}[0] > ${$b}[0]) { prt( "+[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3; return 1; } prt( "=[".${$a}[0]."] == [".${$b}[0]."]\n" ) if $verb3; return 0; } sub mycmp_decend { if (${$a}[0] < ${$b}[0]) { prt( "+[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3; return 1; } if (${$a}[0] > ${$b}[0]) { prt( "-[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3; return -1; } prt( "=[".${$a}[0]."] == [".${$b}[0]."]\n" ) if $verb3; return 0; } # 0=typ, 1=lat, 2=lon, 3=alt, 4=frq, 5-rng, 6-frq2, 7=nid, 8=name, 9=off, 10=dist, 11=az); sub mycmp_decend_dist { return -1 if (${$a}[10] < ${$b}[10]); return 1 if (${$a}[10] > ${$b}[10]); return 0; } # $dist = $aptlist2[$i][12]; # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az]); sub mycmp_decend_ap_dist { return -1 if (${$a}[12] < ${$b}[12]); return 1 if (${$a}[12] > ${$b}[12]); return 0; } ############## ### functions sub trimall { # version 20061127 my ($ln) = shift; chomp $ln; # remove CR (\n) $ln =~ s/\r$//; # remove LF (\r) $ln =~ s/\t/ /g; # TAB(s) to a SPACE while ($ln =~ /\s\s/) { $ln =~ s/\s\s/ /g; # all double space to SINGLE } while ($ln =~ /^\s/) { $ln = substr($ln,1); # remove all LEADING space } while ($ln =~ /\s$/) { $ln = substr($ln,0, length($ln) - 1); # remove all TRAILING space } return $ln; } # 12/12/2008 - Additional distance calculations # from 'signs' perl script # Melchior FRANZ <mfranz # aon : at> # $Id: signs,v 1.37 2005/06/01 15:53:00 m Exp $ # sub ll2xyz($$) { sub ll2xyz { my $lon = (shift) * $D2R; my $lat = (shift) * $D2R; my $cosphi = cos $lat; my $di = $cosphi * cos $lon; my $dj = $cosphi * sin $lon; my $dk = sin $lat; return ($di, $dj, $dk); } # sub xyz2ll($$$) { sub xyz2ll { my ($di, $dj, $dk) = @_; my $aux = $di * $di + $dj * $dj; my $lat = atan2($dk, sqrt $aux) * $R2D; my $lon = atan2($dj, $di) * $R2D; return ($lon, $lat); } # sub coord_dist_sq($$$$$$) { sub coord_dist_sq { my ($xa, $ya, $za, $xb, $yb, $zb) = @_; my $x = $xb - $xa; my $y = $yb - $ya; my $z = $zb - $za; return $x * $x + $y * $y + $z * $z; } sub give_help { prt( "FLIGHTGEAR AIRPORT SEARCH UTILITY - $VERS\n" ); prt( "Usage: $pgmname options\n" ); prt( "Options: A ? anywhere for this help.\n" ); prt( " --file <file> (-f) = Load commands from this 'file' of commands...\n"); prt( " -icao=$apticao - Search using icao.\n" ); prt( " -latlon=$g_lat,$g_lon - Search using latitude, longitude.\n" ); prt( " -maxout=$max_cnt - Limit the airport output. A 0 for ALL.\n" ); prt( " -maxll=$maxlatd,$maxlond - Maximum difference, when searching ariports using lat,lon.\n" ); prt( " -name=\"$aptname\" - Search using airport name. (A -name=. would match all.)\n" ); prt( " -shownavs (or -s) - Show NAVAIDS around airport found, if any. " ); prt( "(Def=". ($SHOWNAVS ? "On" : "Off") . ")\n" ); prt( " -nmaxll=$nmaxlatd,$nmaxlond - Maximum difference, when searching NAVAID lat,lon.\n" ); prt( " -aptdata=$aptdat - Use a specific AIRPORT data file.\n" ); prt( " -navdata=$navdat - Use a specific NAVAID data file.\n" ); prt( " -range=$max_range_km - Set Km range when checking for NAVAIDS.\n" ); prt( " -r - Use above range ($max_range_km Km) for searching.\n" ); prt( " -tryhard (or -t) - Expand search if no NAVAIDS found in range. " ); prt( "(Def=". ($tryharder ? "On" : "Off") . ")\n" ); prt( " --verbosity (-v[nn]) - Increase or set verbosity.\n"); prt( " --VOR (-V) - List only VOR (+NDB)\n"); prt( " --loadlog (-l) - Load log at end of display.\n"); mydie( " Happy Searching.\n" ); } # Ensure argument exists, or die. sub require_arg { my ($arg, @arglist) = @_; mydie( "ERROR: no argument given for option '$arg' ...\n" ) if ! @arglist; } sub deal_with_verbosity($) { my @av = @_; my ($arg,$sarg); while (@av) { $arg = $av[0]; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if ($sarg =~ /^v/) { if ($sarg =~ /^v.*(\n+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/i) { $verbosity++; $sarg = substr($sarg,1) } } prt( "[v1] Set verbosity to $verbosity\n") if (VERB1()); } } shift @av; } } sub local_strip_both_quotes($) { my $txt = shift; if ($txt =~ /^'(.+)'$/) { return $1; } if ($txt =~ /^"(.+)"$/) { return $1; } return '' if ($txt eq '""'); return '' if ($txt eq "''"); #prt("Stripping [$txt] FAILED\n"); return $txt; } sub load_input_file($$) { my ($arg,$file) = @_; if (open INF, "<$file") { my @lines = <INF>; close INF; my @carr = (); my ($line,@arr,$tmp,$i); my $lncnt = scalar @lines; for ($i = 0; $i < $lncnt; $i++) { $line = $lines[$i]; $line = trim_all($line); next if (length($line) == 0); next if ($line =~ /^\#/); # load CONTINUATION lines - ends in '\' back-slash while (($line =~ /\\$/)&&(($i+1) < $lncnt)) { $i++; $line =~ s/\\$//; $line .= trim_all($lines[$i]); } @arr = split(/\s/,$line); foreach $tmp (@arr) { $tmp = local_strip_both_quotes($tmp); push(@carr,$tmp); } } $in_input_file++; parse_args(@carr); $in_input_file--; } else { pgm_exit(1,"ERROR: Unable to 'open' file [$file]!\n") } } # set $SRCHICAO on/off # set $SRCHONLL on/off sub parse_args { my (@av) = @_; my (@arr,$arg,$sarg,$lcarg,$ch); deal_with_verbosity(@av); while(@av) { $arg = $av[0]; # shift @av; $lcarg = lc($arg); $ch = substr($arg,0,1); $sarg = $arg; $sarg = substr($sarg,1) while ($sarg =~ /^-/); if ($arg =~ /\?/) { give_help(); } elsif ($ch eq '-') { if ($sarg =~ /^v/) { # done verbosity } elsif ($sarg =~ /^f/) { require_arg(@av); shift @av; $sarg = $av[0]; load_input_file($arg,$sarg); } elsif ($sarg =~ /^V/) { $vor_only = 1; prt( "Set VOR (NBD) ONLY flag\n") if (VERB1()); } elsif (( $sarg =~ /^loadlog$/ )||($sarg =~ /^l$/)) { prt("Set load log at end of display.\n") if (VERB1()); $loadlog = 1; } elsif ( $arg =~ /-icao=(.+)/i ) { # BY ICAO $apticao = $1; $SRCHICAO = 1; $SRCHONLL = 0; $SRCHNAME = 0; prt( "Search using ICAO of [$apticao] ...\n" ) if (VERB1()); } elsif ( $lcarg eq '-icao' ) { require_arg(@av); shift @av; $SRCHICAO = 1; $SRCHONLL = 0; $SRCHNAME = 0; $apticao = $av[0]; prt( "Search using ICAO of [$apticao] ...\n" ) if (VERB1()); # BY LAT,LON } elsif ( $arg =~ /-latlon=(.+)/i ) { $SRCHICAO = 0; $SRCHONLL = 1; $SRCHNAME = 0; @arr = split(',', $1); if (scalar @arr == 2) { $g_lat = $arr[0]; $g_lon = $arr[1]; prt( "Search using LAT,LON of [$g_lat,$g_lon] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $g_lat = $arr[0]; require_arg(@av); shift @av; $g_lon = $av[0]; if (($g_lat =~ /^(\d|-|\+|\.)+$/) && ($g_lon =~ /^(\d|-|\+|\.)+$/)) { prt( "Search using LAT,LON of [$g_lat,$g_lon] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find lat,lon in [$arg] [$g_lat,$g_lon]...\n" ); } } } elsif ( $lcarg eq '-latlon' ) { # set a center LAT,LON require_arg(@av); shift @av; $SRCHICAO = 0; $SRCHONLL = 1; # search using lat,lon input... $SRCHNAME = 0; @arr = split(',', $av[0]); if (scalar @arr == 2) { $g_lat = $arr[0]; $g_lon = $arr[1]; prt( "Search using LAT,LON of [$g_lat,$g_lon] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $g_lat = $arr[0]; require_arg(@av); shift @av; $g_lon = $av[0]; if (($g_lat =~ /^(\d|-|\+|\.)+$/) && ($g_lon =~ /^(\d|-|\+|\.)+$/)) { prt( "Search using LAT,LON of [$g_lat,$g_lon] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find lat,lon in [$arg] [$g_lat,$g_lon]...\n" ); } } $got_center_latlon = 1; # given *** CENTER OF WORLD *** position -latlon lat lon # By NAME } elsif ( $arg =~ /-name=(.+)/i ) { $aptname = $1; $SRCHICAO = 0; $SRCHONLL = 0; $SRCHNAME = 1; prt( "Search using NAME of [$aptname] ...\n" ) if (VERB1()); } elsif ( $lcarg eq '-name' ) { require_arg(@av); shift @av; $SRCHICAO = 0; $SRCHONLL = 0; $SRCHNAME = 1; $aptname = $av[0]; prt( "Search using NAME of [$aptname] ...\n" ) if (VERB1()); } elsif ( $arg =~ /^-loadlog$/i ) { $loadlog = 1; prt( "Load log into wordpad.\n" ) if (VERB1()); } elsif ( $arg =~ /^-shownavs$/i ) { $SHOWNAVS = 1; prt( "And show NAVAIDS around airport, if any.\n" ) if (VERB1()); } elsif ( $arg =~ /^-s$/i ) { $SHOWNAVS = 1; prt( "And show NAVAIDS around airport, if any.\n" ) if (VERB1()); } elsif ( $arg =~ /-maxll=(.+)/i ) { @arr = split(',', $1); if (scalar @arr == 2) { $maxlatd = $arr[0]; $maxlond = $arr[1]; prt( "Search maximum difference LAT,LON of [$maxlatd,$maxlond] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $maxlatd = $arr[0]; require_arg(@av); shift @av; $maxlond = $av[0]; if (($maxlatd =~ /^(\d|-|\+|\.)+$/) && ($maxlond =~ /^(\d|-|\+|\.)+$/)) { prt( "Search maximum difference LAT,LON of [$maxlatd,$maxlond] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find maximum lat,lon difference in [$arg] [$maxlatd,$maxlond]...\n" ); } } } elsif ( $lcarg eq '-maxll' ) { require_arg(@av); shift @av; @arr = split(',', $av[0]); if (scalar @arr == 2) { $maxlatd = $arr[0]; $maxlond = $arr[1]; prt( "Search maximum difference LAT,LON of [$maxlatd,$maxlond] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $maxlatd = $arr[0]; require_arg(@av); shift @av; $maxlond = $av[0]; if (($maxlatd =~ /^(\d|-|\+|\.)+$/) && ($maxlond =~ /^(\d|-|\+|\.)+$/)) { prt( "Search maximum difference LAT,LON of [$maxlatd,$maxlond] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find maximum lat,lon difference in [$arg] [$maxlatd,$maxlond]...\n" ); } } } elsif ( $arg =~ /-nmaxll=(.+)/i ) { @arr = split(',', $1); if (scalar @arr == 2) { $nmaxlatd = $arr[0]; $nmaxlond = $arr[1]; prt( "Search maximum NAV difference LAT,LON of [$nmaxlatd,$nmaxlond] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $nmaxlatd = $arr[0]; require_arg(@av); shift @av; $nmaxlond = $av[0]; if (($nmaxlatd =~ /^(\d|-|\+|\.)+$/) && ($nmaxlond =~ /^(\d|-|\+|\.)+$/)) { prt( "Search maximum NAV difference LAT,LON of [$nmaxlatd,$nmaxlond] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find maximum lat,lon NAV difference in [$arg] [$nmaxlatd,$nmaxlond]...\n" ); } } } elsif ( $lcarg eq '-nmaxll' ) { require_arg(@av); shift @av; @arr = split(',', $av[0]); if (scalar @arr == 2) { $nmaxlatd = $arr[0]; $nmaxlond = $arr[1]; prt( "Search maximum NAV difference LAT,LON of [$nmaxlatd,$nmaxlond] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $nmaxlatd = $arr[0]; require_arg(@av); shift @av; $nmaxlond = $av[0]; if (($nmaxlatd =~ /^(\d|-|\+|\.)+$/) && ($nmaxlond =~ /^(\d|-|\+|\.)+$/)) { prt( "Search maximum NAV difference LAT,LON of [$nmaxlatd,$nmaxlond] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find maximum lat,lon NAV difference in [$arg] [$nmaxlatd,$nmaxlond]...\n" ); } } } elsif ( $arg =~ /-aptdata=(.+)/i ) { $aptdat = $1; # the airports data file prt( "Using AIRPORT data file [$aptdat] ...\n" ) if (VERB1()); } elsif ( $lcarg eq '-aptdata' ) { require_arg(@av); shift @av; $aptdat = $av[0]; # the airports data file prt( "Using AIRPORT data file [$aptdat] ...\n" ) if (VERB1()); } elsif ( $arg =~ /-navdata=(.+)/i ) { $navdat = $1; prt( "Using NAVAID data file [$navdat] ...\n" ) if (VERB1()); } elsif ( $lcarg eq '-navdata' ) { require_arg(@av); shift @av; $navdat = $av[0]; prt( "Using NAVAID data file [$navdat] ...\n" ) if (VERB1()); } elsif ( $arg =~ /-maxout=(.+)/i ) { $max_cnt = $1; prt( "Airport output limited to $max_cnt. A zero (0), for no limit\n" ) if (VERB1()); } elsif ( $lcarg eq '-maxout' ) { require_arg(@av); shift @av; $max_cnt = $av[0]; prt( "Airport output limited to $max_cnt. A zero (0), for no limit\n" ) if (VERB1()); } elsif ( $arg =~ /-range=(.+)/i ) { $max_range_km = $1; prt( "Navaid search using $max_range_km Km. A zero (0), for no limit\n" ) if (VERB1()); $usekmrange = 1; prt( "Navaid search using $max_range_km Km.\n" ) if (VERB1()); } elsif ( $lcarg eq '-range' ) { require_arg(@av); shift @av; $max_range_km = $av[0]; prt( "Navaid search using $max_range_km Km. A zero (0), for no limit\n" ) if (VERB1()); $usekmrange = 1; prt( "Navaid search using $max_range_km Km.\n" ) if (VERB1()); } elsif ( $lcarg eq '-r' ) { $usekmrange = 1; prt( "Navaid search using $max_range_km Km.\n" ) if (VERB1()); } elsif (( $lcarg eq '-tryhard' )||( $lcarg eq '-t' )) { $tryharder = 1; # Expand the search for NAVAID, until at least 1 found prt( "Navaid search 'tryharder' set.\n" ) if (VERB1()); } else { mydie( "ERROR: Unknown argument [$arg]. Try ? for HELP ...\n" ); } } else { # ASSUME AN AIRPORT NAME $SRCHICAO = 0; $SRCHONLL = 0; $SRCHNAME = 1; $aptname = $av[0]; prt( "Search using NAME of [$aptname] ...\n" ) if (VERB1()); } shift @av; } if ( ! $in_input_file ) { # NOT in an INPUT file # *** ONLY FOR TESTING *** if ($test_name) { $SRCHICAO = 0; $SRCHONLL = 0; $SRCHNAME = 1; $SHOWNAVS = 1; $usekmrange = 1; $max_range_km = 5; $aptname = $def_name; } elsif ($test_ll) { $g_lat = $def_lat; $g_lon = $def_lon; $maxlatd = 0.1; $maxlond = 0.1; $SRCHICAO = 0; $SRCHONLL = 1; $SRCHNAME = 0; } elsif ($test_icao) { $SRCHICAO = 1; $SRCHONLL = 0; $SRCHNAME = 0; $SHOWNAVS = 1; $apticao = $def_icao; # now have $tryharder to expand this, if NO NAVAIDS found $tryharder = 1; $usekmrange = 1; } if ( ($SRCHICAO == 0) && ($SRCHONLL == 0) && ($SRCHNAME == 0) ) { prt( "ERROR: No valid command action found, like -\n" ); prt( "By ICAO '-icao=KSFO', by LAT/LON '-latlon=21,-122', or '-name=something'!\n" ); give_help(); } } } # eof - findap02.pl