]> git.mxchange.org Git - flightgear.git/blob - scripts/perl/dafif/dafift2ils.pl
Initial revision of script to build the default.ils.gz file from DAFIFT
[flightgear.git] / scripts / perl / dafif / dafift2ils.pl
1 #!/usr/bin/perl
2
3 ########################################################################
4 # Convert DAFIFT ARPT/ILS.TXT to FlightGear format.
5 ########################################################################
6
7 use strict;
8
9 my($faa_ils_file) = shift(@ARGV);
10 my($arpt_file) = shift(@ARGV);
11 my($dafift_ils_file) = shift(@ARGV);
12 my($fgfs_ils_file) = shift(@ARGV);
13
14 die "Usage: $0 " .
15     "<faa_ils_file> <dafift_arpt_file> <dafift_ils_file> <fgfs_ils_file>\n"
16     if !defined($faa_ils_file) || !defined($arpt_file)
17        || !defined($dafift_ils_file) || !defined($fgfs_ils_file);
18
19 my( %Airports );
20 my( %ILS );
21 my( $record );
22
23 my( $id, $rwy, $type );
24 my( $has_dme, $has_gs, $has_loc, $has_im, $has_mm, $has_om );
25 my( $dme_lon, $dme_lat, $dme_elev, $dme_bias );
26 my( $gs_lon, $gs_lat, $gs_elev, $gs_angle );
27 my( $loc_type, $loc_lon, $loc_lat, $loc_elev, $loc_freq, $loc_hdg, $loc_width,
28     $loc_id );
29 my( $im_lon, $im_lat, $mm_lon, $mm_lat, $om_lon, $om_lat );
30
31
32 ########################################################################
33 # Process FAA data
34 ########################################################################
35
36 # Load the DAFIFT ils file
37
38 my( $rec_type, $faa_id, $faa_date, $faa_apt_name, $faa_city, $faa_st,
39     $faa_state, $faa_region, $id, $faa_len, $faa_wid, $faa_cat, $faa_owner,
40     $faa_operator, $faa_bearing, $faa_magvar,
41     $faa_loc_latd, $faa_loc_lats, $faa_loc_lond, $faa_loc_lons,
42     $faa_stop_dist, $faa_app_dist,
43     $faa_gs_type, $faa_gs_freq, $faa_gs_latd, $faa_gs_lats, $faa_gs_lond,
44     $faa_gs_lons, $faa_gs_dist,
45     $faa_im_type, $faa_im_latd, $faa_im_lats, $faa_im_lond, $faa_im_lons,
46     $faa_im_dist,
47     $faa_mm_type, $faa_mm_id, $faa_mm_name, $faa_mm_freq,
48     $faa_mm_latd, $faa_mm_lats, $faa_mm_lond, $faa_mm_lons, $faa_mm_dist,
49     $faa_om_type, $faa_om_id, $faa_om_name, $faa_om_freq,
50     $faa_om_latd, $faa_om_lats, $faa_om_lond, $faa_om_lons, $faa_om_dist,
51     $faa_om_backcourse);
52 open( FAA_ILS, "<$faa_ils_file" ) || die "Cannot open $faa_ils_file\n";
53
54 <FAA_ILS>;                          # skip header line
55
56 while ( <FAA_ILS> ) {
57     chomp;
58     ( $rec_type, $faa_id, $rwy, $type, $faa_date, $faa_apt_name, $faa_city,
59       $faa_st, $faa_state, $faa_region, $id, $faa_len, $faa_wid,
60       $faa_cat, $faa_owner, $faa_operator, $faa_bearing, $faa_magvar,
61       $loc_type, $loc_id, $loc_freq, $faa_loc_latd, $faa_loc_lats,
62       $faa_loc_lond, $faa_loc_lons, $loc_width, $faa_stop_dist, $faa_app_dist,
63       $faa_gs_type, $gs_angle, $faa_gs_freq, $faa_gs_latd, $faa_gs_lats,
64       $faa_gs_lond, $faa_gs_lons, $faa_gs_dist, $gs_elev,
65       $faa_im_type, $faa_im_latd, $faa_im_lats, $faa_im_lond, $faa_im_lons,
66       $faa_im_dist,
67       $faa_mm_type, $faa_mm_id, $faa_mm_name, $faa_mm_freq,
68       $faa_mm_latd, $faa_mm_lats, $faa_mm_lond, $faa_mm_lons, $faa_mm_dist,
69       $faa_om_type, $faa_om_id, $faa_om_name, $faa_om_freq,
70       $faa_om_latd, $faa_om_lats, $faa_om_lond, $faa_om_lons,
71       $faa_om_dist, $faa_om_backcourse
72     )
73         = $_ =~ 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})/;
74
75     $loc_hdg = $faa_bearing + make_dmagvar($faa_magvar);
76     $loc_lat = make_dcoord($faa_loc_lats) / 3600.0;
77     $loc_lon = make_dcoord($faa_loc_lons) / 3600.0;
78     $gs_lat = make_dcoord($faa_gs_lats) / 3600.0;
79     $gs_lon = make_dcoord($faa_gs_lons) / 3600.0;
80     $im_lat = make_dcoord($faa_im_lats) / 3600.0;
81     $im_lon = make_dcoord($faa_im_lons) / 3600.0;
82     $mm_lat = make_dcoord($faa_mm_lats) / 3600.0;
83     $mm_lon = make_dcoord($faa_mm_lons) / 3600.0;
84     $om_lat = make_dcoord($faa_om_lats) / 3600.0;
85     $om_lon = make_dcoord($faa_om_lons) / 3600.0;
86
87     # just hist the start of the next record, dump the current data
88     $record = sprintf( "I ILS   %-4s %-3s  %06.2f %-4s %06.2f %10.6f %11.6f ",
89                        $id, $rwy,
90                        $loc_freq, $loc_id, $loc_hdg, $loc_lat, $loc_lon );
91     $record .= sprintf( "%5d %5.2f %10.6f %11.6f ",
92                         $gs_elev, $gs_angle, $gs_lat, $gs_lon );
93     $record .= sprintf( "%10.6f %11.6f ", $dme_lat, $dme_lon );
94     $record .= sprintf( "%10.6f %11.6f ", $om_lat, $om_lon );
95     $record .= sprintf( "%10.6f %11.6f ", $mm_lat, $mm_lon );
96     $record .= sprintf( "%10.6f %11.6f ", $im_lat, $im_lon );
97     if ( $rec_type eq "ILS1" && $ILS{$id . $rwy} eq "" ) {
98         print "FAA Adding: $id - $rwy $faa_bearing, $faa_magvar - $loc_hdg \n";
99         $ILS{$id . $rwy} = $record;
100     }
101 }
102
103
104 ########################################################################
105 # Process DAFIFT data
106 ########################################################################
107
108 # Load the DAFIFT airport file
109
110 open( ARPT, "<$arpt_file" ) || die "Cannot open $arpt_file\n";
111
112 <ARPT>;                          # skip header line
113
114 while ( <ARPT> ) {
115     chomp;
116     my(@F) = split(/\t/);
117     my($icao) = $F[3];
118     if ( length($icao) < 3 ) {
119         if ( length( $F[4] ) >= 3 ) {
120             $icao = $F[4];
121         } else {
122             $icao = "[none]";
123         }
124     }
125     $Airports{$F[0]} = $icao;
126     # print "$F[0] - $icao\n";
127 }
128
129
130 # Load the DAFIFT ils file
131
132 my( $last_id, $last_rwy ) = ("", "");
133
134 open( DAFIFT_ILS, "<$dafift_ils_file" ) || die "Cannot open $dafift_ils_file\n";
135
136 <DAFIFT_ILS>;                   # skip header line
137
138 while ( <DAFIFT_ILS> ) {
139     chomp;
140     my @F = split(/\t/);
141     $id = $F[0];
142     $rwy = $F[1];
143     if ( $last_id ne "" && ($last_id ne $id || $last_rwy ne $rwy) ) {
144         # just hist the start of the next record, dump the current data
145         $record
146             = sprintf( "I ILS   %-4s %-3s  %06.2f %-4s %06.2f %10.6f %11.6f ",
147                        $Airports{$last_id}, $last_rwy,
148                        $loc_freq, $loc_id, $loc_hdg, $loc_lat, $loc_lon );
149         if ( $has_gs ) {
150             $record .= sprintf( "%5d %5.2f %10.6f %11.6f ",
151                                 $gs_elev, $gs_angle, $gs_lat, $gs_lon );
152         } else {
153             $record .= sprintf( "%5d %5.2f %10.6f %11.6f ", 0, 0, 0, 0 );
154         }
155         if ( $has_dme ) {
156             $record .= sprintf( "%10.6f %11.6f ", $dme_lat, $dme_lon );
157         } else {
158             $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
159         }
160         if ( $has_om ) {
161             $record .= sprintf( "%10.6f %11.6f ", $om_lat, $om_lon );
162         } else {
163             $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
164         }
165         if ( $has_mm ) {
166             $record .= sprintf( "%10.6f %11.6f ", $mm_lat, $mm_lon );
167         } else {
168             $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
169         }
170         if ( $has_im ) {
171             $record .= sprintf( "%10.6f %11.6f ", $im_lat, $im_lon );
172         } else {
173             $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
174         }
175         if ( $ILS{$Airports{$last_id} . $last_rwy} eq "" ) {
176             print "DAFIFT Adding: $Airports{$last_id} - $last_rwy\n";
177             $ILS{$Airports{$last_id} . $last_rwy} = $record;
178         }
179         $has_dme = 0;
180         $has_gs = 0;
181         $has_loc = 0;
182         $has_im = 0;
183         $has_mm = 0;
184         $has_om = 0;
185     }
186     $type = $F[2];
187     if ( $type eq "D" ) {
188         # DME entry
189         $has_dme = 1;
190         $dme_lon = make_dcoord( $F[16] );
191         $dme_lat = make_dcoord( $F[14] );
192         $dme_elev = $F[10];
193         if ( $dme_elev !~ m/\d/ ) {
194             $dme_elev = "";
195         } else {
196             $dme_elev += 0;
197         }
198         $dme_bias = $F[27];
199         # print "$id DME $dme_lon $dme_lat $dme_elev $dme_bias\n";
200     } elsif ( $type eq "G" ) {
201         # GlideSlope entry
202         $has_gs = 1;
203         $gs_lon = make_dcoord( $F[16] );
204         $gs_lat = make_dcoord( $F[14] );
205         $gs_elev = $F[10];
206         if ( $gs_elev !~ m/\d/ ) {
207             $gs_elev = "";
208         } else {
209             $gs_elev += 0;
210         }
211         $gs_angle = $F[7];
212         # print "$id GS $gs_lon $gs_lat $gs_elev $gs_angle\n";
213     } elsif ( $type eq "Z" ) {
214         # Localizer entry
215         $has_loc = 1;
216         $loc_lon = make_dcoord( $F[16] );
217         $loc_lat = make_dcoord( $F[14] );
218         $loc_elev = $F[10];
219         if ( $loc_elev !~ m/\d/ ) {
220             $loc_elev = "";
221         } else {
222             $loc_elev += 0;
223         }
224         ($loc_freq) = $F[5] =~ m/(\d\d\d\d\d\d)/;
225         $loc_freq /= 1000.0;
226         my( $magvar ) = make_dmagvar( $F[22] );
227         # print "mag var = $F[22] (" . $magvar . ")\n";
228         $loc_hdg = $F[24] + make_dmagvar( $F[22] );
229         $loc_width = $F[25];
230         $loc_id = $F[18];
231         # print "$id LOC $loc_lon $loc_lat $loc_elev $loc_freq $loc_hdg $loc_width\n";
232     } elsif ( $type eq "I" ) {
233         # Inner marker entry
234         $has_im = 1;
235         $im_lon = make_dcoord( $F[16] );
236         $im_lat = make_dcoord( $F[14] );
237         # print "$id IM $im_lon $im_lat\n";
238     } elsif ( $type eq "M" ) {
239         # Middle marker entry
240         $has_mm = 1;
241         $mm_lon = make_dcoord( $F[16] );
242         $mm_lat = make_dcoord( $F[14] );
243         # print "$id MM $mm_lon $mm_lat\n";
244     } elsif ( $type eq "O" ) {
245         # Outer marker entry
246         $has_om = 1;
247         $om_lon = make_dcoord( $F[16] );
248         $om_lat = make_dcoord( $F[14] );
249         # print "$id OM $om_lon $om_lat\n";
250     }
251
252     $last_id = $id;
253     $last_rwy = $rwy;
254     # printf("%-5s %10.6f %11.6f\n",  $F[0], $F[14], $F[16]);
255 }
256
257 $record = sprintf( "I ILS   %-4s %-3s  %06.2f %-4s %06.2f %10.6f %11.6f ",
258                    $Airports{$last_id}, $last_rwy,
259                    $loc_freq, $loc_id, $loc_hdg, $loc_lat, $loc_lon );
260 if ( $has_gs ) {
261     $record .= sprintf( "%5d %5.2f %10.6f %11.6f ",
262                         $gs_elev, $gs_angle, $gs_lat, $gs_lon );
263 } else {
264     $record .= sprintf( "%5d %5.2f %10.6f %11.6f ", 0, 0, 0, 0 );
265 }
266 if ( $has_dme ) {
267     $record .= sprintf( "%10.6f %11.6f ", $dme_lat, $dme_lon );
268 } else {
269     $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
270 }
271 if ( $has_om ) {
272     $record .= sprintf( "%10.6f %11.6f ", $om_lat, $om_lon );
273 } else {
274     $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
275 }
276 if ( $has_mm ) {
277     $record .= sprintf( "%10.6f %11.6f ", $mm_lat, $mm_lon );
278 } else {
279     $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
280 }
281 if ( $has_im ) {
282     $record .= sprintf( "%10.6f %11.6f ", $im_lat, $im_lon );
283 } else {
284     $record .= sprintf( "%10.6f %11.6f ", 0, 0 );
285 }
286
287 if ( $ILS{$Airports{$last_id} . $last_rwy} eq "" ) {
288     print "DAFIFT Adding: $Airports{$last_id} - $last_rwy\n";
289     $ILS{$Airports{$last_id} . $last_rwy} = $record;
290 }
291
292
293 ########################################################################
294 # Process FlightGear ILS data
295 ########################################################################
296
297 # Load the FlightGear ils file and fill in any missing ILS approachs
298
299 open( FGILS, "zcat $fgfs_ils_file|" ) || die "Cannot open $fgfs_ils_file\n";
300
301 <FGILS>;                          # skip header line
302
303 while ( <FGILS> ) {
304     chomp;
305     if ( ! m/\[End\]/ && length($_) > 1 ) {
306         # print "$_\n";
307         my( $type_code, $type_name, $icao, $rwy, $loc_freq, $loc_id, $loc_hdg,
308             $loc_lat, $loc_lon, $gs_elev, $gs_angle, $gs_lat, $gs_lon,
309             $dme_lat, $dme_lon, $om_lat, $om_lon, $mm_lat, $mm_lon,
310             $im_lat, $im_lon ) = split(/\s+/);
311         if ( $ILS{$icao . $rwy} eq "" ) {
312             print "X-Plane Adding: $icao $rwy\n";
313             $ILS{$icao . $rwy} = $_;
314         }
315     }
316 }
317
318
319 # dump out the final results
320 print "// FlightGear ILS data, generated from DAFIFT ARPT/ILS.TXT\n";
321 my($key);
322 foreach $key ( sort (keys %ILS) ) {
323     print "$ILS{$key}\n";
324 }
325 print "[End]\n";
326
327
328 sub make_dcoord() {
329     my($coord) = shift;
330     my( $dir, $deg, $min, $sec );
331     my( $value );
332     if ( $coord =~ m/^[WE]/ ) {
333         ( $dir, $deg, $min, $sec )
334             = $coord =~ m/^([EW])(\d\d\d)(\d\d)(\d\d\d\d)/;
335         $value = $deg + $min/60.0 + ($sec/100)/3600.0;
336         if ( $dir eq "W" ) {
337             $value = -$value;
338         }
339     } elsif ( $coord =~ m/^[NS]/ ) {
340         ( $dir, $deg, $min, $sec )
341             = $coord =~ m/^([NS])(\d\d)(\d\d)(\d\d\d\d)/;
342         $value = $deg + $min/60.0 + ($sec/100)/3600.0;
343         if ( $dir eq "S" ) {
344             $value = -$value;
345         }
346     } elsif ( $coord =~ m/[EW]$/ ) {
347         ($value, $dir) = m/(\d{6}\.\d{3})(.)/;
348         if ( $value eq "W" ) {
349             $value = -$value;
350         }
351     } elsif ( $coord =~ m/[NS]$/ ) {
352         ($value, $dir) = m/(\d{6}\.\d{3})(.)/;
353         if ( $value eq "S" ) {
354             $value = -$value;
355         }
356     }
357     # print "$dir $deg:$min:$sec = $value\n";
358     return $value;
359 }
360
361 sub make_dmagvar() {
362     my( $coord ) = shift;
363     my( $value );
364     if ( $coord =~ m/^[EW]/ ) {
365         my( $dir, $deg, $min, $date )
366             = $coord =~ m/^([EW])(\d\d\d)(\d\d\d) (\d\d\d\d)/;
367         $value = $deg + ($min/10)/60.0;
368         if ( $dir eq "W" ) {
369             $value = -$value;
370         }
371     } elsif ( $coord =~ m/[EW]$/ ) {
372         my( $deg, $dir )
373             = $coord =~ m/^(\d\d)([EW])/;
374         $value = $deg;
375         if ( $dir eq "W" ) {
376             $value = -$value;
377         }
378     }
379     # print "$dir $deg:$min = $value\n";
380
381     return $value;
382 }
383
384 # end of dafif2fix.pl