my($dafift_arpt_file) = shift(@ARGV);
my($dafift_ils_file) = shift(@ARGV);
my($fgfs_ils_file) = shift(@ARGV);
+my($output_file) = shift(@ARGV);
die "Usage: $0 " .
- "<faa_ils_file> <dafift_arpt_file> <dafift_ils_file> <fgfs_ils_file>\n"
+ "<faa_ils_file> <dafift_arpt_file> <dafift_ils_file> <fgfs_ils_file> <output_file>\n"
if !defined($faa_ils_file) || !defined($dafift_arpt_file)
- || !defined($dafift_ils_file) || !defined($fgfs_ils_file);
+ || !defined($dafift_ils_file) || !defined($fgfs_ils_file)
+ || !defined($output_file);
-my( %Airports );
+my( %CODES );
+my( %CodesByICAO );
my( %ILS );
+my( %AIRPORTS );
&load_dafift( $dafift_arpt_file, $dafift_ils_file );
&load_faa( $faa_ils_file );
-&load_fgfs( $faa_ils_file );
-&write_result();
+&load_fgfs( $fgfs_ils_file );
+&write_result( $output_file );
exit;
-########################################################################
-# Process FAA data
-########################################################################
-
-sub load_faa() {
- my( $file ) = shift;
-
- open( FAA_ILS, "<$file" ) || die "Cannot open FAA data: $file\n";
-
- <FAA_ILS>; # skip header line
-
- while ( <FAA_ILS> ) {
- chomp;
-
- my ( $rec_type, $faa_id, $rwy, $type, $faa_date,
- $faa_apt_name, $faa_city, $faa_st, $faa_state,
- $faa_region, $id, $faa_len, $faa_wid, $faa_cat,
- $faa_owner, $faa_operator, $faa_bearing, $faa_magvar,
- $loc_type, $loc_id, $loc_freq, $faa_loc_latd,
- $faa_loc_lats, $faa_loc_lond, $faa_loc_lons, $loc_width,
- $faa_stop_dist, $faa_app_dist, $faa_gs_type, $gs_angle,
- $faa_gs_freq, $faa_gs_latd, $faa_gs_lats, $faa_gs_lond,
- $faa_gs_lons, $faa_gs_dist, $gs_elev, $faa_im_type,
- $faa_im_latd, $faa_im_lats, $faa_im_lond, $faa_im_lons,
- $faa_im_dist, $faa_mm_type, $faa_mm_id, $faa_mm_name,
- $faa_mm_freq, $faa_mm_latd, $faa_mm_lats, $faa_mm_lond,
- $faa_mm_lons, $faa_mm_dist, $faa_om_type, $faa_om_id,
- $faa_om_name, $faa_om_freq, $faa_om_latd, $faa_om_lats,
- $faa_om_lond, $faa_om_lons, $faa_om_dist,
- $faa_om_backcourse, $faa_dme_channel, $faa_dme_latd,
- $faa_dme_lats, $faa_dme_lond, $faa_dme_lons, $faa_dme_app_dist,
- $faa_dme_stop_dist, $blank)
- = $_ =~
- m/^(.{4})(.{11})(.{3})(.{10})(.{10})(.{42})(.{26})(.{2})(.{20})(.{3})(.{4})(.{5})(.{4})(.{9})(.{50})(.{50})(.{3})(.{3})(.{15})(.{5})(.{6})(.{14})(.{11})(.{14})(.{11})(.{5})(.{5})(.{6})(.{15})(.{4})(.{6})(.{14})(.{11})(.{14})(.{11})(.{6})(.{7})(.{15})(.{14})(.{11})(.{14})(.{11})(.{6})(.{15})(.{2})(.{5})(.{3})(.{14})(.{11})(.{14})(.{11})(.{6})(.{15})(.{2})(.{5})(.{3})(.{14})(.{11})(.{14})(.{11})(.{6})(.{9})(.{4})(.{14})(.{11})(.{14})(.{11})(.{6})(.{5})(.{34})/;
-
- $loc_id =~ s/-//;
- my( $loc_hdg ) = $faa_bearing + make_dmagvar($faa_magvar);
- my( $loc_lat ) = make_dcoord($faa_loc_lats) / 3600.0;
- my( $loc_lon ) = make_dcoord($faa_loc_lons) / 3600.0;
- my( $gs_lat ) = make_dcoord($faa_gs_lats) / 3600.0;
- my( $gs_lon ) = make_dcoord($faa_gs_lons) / 3600.0;
- my( $im_lat ) = make_dcoord($faa_im_lats) / 3600.0;
- my( $im_lon ) = make_dcoord($faa_im_lons) / 3600.0;
- my( $mm_lat ) = make_dcoord($faa_mm_lats) / 3600.0;
- my( $mm_lon ) = make_dcoord($faa_mm_lons) / 3600.0;
- my( $om_lat ) = make_dcoord($faa_om_lats) / 3600.0;
- my( $om_lon ) = make_dcoord($faa_om_lons) / 3600.0;
- my( $dme_lat ) = make_dcoord($faa_dme_lats) / 3600.0;
- my( $dme_lon ) = make_dcoord($faa_dme_lons) / 3600.0;
-
- if ( $rec_type eq "ILS1" ) {
- if ( $ILS{$id . $rwy} eq "" ) {
- print "FAA adding: $id - $rwy\n";
- add_record( $id, $rwy, $loc_freq, $loc_id, $loc_hdg, $loc_lat,
- $loc_lon, $gs_elev, $gs_angle, $gs_lat, $gs_lon,
- $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat,
- $mm_lon, $im_lat, $im_lon );
- }
- }
- }
-}
-
-
########################################################################
# Process DAFIFT data
########################################################################
$icao = "[none]";
}
}
- $Airports{$F[0]} = $icao;
+ $CODES{$F[0]} = $icao;
+ $CodesByICAO{$icao} = 1;
# print "$F[0] - $icao\n";
}
if ( ! $has_im ) {
( $im_lat, $im_lon ) = ( 0, 0 );
}
- if ( $ILS{$Airports{$last_id} . $last_rwy} eq "" ) {
- print "DAFIFT adding: $Airports{$last_id} - $last_rwy\n";
- add_record( $Airports{$last_id}, $last_rwy, $loc_freq,
- $loc_id, $loc_hdg, $loc_lat, $loc_lon,
- $gs_elev, $gs_angle, $gs_lat, $gs_lon,
- $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat,
- $mm_lon, $im_lat, $im_lon );
+ if ( $ILS{$CODES{$last_id} . $last_rwy} eq "" ) {
+ print "DAFIFT adding: $CODES{$last_id} - $last_rwy\n";
+ &safe_add_record( $CODES{$last_id}, $last_rwy, "ILS",
+ $loc_freq, $loc_id, $loc_hdg, $loc_lat,
+ $loc_lon, $gs_elev, $gs_angle, $gs_lat,
+ $gs_lon, $dme_lat, $dme_lon, $om_lat,
+ $om_lon, $mm_lat, $mm_lon, $im_lat,
+ $im_lon );
}
$has_dme = 0;
$loc_hdg = $F[24] + make_dmagvar( $F[22] );
$loc_width = $F[25];
$loc_id = $F[18];
+ if ( length( $loc_id ) >= 4 ) {
+ $loc_id =~ s/^I//;
+ }
# print "$id LOC $loc_lon $loc_lat $loc_elev $loc_freq $loc_hdg $loc_width\n";
} elsif ( $type eq "I" ) {
# Inner marker entry
if ( ! $has_im ) {
( $im_lat, $im_lon ) = ( 0, 0 );
}
- if ( $ILS{$Airports{$last_id} . $last_rwy} eq "" ) {
- print "DAFIFT adding (last): $Airports{$last_id} - $last_rwy\n";
- add_record( $Airports{$last_id}, $last_rwy, $loc_freq,
- $loc_id, $loc_hdg, $loc_lat, $loc_lon,
- $gs_elev, $gs_angle, $gs_lat, $gs_lon,
- $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat,
- $mm_lon, $im_lat, $im_lon );
+ if ( $ILS{$CODES{$last_id} . $last_rwy} eq "" ) {
+ print "DAFIFT adding (last): $CODES{$last_id} - $last_rwy\n";
+ &safe_add_record( $CODES{$last_id}, $last_rwy, "ILS", $loc_freq,
+ $loc_id, $loc_hdg, $loc_lat, $loc_lon,
+ $gs_elev, $gs_angle, $gs_lat, $gs_lon,
+ $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat,
+ $mm_lon, $im_lat, $im_lon );
+ }
+}
+
+
+########################################################################
+# Process FAA data
+########################################################################
+
+sub load_faa() {
+ my( $file ) = shift;
+
+ open( FAA_ILS, "<$file" ) || die "Cannot open FAA data: $file\n";
+
+ <FAA_ILS>; # skip header line
+
+ while ( <FAA_ILS> ) {
+ chomp;
+
+ my ( $rec_type, $faa_id, $rwy, $type, $faa_date,
+ $faa_apt_name, $faa_city, $faa_st, $faa_state,
+ $faa_region, $id, $faa_len, $faa_wid, $faa_cat,
+ $faa_owner, $faa_operator, $faa_bearing, $faa_magvar,
+ $loc_type, $loc_id, $loc_freq, $faa_loc_latd,
+ $faa_loc_lats, $faa_loc_lond, $faa_loc_lons, $loc_width,
+ $faa_stop_dist, $faa_app_dist, $faa_gs_type, $gs_angle,
+ $faa_gs_freq, $faa_gs_latd, $faa_gs_lats, $faa_gs_lond,
+ $faa_gs_lons, $faa_gs_dist, $gs_elev, $faa_im_type,
+ $faa_im_latd, $faa_im_lats, $faa_im_lond, $faa_im_lons,
+ $faa_im_dist, $faa_mm_type, $faa_mm_id, $faa_mm_name,
+ $faa_mm_freq, $faa_mm_latd, $faa_mm_lats, $faa_mm_lond,
+ $faa_mm_lons, $faa_mm_dist, $faa_om_type, $faa_om_id,
+ $faa_om_name, $faa_om_freq, $faa_om_latd, $faa_om_lats,
+ $faa_om_lond, $faa_om_lons, $faa_om_dist,
+ $faa_om_backcourse, $faa_dme_channel, $faa_dme_latd,
+ $faa_dme_lats, $faa_dme_lond, $faa_dme_lons, $faa_dme_app_dist,
+ $faa_dme_stop_dist, $blank)
+ = $_ =~
+ m/^(.{4})(.{11})(.{3})(.{10})(.{10})(.{42})(.{26})(.{2})(.{20})(.{3})(.{4})(.{5})(.{4})(.{9})(.{50})(.{50})(.{3})(.{3})(.{15})(.{5})(.{6})(.{14})(.{11})(.{14})(.{11})(.{5})(.{5})(.{6})(.{15})(.{4})(.{6})(.{14})(.{11})(.{14})(.{11})(.{6})(.{7})(.{15})(.{14})(.{11})(.{14})(.{11})(.{6})(.{15})(.{2})(.{5})(.{3})(.{14})(.{11})(.{14})(.{11})(.{6})(.{15})(.{2})(.{5})(.{3})(.{14})(.{11})(.{14})(.{11})(.{6})(.{9})(.{4})(.{14})(.{11})(.{14})(.{11})(.{6})(.{5})(.{34})/;
+
+ $id = &strip_ws( $id );
+ $rwy = &strip_ws( $rwy );
+ $rwy =~ s/\/$//;
+ $rwy =~ s/\/$//;
+ $loc_id =~ s/^I-//;
+ my( $loc_hdg ) = $faa_bearing + make_dmagvar($faa_magvar);
+ my( $loc_lat ) = make_dcoord($faa_loc_lats) / 3600.0;
+ my( $loc_lon ) = make_dcoord($faa_loc_lons) / 3600.0;
+ # print "$loc_lon $loc_lat $faa_loc_lons $faa_loc_lats\n";
+ my( $gs_lat ) = make_dcoord($faa_gs_lats) / 3600.0;
+ my( $gs_lon ) = make_dcoord($faa_gs_lons) / 3600.0;
+ my( $im_lat ) = make_dcoord($faa_im_lats) / 3600.0;
+ my( $im_lon ) = make_dcoord($faa_im_lons) / 3600.0;
+ my( $mm_lat ) = make_dcoord($faa_mm_lats) / 3600.0;
+ my( $mm_lon ) = make_dcoord($faa_mm_lons) / 3600.0;
+ my( $om_lat ) = make_dcoord($faa_om_lats) / 3600.0;
+ my( $om_lon ) = make_dcoord($faa_om_lons) / 3600.0;
+ my( $dme_lat ) = make_dcoord($faa_dme_lats) / 3600.0;
+ my( $dme_lon ) = make_dcoord($faa_dme_lons) / 3600.0;
+
+ # my( $key );
+ # print "$id - $rwy\n";
+ # $key = $id . $rwy;
+ # print "-> $key -> $ILS{$key}\n";
+ # $key = "K" . $id . $rwy;
+ # print "-> $key -> $ILS{$key}\n";
+
+ if ( $rec_type eq "ILS1" ) {
+ if ( length( $id ) < 4 ) {
+ if ( $CodesByICAO{"K" . $id} ) {
+ $id = "K" . $id;
+ }
+ }
+ if ( $ILS{$id . $rwy} ne "" ) {
+ print "FAA updating: $id - $rwy $type\n";
+ &update_type( $id, $rwy, $type );
+ } else {
+ print "FAA adding: $id - $rwy\n";
+ &safe_add_record( $id, $rwy, $type, $loc_freq, $loc_id,
+ $loc_hdg, $loc_lat, $loc_lon, $gs_elev,
+ $gs_angle, $gs_lat, $gs_lon, $dme_lat,
+ $dme_lon, $om_lat, $om_lon, $mm_lat,
+ $mm_lon, $im_lat, $im_lon );
+ }
+ }
}
}
sub load_fgfs() {
my( $ils_file ) = shift;
-
open( FGILS, "zcat $ils_file|" ) || die "Cannot open FGFS: $ils_file\n";
<FGILS>; # skip header line
$loc_hdg, $loc_lat, $loc_lon, $gs_elev, $gs_angle, $gs_lat,
$gs_lon, $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat, $mm_lon,
$im_lat, $im_lon ) = split(/\s+/);
- if ( $ILS{$icao . $rwy} eq "" ) {
+ my( $code ) = $icao;
+ $code =~ s/^K//;
+ if ( $ILS{$icao . $rwy} ne "" ) {
+ print "FGFS: Skipping $icao - $rwy - already exists\n";
+ # skip approaches already in FAA or DAFIFT data
+ } elsif ( length( $icao ) < 4 || $icao =~ m/^K/ ) {
+ print "FGFS: Skipping $icao - $rwy - USA\n";
+ # skip USA approaches not found in FAA or DAFIFT data
+ } else {
print "FGFS adding: $icao $rwy\n";
- $ILS{$icao . $rwy} = $_;
+ &safe_add_record( $icao, $rwy, $type_name, $loc_freq, $loc_id,
+ $loc_hdg, $loc_lat, $loc_lon, $gs_elev,
+ $gs_angle, $gs_lat, $gs_lon, $dme_lat,
+ $dme_lon, $om_lat, $om_lon, $mm_lat,
+ $mm_lon, $im_lat, $im_lon );
}
+ } else {
+ print "FGFS discarding: $_\n";
}
}
}
########################################################################
sub write_result() {
+ my( $outfile ) = shift;
+
+ open( OUT, ">$outfile" ) || die "Cannot write to: $outfile\n";
+
# dump out the final results
- print "// FlightGear ILS data, generated from DAFIFT ARPT/ILS.TXT\n";
- my($key);
+ print OUT "// FlightGear ILS data, generated from DAFIFT ARPT/ILS.TXT and FAA data\n";
+
+ my( $key );
foreach $key ( sort (keys %ILS) ) {
- print "$ILS{$key}\n";
+ print OUT "$ILS{$key}\n";
}
- print "[End]\n";
+ print OUT "[End]\n";
}
########################################################################
-# add a record to the master list
+# add a record to the master list if it doesn't already exist
-sub add_record() {
+sub safe_add_record() {
my( $apt_id ) = shift;
my( $rwy ) = shift;
+ my( $type ) = shift;
+ my( $loc_freq ) = shift;
+ my( $loc_id ) = shift;
+ my( $loc_hdg ) = shift;
+ my( $loc_lat ) = shift;
+ my( $loc_lon ) = shift;
+ my( $gs_elev ) = shift;
+ my( $gs_angle ) = shift;
+ my( $gs_lat ) = shift;
+ my( $gs_lon ) = shift;
+ my( $dme_lat ) = shift;
+ my( $dme_lon ) = shift;
+ my( $om_lat ) = shift;
+ my( $om_lon ) = shift;
+ my( $mm_lat ) = shift;
+ my( $mm_lon ) = shift;
+ my( $im_lat ) = shift;
+ my( $im_lon ) = shift;
+
+ if ( $ILS{$apt_id . $rwy} eq "" ) {
+ # print "Safe adding (common): $apt_id - $rwy\n";
+ &update_record( $apt_id, $rwy, $type, $loc_freq, $loc_id,
+ $loc_hdg, $loc_lat, $loc_lon, $gs_elev,
+ $gs_angle, $gs_lat, $gs_lon, $dme_lat,
+ $dme_lon, $om_lat, $om_lon, $mm_lat,
+ $mm_lon, $im_lat, $im_lon );
+ }
+}
+
+
+# replace a record in the master list (or add it if it doesn't exist)
+
+sub update_record() {
+ my( $apt_id ) = shift;
+ my( $rwy ) = shift;
+ my( $type ) = shift;
my( $loc_freq ) = shift;
my( $loc_id ) = shift;
my( $loc_hdg ) = shift;
my( $im_lon ) = shift;
my( $record );
- $record = sprintf( "I ILS %-4s %-3s %06.2f %-4s %06.2f %10.6f %11.6f ",
- $apt_id, $rwy,
+
+ # remap $type as needed
+ $type = &strip_ws( $type );
+ if ( $type eq "LOCALIZER" ) {
+ $type = "LOC";
+ } elsif ( $type eq "ILS/DME" ) {
+ $type = "ILS";
+ } elsif ( $type eq "SDF/DME" ) {
+ $type = "SDF";
+ } elsif ( $type eq "LOC/DME" ) {
+ $type = "ILS";
+ } elsif ( $type eq "LOC/GS" ) {
+ $type = "LOC";
+ } elsif ( $type eq "LDA/DME" ) {
+ $type = "LDA";
+ }
+
+ $record = sprintf( "%1s %-5s %-4s %-3s %06.2f %-4s %06.2f %10.6f %11.6f ",
+ substr( $type, 0, 1 ), $type, $apt_id, $rwy,
$loc_freq, $loc_id, $loc_hdg, $loc_lat, $loc_lon );
$record .= sprintf( "%5d %5.2f %10.6f %11.6f ",
$gs_elev, $gs_angle, $gs_lat, $gs_lon );
$record .= sprintf( "%10.6f %11.6f ", $mm_lat, $mm_lon );
$record .= sprintf( "%10.6f %11.6f ", $im_lat, $im_lon );
- if ( $ILS{$apt_id . $rwy} eq "" ) {
- print "Adding (common): $apt_id - $rwy\n";
- $ILS{$apt_id . $rwy} = $record;
+ # print "Updating (common): $apt_id - $rwy\n";
+ $ILS{$apt_id . $rwy} = $record;
+ $AIRPORTS{$apt_id} = 1;
+}
+
+
+# update the $type of the record
+sub update_type() {
+ my( $apt_id ) = shift;
+ my( $rwy ) = shift;
+ my( $new_type ) = shift;
+
+ my( $record );
+
+ if ( $ILS{$apt_id . $rwy} ne "" ) {
+ my( $type_code, $type_name, $apt_id, $rwy, $loc_freq, $loc_id,
+ $loc_hdg, $loc_lat, $loc_lon, $gs_elev, $gs_angle, $gs_lat,
+ $gs_lon, $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat, $mm_lon,
+ $im_lat, $im_lon ) = split( /\s+/, $ILS{$apt_id . $rwy} );
+ # print "Updating type: $apt_id $rwy: $type_name -> $new_type\n";
+ $type_name = $new_type;
+ &update_record( $apt_id, $rwy, $type_name, $loc_freq, $loc_id,
+ $loc_hdg, $loc_lat, $loc_lon, $gs_elev,
+ $gs_angle, $gs_lat, $gs_lon, $dme_lat,
+ $dme_lon, $om_lat, $om_lon, $mm_lat,
+ $mm_lon, $im_lat, $im_lon );
+ } else {
+ die "Error, trying to update $apt_id - $rwy which doesn't exist\n";
}
}
sub make_dcoord() {
my($coord) = shift;
my( $dir, $deg, $min, $sec );
- my( $value );
+ my( $value ) = 0.0;
+
+ $coord = &strip_ws( $coord );
+
if ( $coord =~ m/^[WE]/ ) {
( $dir, $deg, $min, $sec )
= $coord =~ m/^([EW])(\d\d\d)(\d\d)(\d\d\d\d)/;
$value = -$value;
}
} elsif ( $coord =~ m/[EW]$/ ) {
- ($value, $dir) = $coord =~ m/(\d{6}\.\d{3})(.)/;
- if ( $value eq "W" ) {
+ ($value, $dir) = $coord =~ m/([\d\s\.]+)([EW])/;
+ if ( $dir eq "W" ) {
$value = -$value;
}
} elsif ( $coord =~ m/[NS]$/ ) {
- ($value, $dir) = $coord =~ m/(\d{6}\.\d{3})(.)/;
- if ( $value eq "S" ) {
+ ($value, $dir) = $coord =~ m/([\d\s\.]+)([NS])/;
+ if ( $dir eq "S" ) {
$value = -$value;
}
}
sub make_dmagvar() {
my( $coord ) = shift;
my( $value );
+
if ( $coord =~ m/^[EW]/ ) {
my( $dir, $deg, $min, $date )
= $coord =~ m/^([EW])(\d\d\d)(\d\d\d) (\d\d\d\d)/;
return $value;
}
+
+# strip white space off front and back of string
+
+sub strip_ws() {
+ my( $string ) = shift;
+ $string =~ s/^\s+//;
+ $string =~ s/\s+$//;
+ return $string;
+}