#!/usr/bin/perl -w # NAME: gencircuit.pl # AIM: Experiments with generating a flight circuit for an airport. # Inistially for YGIL, then YSDU airport, but want to expand that... # given a GPS point, plot a TRACK, to join the VFR circuit, .... # 2020-01-24 - review... # 27/06/2015 geoff mclane http://geoffair.net/mperl use strict; use warnings; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) use Math::Trig; use Cwd; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; my $temp_dir = '/tmp'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $temp_dir = $perl_dir; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n"; require 'fg_wsg84.pl' or die "Unable to load fg_wsg84.pl ...\n"; require "Bucket2.pm" or die "Unable to load Bucket2.pm ...\n"; # log file stuff our ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt"; open_log($outfile); # user variables my $VERS = "0.0.6 2020-01-24"; # $VERS = "0.0.5 2015-01-09"; my $load_log = 0; my $in_file = ''; my $verbosity = 0; my $out_file = ''; my ($start_lat,$start_lon); my ($next_targ_lat,$next_targ_lon); # ### DEBUG ### my $debug_on = 0; my $def_file = 'def_file'; my $tmp_circuit = $perl_dir."\\tempcircuit2.txt"; my $tmp_circuit_xg = $perl_dir."\\tempcircuit2.xg"; ### program variables my @warnings = (); my $cwd = cwd(); sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { prt( "\nNo warnings issued.\n\n" ) if (VERB9()); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } sub process_in_file($) { my ($inf) = @_; if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; prt("Processing $lncnt lines, from [$inf]...\n"); my ($line,$inc,$lnn); $lnn = 0; foreach $line (@lines) { chomp $line; $lnn++; if ($line =~ /\s*#\s*include\s+(.+)$/) { $inc = $1; prt("$lnn: $inc\n"); } } } my $dbg_01 = 0; my $dbg_02 = 0; my $stand_glide_degs = 3; # degrees my $stand_patt_alt = 1000; # feet my $stand_cross_nm = 2.1; # nm, but this will depend on the aircraft ### constants my $SGD_PI = 3.1415926535; my $SGD_DEGREES_TO_RADIANS = $SGD_PI / 180.0; my $SGD_RADIANS_TO_DEGREES = 180.0 / $SGD_PI; my $DEF_GS = 3; my $ATAN3 = atan( $DEF_GS * $SGD_DEGREES_TO_RADIANS ); # /** Feet to Meters */ my $SG_FEET_TO_METER = 0.3048; # /** Meters to Feet */ my $SG_METER_TO_FEET = 3.28083989501312335958; my $SG_NM_TO_METER = 1852; my $SG_METER_TO_NM = 0.0005399568034557235; my $a_gil_lat = -31.697287500; my $a_gil_lon = 148.636942500; my $a_dub_lat = -32.2174865; my $a_dub_lon = 148.57727; # rough Gil circuit - will be replaced by CALCULATED values my $tl_lat = -31.684063; my $tl_lon = 148.614120; my $bl_lat = -31.723495; my $bl_lon = 148.633003; my $br_lat = -31.716778; my $br_lon = 148.666992; my $tr_lat = -31.672960; my $tr_lon = 148.649139; my $use_pattern = 1; # adjust the above values to the computed circuit my $add_text_count = 1; # add text count my $try_dash_line = 1; ############################################################## my $switch_circuit = 0; # should DEPEND on the targeted RUNWAY my $active_key = 'YGIL'; my $active_runway = '33'; # Access to RUNWAY INFORMATION, like # ${$rrwys}[$off][$RW_LLAT] = $elat1; # ${$rrwys}[$off][$RW_LLON] = $elon1; # ${$rrwys}[$off][$RW_RLAT] = $elat2; # ${$rrwys}[$off][$RW_RLON] = $elon2; my ($active_ref_rwys,$active_off_rwys); # RUNWAY ARRAY OFFSETS my $RW_LEN = 0; my $RW_HDG = 1; my $RW_REV = 2; my $RW_TT1 = 3; my $RW_TT2 = 4; my $RW_CLAT = 5; my $RW_CLON = 6; my $RW_LLAT = 7; my $RW_LLON = 8; my $RW_RLAT = 9; my $RW_RLON = 10; my $RW_DONE = 11; # Len Hdg Rev Title RTit Ctr Lat Ctr Lon # 0 1 2 3 4 5 6 7 8 9 10 11 my @gil_patt = (); ###my @gil_rwys = ( [4204, 162.0, 0, '15', '33', -31.696928, 148.636404, 0, 0, 0, 0, 0 ] ); my @gil_rwys = ( [3984, 162.22, 0, '15', '33', -31.69656323, 148.6363057, 0, 0, 0, 0, 0 ] ); #my @gil_navs = ( ["", 0 ] ); my @gil_navs = (); #my @gil_rwys = ( [162.0, 4204], [93.0, 1902] ); my @dub_patt = ( [ ] ); my @dub_rwys = ( [5600, 53.61, 0, '05', '23', -32.218265, 148.576145, 0, 0, 0, 0, 0 ] ); my @dub_navs = ( ["VOR", 114.4], ["NDB", 251] ); my $OL_LAT = 0; my $OL_LON = 1; my $OL_NAV = 2; my $OL_RWY = 3; my $OL_PAT = 4; my %apt_locations = ( # ICAO Center LAT, LON NAVAIDS RUNWAYS 'YGIL' => [$a_gil_lat, $a_gil_lon, \@gil_navs, \@gil_rwys, \@gil_patt ], 'YSDU' => [$a_dub_lat, $a_dub_lon, \@dub_navs, \@dub_rwys, \@dub_patt ] ); sub get_locations() { return \%apt_locations; } my ($ref_circuit_hash); sub set_dist_stg($) { my ($rd) = @_; my $dist = ${$rd}; my ($sc); if ($dist < 1000) { $dist = int($dist); $sc = 'm'; } else { $dist = (int(($dist / 1000) * 10) / 10); $sc = 'Km'; } ${$rd} = "$dist$sc"; } sub set_decimal1_stg($) { my $r = shift; ${$r} = int((${$r} + 0.05) * 10) / 10; ${$r} = "0.0" if (${$r} == 0); ${$r} .= ".0" if !(${$r} =~ /\./); } sub set_decimal2_stg($) { my $r = shift; ${$r} = int((${$r} + 0.005) * 100) / 100; ${$r} = "0.0" if (${$r} == 0); ${$r} .= ".0" if !(${$r} =~ /\./); } sub set_decimal3_stg($) { my $r = shift; ${$r} = int((${$r} + 0.0005) * 1000) / 1000; ${$r} = "0.0" if (${$r} == 0); ${$r} .= ".0" if !(${$r} =~ /\./); } sub set_int_stg($) { my $r = shift; ${$r} = int(${$r} + 0.5); } sub get_dist_stg_nm($) { my ($dist) = @_; my $nm = $dist * $SG_METER_TO_NM; set_decimal1_stg(\$nm); $nm .= "nm"; return $nm; } sub set_dist_m2kmnm_stg($) { my ($rd) = @_; my $distm = ${$rd}; my $km = $distm; set_dist_stg(\$km); $km .= '/'; $km .= get_dist_stg_nm($distm); ${$rd} = $km; } sub set_hdg_stg1($) { my ($rh) = @_; my $hdg = ${$rh}; $hdg = (int(($hdg+0.05) * 10) / 10); ${$rh} = $hdg; } sub set_lat_stg($) { my ($rl) = @_; ${$rl} = sprintf("%2.7f",${$rl}); } sub set_lon_stg($) { my ($rl) = @_; ${$rl} = sprintf("%3.7f",${$rl}); } sub set_hdg_stg($) { my ($rh) = @_; my $hdg = ${$rh}; $hdg = 360 if ($hdg == 0); # always replace 000 with 360 ;=)) $hdg = sprintf("%03d",int($hdg+0.5)); ${$rh} = $hdg; } sub set_hdg_stg3($) { my $r = shift; set_int_stg($r); my $r3 = sprintf("%3d",${$r}); ${$r} = $r3; } sub set_int_dist_stg5($) { my $r = shift; set_int_stg($r); my $r5 = sprintf("%5d",${$r}); ${$r} = $r5; } sub normalised_hdg($) { my $hdg = shift; $hdg += 360 if ($hdg < 0); $hdg -= 360 if ($hdg >= 360); return $hdg; } sub show_distance_heading($$$$) { my ($lat1,$lon1,$lat2,$lon2) = @_; my ($az1,$az2,$dist); fg_geo_inverse_wgs_84 ($lat1,$lon1,$lat2,$lon2,\$az1,\$az2,\$dist); $dist = get_dist_stg_nm($dist); set_hdg_stg(\$az1); prt("Is $dist, on heading $az1\n"); } sub get_mid_pt($$$$) { my ($elat1,$elon1,$elat2,$elon2) = @_; my ($az1,$az2,$dist,$rclat,$rclon,$az3); fg_geo_inverse_wgs_84($elat1,$elon1,$elat2,$elon2,\$az1,\$az2,\$dist); fg_geo_direct_wgs_84($elat2,$elon2,$az2,($dist / 2),\$rclat,\$rclon,\$az3 ); return ($rclat,$rclon,$az3); } sub get_circuit_hash() { my %h = (); $h{'tl_lat'} = $tl_lat; $h{'tl_lon'} = $tl_lon; $h{'bl_lat'} = $bl_lat; $h{'bl_lon'} = $bl_lon; $h{'br_lat'} = $br_lat; $h{'br_lon'} = $br_lon; $h{'tr_lat'} = $tr_lat; $h{'tr_lon'} = $tr_lon; set_circuit_values(\%h,1); return \%h; } sub set_circuit_values($$) { my ($rch,$show) = @_; my ($az1,$az2,$dist); my ($dwd,$dwa,$bsd,$bsa,$rwd,$rwa,$crd,$cra); my ($tllat,$tllon,$bllat,$bllon,$brlat,$brlon,$trlat,$trlon); my ($elat1,$elon1); # nearest end fg_geo_inverse_wgs_84 (${$rch}{'tl_lat'},${$rch}{'tl_lon'},${$rch}{'bl_lat'},${$rch}{'bl_lon'},\$az1,\$az2,\$dist); ${$rch}{'l1_az1'} = $az1; ${$rch}{'l1_az2'} = $az2; ${$rch}{'l1_dist'} = $dist; ${$rch}{'TL'} = [$az1,$az2,$dist]; fg_geo_inverse_wgs_84 (${$rch}{'bl_lat'},${$rch}{'bl_lon'},${$rch}{'br_lat'},${$rch}{'br_lon'},\$az1,\$az2,\$dist); ${$rch}{'l2_az1'} = $az1; ${$rch}{'l2_az2'} = $az2; ${$rch}{'l2_dist'} = $dist; ${$rch}{'BL'} = [$az1,$az2,$dist]; fg_geo_inverse_wgs_84 (${$rch}{'br_lat'},${$rch}{'br_lon'},${$rch}{'tr_lat'},${$rch}{'tr_lon'},\$az1,\$az2,\$dist); ${$rch}{'l3_az1'} = $az1; ${$rch}{'l3_az2'} = $az2; ${$rch}{'l3_dist'} = $dist; ${$rch}{'BR'} = [$az1,$az2,$dist]; fg_geo_inverse_wgs_84 (${$rch}{'tr_lat'},${$rch}{'tr_lon'},${$rch}{'tl_lat'},${$rch}{'tl_lon'},\$az1,\$az2,\$dist); ${$rch}{'l4_az1'} = $az1; ${$rch}{'l4_az2'} = $az2; ${$rch}{'l4_dist'} = $dist; ${$rch}{'TR'} = [$az1,$az2,$dist]; ${$rch}{'rwy_ref'} = $active_ref_rwys; ${$rch}{'rwy_off'} = $active_off_rwys; # ================================================ $tllat = ${$rch}{'tl_lat'}; $tllon = ${$rch}{'tl_lon'}; $bllat = ${$rch}{'bl_lat'}; $bllon = ${$rch}{'bl_lon'}; $brlat = ${$rch}{'br_lat'}; $brlon = ${$rch}{'br_lon'}; $trlat = ${$rch}{'tr_lat'}; $trlon = ${$rch}{'tr_lon'}; my $msg = "# $active_key circuit\n"; $msg .= "[$active_key]\n"; $msg .= "P1=$tllat,$tllon\n"; $msg .= "P2=$bllat,$bllon\n"; $msg .= "P3=$brlat,$brlon\n"; $msg .= "P4=$trlat,$trlon\n"; $msg .= "direction=anticlockwise\n"; write2file($msg,$tmp_circuit); prt("Circuit written to $tmp_circuit file\n"); # ================================================ if ($show) { ### my ($elat2,$elon2); ### my ($az11,$az21,$dist1); $tllat = ${$rch}{'tl_lat'}; $tllon = ${$rch}{'tl_lon'}; $bllat = ${$rch}{'bl_lat'}; $bllon = ${$rch}{'bl_lon'}; $brlat = ${$rch}{'br_lat'}; $brlon = ${$rch}{'br_lon'}; $trlat = ${$rch}{'tr_lat'}; $trlon = ${$rch}{'tr_lon'}; # extract values $dwa = ${$rch}{'l1_az1'}; $dwd = ${$rch}{'l1_dist'}; $bsd = ${$rch}{'l2_dist'}; $bsa = ${$rch}{'l2_az1'}; $rwd = ${$rch}{'l3_dist'}; $rwa = ${$rch}{'l3_az1'}; $crd = ${$rch}{'l4_dist'}; $cra = ${$rch}{'l4_az1'}; # get NEAREST runway END $elat1 = ${$active_ref_rwys}[$active_off_rwys][$RW_LLAT]; $elon1 = ${$active_ref_rwys}[$active_off_rwys][$RW_LLON]; fg_geo_inverse_wgs_84 (${$rch}{'br_lat'},${$rch}{'br_lon'},$elat1,$elon1,\$az1,\$az2,\$dist); # get OTHER runway END # $elat2 = ${$active_ref_rwys}[$active_off_rwys][$RW_RLAT]; # $elon2 = ${$active_ref_rwys}[$active_off_rwys][$RW_RLON]; ### fg_geo_inverse_wgs_84 (${$rch}{'br_lat'},${$rch}{'br_lon'},$elat2,$elon2,\$az11,\$az21,\$dist1); # set for display - values DESTROYED for calculations # =================================================== set_dist_stg(\$dist); set_int_stg(\$az1); ### set_dist_stg(\$dist1); set_lat_stg(\$tllat); set_lat_stg(\$bllat); set_lat_stg(\$brlat); set_lat_stg(\$trlat); set_lon_stg(\$tllon); set_lon_stg(\$bllon); set_lon_stg(\$brlon); set_lon_stg(\$trlon); prt("Set, show circuit...\nTL $tllat,$tllon\nBL ". "$bllat,$bllon\nBR ". "$brlat,$brlon\nTR ". "$trlat,$trlon\n"); set_int_dist_stg5(\$dwd); set_hdg_stg3(\$dwa); set_int_dist_stg5(\$bsd); set_hdg_stg3(\$bsa); set_int_dist_stg5(\$rwd); set_hdg_stg3(\$rwa); set_int_dist_stg5(\$crd); set_hdg_stg3(\$cra); prt("l1 $dwd m, on $dwa (tl2bl) - downwind, turn $bsa to base\n"); prt("l2 $bsd m, on $bsa (bl2br) - base, turn $rwa to final $active_key $active_runway $dist on $az1\n"); prt("l3 $rwd m, on $rwa (br2tr) - runway, turn $cra to cross\n"); prt("l4 $crd m, on $cra (tr2tl) - cross, turn $dwa to downwind\n"); } } sub show_rw_patt($$) { my ($key,$rpatts) = @_; my $cnt = scalar @{$rpatts}; prt("Display of $cnt patterns/circuits for $key...\n"); my ($i,$lat1,$lon1,$lat2,$lon2,$j); for ($i = 0; $i < $cnt; $i++) { for ($j = 0; $j < 8; $j += 2) { $lat1 = ${$rpatts}[$i][$j+0]; $lon1 = ${$rpatts}[$i][$j+1]; if ($j == 6) { $lat2 = ${$rpatts}[$i][0]; $lon2 = ${$rpatts}[$i][1]; } else { $lat2 = ${$rpatts}[$i][$j+2]; $lon2 = ${$rpatts}[$i][$j+3]; } prt("$i:$j: $lat1,$lon1 $lat2,$lon2\n"); show_distance_heading($lat1,$lon1,$lat2,$lon2); } } } sub set_runway_ends_and_patt($$$$$) { my ($rrwys,$off,$key,$rpatts,$set) = @_; # set ENDS of runway my $rlen = ${$rrwys}[$off][$RW_LEN]; my $rhdg = ${$rrwys}[$off][$RW_HDG]; my $clat = ${$rrwys}[$off][$RW_CLAT]; my $clon = ${$rrwys}[$off][$RW_CLON]; my $rty1 = ${$rrwys}[$off][$RW_TT1]; my $rty2 = ${$rrwys}[$off][$RW_TT2]; my $rwlen2 = ($rlen * $SG_FEET_TO_METER) / 2; my ($elat1,$elon1,$eaz1,$elat2,$elon2,$eaz2); my $hdgr = $rhdg + 180; $hdgr -= 360 if ($hdgr >= 360); ${$rrwys}[$off][$RW_REV] = $hdgr; fg_geo_direct_wgs_84( $clat, $clon, $rhdg, $rwlen2, \$elat1, \$elon1, \$eaz1 ); fg_geo_direct_wgs_84( $clat, $clon, $hdgr, $rwlen2, \$elat2, \$elon2, \$eaz2 ); ${$rrwys}[$off][$RW_LLAT] = $elat1; ${$rrwys}[$off][$RW_LLON] = $elon1; ${$rrwys}[$off][$RW_RLAT] = $elat2; ${$rrwys}[$off][$RW_RLON] = $elon2; ${$rrwys}[$off][$RW_DONE] = $off + 1; my ($az1,$az2,$dist); fg_geo_inverse_wgs_84 ($elat1,$elon1,$elat2,$elon2,\$az1,\$az2,\$dist); $dist = $dist * $SG_METER_TO_FEET; set_int_stg(\$az1); set_int_stg(\$az2); set_int_stg(\$dist); # init: YSDU: 23: -32.2136987804606,148.583432501246 05: -32.2228307960945,148.568856770273 234 5600 54 vs 53.61 5600 # init: YGIL: 33: -31.7024233216057,148.638492502638 15: -31.6914326394609,148.634315743548 342 4204 162 vs 162 4204 #prt("init: $key: $rty2: $elat1,$elon1 $az1 $rty1: $elat2,$elon2 $az1 $dist $az2 vs $rhdg $rlen\n"); prt("init:$set:$off: $key: $rty2 on $az1: $elat1,$elon1 and $rty1 on $az2: $elat2,$elon2\n"); # We have the RUNWAY ends - now extend out to first turn to crosswind leg, and turn to final # but by how MUCH - ok decide from runway end, out to where it is a 3 degree glide from 1000 feet $dist = ($stand_patt_alt * $SG_FEET_TO_METER) / tan($stand_glide_degs * $SGD_DEGREES_TO_RADIANS); my ($plat11,$plon11,$plat12,$plon12,$plat13,$plon13,$paz1); my ($plat21,$plon21,$plat22,$plon22,$plat23,$plon23,$paz2); my ($hdg1L,$hdg1R,$crossd); fg_geo_direct_wgs_84( $clat, $clon, $rhdg, $rwlen2+$dist, \$plat11, \$plon11, \$paz1 ); fg_geo_direct_wgs_84( $clat, $clon, $hdgr, $rwlen2+$dist, \$plat21, \$plon21, \$paz2 ); $hdg1L = normalised_hdg($rhdg - 90); $hdg1R = normalised_hdg($rhdg + 90); $crossd = $stand_cross_nm * $SG_NM_TO_METER; # ON $rhdg to $elat1, $elon1 to ... turn point, go LEFT and to get NEXT points, this end fg_geo_direct_wgs_84( $plat11, $plon11, $hdg1L, $crossd, \$plat12, \$plon12, \$paz1 ); fg_geo_direct_wgs_84( $plat21, $plon21, $hdg1L, $crossd, \$plat13, \$plon13, \$paz1 ); # from the turn point, go LEFT and RIGHT to get NEXT points, this other end fg_geo_direct_wgs_84( $plat21, $plon21, $hdg1R, $crossd, \$plat22, \$plon22, \$paz2 ); fg_geo_direct_wgs_84( $plat11, $plon11, $hdg1R, $crossd, \$plat23, \$plon23, \$paz2 ); if ($use_pattern && ($key eq $active_key)) { # 'YGIL', 'YSDU' # if ($use_pattern && ($key eq 'YGIL')) { if ($switch_circuit) { # At YGIL, this is a 15 circuit (the prevailing wind! SSE... $tl_lat = $plat12; $tl_lon = $plon12; $bl_lat = $plat13; $bl_lon = $plon13; $br_lat = $plat21; $br_lon = $plon21; $tr_lat = $plat11; $tr_lon = $plon11; $active_runway = '05'; # '15'; } else { # At YGIL, this is a 33 circuit $tl_lat = $plat22; #-31.684063; $tl_lon = $plon22; #148.614120; $bl_lat = $plat23; #-31.723495; $bl_lon = $plon23; #148.633003; $br_lat = $plat11; #-31.716778; $br_lon = $plon11; #148.666992; $tr_lat = $plat21; #-31.672960; $tr_lon = $plon21; #148.649139; $active_runway = '33'; } prt("Set pattern as the rectangle for $key $active_runway...\n"); $active_ref_rwys = $rrwys; $active_off_rwys = $off; } if ($dbg_01) { # now we have 4 points, either side of the runway prt("On $rhdg, at $plat11,$plon11 turn $hdg1L to $plat12,$plon12\n"); show_distance_heading($plat11,$plon11,$plat12,$plon12); # This is the LONG downwind side 12 to 13 prt("On $hdg1L at $plat12,$plon12, turn $hdgr to $plat13,$plon13\n"); show_distance_heading($plat12,$plon12,$plat13,$plon13); prt("On $hdgr at $plat13,$plon13 turn $hdg1R to $plat21,$plon21\n"); show_distance_heading($plat13,$plon13,$plat21,$plon21); prt("On $hdg1R at $plat21,$plon21 turn $rhdg to $elat1,$elon1\n"); show_distance_heading($plat21,$plon21,$elat1,$elon2); prt("\n"); #E.G. for YGIL - TO 15 #On 162, at -31.7523059488988,148.65746239832 turn 72 to -31.7414611993009,148.696497359091 #Is 2.1nm, on heading 72 #On 72 at -31.7414611993009,148.696497359091, turn 342 to -31.630701184372,148.654359238954 #Is 7.0nm, on heading 342 #On 342 at -31.630701184372,148.654359238954 turn 252 to -31.6415460967825,148.615370603846 #Is 2.1nm, on heading 252 #On 252 at -31.6415460967825,148.615370603846 turn 162 to -31.7024233216057,148.638492502638 #Is 3.8nm, on heading 165 prt("On $hdgr at $plat21,$plon21 turn $hdg1R to $plat22,$plon22\n"); show_distance_heading($plat21,$plon21,$plat22,$plon22); # This is the LONG downwind side 22 to 23 prt("On $hdg1R at $plat22,$plon22 turn $rhdg to $plat23,$plon23\n"); show_distance_heading($plat22,$plon22,$plat23,$plon23); prt("On $rhdg at $plat23,$plon23 turn $hdg1L to $plat11,$plon11\n"); show_distance_heading($plat23,$plon23,$plat11,$plon11); prt("On $hdg1L at $plat11,$plon11 turn $hdgr to $elat2,$elon2\n"); show_distance_heading($plat11,$plon11,$elat2,$elon2); prt("\n"); #E.G. for YGIL, TO 33 #On 342 at -31.6415460967825,148.615370603846 turn 252 to -31.6523790808638,148.576372922039 #Is 2.1nm, on heading 252 #On 252 at -31.6523790808638,148.576372922039 turn 162 to -31.7631387187979,148.618418340898 #Is 7.0nm, on heading 162 #On 162 at -31.7631387187979,148.618418340898 turn 72 to -31.7523059488988,148.65746239832 #Is 2.1nm, on heading 72 #On 72 at -31.7523059488988,148.65746239832 turn 342 to -31.6914326394609,148.634315743548 #Is 3.8nm, on heading 342 } @{$rpatts} = (); # add notional RIGHT side circuit first push(@{$rpatts}, [$plat11,$plon11,$plat12,$plon12,$plat13,$plon13,$plat21,$plon21,$clat,$clon,$rlen,$rhdg]); # then notional LEFT size circuit push(@{$rpatts}, [$plat21,$plon21,$plat22,$plon22,$plat23,$plon23,$plat11,$plon11,$clat,$clon,$rlen,$hdgr]); } sub init_runway_array() { my $rl = get_locations(); # %apt_locations, with YGIL, YSDU, ... my ($key,$off,$cnt,$rrwys,$rpatts,$set); $set = 0; foreach $key (keys %{$rl}) { $set++; $rrwys = ${$rl}{$key}[$OL_RWY]; $rpatts = ${$rl}{$key}[$OL_PAT]; $cnt = scalar @{$rrwys}; for ($off = 0; $off < $cnt; $off++) { prt("Key $key: Doing set $set, offset $off of $cnt\n"); set_runway_ends_and_patt($rrwys,$off,$key,$rpatts,$set); } } if ($dbg_02) { foreach $key (keys %{$rl}) { $rpatts = ${$rl}{$key}[$OL_PAT]; show_rw_patt($key,$rpatts); } } # pgm_exit(1,"Temp exit"); } sub get_runways_and_pattern($$) { my ($rh,$key) = @_; my $rl = get_locations(); # %apt_locations, with YGIL, YSDU, ... my ($rrwys,$rpatts); if (defined ${$rl}{$key}) { $rrwys = ${$rl}{$key}[$OL_RWY]; $rpatts = ${$rl}{$key}[$OL_PAT]; ${$rh}{'runways'} = $rrwys; ${$rh}{'pattern'} = $rpatts; ${$rh}{'airport'} = $key; } else { pgm_exit(1,"ERROR: Key [$key] NOT in locations!\n"); } } sub set_runway_ends($$) { my ($rrwys,$off) = @_; my $rlen = ${$rrwys}[$off][$RW_LEN]; my $rhdg = ${$rrwys}[$off][$RW_HDG]; my $clat = ${$rrwys}[$off][$RW_CLAT]; my $clon = ${$rrwys}[$off][$RW_CLON]; my $rty1 = ${$rrwys}[$off][$RW_TT1]; my $rty2 = ${$rrwys}[$off][$RW_TT2]; my $rwlen2 = ($rlen * $SG_FEET_TO_METER) / 2; my ($elat1,$elon1,$eaz1,$elat2,$elon2,$eaz2); my $hdg1 = $rhdg + 90; $hdg1 -= 360 if ($hdg1 >= 360); my $hdg2 = $rhdg - 90; $hdg2 += 360 if ($hdg2 < 0); my $xg = "# Runway ".${$rrwys}[$off][$RW_DONE]."\n"; $elat1 = ${$rrwys}[$off][$RW_LLAT]; $elon1 = ${$rrwys}[$off][$RW_LLON]; $elat2 = ${$rrwys}[$off][$RW_RLAT]; $elon2 = ${$rrwys}[$off][$RW_RLON]; ###my $width = 250 * $SG_FEET_TO_METER / 2; # maybe this is BIT large for YGIL my $width = 150 * $SG_FEET_TO_METER / 2; # maybe this is BIT large for YGIL $xg .= "color blue\n"; $xg .= "$elon1 $elat1\n"; $xg .= "$elon2 $elat2\n"; $xg .= "NEXT\n"; my ($clat1,$clon1,$clat2,$clon2,$clat3,$clon3,$clat4,$clon4); my ($az1,$az2,$dist); my ($rclat,$rclon,$az3); fg_geo_inverse_wgs_84($elat1,$elon1,$elat2,$elon2,\$az1,\$az2,\$dist); fg_geo_direct_wgs_84( $elat1,$elon1,$az1,($dist / 2),\$rclat,\$rclon,\$az3 ); my $daz = sprintf("%03u", int($az1)); my $draz = sprintf("%03u", int($az3)); $xg .= "anno $rclon $rclat RW $rty1/$rty2 $draz/$daz\n"; fg_geo_direct_wgs_84( $elat1, $elon1, $hdg1, $width, \$clat1, \$clon1, \$eaz1 ); fg_geo_direct_wgs_84( $elat1, $elon1, $hdg2, $width, \$clat2, \$clon2, \$eaz2 ); fg_geo_direct_wgs_84( $elat2, $elon2, $hdg1, $width, \$clat3, \$clon3, \$eaz1 ); fg_geo_direct_wgs_84( $elat2, $elon2, $hdg2, $width, \$clat4, \$clon4, \$eaz2 ); $xg .= "color red\n"; $xg .= "$clon1 $clat1\n"; $xg .= "$clon2 $clat2\n"; $xg .= "$clon4 $clat4\n"; $xg .= "$clon3 $clat3\n"; $xg .= "$clon1 $clat1\n"; $xg .= "NEXT\n"; return $xg; } # set current distances # circuit decribed as # top left tl top right tr # --------------- # | | # ... # | | # --------------- # bottom left bl bottom right br sub set_distances_bearings($$$$) { my ($rh,$lat,$lon,$msg) = @_; ${$rh}{'usr_lat'} = $lat; ${$rh}{'usr_lon'} = $lon; ${$rh}{'usr_msg'} = $msg; my ($tlat,$tlon); my ($az1,$az2,$dist); $msg = ''; # start a DEBUG message $tlat = ${$rh}{'tl_lat'}; # = -31.684063; $tlon = ${$rh}{'tl_lon'}; # = 148.614120; fg_geo_inverse_wgs_84 ($lat,$lon,$tlat,$tlon,\$az1,\$az2,\$dist); ${$rh}{'tl_az1'} = $az1; ${$rh}{'tl_az2'} = $az2; ${$rh}{'tl_dist'} = $dist; # distance to top-left set_int_dist_stg5(\$dist); $msg .= "TL $dist "; $tlat = ${$rh}{'bl_lat'}; # = -31.723495; $tlon = ${$rh}{'bl_lon'}; # = 148.633003; fg_geo_inverse_wgs_84 ($lat,$lon,$tlat,$tlon,\$az1,\$az2,\$dist); ${$rh}{'bl_az1'} = $az1; ${$rh}{'bl_az2'} = $az2; ${$rh}{'bl_dist'} = $dist; # distance to bottom left set_int_dist_stg5(\$dist); $msg .= "BL $dist "; $tlat = ${$rh}{'br_lat'}; # = -31.716778; $tlon = ${$rh}{'br_lon'}; # = 148.666992; fg_geo_inverse_wgs_84 ($lat,$lon,$tlat,$tlon,\$az1,\$az2,\$dist); ${$rh}{'br_az1'} = $az1; # from 'test' to BR point ${$rh}{'br_az2'} = $az2; ${$rh}{'br_dist'} = $dist; # distance to bottom right set_int_dist_stg5(\$dist); $msg .= "BR $dist "; $tlat = ${$rh}{'tr_lat'}; # = -31.672960; $tlon = ${$rh}{'tr_lon'}; # = 148.649139; fg_geo_inverse_wgs_84 ($lat,$lon,$tlat,$tlon,\$az1,\$az2,\$dist); ${$rh}{'tr_az1'} = $az1; ${$rh}{'tr_az2'} = $az2; ${$rh}{'tr_dist'} = $dist; # distance to top right set_int_dist_stg5(\$dist); $msg .= "TR $dist "; prt("Distances: $msg\n"); } sub get_next_pointset($$$$$) { my ($rh,$ptset,$rlat,$rlon,$show) = @_; my $nxps = 'none'; my ($nlat,$nlon); if ($ptset eq 'TL') { $nxps = 'BL'; $nlat = ${$rh}{'bl_lat'}; $nlon = ${$rh}{'bl_lon'}; } elsif ($ptset eq 'BL') { $nxps = 'BR'; $nlat = ${$rh}{'br_lat'}; $nlon = ${$rh}{'br_lon'}; } elsif ($ptset eq 'BR') { $nxps = 'TR'; $nlat = ${$rh}{'tr_lat'}; $nlon = ${$rh}{'tr_lon'}; } elsif ($ptset eq 'TR') { $nxps = 'TL'; $nlat = ${$rh}{'tl_lat'}; $nlon = ${$rh}{'tl_lon'}; } else { prtw("WARNING: point [$ptset] set NOT one of 'TL', 'BR', 'TR', or 'TL'!"); } ${$rlat} = $nlat; ${$rlon} = $nlon; prt("get_next_pointset: from $ptset to $nxps $nlat,$nlon\n") if ($show); return $nxps; } sub get_closest_ptset($$$$$$) { my ($rch,$slat,$slon,$rpt,$rlat,$rlon) = @_; set_distances_bearings($rch,$slat,$slon,"Initial position"); my $pt = "TL"; my $dist = ${$rch}{'tl_dist'}; # distance to top-left my $tlat = ${$rch}{'tl_lat'}; my $tlon = ${$rch}{'tl_lon'}; if (${$rch}{'bl_dist'} < $dist) { # distance to bottom left # BOTTOM LEFT $dist = ${$rch}{'bl_dist'}; $pt = "BL"; $tlat = ${$rch}{'bl_lat'}; $tlon = ${$rch}{'bl_lon'}; } if (${$rch}{'br_dist'} < $dist) { # distance to bottom right # BOTTOM RIGHT $dist = ${$rch}{'br_dist'}; $pt = "BR"; $tlat = ${$rch}{'br_lat'}; $tlon = ${$rch}{'br_lon'}; } if (${$rch}{'tr_dist'} < $dist) { # distance to top right # TOP RIGHT $dist = ${$rch}{'tr_dist'}; $pt = "TR"; $tlat = ${$rch}{'tr_lat'}; $tlon = ${$rch}{'tr_lon'}; } ${$rpt} = $pt; ${$rlat} = $tlat; ${$rlon} = $tlon; } # This will return the next target when joining a circuit from in or out of current circuit sub get_next_in_circuit_targ($$) { my ($slat,$slon) = @_; my $rch = $ref_circuit_hash; # get_closest_ptset($$$$$$) my ($pt,$tlat,$tlon); get_closest_ptset($rch,$slat,$slon,\$pt,\$tlat,\$tlon); my ($nlat,$nlon,$nxps); ## get next ptset $nxps = get_next_pointset($rch,$pt,\$nlat,\$nlon,0); ### This seems the BEST ;=)) my ($clat,$clon); $clat = ($tlat + $nlat) / 2; $clon = ($tlon + $nlon) / 2; ### $next_targ_lat = $clat; ### $next_targ_lon = $clon; ## prt("Set target lat, lon $clat,$clon\n"); my ($distm,$az1,$az2); fg_geo_inverse_wgs_84 ($slat,$slon,$clat,$clon,\$az1,\$az2,\$distm); ${$rch}{'user_lat'} = $slat; ${$rch}{'user_lon'} = $slon; ${$rch}{'target_lat'} = $clat; # $targ_lat; ${$rch}{'target_lon'} = $clon; # $targ_lon; ${$rch}{'target_hgd'} = $az1; ${$rch}{'target_dist'} = $distm; ${$rch}{'targ_ptset'} = $nxps; # current chosen point = TARGET point ${$rch}{'prev_ptset'} = $pt; # previous to get TARGET TRACK my $distnm = get_dist_stg_nm($distm); set_hdg_stg(\$az1); # Suggest HEAD for prt("Suggest head for $clat,$clon, on $az1, $distnm, prev $pt, next $nxps\n"); } # TL -31.6523791,148.5763729 # BL -31.7631387,148.6184183 # BR -31.7523059,148.6574624 # TR -31.6415461,148.6153706 sub sel_track_to_circuit($$) { my ($slat,$slon) = @_; my $min_lat = $slat; my $max_lat = $slat; my $min_lon = $slon; my $max_lon = $slon; my $rch = $ref_circuit_hash; my $xg = "# start lon,lat\n"; $xg .= "color white\n"; $xg .= "$slon $slat # current pos (lon,lat)\n"; $xg .= "NEXT\n"; $xg .= "anno $slon $slat Curr. POS\n"; # start TOP LEFT #get_closest_ptset($$$$$$) my ($pt,$tlat,$tlon); get_closest_ptset($rch,$slat,$slon,\$pt,\$tlat,\$tlon); $xg .= "# track to nearest $pt\n"; $xg .= "color white\n"; $xg .= "$slon $slat\n"; $xg .= "$tlon $tlat\n"; $xg .= "NEXT\n"; $xg .= "color white\n"; $xg .= "$tlon $tlat # nearest circuit.\n"; $xg .= "NEXT\n"; # max min $min_lat = $tlat if ($tlat < $min_lat); $max_lat = $tlat if ($tlat > $max_lat); $min_lon = $tlon if ($tlat < $min_lon); $min_lon = $tlon if ($tlon > $max_lon); my ($clat,$clon,$az3) = get_mid_pt($slat,$slon,$tlat,$tlon); $az3 = sprintf("%03u", int($az3 + 0.5)); $xg .= "anno $clon $clat track $az3\n"; return $xg; } sub sel_track_to_circuit_NOT_GOOD($$) { my ($slat,$slon) = @_; my $min_lat = $slat; my $max_lat = $slat; my $min_lon = $slon; my $max_lon = $slon; my $rch = $ref_circuit_hash; my $xg = "# start lon,lat\n"; $xg .= "color white\n"; $xg .= "$slon $slat # current pos (lon,lat)\n"; $xg .= "NEXT\n"; $xg .= "anno $slon $slat Curr. POS\n"; # start TOP LEFT #get_closest_ptset($$$$$$) my ($pt,$tlat,$tlon); get_closest_ptset($rch,$slat,$slon,\$pt,\$tlat,\$tlon); $xg .= "# track to nearest $pt\n"; $xg .= "color white\n"; $xg .= "$slon $slat\n"; $xg .= "$tlon $tlat\n"; $xg .= "NEXT\n"; $xg .= "color white\n"; $xg .= "$tlon $tlat # nearest circuit.\n"; $xg .= "NEXT\n"; # max min $min_lat = $tlat if ($tlat < $min_lat); $max_lat = $tlat if ($tlat > $max_lat); $min_lon = $tlon if ($tlat < $min_lon); $min_lon = $tlon if ($tlon > $max_lon); my ($nlat,$nlon,$nxps); $nxps = get_next_pointset($rch,$pt,\$nlat,\$nlon,1); $xg .= "# track to next $nxps\n"; $xg .= "color green\n"; $xg .= "$slon $slat\n"; $xg .= "$nlon $nlat\n"; $xg .= "NEXT\n"; $xg .= "color white\n"; $xg .= "$nlon $nlat # next on circuit\n"; $xg .= "NEXT\n"; # max min $min_lat = $nlat if ($nlat < $min_lat); $max_lat = $nlat if ($nlat > $max_lat); $min_lon = $nlon if ($nlat < $min_lon); $min_lon = $nlon if ($nlon > $max_lon); ####################################### ### This seems the BEST ;=)) my ($clat,$clon); $clat = ($tlat + $nlat) / 2; $clon = ($tlon + $nlon) / 2; $xg .= "# track to center...\n"; $xg .= "color blue\n"; $xg .= "$slon $slat\n"; $xg .= "$clon $clat\n"; $xg .= "NEXT\n"; $xg .= "color white\n"; $xg .= "$clon $clat # leg center point target lon,lat\n"; $xg .= "NEXT\n"; $xg .= "anno $clon $clat Join pt\n"; $next_targ_lat = $clat; $next_targ_lon = $clon; # max min # $min_lat = $clat if ($clat < $min_lat); # $max_lat = $clat if ($clat > $max_lat); # $min_lon = $clon if ($clat < $min_lon); # $min_lon = $clon if ($clon > $max_lon); my $tmp = "# bbox of scene\n"; $tmp .= "color gray\n"; $tmp .= "$min_lon $min_lat\n"; $tmp .= "$min_lon $max_lat\n"; $tmp .= "$max_lon $max_lat\n"; $tmp .= "$max_lon $min_lat\n"; $tmp .= "$min_lon $min_lat\n"; $tmp .= "NEXT\n"; return $tmp.$xg; } sub get_track_to_circuit() { if (! defined $start_lat || !defined $start_lon) { prt("No start lat,lon given...\n"); return "# no start lat,lon\n"; } get_next_in_circuit_targ($start_lat,$start_lon); undef $next_targ_lat; undef $next_targ_lon; my $xg = sel_track_to_circuit($start_lat,$start_lon); if ( defined $next_targ_lat && defined $next_targ_lon) { my ($clat,$clon,$az1,$distm,$nxps,$ppt); my $rch = $ref_circuit_hash; $clat = ${$rch}{'target_lat'}; # $targ_lat; $clon = ${$rch}{'target_lon'}; # $targ_lon; $az1 = ${$rch}{'target_hgd'}; $distm = ${$rch}{'target_dist'}; $nxps = ${$rch}{'targ_ptset'}; # NEXT target point $ppt = ${$rch}{'prev_ptset'}; # PREVIOUS my $distnm = get_dist_stg_nm($distm); set_hdg_stg(\$az1); # prt("Set target lat, lon $clat,$clon, on $az1, $distnm\n"); prt("Suggest HEAD for $next_targ_lat,$next_targ_lon, on $az1, $distnm, prev $ppt, next $nxps\n"); } else { prt("No next lat,lon selected...\n"); } return $xg; } sub tri_hypotenuse($$) { my ($side1, $side2) = @_; return sqrt( ($side1 ** 2) + ($side2 ** 2) ); } sub gen_circle_2_pts_of_r($$$$$$) { my ($x,$y,$x1,$y1,$rad,$flag) = @_; # circle 1 # (x-x1)^2 + (y-y1)^2 = r^2 # circle 2 # (x-x2)^2 + (y-y2)^2 = r^2 my $d1 = ($x-$x1) * ($x-$x1); my $d2 = ($y-$y1) * ($y-$y1); my $r2 = $d1 + $d2; my $r = sqrt($r2); } sub write_xg() { my ($tllat,$tllon,$bllat,$bllon,$brlat,$brlon,$trlat,$trlon); my $rch = $ref_circuit_hash; # current circuit $tllat = ${$rch}{'tl_lat'}; $tllon = ${$rch}{'tl_lon'}; $bllat = ${$rch}{'bl_lat'}; $bllon = ${$rch}{'bl_lon'}; $brlat = ${$rch}{'br_lat'}; $brlon = ${$rch}{'br_lon'}; $trlat = ${$rch}{'tr_lat'}; $trlon = ${$rch}{'tr_lon'}; my $msg = "# $active_key circuit\n"; $msg .= "color green\n"; $msg .= "$tllon $tllat # top left\n"; $msg .= "$bllon $bllat # bottom left\n"; $msg .= "$brlon $brlat # bottom right\n"; $msg .= "$trlon $trlat # top right\n"; $msg .= "$tllon $tllat # top left - close\n"; $msg .= "NEXT\n"; ################################################ # add annotations my $anno = "# add corner labels\n"; $anno .= "anno $tllon $tllat TL\n"; $anno .= "anno $bllon $bllat BL\n"; $anno .= "anno $brlon $brlat BR\n"; $anno .= "anno $trlon $trlat TR\n"; my ($clat,$clon,$az3) = get_mid_pt($tllat,$tllon,$bllat,$bllon); $az3 = sprintf("%03u", int($az3 + 0.5)); $anno .= "anno $clon $clat downwind $az3\n"; ($clat,$clon,$az3) = get_mid_pt($bllat,$bllon,$brlat,$brlon); $az3 = sprintf("%03u", int($az3 + 0.5)); $anno .= "anno $clon $clat base $az3\n"; ($clat,$clon,$az3) = get_mid_pt($brlat,$brlon,$trlat,$trlon); my ($lat4,$lon4,$az4) = get_mid_pt($brlat,$brlon,$clat,$clon); $az4 = sprintf("%03u", int($az4 + 0.5)); $anno .= "anno $lon4 $lat4 FINAL $az4\n"; ($lat4,$lon4,$az4) = get_mid_pt($clat,$clon,$trlat,$trlon); $az4 = sprintf("%03u", int($az4 + 0.5)); $anno .= "anno $lon4 $lat4 upwind $az4\n"; ($clat,$clon,$az3) = get_mid_pt($trlat,$trlon,$tllat,$tllon); $az3 = sprintf("%03u", int($az3 + 0.5)); $anno .= "anno $clon $clat crosswind $az3\n"; $msg .= $anno; ################################################ # add the runways my ($rl,$key,$rrwys,$cnt,$off); $rl = get_locations(); # %apt_locations, with YGIL, YSDU, ... $key = $active_key; # 'YGIL' 'YSDU' if (defined ${$rl}{$key}) { $rrwys = ${$rl}{$key}[$OL_RWY]; $cnt = scalar @{$rrwys}; for ($off = 0; $off < $cnt; $off++) { $msg .= set_runway_ends($rrwys,$off); } } $msg .= get_track_to_circuit(); write2file($msg,$tmp_circuit_xg); prt("Circuit written to $tmp_circuit_xg file... use pv to view\n"); } ######################################### ### MAIN ### #$active_key = 'YGIL'; #$active_runway = '33'; $active_key = 'YSDU'; $active_runway = '11'; parse_args(@ARGV); #process_in_file($in_file); init_runway_array(); $ref_circuit_hash = get_circuit_hash(); # ${$rch}{'TL'} = [$az1,$az2,$dist]; etc... #get_runways_and_pattern($ref_circuit_hash,'YGIL'); get_runways_and_pattern($ref_circuit_hash,$active_key); write_xg(); pgm_exit(0,""); ######################################## sub need_arg { my ($arg,@av) = @_; pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av); } sub parse_args { my (@av) = @_; my ($arg,$sarg,@arr); my $verb = VERB2(); while (@av) { $arg = $av[0]; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg =~ /^h/i)||($sarg eq '?')) { give_help(); pgm_exit(0,"Help exit(0)"); } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v.*(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } $verb = VERB2(); prt("Verbosity = $verbosity\n") if ($verb); } elsif ($sarg =~ /^l/) { if ($sarg =~ /^ll/) { $load_log = 2; } else { $load_log = 1; } prt("Set to load log at end. ($load_log)\n") if ($verb); } elsif ($sarg =~ /^o/) { need_arg(@av); shift @av; $sarg = $av[0]; $out_file = $sarg; prt("Set out file to [$out_file].\n") if ($verb); } elsif ($sarg =~ /^p/) { need_arg(@av); shift @av; $sarg = $av[0]; if ($sarg =~ /,/) { @arr = split(",",$sarg); if (scalar @arr == 2) { $start_lat = $arr[0]; $start_lon = $arr[1]; } else { pgm_exit(1,"Argument '$sarg' did not split in 2 lat,lon\n"); } } else { $start_lat = $sarg; need_arg(@av); shift @av; $sarg = $av[0]; $start_lon = $sarg; } } else { pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n"); } } else { #$in_file = $arg; pgm_exit(1,"Unknown bear argument '$arg'!\n"); } shift @av; } # test 1 = 3 Km West of TL # $start_lat = -31.6523751810451; # $start_lon = 148.54474331625; # test 2 = 3 Km East of TL #$start_lat = -31.6523751810451; #$start_lon = 148.60800248375; # test 3 = 2 Km South of BR #$start_lat = -31.7811757576552; #$start_lon = 148.6184183; # test 4 = 3 Km North of BR #$start_lat = -31.7360830176463; #$start_lon = 148.6184183; # test 5 = from YSDU #$start_lat = -32.218722; #$start_lon = 148.570877; # test 6 btw TL BL YSDU #148.608615657398 -32.15433436718 # top left #148.494691699897 -32.2256985481814 # bottom left $start_lat = -32.15433436718; $start_lon = 148.494691699897; #if ($debug_on) { # prtw("WARNING: DEBUG is ON!\n"); # if (length($in_file) == 0) { # $in_file = $def_file; # prt("Set DEFAULT input to [$in_file]\n"); # } #} #if (length($in_file) == 0) { # pgm_exit(1,"ERROR: No input files found in command!\n"); #} #if (! -f $in_file) { # pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n"); #} } sub give_help { prt("$pgmname: version $VERS\n"); prt("Usage: $pgmname [options]\n"); prt("Options:\n"); prt(" --help (-h or -?) = This help, and exit 0.\n"); prt(" --verb[n] (-v) = Bump [or set] verbosity. def=$verbosity\n"); prt(" --load (-l) = Load LOG at end. ($outfile)\n"); prt(" --out (-o) = Write output to this file.\n"); prt(" --pos lat,lon (-p) = Start position. Find best location to head for\n"); prt(" to join the circuit.\n"); } # eof - gencircuit.pl