Generated: Sun Apr 15 11:46:14 2012 from findap03.pl 2011/11/16 97.7 KB.
#!/usr/bin/perl # NAME: findap03.pl # AIM: Read FlightGear apt.dat, and find an airport given the name, # 16/11/2011 - A little more information if -v9 # 16/09/2011 - Fix bug $$g_acnt to $g_acnt about line 650 # 02/05/2011 - Add the tile INDEX to the fg=<chunk>/<tile>/index # 21/02/2011 - Add AMSL (Airport altitude) to airport output # 20/02/2011 - If VERB1, add runway center, if VERB2, add runway ends # 09/02/2011 - Add more information about runways. # 25/01/2011 - If the raw input looks like a 4 letter ICAO, then search for that # 29/12/2010 - Add altitude, and frequencies, to airport display ($aalt) # 15/12/2010 - Fix in the display of the FG CHUNK - now show chunk/tile path, and rwy opp nums # 26/11/2010 - No show of navs if search a/p, and none found # 12/11/2010-11/11/2010 - Rel 03 - 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"; my $CDATROOT="C:/FGCVS/FlightGear/data"; # my $CDATROOT="C:/FGCVS/FlightGear/data"; # ============================================================================= # This NEEDS to be adjusted to YOUR particular default location of these files. my $FGROOT = (exists $ENV{'FG_ROOT'})? $ENV{'FG_ROOT'} : $CDATROOT; #my $FGROOT = (exists $ENV{'FG_ROOT'})? $ENV{'FG_ROOT'} : "C:/FG/27/data"; # file spec : http://data.x-plane.com/file_specs/Apt810.htm my $APTFILE = "$FGROOT/Airports/apt.dat.gz"; # the airports data file my $NAVFILE = "$FGROOT/Navaids/nav.dat.gz"; # the NAV, NDB, etc. data file # add these files my $FIXFILE = "$FGROOT/Navaids/fix.dat.gz"; # the FIX data file my $AWYFILE = "$FGROOT/Navaids/awy.dat.gz"; # Airways data # ============================================================================= my $VERS="Feb 10, 2011. version 1.0.2"; # 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 $g_fixfile = $FIXFILE; my $g_awyfile = $AWYFILE; 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 = 24; # was 32; # was 24 my $aptname = "strasbourg"; my $apticao = 'KSFO'; my $g_center_lat = 0; # 37.6; my $g_center_lon = 0; # -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 my $g_fix_name = "ASKIK"; # 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 = 0; # sort NAVAIDS by FREQUENCY my $sort_by_distance = 1; # sort NAVAIDS by DISTANCE from CENTER my $verbosity = 0; # just info neeeded... my $vor_only = 0; my $loadlog = 0; my $check_sg_dist = 1; # do calc again, and show... my $use_full_list = 0; # seems better to GROUP frequencies # 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; my $SG_EPSILON = 0.0000001; my $SG_FEET_TO_METER = 0.3048; # /** Feet to Meters */ # 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 # Radio Frequencies # AWOS (Automatic Weather Observation System), ASOS (Automatic Surface Observation System) my $minatc = '50'; # ATIS (Automated Terminal Information System). AWIS (Automatic Weather Information Service) my $unicom = '51'; # Unicom or CTAF (USA), radio (UK) - open channel for pilot position reporting at uncontrolled airports. my $cleara = '52'; # Clearance delivery. my $goundf = '53'; # ground my $twrfrq = '54'; # like 12210 TWR my $appfrq = '55'; # like 11970 ROTTERDAM APP my $maxatc = '56'; # Departure. my %off2name = ( 0 => 'ATIS', 1 => 'Unicom', 2 => 'Clearance', 3 => 'Ground', 4 => 'Tower', 5 => 'Approach', 6 => 'Departure' ); # offset 10 in runway array my %runway_surface = ( 1 => 'Asphalt', 2 => 'Concrete', 3 => 'Turf/grass', 4 => 'Dirt', 5 => 'Gravel', 6 => 'H-Asphalt', # helepad (big 'H' in the middle). 7 => 'H-Concrete', # helepad (big 'H' in the middle). 8 => 'H-Turf', # helepad (big 'H' in the middle). 9 => 'H-Dirt', # helepad (big 'H' in the middle). 10 => 'T-Asphalt', # taxiway - with yellow hold line across long axis (not available from WorldMaker). 11 => 'T-Concrete', # taxiway - with yellow hold line across long axis (not available from WorldMaker). 12 => 'Dry Lakebed', # (eg. at KEDW Edwards AFB). 13 => 'Water' # runways (marked with bobbing buoys) for seaplane/floatplane bases (available in X-Plane 7.0 and later). ); # ===================================================================================================== 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 ); # set lengths for common outputs my $maxnnlen = 4; my $g_maxnaltl = 5; my $g_maxnfrql = 5; my $g_maxnrngl = 5; my $g_maxnfq2l = 10; my $g_maxnnidl = 4; my $g_maxnlatl = 12; my $g_maxnlonl = 13; my $g_nav_hdr = "Type Latitude Logitude Alt. Freq. Range Frequency2 ID Name"; # global program variables my $actnav = ''; my @g_aptlist = (); # ALL airports found, for research, if needed # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@runways,$aalt]); 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" ); } } } sub load_gzip_file($) { my ($fil) = shift; prt("[v2] Loading [$fil] file... moment...\n") if (VERB2()); mydie("ERROR: Can NOT locate [$fil]!\n") if ( !( -f $fil) ); open NIF, "gzip -d -c $fil|" or mydie( "ERROR: CAN NOT OPEN $fil...$!...\n" ); my @arr = <NIF>; close NIF; prt("[v9] Got ".scalar @arr." lines to scan...\n") if (VERB9()); return \@arr; } sub load_fix_file { return load_gzip_file($g_fixfile); } sub load_awy_file { return load_gzip_file($g_awyfile); } ######################################################################## ### 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 ctr_latlon_stg() { return "$g_center_lat,$g_center_lon"; } sub get_fg_dist_dir($$$$) { my ($lat1,$lon1,$lat2,$lon2) = @_; my ($sg_az1,$sg_az2,$sg_dist); my $res = fg_geo_inverse_wgs_84 ($lat1,$lon1,$lat2,$lon2,\$sg_az1,\$sg_az2,\$sg_dist); my $sg_km = $sg_dist / 1000; my $sg_im = int($sg_dist); my $sg_ikm = int($sg_km + 0.5); # if (abs($sg_pdist) < $CP_EPSILON) my $dist_hdg = ""; # or say "(SG: "; $sg_az1 = int(($sg_az1 * 10) + 0.05) / 10; if (abs($sg_km) > $SG_EPSILON) { # = 0.0000001; # EQUALS SG_EPSILON 20101121 if ($sg_ikm && ($sg_km >= 1)) { $sg_km = int(($sg_km * 10) + 0.05) / 10; $dist_hdg .= "$sg_km km"; } else { $dist_hdg .= "$sg_im m, <1km"; } } else { $dist_hdg .= "0 m"; } $dist_hdg .= " on $sg_az1 d."; #$dist_hdg .= ")"; return $dist_hdg; } ## 0 1 2 3 4 5 6 #push(@g_aptlist, [$diff, $icao, $name, $alat, $alon, $aalt, \@f]); sub get_g_aptlist_off($) { my ($icao) = @_; my $max = scalar @g_aptlist; my ($i,$t); for ($i = 0; $i < $max; $i++) { $t = $g_aptlist[$i][1]; if ($icao eq $t) { return ($i + 1); } } return 0; } sub get_atis_info($$$$$$$) { my ($ii,$scnt,$raptlist2,$gaoff,$alat,$alon,$aalt) = @_; my $info = ''; my $rfa = $g_aptlist[$gaoff-1][6]; # get the ATIS, Tower, ..., frequecies array (ref) my $rfc = scalar @{$rfa}; # get count for this airport my $rj = 0; my ($rfna); my %names = (); $info = ''; $info .= "\n" if (VERB1()); if ($rfc) { $info .= " rt:".$rfc." ["; for ($rj = 0; $rj < $rfc; $rj++) { my $ev = ${$rfa}[$rj][0]; # number in file 50, 51, ...., 56 my $fr = (${$rfa}[$rj][1] / 100); # frequency x 100 my $fn = ${$rfa}[$rj][2]; # type AWIS, CTAF, ... # prepare information my $evnm = 'UNK'.$ev.'?'; my $ftyp = $ev - 50; if (($ftyp >= 0)&&($ftyp <= 6)) { $evnm = $off2name{$ftyp}; } #$info .= " $ev $fr $fn"; #$info .= " $evnm $fn $fr"; if ($use_full_list) { $info .= " $evnm $fr ($fn)"; } else { if (!defined $names{$evnm}) { $names{$evnm} = [ ]; } $rfna = $names{$evnm}; push(@{$rfna}, "$fr ($fn)"); } } if (!$use_full_list) { my ($key,$val); foreach $key (sort keys %names) { $rfna = $names{$key}; $info .= " $key:"; foreach $val (@{$rfna}) { $info .= " $val"; } } } $info .= ']'; } else { $info .= " [No freq. info]"; } return $info; } # 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]); 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); my ($rrwys,$aalt); my $c_lat = $g_center_lat; my $c_lon = $g_center_lon; my ($dlat,$dlon); $msg = '[v1] '; 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 [".ctr_latlon_stg()."], using diff [$maxlatd,$maxlond] ..."; } else { $msg .= "matching [$aptname] ..."; } prt("$msg\n") if (VERB1()); # ========================================================================================================= # search the airport list # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@runways,$aalt]); @aptlist2 = sort mycmp_decend_ap_dist @aptlist2 if ($got_center_latlon); my ($i,$ra,$rtyp,$info,$rwycnt,$hdg,$rhdg,$gaoff,$tmp,$surf); for ($i = 0; $i < $scnt; $i++) { $diff = $aptlist2[$i][0]; $icao = $aptlist2[$i][1]; $name = $aptlist2[$i][2]; $name = elim_the_dupes($name); # locations $dlat = $aptlist2[$i][3]; # LAT $dlon = $aptlist2[$i][4]; # LON $aalt = $aptlist2[$i][15]; # ALT (AMSL) $alat = $dlat; $alon = $dlon; # from center point, if there is one $dist = $aptlist2[$i][12]; $az = $aptlist2[$i][13]; # get airport reference from main @g_aptlist $gaoff = get_g_aptlist_off($icao); if ($SRCHONLL) { if (int($az) == 400) { } } # @runways reference # 0 1=lat 2=lon 3=s 4=hdg 5=len 6=offsets 7=stopway 8=wid 9=lights 10=surf 11 12 13 14 15 # 10 36.962213 127.031071 14x 131.52 8208 1595.0620 0000.0000 150 321321 1 0 3 0.25 0 0300.0300 # 11=shoulder 12=marks 13=smooth 14=signs 15=GS angles # 0 3 0.25 0 0300.0300 $rrwys = $aptlist2[$i][14]; $rwycnt = scalar @{$rrwys}; $info = "rwy:$rwycnt: "; foreach $ra (@{$rrwys}) { $tmp = scalar @{$ra}; if ($tmp < 15) { foreach $hdg (@{$ra}) { $info .= "[$hdg] "; } pgm_exit(1,"ERROR: Invalid runway array cnt $tmp! $info\n"); } $rtyp = ${$ra}[3]; $hdg = ${$ra}[4]; $rtyp =~ s/x+$//; if ($rtyp =~ /^\d+$/) { $rhdg = $rtyp * 10; # 2010-12-15 - get opposite end numbers } else { $rhdg = $hdg; # get opp heading, but may NOT be per numbers } $rhdg += 180; # reverse it $rhdg -= 360 if ($rhdg >= 360); # drop wrap # display it #$rtyp .= ' ' while (length($rtyp) < 3); $rhdg = int($rhdg / 10); $rhdg = "0$rhdg" if ($rhdg < 10); $info .= "\n" if (VERB1()); # new line $info .= " $rtyp/$rhdg ($hdg) "; $info .= ${$ra}[5]." ft."; $surf = ${$ra}[10]; # add surface type if (defined $runway_surface{$surf}) { $info .= " (s=".$runway_surface{$surf}.")"; } if (VERB1()) { $info .= " ".${$ra}[1].",".${$ra}[2]; if (VERB2()) { # show ENDS of runway my $rwlen2 = (${$ra}[5] * $SG_FEET_TO_METER) / 2; my ($elat1,$elon1,$eaz1,$elat2,$elon2,$eaz2); my $hdgr = $hdg + 180; $hdgr -= 360 if ($hdgr >= 360); fg_geo_direct_wgs_84( ${$ra}[1], ${$ra}[2], $hdg , $rwlen2, \$elat1, \$elon1, \$eaz1 ); fg_geo_direct_wgs_84( ${$ra}[1], ${$ra}[2], $hdgr, $rwlen2, \$elat2, \$elon2, \$eaz2 ); $info .= "\n $rtyp: $elat1,$elon1 $rhdg: $elat2,$elon2"; } } } $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 .= ' '; } # start the OUTPUT of an airport #$line = $diff; $line = $aalt; # start with ALTITUDE (AMSL) feet $line = ' '.$line while (length($line) < 6); # 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 .= " "; if ($SRCHONLL) { # more information on a/p found... # $line .= ", ".$adkm."Km on $ahdg"; $line .= get_fg_dist_dir($c_lat,$c_lon,$dlat,$dlon)." "; } $line .= "\n" if (VERB1()); $line .= $info; if ($gaoff) { $info = get_atis_info($i,$scnt,\@aptlist2,$gaoff,$dlat,$dlon,$aalt); $line .= $info; } $line .= " fg=".get_tile($alon,$alat); # +/or? ." (".get_tile_calc($alon,$alat).")"; # $line .= ")"; # close # show it prt("$line\n"); # print $outcount++; add_2_tiles($tile); } prt( "[v2] Done $scnt list ...\n" ) if (VERB2()); return $scnt; } # 14/12/2010 - Switch to using the Bucket2.pm # 02/05/2011 - add the tile INDEX sub get_tile { # $alon, $alat my ($lon, $lat) = @_; my $b = Bucket2->new(); $b->set_bucket($lon,$lat); return $b->gen_base_path()."/".$b->gen_index(); } # 14/12/2010 - Add a fix for latitude south # that is -30 is s40 sub get_tile_calc { # $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; $lat += 10; } else { $tile .= 'n'; } my $ilat = int($lat / 10) * 10; if ($ilat < 10) { $tile .= "0$ilat"; } elsif ($ilon < 100) { $tile .= "$ilat"; } else { $tile .= "$ilat" # SHOULD NOT EXIST } 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 ".ctr_latlon_stg()." ...(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()); } } } # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@runways,$aalt]); # 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, $rdist, $raz) = @_; if ( not_in_world_range($lt,$ln) ) { prtw("WARNING: near_given_point given OUT OF WORLD RANGE [$lt,$ln]\n"); return 0; } 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_center_lat; $alon = $g_center_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); ${$rdist} = $s; ${$raz} = $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); ${$rdist} = $s; ${$raz} = $az1; $ngp_ret = 1; } } } return $ngp_ret; } sub show_nav_list($) { my ($rnl) = @_; my $cnt = scalar @{$rnl}; my ($ic,$typ,$nlat,$nlon,$nalt,$nfrq,$nrng,$nfrq2,$nid,$name,$off,$dist,$az,$line); prt("$g_nav_hdr\n"); for ($ic = 0; $ic < $cnt; $ic++) { $typ = ${$rnl}[$ic][0]; $nlat = ${$rnl}[$ic][1]; $nlon = ${$rnl}[$ic][2]; $nalt = ${$rnl}[$ic][3]; $nfrq = ${$rnl}[$ic][4]; $nrng = ${$rnl}[$ic][5]; $nfrq2 = ${$rnl}[$ic][6]; $nid = ${$rnl}[$ic][7]; $name = ${$rnl}[$ic][8]; $off = ${$rnl}[$ic][9]; $dist = ${$rnl}[$ic][10]; $az = ${$rnl}[$ic][11]; $nalt = ' '.$nalt while (length($nalt) < $g_maxnaltl); $nfrq = ' '.$nfrq while (length($nfrq) < $g_maxnfrql); $nrng = ' '.$nrng while (length($nrng) < $g_maxnrngl); $nfrq2 = ' '.$nfrq2 while (length($nfrq2) < $g_maxnfq2l); $nid = ' '.$nid while (length($nid) < $g_maxnnidl); $nlat = ' '.$nlat while (length($nlat) < $g_maxnlatl); $nlon = ' '.$nlon while (length($nlon) < $g_maxnlonl); is_valid_nav($typ); # set global $actnav $line = $actnav; $line .= ' ' while (length($line) < $maxnnlen); $line .= ' '; $line .= "$nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name"; prt("$line\n"); } } sub show_navaids_found { my ($ic, $in, $line, $lcnt, $dnone); my ($icao, $alat, $alon); # my ($diff); 20110221 - remove display of this DIFF??? my ($typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off); my ($dist, $az, $adkm, $ahdg); my ($apds,$apaz,$dist_hdg,$add,$ap_line,$amsl); 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; # found APT list count # found within range of AP (or CENTER) if ($sort_by_distance) { @navlist2 = sort mycmp_decend_dist @navlist2; } elsif ($sortbyfreq) { @navlist2 = sort mycmp_ascend_n4 @navlist2; } 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") if (VERB1()); $lcnt = 0; prt("List $nearna NEAR [".ctr_latlon_stg()."]...\n") if ($nearna && VERB1()); #my @navlist3 = sort mycmp_decend_dist @g_navlist3; #my $rnavlist3 = \@navlist3; @g_navlist3 = sort mycmp_decend_dist @g_navlist3; my $rnavlist_d = \@g_navlist3; my @g_navlist_az = sort mycmp_decend_az @g_navlist3; my $rnavlist3 = \@g_navlist_az; $dspcnt = 0; $dnone = 0; # header display line control my ($dlat,$dlon); # here $nlat is often 'extended' for display, but this is the NUMBER for ($ic = 0; $ic < $nearna; $ic++) { $typ = ${$rnavlist3}[$ic][0]; $dlat = ${$rnavlist3}[$ic][1]; $dlon = ${$rnavlist3}[$ic][2]; $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); # set global $actnav 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)"; # keep separate $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" ) if (VERB1()); $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" ) if (VERB9()); $outcount++; $lcnt++; $g_dupe_shown{$line} = 1; $msg = $actnav; $msg .= ' ' while (length($msg) < $maxnnlen); $adkm = sprintf( "%03.1f", ($dist / 1000.0)); # get kilometers $adkm = " $adkm" while (length($adkm) < 6); $ahdg = sprintf( "%03.1f", $az ); # and azimuth $ahdg = " $ahdg" while (length($ahdg) < 5); $msg .= "$adkm"."Km on hdg $ahdg"; $msg .= ", freq $nfrq, ident $nid $name $nlat $nlon"; prt("$msg\n"); } } prt("Done $dspcnt of $nearna NEAR [".ctr_latlon_stg()."]...\n") if ($nearna && VERB1()); $lcnt = 0; # count objects for display... $dspcnt = 0; # go through found airport list 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]; $amsl = $aptlist2[$ic][15]; # get APT altitude (AMSL) feet $icao .= ' ' while (length($icao) < 4); # $line = $diff; # this 'diff' is what exactly? $line = $amsl; # 20110221 - Now start with AMSL (feet) $line = ' '.$line while (length($line) < 6); $line .= ' '.$icao.' '.$name.' ('.$alat.','.$alon.')'; $dnone = 0; for ( $in = 0; $in < $nc; $in++ ) { $typ = $navlist2[$in][0]; $dlat = ${$rnavlist3}[$ic][1]; $dlon = ${$rnavlist3}[$ic][2]; $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 && VERB1()); } prt("List for $ac airports... near [".ctr_latlon_stg()."]... display $dspcnt...\n") if ($ac && VERB1()); $lcnt = 0; $ap_line = ''; 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]; $amsl = $aptlist2[$ic][15]; $icao .= ' ' while (length($icao) < 4); # $line = $diff; # start with 'offset' from center point $line = $amsl; # start with ALTITUDE (AMSL) feet $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 && VERB1()); # prt("$line\n"); $ap_line = $line; # setup to SHOW, only if a NAV AID is to be displayed $outcount++; $dnone = 0; $line = ''; for ( $in = 0; $in < $nc; $in++ ) { $typ = $navlist2[$in][0]; $dlat = $navlist2[$in][1]; $dlon = $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]; $nlat = $dlat; $nlon = $dlon; 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" ); if (VERB1()) { if (length($ap_line)) { prt("$ap_line\n"); $ap_line = ''; } 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 { if (length($ap_line)) { prt("$ap_line\n"); $ap_line = ''; } if ($check_sg_dist) { my ($sg_az1,$sg_az2,$sg_dist); my $res = fg_geo_inverse_wgs_84 ($g_center_lat,$g_center_lon,$dlat,$dlon,\$sg_az1,\$sg_az2,\$sg_dist); my $sg_km = $sg_dist / 1000; my $sg_im = int($sg_dist); my $sg_ikm = int($sg_km + 0.5); # if (abs($sg_pdist) < $CP_EPSILON) $dist_hdg .= " (SGDist: "; $sg_az1 = int(($sg_az1 * 10) + 0.05) / 10; if (abs($sg_km) > $SG_EPSILON) { # = 0.0000001; # EQUALS SG_EPSILON 20101121 if ($sg_ikm && ($sg_km >= 1)) { $sg_km = int(($sg_km * 10) + 0.05) / 10; $dist_hdg .= "$sg_km km"; } else { $dist_hdg .= "$sg_im m, <1km"; } } else { $dist_hdg .= "0 m"; } $dist_hdg .= " on $sg_az1"; $dist_hdg .= ")"; } #prt( "$lcnt: $line $dist_hdg\n" ); prt( "$line $dist_hdg\n" ); $g_dupe_shown{$line} = 1; add_2_tiles( get_bucket_info( $nlon, $nlat ) ); } } } prt( "$hdr\n" ) if ($dnone && VERB1() ); } prt( "[v5] Listed $lcnt NAVAIDS ...\n" ) if (VERB5()); } # LOAD apt.dat.gz # details see : http://data.x-plane.com/file_specs/Apt810.htm # Line codes used in apt.dat (810 version) # Airport Line - eg # 0 1 2 3 4 5++ # 1 1050 0 0 YGIL Gilgandra # ID AMSL Twr Bld ICAO Name # Code (apt.dat) Used for # 1 Airport header data. # 16 Seaplane base header data. No airport buildings or boundary fences will be rendered in X-Plane. # 17 Heliport header data. No airport buildings or boundary fences will be rendered in X-Plane. # 10 Runway or taxiway at an airport. # 14 Tower view location. # 15 Ramp startup position(s) # 18 Airport light beacons (usually "rotating beacons" in the USA). Different colours may be defined. # 19 Airport windsocks. # 50 to 56 Airport ATC (Air Traffic Control) frequencies. # runway # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 10 -31.696928 148.636404 15x 162.00 4204 0000.0000 0000.0000 98 121121 5 0 2 0.25 0 0000.0000 # rwy lat lon num true feet displament/extension wid lights surf shld mark smooth signs VASI 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; prt("[v9] Got $cnt lines to scan...\n") if (VERB9()); my ($add,$alat,$alon); # ================ # SEARCH THE LINES # search ICAO, POSITION, or NAME... # ================ $add = 0; my ($off,$dist,$az,@arr,@arr2,$rwyt,$glat,$glon,$dlat,$dlon,$rlat,$rlon); my ($line,$apt,$diff,$rwycnt,$icao,$name,@runways,$version); my ($aalt,$actl,$abld,$ftyp,$cfrq,$frqn,@freqs); my $total_apts = 0; my $total_lat = 0; my $total_lon = 0; my $c_lat = $g_center_lat; my $c_lon = $g_center_lon; $off = 0; $dist = 0; $az = 0; $glat = 0; $glon = 0; $apt = ''; $rwycnt = 0; @runways = (); @freqs = (); $msg = '[v1] '; if ($SRCHICAO) { $msg .= "Search ICAO [$apticao]..."; } elsif ($SRCHONLL) { $msg .= "Search LAT,LON [".ctr_latlon_stg()."], w/diff [$maxlatd,$maxlond]..."; } else { $msg .= "Search NAME [$aptname]..."; } $msg .= " got $cnt lines, FOR airports,rwys,txwys... "; foreach $line (@lines) { $line = trimall($line); if ($line =~ /\s+Version\s+/i) { @arr2 = split(/\s+/,$line); $version = $arr2[0]; $msg .= "Version $version"; last; } } prt("$msg\n") if (VERB1()); my $lncnt = 0; foreach $line (@lines) { $lncnt++; $line = trimall($line); ###prt("$line\n"); my @arr = split(/ /,$line); if ($line =~ /^$aln\s+/) { # start with '1' # 0 1 2 3 4 # 17 126 0 0 EH0001 [H] VU medisch centrum # ID ALT C B NAME++ if (length($apt) && ($rwycnt > 0)) { # average position $alat = $glat / $rwycnt; $alon = $glon / $rwycnt; $off = -1; $dist = 9999000; $az = 400; #$off = near_given_point( $alat, $alon, \$dist, \$az ); $dlat = abs( $c_lat - $alat ); $dlon = abs( $c_lon - $alon ); $diff = int( ($dlat * 10) + ($dlon * 10) ); @arr2 = split(/ /,$apt); $aalt = $arr2[1]; # Airport (general) ALTITUDE AMSL $actl = $arr2[2]; # control tower $abld = $arr2[3]; # buildings $icao = $arr2[4]; # ICAO $name = join(' ', splice(@arr2,5)); # Name ##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]); my @f = @freqs; # 0 1 2 3 4 5 6 push(@g_aptlist, [$diff, $icao, $name, $alat, $alon, $aalt, \@f]); #prt("$icao, $name, $alat, $alon, $aalt, $rwycnt runways\n"); $add = 0; # add to FOUND a/p, IFF if ($SRCHICAO) { # 1 - ICAO matches $add = 1 if ($icao =~ /$apticao/); } elsif ($SRCHONLL) { # 2 - searching by LAT,LON position if (($dlat < $maxlatd) && ($dlon < $maxlond)) { $add = 1; } } else { # 3 - searching by airport name $add = 1 if ($name =~ /$aptname/i); } if ($add) { $off = near_given_point( $alat, $alon, \$dist, \$az ); # if ($SRCHONLL), near GLOBAL center prt("[v1] Adding: $icao, $name, $alat, $alon, rwys $rwycnt...\n") if ($dbg1 || VERB1()); # 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]); my @a = @runways; # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@a, $aalt]); # = @runways $total_lat += $alat; $total_lon += $alon; $total_apts++; } } $apt = $line; $rwycnt = 0; @runways = (); # clear RUNWAY list @freqs = (); # clear frequencies $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]; # text 'xxx'=taxiway, 'H1x'=heleport, else a runway ###prt( "$line [$rlat, $rlon]\n" ); if ( $rwyt ne "xxx" ) { $glat += $rlat; $glon += $rlon; $rwycnt++; push(@runways, \@arr); } } elsif ($line =~ /^5(\d+)\s+/) { # frequencies $ftyp = $1; $cfrq = $arr[1]; $frqn = $arr[2]; $add = 0; if ($ftyp == 0) { $add = 1; # ATIS } elsif ($ftyp == 1) { $add = 1; # Unicom } elsif ($ftyp == 2) { $add = 1; # clearance } elsif ($ftyp == 3) { $add = 1; # ground } elsif ($ftyp == 4) { $add = 1; # tower } elsif ($ftyp == 5) { $add = 1; # approach } elsif ($ftyp == 6) { $add = 1; # departure } if ($add) { push(@freqs, \@arr); # save the freq array } else { pgm_exit(1, "WHAT IS THIS [5$ftyp $cfrq $frqn] [$line]\n FIX ME!!!"); } } elsif ($line =~ /^$sealn\s+/) { # = '16'; # Seaplane base header data. $rwycnt = 0; @runways = (); # clear RUNWAY list @freqs = (); # clear frequencies $glat = 0; $glon = 0; } elsif ($line =~ /^$heliln\s+/) { # = '17'; # Heliport header data. $rwycnt = 0; @runways = (); # clear RUNWAY list @freqs = (); # clear frequencies $glat = 0; $glon = 0; } 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( $c_lat - $alat ); $dlon = abs( $c_lon - $alon ); $diff = int( ($dlat * 10) + ($dlon * 10) ); @arr2 = split(/ /,$apt); $aalt = $arr2[1]; $actl = $arr2[2]; # control tower $abld = $arr2[3]; # buildings $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]); my @f = @freqs; # 0 1 2 3 4 5 6 push(@g_aptlist, [$diff, $icao, $name, $alat, $alon, $aalt, \@f]); $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 ); # if ($SRCHONLL), near GLOBAL center prt("$icao, $name, $alat, $alon, rwycnt $rwycnt - LAST\n") if ($dbg1); # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@runways,$aalt]); # 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]); my @a2 = @runways; push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@a2, $aalt]); # = @runways + altitude $total_lat += $alat; $total_lon += $alon; $total_apts++; } } if ( (! $SRCHONLL) && $total_apts) { # either by ICAO or Name search, so this become CENTER lat/lon $g_center_lat = $total_lat / $total_apts; $g_center_lon = $total_lon / $total_apts; prt( "[v1] Set CENTER LAT,LON [".ctr_latlon_stg()."]\n" ) if (VERB1()); } ### pgm_exit(1,"TEMP EXIT"); $cnt =scalar @g_aptlist; prt("[v9] Done scan of $lncnt lines for $cnt airports...\n") if (VERB9()); } 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; prt("[v9] Got ".scalar @nav_lines." lines to scan...\n") if (VERB9()); return @nav_lines; } # we have NOT found an airport by an ICAO name, search, # and group by area nav with PART of this name... sub search_nav_name() { my $cnt = 0; my @nav_lines = load_nav_file(); my ($line,$lnn,$len,$nc,$vcnt); my ($nlat,$nlon,$nalt,$nfreq,$nid,$name,$i,$ln); my (@arr,$typ,$off,$nfrq,$nfrq2,$nrng,$dist,$az); my $rnls = \@nav_lines; my $nav_cnt = scalar @{$rnls}; my $aptid = substr($apticao,1); # drop the country letter my $found = 0; my @navlist = (); prt("Searching $nav_cnt navaid records...using ICAO [$apticao], apt-id [$aptid]...\n"); for ($ln = 0; $ln < $nav_cnt; $ln++) { $line = ${$rnls}[$ln]; $line = trimall($line); $len = length($line); $lnn++; next if ($line =~ /\s+Version\s+/i); next if ($line =~ /^I/); next if ($len == 0); @arr = split(/ /,$line); $nc = scalar @arr; $typ = $arr[0]; last if ($typ == 99); if ($nc < 8) { prt("Type: [$typ] - Handle this line [$line] - count = $nc...\n"); pgm_exit(1,"ERROR: FIX ME FIRST!\n"); } # 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 ($i = 8; $i < $nc; $i++) { $name .= ' ' if length($name); $name .= $arr[$i]; } if ($nid =~ /$aptid/) { $off = 0; $dist = -1; # this is by NAME, not location $az = 400; prt( "[04] $actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name\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(@navlist, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off, $dist, $az]); $found++; } } } prt("Searched $vcnt navais records... found $found with [$aptid]...\n"); if ($found) { show_nav_list(\@navlist); } } # --------------------------------------------------------- # sub search_nav # Scan the NAVAID lines # Run 1: # Populate @g_navlist3 with navaids found within a given range of a CENTER point ($g_lat,$g_lon) # 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]); # Run 2: # Populate @navlist2 with navaids found within a given range of the AIRPORTS found, else the CENTER point #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]); # # --------------------------------------------------------- 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 [".ctr_latlon_stg()."]... "; # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@runways,$aalt]); 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" ) if (VERB1()); } else { prt("Expanded to [$nmaxlatd,$nmaxlond] from $ac airport(s)...\n" ) if (VERB1()); } 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; } $msg = "Found $navs_found nearby NAVAIDS, "; if ($usekmrange) { $msg .= "using distance $max_range_km Km..."; } else { $msg .= "using difference $nmaxlatd, $nmaxlond..."; } prt("$msg\n") if (VERB1()); $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; } sub mycmp_decend_az { return -1 if (${$a}[11] < ${$b}[11]); return 1 if (${$a}[11] > ${$b}[11]); return 0; } # $dist = $aptlist2[$i][12]; # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #push(@aptlist2, [$diff, $icao, $name, $alat, $alon, -1, 0, 0, 0, $icao, $name, $off, $dist, $az, \@runways,$aalt]); 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 get_fix_sample() { my $stg = <<EOF; I 600 Version - data cycle 2009.12, build 20091080, metadata FixXP700. Copyright © 2009, Robin A. Peel (robin\@xsquawkbox.net). 52.013889 -000.052778 ASKEY 50.052778 008.533611 ASKIK 54.503333 031.086667 ASKIL 99 EOF return $stg; } sub load_fix_hash($) { my ($rfa) = @_; my $max = scalar @{$rfa}; my ($line,$len,@arr,$cnt,$typ,$flat,$flon,$fname,$name,$key); my %h; foreach $line (@{$rfa}) { chomp $line; $line = trim_all($line); $len = length($line); next if ($len == 0); next if ($line =~ /^I/); @arr = split(/\s+/,$line); $cnt = scalar @arr; $typ = $arr[0]; next if ($typ == 600); last if ($typ == 99); if ($cnt >= 3) { $flat = $arr[0]; $flon = $arr[1]; $name = trim_all($arr[2]); $h{$name} = [ $flat, $flon ]; } } return \%h; } sub search_fix_file($) { my ($name) = @_; my ($flat,$flon,$rll,$key); my $rfa = load_fix_file(); # my $raa = load_awy_file(); my $tfh = load_fix_hash($rfa); my $cnt = scalar keys %{$tfh}; prt("[v2] Searching $cnt fix records for [$name]\n") if (VERB2()); $cnt = 0; foreach $key (keys %{$tfh}) { if ($key =~ /$name/) { $rll = ${$tfh}{$key}; $flat = ${$rll}[0]; $flon = ${$rll}[1]; $flat = ' '.$flat while (length($flat) < $g_maxnlatl); $flon = ' '.$flon while (length($flon) < $g_maxnlonl); prt("FIX: $key $flat $flon\n"); $cnt++; } } return $cnt; } sub get_awy_sample() { my $stg = <<EOF; I 640 Version - data cycle 2009.12, build 20091080, metadata AwyXP700. Copyright © 2009, Robin A. Peel (robin\@xsquawkbox.net). ASKER 38.273889 038.774722 ERH 38.463333 038.112222 1 115 285 W73 ASKER 38.273889 038.774722 GAZ 36.950278 037.473333 1 255 285 W701 ASKIK 50.052778 008.533611 DONIS 49.930556 008.859444 1 120 240 Z74 ASKIK 50.052778 008.533611 FFM 50.053742 008.637092 1 050 240 L984 ASKIK 50.052778 008.533611 MODAU 49.815000 008.811944 1 050 240 T840 ASKIK 50.052778 008.533611 RUDUS 50.047500 008.078333 1 050 240 L984 ASKIK 50.052778 008.533611 TABUM 50.290833 008.405000 1 050 240 T840 ASKIL 54.503333 031.086667 KOSAN 54.775000 029.278333 1 100 190 L736 99 EOF return $stg; } sub show_awy_item($$$$$$$$$$) { my ($name,$from,$flat,$flon,$to,$tlat,$tlon,$cat,$bfl,$efl) = @_; my ($sg_az1,$sg_az2,$sg_dist); my $ret = fg_geo_inverse_wgs_84($flat, $flon, $tlat, $tlon, \$sg_az1, \$sg_az2, \$sg_dist); my $sg_km = $sg_dist / 1000; my $sg_im = int($sg_dist); my $sg_ikm = int($sg_km + 0.5); my $sg_idegs = int($sg_az1 + 0.5); $sg_idegs = " $sg_idegs" while (length($sg_idegs) < 3); $sg_ikm = " $sg_ikm" while (length($sg_ikm) < 3); # begin bulding a display line my $line = "$name "; my $len = 6+1; my $max = 0; $line .= ' ' while (length($line) < $len); $len += 6+1; $line .= "$from "; $line .= ' ' while (length($line) < $len); $max = $g_maxnlatl - (length($line) - $len); $flat = ' '.$flat while (length($flat) < $max); $len += $g_maxnlatl+1; $line .= "$flat "; $line .= ' ' while (length($line) < $len); $max = $g_maxnlonl - (length($line) - $len); $flon = ' '.$flon while (length($flon) < $max); $len += $g_maxnlatl+1; $line .= "$flon "; $line .= ' ' while (length($line) < $len); $line .= "$to "; $len += 6 + 1; $line .= ' ' while (length($line) < $len); $max = $g_maxnlatl - (length($line) - $len); $tlat = ' '.$tlat while (length($tlat) < $max); $len += $g_maxnlatl+1; $line .= "$tlat "; $line .= ' ' while (length($line) < $len); $max = $g_maxnlonl - (length($line) - $len); $tlon = ' '.$tlon while (length($tlon) < $max); $len += $g_maxnlatl+1; $line .= "$tlon "; $line .= ' ' while (length($line) < $len); prt("AWY: $line (on $sg_idegs for $sg_ikm km).\n"); } # from airways.cxx # in >> identStart; # if (identStart == "99") { break; } # in >> latStart >> lonStart >> identEnd >> latEnd >> lonEnd >> type >> base >> top >> name; # // type = 1; low-altitude # // type = 2; high-altitude # Network* net = (type == 1) ? static_lowLevel : static_highLevel; sub load_awy_hash($) { my ($raa) = @_; my $max = scalar @{$raa}; my ($line,$len,@arr,$cnt,$typ,$flat,$flon,$fname,$name,$key); my ($tlat,$tlon,$from,$to,$hadver); my ($cat,$bfl,$efl,$ra,$lnn); my %ids = (); $lnn = 0; $hadver = 0; foreach $line (@{$raa}) { $lnn++; chomp $line; $line = trim_all($line); $len = length($line); next if ($len == 0); next if (($line =~ /^I/)&&($hadver == 0)); if ($line =~ /\s+Version\s+/) { $hadver = 1; #next if ($typ == 640); next; } @arr = split(/\s+/,$line); $cnt = scalar @arr; $typ = $arr[0]; last if ($typ =~ /^99/); if ($cnt >= 10) { # 0 1 2 3 4 5 6 7 8 9 # ASKIK 50.052778 008.533611 RUDUS 50.047500 008.078333 1 050 240 L984 $from = $arr[0]; $flat = $arr[1]; $flon = $arr[2]; $to = $arr[3]; $tlat = $arr[4]; $tlon = $arr[5]; # 1 115 285 W73 $cat = $arr[6]; # category 1 == low altitude, 2 == high altitude $bfl = $arr[7]; # begin flight level $efl = $arr[8]; # end flight level $name = trim_all($arr[9]); $ids{$name} = [ ] if (!defined $ids{$name}); $ra = $ids{$name}; push(@{$ra}, [ $from, $flat, $flon, $to, $tlat, $tlon, $cat, $bfl, $efl ]); } } return \%ids; } # from airways.cxx # in >> identStart; # if (identStart == "99") { break; } # in >> latStart >> lonStart >> identEnd >> latEnd >> lonEnd >> type >> base >> top >> name; # // type = 1; low-altitude # // type = 2; high-altitude # Network* net = (type == 1) ? static_lowLevel : static_highLevel; sub search_awy_file($) { my ($name) = @_; my ($from,$flat,$flon,$rll,$key); my $raa = load_awy_file(); # my $raa = load_awy_file(); my $tah = load_awy_hash($raa); my $cnt = scalar keys %{$tah}; my ($acnt,$to,$tlat,$tlon,$cat,$bfl,$efl,$id,$i); prt("[v2] Searching $cnt airway records for [$name]\n") if (VERB2()); $cnt = 0; foreach $key (keys %{$tah}) { if ($key =~ /$name/) { $rll = ${$tah}{$key}; $acnt = scalar @{$rll}; for ($i = 0; $i < $acnt; $i++) { ## 0 1 2 3 4 5 6 7 8 #$ids{$name} = [ $from, $flat, $flon, $to, $tlat, $tlon, $cat, $bfl, $efl ]; $from = ${$rll}[$i][0]; $flat = ${$rll}[$i][1]; $flon = ${$rll}[$i][2]; $to = ${$rll}[$i][3]; $tlat = ${$rll}[$i][4]; $tlon = ${$rll}[$i][5]; # 1 115 285 W73 $cat = ${$rll}[$i][6]; # category 1 = low, 2 = high $bfl = ${$rll}[$i][7]; # begin flight level $efl = ${$rll}[$i][8]; # end flight level show_awy_item($key,$from,$flat,$flon,$to,$tlat,$tlon,$cat,$bfl,$efl); $cnt++; } } } return $cnt; } sub show_awy_array($$) { my ($name,$ra) = @_; #my $tmp = ref($ra); #prt("Got ref [$tmp]\n"); ## 0 1 2 3 4 5 6 7 8 #$ids{$name} = [ $from, $flat, $flon, $to, $tlat, $tlon, $cat, $bfl, $efl ]; my $from = ${$ra}[0]; my $flat = ${$ra}[1]; my $flon = ${$ra}[2]; my $to = ${$ra}[3]; my $tlat = ${$ra}[4]; my $tlon = ${$ra}[5]; # 1 115 285 W73 my $cat = ${$ra}[6]; # category 1 = low, 2 = high my $bfl = ${$ra}[7]; # begin flight level my $efl = ${$ra}[8]; # end flight level show_awy_item($name,$from,$flat,$flon,$to,$tlat,$tlon,$cat,$bfl,$efl); } sub list_awy_file() { my $raa = load_awy_file(); my $tah = load_awy_hash($raa); my $cnt = scalar keys %{$tah}; prt("Listing $cnt airway records..\n"); # if (VERB2()); my ($name,$val,$acnt,$i,$ra,$tmp); foreach $name (sort keys %{$tah}) { $val = ${$tah}{$name}; $acnt = scalar @{$val}; for ($i = 0; $i < $acnt; $i++) { $ra = ${$val}[$i]; $tmp = ref($ra); # prt("Extracted a [$tmp]\n"); show_awy_array($name,$ra); } } } sub load_awy_hash2($) { my ($raa) = @_; my $max = scalar @{$raa}; my ($line,$len,@arr,$cnt,$typ,$flat,$flon,$fname,$name,$key); my ($tlat,$tlon,$from,$to,$hadver); my ($cat,$bfl,$efl,$ra,$lnn); my %h = (); $lnn = 0; $hadver = 0; foreach $line (@{$raa}) { $lnn++; chomp $line; $line = trim_all($line); $len = length($line); next if ($len == 0); next if (($line =~ /^I/)&&($hadver == 0)); if ($line =~ /\s+Version\s+/) { $hadver = 1; #next if ($typ == 640); next; } @arr = split(/\s+/,$line); $cnt = scalar @arr; $typ = $arr[0]; last if ($typ =~ /^99/); if ($cnt >= 10) { # 0 1 2 3 4 5 6 7 8 9 # ASKIK 50.052778 008.533611 RUDUS 50.047500 008.078333 1 050 240 L984 $from = $arr[0]; $flat = $arr[1]; $flon = $arr[2]; $to = $arr[3]; $tlat = $arr[4]; $tlon = $arr[5]; # 1 115 285 W73 $cat = $arr[6]; # category 1 == low altitude, 2 == high altitude $bfl = $arr[7]; # begin flight level $efl = $arr[8]; # end flight level $name = trim_all($arr[9]); $h{$from} = [ ] if (!defined $h{$from}); $ra = $h{$from}; # 0 1 2 3 4 5 6 7 8 push(@{$ra}, [ $flat, $flon, $to, $tlat, $tlon, $cat, $bfl, $efl, $name ]); $h{$to} = [ ] if (!defined $h{$to}); $ra = $h{$to}; push(@{$ra}, [ $tlat, $tlon, $from, $flat, $flon, $cat, $bfl, $efl, $name ]); } } return \%h; } sub search_awy_file_prev($) { my ($name) = @_; my ($flat,$flon,$rll,$key); my $raa = load_awy_file(); # my $raa = load_awy_file(); my $tah = load_awy_hash2($raa); my $cnt = scalar keys %{$tah}; my ($acnt,$to,$tlat,$tlon,$cat,$bfl,$efl,$id,$i); my ($ret,$sg_az1,$sg_az2,$sg_dist); prt("[v2] Searching $cnt airway records for [$name]\n") if (VERB2()); $cnt = 0; foreach $key (keys %{$tah}) { if ($key =~ /$name/) { $rll = ${$tah}{$key}; $acnt = scalar @{$rll}; for ($i = 0; $i < $acnt; $i++) { $flat = ${$rll}[$i][0]; $flon = ${$rll}[$i][1]; $to = ${$rll}[$i][2]; $tlat = ${$rll}[$i][3]; $tlon = ${$rll}[$i][4]; # 1 115 285 W73 $cat = ${$rll}[$i][5]; # category 1 = low, 2 = high $bfl = ${$rll}[$i][6]; # begin flight level $efl = ${$rll}[$i][7]; # end flight level $id = ${$rll}[$i][8]; # airway NAME $ret = fg_geo_inverse_wgs_84($flat, $flon, $tlat, $tlon, \$sg_az1, \$sg_az2, \$sg_dist); my $sg_km = $sg_dist / 1000; my $sg_im = int($sg_dist); my $sg_ikm = int($sg_km + 0.5); my $sg_idegs = int($sg_az1 + 0.5); $sg_idegs = " $sg_idegs" while (length($sg_idegs) < 3); $sg_ikm = " $sg_ikm" while (length($sg_ikm) < 3); $flat = ' '.$flat while (length($flat) < $g_maxnlatl); $flon = ' '.$flon while (length($flon) < $g_maxnlonl); $to .= ' ' while (length($to) < 6); $tlat = ' '.$tlat while (length($tlat) < $g_maxnlatl); $tlon = ' '.$tlon while (length($tlon) < $g_maxnlonl); prt("AWY: $key $flat $flon $to $tlat $tlon on $sg_az1 ($sg_idegs at $sg_ikm km).\n"); $cnt++; } } } return $cnt; } sub do_looks_like_fix() { # looks like a FIX... my $cnt = 0; prt("ICAO has len greater than 4, so assume a FIX... [$apticao]\n"); $g_fix_name = $apticao; if (search_fix_file($g_fix_name)) { prt("Found the above fix...\n"); $cnt++; } if (search_awy_file($g_fix_name)) { prt("Found the above airways...\n"); $cnt++; } if ($cnt) { prt("Hope your search for $apticao is one of these ;=)) Or try another name...\n"); } else { prt("ICAO $apticao NOT found ;=(( Try another name...\n"); } pgm_exit(0,""); } #====================================================== ### MAIN ### # ========== #search_fix_file($g_fix_name); #pgm_exit(1,""); #list_awy_file(); #$loadlog = 1; #pgm_exit(1,""); parse_args(@ARGV); # collect command line arguments ... prt( "$pgmname ... Hello, World ... ".scalar localtime(time())."\n" ) if (VERB9()); if ($SRCHICAO && (length($apticao) > 4)) { do_looks_like_fix(); } load_apt_data(); set_average_apt_latlon(); #my @aptsort = sort mycmp_ascend @aptlist; if ( show_airports_found($max_cnt) || $SRCHONLL ) { if ($SHOWNAVS) { search_nav(); show_navaids_found(); show_airports_found($max_cnt) if (VERB9()); } show_scenery_tiles(); } elsif ( $SHOWNAVS ) { prt("No airport found, so no show of nav's around it...\n"); if ($SRCHICAO) { search_nav_name(); } } my $elapsed = tv_interval ( $t0, [gettimeofday]); prt( "Ran for $elapsed seconds ...\n" ) if (VERB5()); pgm_exit(0,""); ####################################################### ### HELP AND COMMAND LINE 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_center_lat,$g_center_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 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") } } sub deal_with_verbosity($) { my ($rav) = @_; my ($arg,$sarg,$i,$cnt); $cnt = scalar @{$rav}; #prt("Doing verbosity check of $cnt args...\n"); for ($i = 0; $i < $cnt; $i++) { $arg = ${$rav}[$i]; #prt("Checking [$arg]...\n"); if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if ($sarg =~ /^v/) { #prt("Got -v... [$arg]\n"); if ($sarg =~ /^v.*(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/i) { $verbosity++; $sarg = substr($sarg,1) } } prt( "[v1] Set verbosity to $verbosity\n") if (VERB1()); } } } } # set $SRCHICAO on/off # set $SRCHONLL on/off sub parse_args { my (@av) = @_; my (@arr,$arg,$sarg,$lcarg,$ch); $arg = scalar @av; #prt("Deal with $arg command arguments...\n"); 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( "[v1] Set VOR (NBD) ONLY flag\n") if (VERB1()); } elsif (( $sarg =~ /^loadlog$/ )||($sarg =~ /^l$/)) { prt("[v1] 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( "[v1] Set 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( "[v1] Set 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_center_lat = $arr[0]; $g_center_lon = $arr[1]; prt( "[v1] Set search using LAT,LON of [".ctr_latlon_stg()."] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $g_center_lat = $arr[0]; require_arg(@av); shift @av; $g_center_lon = $av[0]; if (($g_center_lat =~ /^(\d|-|\+|\.)+$/) && ($g_center_lon =~ /^(\d|-|\+|\.)+$/)) { prt( "[v1] Set search using LAT,LON of [".ctr_latlon_stg()."] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find lat,lon in [$arg] [".ctr_latlon_stg()."]...\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_center_lat = $arr[0]; $g_center_lon = $arr[1]; prt( "[v1] Set search using LAT,LON of [".ctr_latlon_stg()."] ...\n" ) if (VERB1()); } else { # 17/08/2010 - assume lat and lon also split, and try harder $g_center_lat = $arr[0]; require_arg(@av); shift @av; $g_center_lon = $av[0]; if (($g_center_lat =~ /^(\d|-|\+|\.)+$/) && ($g_center_lon =~ /^(\d|-|\+|\.)+$/)) { prt( "[v1] Set search using LAT,LON of [".ctr_latlon_stg()."] ...\n" ) if (VERB1()); } else { mydie( "ERROR: Failed to find lat,lon in [$arg] [".ctr_latlon_stg()."]...\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( "[v1] Set 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( "[v1] Set search using NAME of [$aptname] ...\n" ) if (VERB1()); } elsif ( $arg =~ /^-loadlog$/i ) { $loadlog = 1; prt( "[v1] Set load log into wordpad.\n" ) if (VERB1()); } elsif ( $arg =~ /^-shownavs$/i ) { $SHOWNAVS = 1; prt( "[v1] Set show NAVAIDS around airport, if any.\n" ) if (VERB1()); } elsif ( $arg =~ /^-s$/i ) { $SHOWNAVS = 1; prt( "[v1] Set 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( "[v1] Set 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( "[v1] Set 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( "[v1] Set 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( "[v1] Set 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( "[v1] Set 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( "[v1] Set 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( "[v1] Set 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( "[v1] Set using AIRPORT data file [$aptdat] ...\n" ) if (VERB1()); } elsif ( $arg =~ /-navdata=(.+)/i ) { $navdat = $1; prt( "[v1] Set using NAVAID data file [$navdat] ...\n" ) if (VERB1()); } elsif ( $lcarg eq '-navdata' ) { require_arg(@av); shift @av; $navdat = $av[0]; prt( "[v1] Set Using NAVAID data file [$navdat] ...\n" ) if (VERB1()); } elsif ( $arg =~ /-maxout=(.+)/i ) { $max_cnt = $1; prt( "[v1] Set 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( "[v1] Set AIRPORT output limited to $max_cnt. A zero (0), for no limit\n" ) if (VERB1()); } elsif ( $arg =~ /-range=(.+)/i ) { $max_range_km = $1; # prt( "Set navaid search range $max_range_km Km. A zero (0), for no limit\n" ) if (VERB1()); $usekmrange = 1; prt( "[v1] Set NAVAID search range $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( "[v1] Set NAVAID search range $max_range_km Km.\n" ) if (VERB1()); } elsif ( $lcarg eq '-r' ) { $usekmrange = 1; prt( "[v1] 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( "[v1] Set NAVAID search 'tryharder'...\n" ) if (VERB1()); } else { mydie( "ERROR: Unknown argument [$arg]. Try ? for HELP ...\n" ); } } else { # ASSUME AN AIRPORT NAME $SRCHICAO = 0; $SRCHONLL = 0; $SRCHNAME = 1; if ((length($arg) == 4)&&($arg =~ /^[A-Z0-9]+$/)) { # assume is an ICAO value # BY ICAO $apticao = $arg; $SRCHICAO = 1; $SRCHONLL = 0; $SRCHNAME = 0; prt( "[v1] Set search using ICAO of [$apticao] ...\n" ) if (VERB1()); } else { $aptname = $arg; prt( "[v1] 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_center_lat = $def_lat; $g_center_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 - findap03.pl