]> git.mxchange.org Git - flightgear.git/blob - GenAirports/main.cxx
Rearrange a bit of code ...
[flightgear.git] / GenAirports / main.cxx
1 // main.cxx -- main loop
2 //
3 // Written by Curtis Olson, started March 1998.
4 //
5 // Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22 // (Log is kept at end of this file)
23 //
24
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include <Include/compiler.h>
31
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35
36 #include <list>
37 #include <stdio.h>
38 #include <string.h>
39 #include STL_STRING
40
41 #include <Bucket/newbucket.hxx>
42 #include <Debug/logstream.hxx>
43 #include <Include/fg_constants.h>
44 #include <Misc/fgstream.hxx>
45 #include <Polygon/index.hxx>
46
47 #include "area.hxx"
48 #include "convex_hull.hxx"
49
50
51 // write out airport data
52 void write_airport( int p_index, list_container hull_list, FGBucket b, 
53                     const string& root, const bool cut_and_keep ) {
54     char tile_name[256], poly_index[256];
55
56     string base = b.gen_base_path();
57     string path = root + "/Scenery/" + base;
58     string command = "mkdir -p " + path;
59     system( command.c_str() );
60
61     long int b_index = b.gen_index();
62     sprintf(tile_name, "%ld", b_index);
63     string aptfile = path + "/" + tile_name;
64
65     sprintf( poly_index, "%d", p_index );
66     aptfile += ".";
67     aptfile += poly_index;
68     cout << "apt file = " << aptfile << endl;
69
70     FILE *fd;
71     if ( (fd = fopen(aptfile.c_str(), "a")) == NULL ) {
72         cout << "Cannot open file: " << aptfile << endl;
73         exit(-1);
74     }
75
76     // polygon type
77     if ( cut_and_keep ) {
78         fprintf( fd, "AirportKeep\n" );
79     } else {
80         fprintf( fd, "AirportIgnore\n" );
81     }
82
83     // number of contours
84     fprintf( fd, "1\n" );
85
86     // size of first contour
87     fprintf( fd, "%d\n", hull_list.size() );
88
89     // write contour (polygon) points
90     list_iterator current = hull_list.begin();
91     list_iterator last = hull_list.end();
92     for ( ; current != last ; ++current ) {
93         fprintf( fd, "%.7f %.7f\n", (*current).lon, (*current).lat );
94     }
95
96     fclose(fd);
97 }
98
99
100 // process and airport + runway list
101 void process_airport( string airport, list < string > & runway_list,
102                       const string& root ) {
103     list_container rwy_list, apt_list, hull_list;
104     list_iterator current, last;
105
106     // parse main airport information
107     int elev;
108
109     cout << airport << endl;
110     string apt_type = airport.substr(0, 1);
111     string apt_code = airport.substr(2, 4);
112     string apt_lat = airport.substr(7, 10);
113     string apt_lon = airport.substr(18, 11);
114     string apt_elev = airport.substr(30, 5);
115     sscanf( apt_elev.c_str(), "%d", &elev );
116     string apt_use = airport.substr(36, 1);
117     string apt_twr = airport.substr(37, 1);
118     string apt_bldg = airport.substr(38, 1);
119     string apt_name = airport.substr(40);
120
121     /*
122     cout << "  type = " << apt_type << endl;
123     cout << "  code = " << apt_code << endl;
124     cout << "  lat  = " << apt_lat << endl;
125     cout << "  lon  = " << apt_lon << endl;
126     cout << "  elev = " << apt_elev << " " << elev << endl;
127     cout << "  use  = " << apt_use << endl;
128     cout << "  twr  = " << apt_twr << endl;
129     cout << "  bldg = " << apt_bldg << endl;
130     cout << "  name = " << apt_name << endl;
131     */
132
133     // parse runways and generate the vertex list
134     string rwy_str;
135     double lon, lat, hdg;
136     int len, width;
137
138     list < string >::iterator last_runway = runway_list.end();
139     for ( list < string >::iterator current_runway = runway_list.begin();
140           current_runway != last_runway ; ++current_runway ) {
141         rwy_str = (*current_runway);
142
143         cout << rwy_str << endl;
144         string rwy_no = rwy_str.substr(2, 4);
145         string rwy_lat = rwy_str.substr(6, 10);
146         sscanf( rwy_lat.c_str(), "%lf", &lat);
147         string rwy_lon = rwy_str.substr(17, 11);
148         sscanf( rwy_lon.c_str(), "%lf", &lon);
149         string rwy_hdg = rwy_str.substr(29, 7);
150         sscanf( rwy_hdg.c_str(), "%lf", &hdg);
151         string rwy_len = rwy_str.substr(36, 7);
152         sscanf( rwy_len.c_str(), "%d", &len);
153         string rwy_width = rwy_str.substr(43, 4);
154         sscanf( rwy_width.c_str(), "%d", &width);
155         string rwy_sfc = rwy_str.substr(47, 4);
156         string rwy_end1 = rwy_str.substr(52, 6);
157         string rwy_end2 = rwy_str.substr(59, 6);
158
159         /*
160         cout << "  no    = " << rwy_no << endl;
161         cout << "  lat   = " << rwy_lat << " " << lat << endl;
162         cout << "  lon   = " << rwy_lon << " " << lon << endl;
163         cout << "  hdg   = " << rwy_hdg << " " << hdg << endl;
164         cout << "  len   = " << rwy_len << " " << len << endl;
165         cout << "  width = " << rwy_width << " " << width << endl;
166         cout << "  sfc   = " << rwy_sfc << endl;
167         cout << "  end1  = " << rwy_end1 << endl;
168         cout << "  end2  = " << rwy_end2 << endl;
169         */
170         
171         rwy_list = gen_runway_area( lon, lat, hdg * DEG_TO_RAD, 
172                                     (double)len * FEET_TO_METER,
173                                     (double)width * FEET_TO_METER );
174
175         // add rwy_list to apt_list
176         current = rwy_list.begin();
177         last = rwy_list.end();
178         for ( ; current != last ; ++current ) {
179             apt_list.push_back(*current);
180         }
181     }
182
183     if ( apt_list.size() == 0 ) {
184         cout << "no runway points generated" << endl;
185         return;
186     }
187
188     // printf("Runway points in degrees\n");
189     // current = apt_list.begin();
190     // last = apt_list.end();
191     // for ( ; current != last; ++current ) {
192     //   printf( "%.5f %.5f\n", current->lon, current->lat );
193     // }
194     // printf("\n");
195
196     // generate convex hull
197     hull_list = convex_hull(apt_list);
198
199     // get next polygon index
200     int index = poly_index_next();
201
202     // find average center, min, and max point of convex hull
203     point2d average, min, max;
204     double sum_x, sum_y;
205     int count = hull_list.size();
206     current = hull_list.begin();
207     last = hull_list.end();
208     sum_x = sum_y = 0.0;
209     min.x = min.y = 200.0;
210     max.x = max.y = -200.0;
211     for ( ; current != last; ++current ) {
212         // printf("return = %.6f %.6f\n", (*current).x, (*current).y);
213         sum_x += (*current).x;
214         sum_y += (*current).y;
215
216         if ( (*current).x < min.x ) { min.x = (*current).x; }
217         if ( (*current).y < min.y ) { min.y = (*current).y; }
218         if ( (*current).x > max.x ) { max.x = (*current).x; }
219         if ( (*current).y > max.y ) { max.y = (*current).y; }
220     }
221     average.x = sum_x / count;
222     average.y = sum_y / count;
223
224     // find buckets for center, min, and max points of convex hull.
225     // note to self: self, you should think about checking for runways
226     // that span the data line
227     FGBucket b(average.lon, average.lat);
228     FGBucket b_min(min.x, min.y);
229     FGBucket b_max(max.x, max.y);
230     cout << "Bucket center = " << b << endl;
231     cout << "Bucket min = " << b_min << endl;
232     cout << "Bucket max = " << b_max << endl;
233     
234     if ( b_min == b_max ) {
235         write_airport( index, hull_list, b, root, true );
236     } else {
237         FGBucket b_cur;
238         int dx, dy, i, j;
239
240         fgBucketDiff(b_min, b_max, &dx, &dy);
241         cout << "airport spans tile boundaries" << endl;
242         cout << "  dx = " << dx << "  dy = " << dy << endl;
243
244         if ( (dx > 1) || (dy > 1) ) {
245             cout << "somethings really wrong!!!!" << endl;
246             exit(-1);
247         }
248
249         for ( j = 0; j <= dy; j++ ) {
250             for ( i = 0; i <= dx; i++ ) {
251                 b_cur = fgBucketOffset(min.x, min.y, i, j);
252                 if ( b_cur == b ) {
253                     write_airport( index, hull_list, b_cur, root, true );
254                 } else {
255                     write_airport( index, hull_list, b_cur, root, false );
256                 }
257             }
258         }
259         // string answer; cin >> answer;
260     }
261 }
262
263
264 // reads the apt_full file and extracts and processes the individual
265 // airport records
266 int main( int argc, char **argv ) {
267     list < string > runway_list;
268     string airport, last_airport;
269     string line;
270     char tmp[256];
271
272     fglog().setLogLevels( FG_ALL, FG_DEBUG );
273
274     if ( argc != 3 ) {
275         FG_LOG( FG_GENERAL, FG_ALERT, 
276                 "Usage " << argv[0] << " <apt_file> <work_dir>" );
277         exit(-1);
278     }
279
280     // make work directory
281     string work_dir = argv[2];
282     string command = "mkdir -p " + work_dir;
283     system( command.c_str() );
284
285     // initialize persistant polygon counter
286     string counter_file = work_dir + "/polygon.counter";
287     poly_index_init( counter_file );
288
289     fg_gzifstream in( argv[1] );
290     if ( !in ) {
291         FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << argv[1] );
292         exit(-1);
293     }
294
295     // throw away the first 3 lines
296     in.getline(tmp, 256);
297     in.getline(tmp, 256);
298     in.getline(tmp, 256);
299
300     last_airport = "";
301
302     while ( ! in.eof() ) {
303         in.getline(tmp, 256);
304         line = tmp;
305         // cout << line << endl;
306
307         if ( line.length() == 0 ) {
308             // empty, skip
309         } else if ( line[0] == '#' ) {
310             // comment, skip
311         } else if ( (line[0] == 'A') || (line[0] == 'S') ) {
312             // start of airport record
313             airport = line;
314
315             if ( last_airport.length() ) {
316                 // process previous record
317                 process_airport(last_airport, runway_list, argv[2]);
318             }
319
320             // clear runway list for start of next airport
321             runway_list.erase(runway_list.begin(), runway_list.end());
322
323             last_airport = airport;
324         } else if ( line[0] == 'R' ) {
325             // runway entry
326             runway_list.push_back(line);
327         } else if ( line == "99" ) {
328             // end of file
329             break;
330         } else {
331             FG_LOG( FG_GENERAL, FG_ALERT, 
332                     "Unknown line in file" << endl << line );
333             exit(-1);
334         }
335     }
336
337     if ( last_airport.length() ) {
338         // process previous record
339         process_airport(last_airport, runway_list, argv[2]);
340     }
341
342     return 0;
343 }
344
345
346 // $Log$
347 // Revision 1.9  1999/03/12 22:54:19  curt
348 // Rearrange a bit of code ...
349 //
350 // Revision 1.8  1999/03/01 15:35:26  curt
351 // Fixed bug in output format generated.
352 //
353 // Revision 1.7  1999/02/25 21:32:49  curt
354 // Modified to adhere to new polygon naming convention, and also to read the
355 // new Robin Peel aiport format.
356 //
357 // Revision 1.6  1999/02/11 01:10:51  curt
358 // Start of scenery revamp project.
359 //
360 // Revision 1.5  1998/09/17 18:40:43  curt
361 // Debug message tweaks.
362 //
363 // Revision 1.4  1998/09/09 20:59:56  curt
364 // Loop construct tweaks for STL usage.
365 // Output airport file to be used to generate airport scenery on the fly
366 //   by the run time sim.
367 //
368 //