From 27dd0a41d8201d3e72b5b51f52d8abe4ab4cbc78 Mon Sep 17 00:00:00 2001 From: Ralf Gerlich <ralf.gerlich@custom-scenery.org> Date: Thu, 8 Nov 2007 22:27:02 +0100 Subject: [PATCH] Fixed the genapts apt.dat parser: - The VASI GS angle is properly parsed - Don't assume given column numbers but properly split the lines at whitespaces - actually make use of the order of taxiways as specified in the apt.dat - make the min/max lat/lon work (patch provided by Torsten Dreyer on terragear-devel [1]) [1] http://mail.flightgear.org/pipermail/terragear-devel/2007-January/001389.html --- src/Airports/GenAirports/build.cxx | 56 ++++++++++++++++----------- src/Airports/GenAirports/main.cxx | 62 +++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/Airports/GenAirports/build.cxx b/src/Airports/GenAirports/build.cxx index bb873314..d705ccda 100644 --- a/src/Airports/GenAirports/build.cxx +++ b/src/Airports/GenAirports/build.cxx @@ -426,10 +426,14 @@ void build_airport( string airport_id, float alt_m, rwy.smoothness = atof( token[13].c_str() ); rwy.dist_remaining = (atoi( token[14].c_str() ) == 1 ); - string vasi_angles = token[15]; - vector<string> vasis = simgear::strutils::split( vasi_angles, "." ); - rwy.gs_angle1 = atof( vasis[0].c_str() ) * 0.01; - rwy.gs_angle2 = atof( vasis[1].c_str() ) * 0.01; + if (token.size()>15) { + string vasi_angles = token[15]; + vector<string> vasis = simgear::strutils::split( vasi_angles, "." ); + rwy.gs_angle1 = atof( vasis[0].c_str() ) * 0.01; + rwy.gs_angle2 = atof( vasis[1].c_str() ) * 0.01; + } else { + rwy.gs_angle1 = rwy.gs_angle2 = 3.0; + } SG_LOG( SG_GENERAL, SG_DEBUG, " no = " << rwy.rwy_no); SG_LOG( SG_GENERAL, SG_DEBUG, " lat = " << rwy.lat); @@ -463,18 +467,14 @@ void build_airport( string airport_id, float alt_m, point_list beacons; beacons.clear(); for ( i = 0; i < (int)beacons_raw.size(); ++i ) { string beacon_str = beacons_raw[i]; + vector<string> token = simgear::strutils::split( beacon_str ); Point3D beacon; SG_LOG(SG_GENERAL, SG_INFO, beacon_str); - string beacon_lat = beacon_str.substr(2, 10); - beacon.setlat( atof( beacon_lat.c_str() ) ); - - string beacon_lon = beacon_str.substr(13, 11); - beacon.setlon( atof( beacon_lon.c_str() ) ); - - string beacon_type = beacon_str.substr(25, 1); + beacon.setlat( atof( token[1].c_str() ) ); + beacon.setlon( atof( token[2].c_str() ) ); SG_LOG( SG_GENERAL, SG_DEBUG, " beacon = " << beacon ); @@ -484,18 +484,19 @@ void build_airport( string airport_id, float alt_m, point_list towers; towers.clear(); for ( i = 0; i < (int)towers_raw.size(); ++i ) { string tower_str = towers_raw[i]; + vector<string> token = simgear::strutils::split( tower_str ); Point3D tower; SG_LOG(SG_GENERAL, SG_INFO, tower_str); - string tower_lat = tower_str.substr(2, 10); - tower.setlat( atof( tower_lat.c_str() ) ); + tower.setlat( atof( token[1].c_str() ) ); + tower.setlon( atof( token[2].c_str() ) ); - string tower_lon = tower_str.substr(13, 11); - tower.setlon( atof( tower_lon.c_str() ) ); - - string tower_type = tower_str.substr(25, 1); + if (!atoi(token[4].c_str())) { + // Ralf Gerlich: Skip towers that shall not be drawn + continue; + } SG_LOG( SG_GENERAL, SG_DEBUG, " tower = " << tower ); @@ -506,18 +507,16 @@ void build_airport( string airport_id, float alt_m, int_list windsock_types; windsock_types.clear(); for ( i = 0; i < (int)windsocks_raw.size(); ++i ) { string windsock_str = windsocks_raw[i]; + vector<string> token = simgear::strutils::split( windsock_str ); Point3D windsock; SG_LOG(SG_GENERAL, SG_INFO, windsock_str); - string windsock_lat = windsock_str.substr(2, 10); - windsock.setlat( atof( windsock_lat.c_str() ) ); + windsock.setlat( atof( token[1].c_str() ) ); + windsock.setlon( atof( token[2].c_str() ) ); - string windsock_lon = windsock_str.substr(13, 11); - windsock.setlon( atof( windsock_lon.c_str() ) ); - - string windsock_type = windsock_str.substr(25, 1); + string windsock_type = token[3]; SG_LOG( SG_GENERAL, SG_DEBUG, " windsock = " << windsock ); @@ -578,6 +577,7 @@ void build_airport( string airport_id, float alt_m, // 4th pass: generate all taxiways +#if 0 // we want to generate in order of largest size first so this will // look a little weird, but that's all I'm doing, otherwise a // simple list traversal would work fine. @@ -607,6 +607,16 @@ void build_airport( string airport_id, float alt_m, done = true; } } +#else + /* Ralf Gerlich: Generate Taxiways in specified order from bottom to top */ + for ( size_t i=0; i<taxiways.size(); ++i ) { + SG_LOG( SG_GENERAL, SG_DEBUG, "generating " << i ); + build_runway( taxiways[i], alt_m, + &rwy_polys, &texparams, &accum, + &apt_base, &apt_clearing ); + taxiways[i].generated = true; + } +#endif // Now generate small surface for each beacon TGPolygon obj_base, obj_safe_base; diff --git a/src/Airports/GenAirports/main.cxx b/src/Airports/GenAirports/main.cxx index a4fca964..38b86f72 100644 --- a/src/Airports/GenAirports/main.cxx +++ b/src/Airports/GenAirports/main.cxx @@ -18,7 +18,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// $Id: main.cxx,v 1.37 2005-12-19 15:53:21 curt Exp $ +// $Id: main.cxx,v 1.37 2005/12/19 15:53:21 curt Exp $ // @@ -61,6 +61,7 @@ SG_USING_STD(vector); int nudge = 10; +static int is_in_range( string_list & runway_list, float min_lat, float max_lat, float min_lon, float max_lon ); // Display usage static void usage( int argc, char **argv ) { @@ -319,13 +320,15 @@ int main( int argc, char **argv ) { // skip building heliports and // seaplane bases } else { - build_airport( last_apt_id, - elev * SG_FEET_TO_METER, - runways_list, - beacon_list, - tower_list, - windsock_list, - work_dir, elev_src ); + if( is_in_range( runways_list, min_lat, max_lat, min_lon, max_lon ) ) { + build_airport( last_apt_id, + elev * SG_FEET_TO_METER, + runways_list, + beacon_list, + tower_list, + windsock_list, + work_dir, elev_src ); + } } } catch (sg_exception &e) { SG_LOG( SG_GENERAL, SG_ALERT, @@ -417,12 +420,14 @@ int main( int argc, char **argv ) { // skip building heliports and // seaplane bases } else { - build_airport( last_apt_id, elev * SG_FEET_TO_METER, - runways_list, - beacon_list, - tower_list, - windsock_list, - work_dir, elev_src ); + if( is_in_range( runways_list, min_lat, max_lat, min_lon, max_lon ) ) { + build_airport( last_apt_id, elev * SG_FEET_TO_METER, + runways_list, + beacon_list, + tower_list, + windsock_list, + work_dir, elev_src ); + } } } catch (sg_exception &e) { SG_LOG( SG_GENERAL, SG_ALERT, @@ -441,3 +446,32 @@ int main( int argc, char **argv ) { return 0; } + +static int is_in_range( string_list & runways_raw, float min_lat, float max_lat, float min_lon, float max_lon ) +{ + int i; + int rwy_count = 0; + double apt_lon = 0.0, apt_lat = 0.0; + + for ( i = 0; i < (int)runways_raw.size(); ++i ) { + ++rwy_count; + + string rwy_str = runways_raw[i]; + vector<string> token = simgear::strutils::split( rwy_str ); + + apt_lat += atof( token[1].c_str() ); + apt_lon += atof( token[2].c_str() ); + } + + if( rwy_count > 0 ) { + apt_lat /= rwy_count; + apt_lon /= rwy_count; + } + + if( apt_lat >= min_lat && apt_lat <= max_lat && + apt_lon >= min_lon && apt_lon <= max_lon ) { + return 1; + } + + return 0; +}