]> git.mxchange.org Git - flightgear.git/blob - src/Airports/apt_loader.cxx
Make it optional whether a dialog can be dragged or not.
[flightgear.git] / src / Airports / apt_loader.cxx
1 // apt_loader.cxx -- a front end loader of the apt.dat file.  This loader
2 //                   populates the runway and basic classes.
3 //
4 // Written by Curtis Olson, started August 2000.
5 //
6 // Copyright (C) 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <simgear/compiler.h>
30
31 #include <stdlib.h> // atof(), atoi()
32
33 #include <simgear/constants.h>
34 #include <simgear/debug/logstream.hxx>
35 #include <simgear/misc/sgstream.hxx>
36 #include <simgear/misc/strutils.hxx>
37
38 #include STL_STRING
39
40 #include "simple.hxx"
41 #include "runways.hxx"
42
43 #include "apt_loader.hxx"
44
45
46 // Load the airport data base from the specified aptdb file.  The
47 // metar file is used to mark the airports as having metar available
48 // or not.
49 bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
50                       const string &aptdb_file, const string &metar_file )
51 {
52     //
53     // Load the apt.dat file
54     //
55
56     sg_gzifstream in( aptdb_file );
57     if ( !in.is_open() ) {
58         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << aptdb_file );
59         exit(-1);
60     }
61
62     vector<string> token;
63     string last_apt_id = "";
64     double last_apt_elev = 0.0;
65     string last_apt_name = "";
66     string last_apt_info = "";
67     string last_apt_type = "";
68     string line;
69     char tmp[2048];
70
71     double rwy_lon_accum = 0.0;
72     double rwy_lat_accum = 0.0;
73     int rwy_count = 0;
74
75     while ( ! in.eof() ) {
76         in.getline(tmp, 2048);
77         line = tmp;
78         SG_LOG( SG_GENERAL, SG_BULK, "-> '" << line << "'" );
79         if ( line.length() ) {
80             token = simgear::strutils::split( line );
81             if ( token.size() ) {
82                 SG_LOG( SG_GENERAL, SG_BULK, "token[0] " << token[0] );
83             }
84         } else {
85             token.clear();
86         }
87
88         if ( !line.length() || !token.size() ) {
89             // empty line, skip
90         } else if ( (token[0] == "#") || (token[0] == "//") ) {
91             // comment, skip
92         } else if ( token[0] == "I" ) {
93             // First line, indicates IBM (i.e. DOS line endings I
94             // believe.)
95
96             // move past this line and read and discard the next line
97             // which is the version and copyright information
98             in.getline(tmp, 2048);
99             vector<string> vers_token = simgear::strutils::split( tmp );
100             SG_LOG( SG_GENERAL, SG_INFO, "Data file version = "
101                     << vers_token[0] );
102         } else if ( token[0] == "1" /* Airport */ ||
103                     token[0] == "16" /* Seaplane base */ ||
104                     token[0] == "17" /* Heliport */ ) {
105
106             string id = token[4];
107             double elev = atof( token[1].c_str() );
108             SG_LOG( SG_GENERAL, SG_BULK, "Next airport = " << id << " "
109                     << elev );
110
111             if ( !last_apt_id.empty()) {
112                 if ( rwy_count > 0 ) {
113                     double lat = rwy_lat_accum / (double)rwy_count;
114                     double lon = rwy_lon_accum / (double)rwy_count;
115                     airports->add( last_apt_id, lon, lat, last_apt_elev,
116                                    last_apt_name, false );
117                 } else {
118                     if ( !last_apt_id.length() ) {
119                         SG_LOG(SG_GENERAL, SG_ALERT,
120                                "ERROR: No runways for " << last_apt_id
121                                << " skipping." );
122                     }
123                 }
124             }
125
126             last_apt_id = id;
127             last_apt_elev = atof( token[1].c_str() );
128             last_apt_name = "";
129
130             // build the name
131             for ( unsigned int i = 5; i < token.size() - 1; ++i ) {
132                 last_apt_name += token[i];
133                 last_apt_name += " ";
134             }
135             last_apt_name += token[token.size() - 1];
136
137             last_apt_info = line;
138             last_apt_type = token[0];
139
140             // clear runway list for start of next airport
141             rwy_lon_accum = 0.0;
142             rwy_lat_accum = 0.0;
143             rwy_count = 0;
144         } else if ( token[0] == "10" ) {
145             // runway entry
146             double lat = atof( token[1].c_str() );
147             double lon = atof( token[2].c_str() );
148             rwy_lat_accum += lat;
149             rwy_lon_accum += lon;
150             rwy_count++;
151
152             string rwy_no = token[3];
153
154             double heading = atof( token[4].c_str() );
155             double length = atoi( token[5].c_str() );
156             double width = atoi( token[8].c_str() );
157
158             string rwy_displ_threshold = token[6];
159             vector<string> displ
160                 = simgear::strutils::split( rwy_displ_threshold, "." );
161             double displ_thresh1 = atof( displ[0].c_str() );
162             double displ_thresh2 = atof( displ[1].c_str() );
163
164             string rwy_stopway = token[7];
165             vector<string> stop
166                 = simgear::strutils::split( rwy_stopway, "." );
167             double stopway1 = atof( stop[0].c_str() );
168             double stopway2 = atof( stop[1].c_str() );
169
170             string lighting_flags = token[9];
171             int surface_code = atoi( token[10].c_str() );
172             string shoulder_code = token[11];
173             int marking_code = atoi( token[12].c_str() );
174             double smoothness = atof( token[13].c_str() );
175             bool dist_remaining = (atoi( token[14].c_str() ) == 1 );
176
177             runways->add( last_apt_id, rwy_no, lon, lat, heading, length,
178                           width, displ_thresh1, displ_thresh2,
179                           stopway1, stopway2, lighting_flags, surface_code,
180                           shoulder_code, marking_code, smoothness,
181                           dist_remaining );
182         } else if ( token[0] == "18" ) {
183             // beacon entry (ignore)
184         } else if ( token[0] == "14" ) {
185             // control tower entry (ignore)
186         } else if ( token[0] == "19" ) {
187             // windsock entry (ignore)
188         } else if ( token[0] == "15" ) {
189             // custom startup locations (ignore)
190         } else if ( token[0] == "50" || token[0] == "51" || token[0] == "52" 
191                     || token[0] == "53" || token[0] == "54" || token[0] == "55" 
192                     || token[0] == "56" )
193         {
194             // frequency entries (ignore)
195         } else if ( token[0] == "99" ) {
196             SG_LOG( SG_GENERAL, SG_DEBUG, "End of file reached" );
197         } else {
198             SG_LOG( SG_GENERAL, SG_ALERT, 
199                     "Unknown line in file: " << line );
200             exit(-1);
201         }
202     }
203
204     if ( !last_apt_id.empty()) {
205         if ( rwy_count > 0 ) {
206             double lat = rwy_lat_accum / (double)rwy_count;
207             double lon = rwy_lon_accum / (double)rwy_count;
208             airports->add( last_apt_id, lon, lat, last_apt_elev,
209                            last_apt_name, false );
210         } else {
211             if ( !last_apt_id.length() ) {
212                 SG_LOG(SG_GENERAL, SG_ALERT,
213                        "ERROR: No runways for " << last_apt_id
214                        << " skipping." );
215             }
216         }
217     }
218
219     //
220     // Load the metar.dat file and update apt db with stations that
221     // have metar data.
222     //
223
224     sg_gzifstream metar_in( metar_file );
225     if ( !metar_in.is_open() ) {
226         SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << metar_file );
227     }
228
229     string ident;
230     while ( metar_in ) {
231         metar_in >> ident;
232         if ( ident == "#" || ident == "//" ) {
233             metar_in >> skipeol;
234         } else {
235             const FGAirport &a = airports->search( ident );
236             if ( a.getId() == ident ) {
237                 airports->has_metar( ident );
238             }
239         }
240     }
241
242     SG_LOG(SG_GENERAL, SG_INFO, "[FINISHED LOADING]");
243
244     return true;
245 }