From 7345a044e028c6c0a843d7de96adfb4217422112 Mon Sep 17 00:00:00 2001 From: jmt Date: Mon, 29 Dec 2008 22:23:22 +0000 Subject: [PATCH 1/2] Split runway and taxiway into separate classes, with a (new) common base. This makes taxiways smaller (important since at present there are so many). Restructure the apt.dat parsing code to use a helper class instead of one long function, and to do less work when parsing the file. Some of these ideas come from Yon Uriarte's patches - thanks Yon. --- src/ATCDCL/ATCutils.cxx | 2 +- src/ATCDCL/ATCutils.hxx | 2 +- src/Airports/Makefile.am | 3 +- src/Airports/apt_loader.cxx | 381 ++++++++++++++-------------- src/Airports/runwaybase.cxx | 86 +++++++ src/Airports/runwaybase.hxx | 108 ++++++++ src/Airports/runways.cxx | 63 +---- src/Airports/runways.hxx | 68 +---- src/Airports/simple.cxx | 17 +- src/Airports/simple.hxx | 9 +- src/Instrumentation/groundradar.cxx | 6 +- src/Instrumentation/groundradar.hxx | 4 +- 12 files changed, 420 insertions(+), 329 deletions(-) create mode 100644 src/Airports/runwaybase.cxx create mode 100644 src/Airports/runwaybase.hxx diff --git a/src/ATCDCL/ATCutils.cxx b/src/ATCDCL/ATCutils.cxx index 03ed9f43d..20460524e 100644 --- a/src/ATCDCL/ATCutils.cxx +++ b/src/ATCDCL/ATCutils.cxx @@ -293,7 +293,7 @@ double GetAngleDiff_deg( const double &a1, const double &a2) { // Runway stuff // Given a Point3D (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway -bool OnRunway(const Point3D& pt, const FGRunway* rwy) { +bool OnRunway(const Point3D& pt, const FGRunwayBase* rwy) { FGATCAlignedProjection ortho; Point3D centre(rwy->longitude(), rwy->latitude(), 0.0); // We don't need the elev ortho.Init(centre, rwy->headingDeg()); diff --git a/src/ATCDCL/ATCutils.hxx b/src/ATCDCL/ATCutils.hxx index 7a53564a4..c47c3469a 100644 --- a/src/ATCDCL/ATCutils.hxx +++ b/src/ATCDCL/ATCutils.hxx @@ -99,5 +99,5 @@ double GetAngleDiff_deg( const double &a1, const double &a2); ****************/ // Given a Point3D (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway -bool OnRunway(const Point3D& pt, const FGRunway* rwy); +bool OnRunway(const Point3D& pt, const FGRunwayBase* rwy); diff --git a/src/Airports/Makefile.am b/src/Airports/Makefile.am index 73e3398ff..09969cb2b 100644 --- a/src/Airports/Makefile.am +++ b/src/Airports/Makefile.am @@ -13,7 +13,8 @@ libAirports_a_SOURCES = \ dynamics.cxx dynamics.hxx \ dynamicloader.cxx dynamicloader.hxx \ runwayprefloader.cxx runwayprefloader.hxx \ - xmlloader.cxx xmlloader.hxx + xmlloader.cxx xmlloader.hxx \ + runwaybase.cxx runwaybase.hxx \ calc_loc_SOURCES = calc_loc.cxx calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lsgstructure -lz $(base_LIBS) diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index ef825295f..b12d06232 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -57,17 +57,116 @@ static FGPositioned::Type fptypeFromRobinType(int aType) } } -FGAirport* addAirport(const string& apt_id, const string& apt_name, - int rwy_count, double rwy_lat_accum, double rwy_lon_accum, double last_rwy_heading, - double apt_elev, SGGeod& tower, bool got_tower, int type) +class APTLoader { - if (apt_id.empty()) - return NULL; +public: + void parseAPT(const string &aptdb_file) + { + sg_gzifstream in( aptdb_file ); + if ( !in.is_open() ) { + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << aptdb_file ); + exit(-1); + } + + string line; + char tmp[2049]; + tmp[2048] = 0; + + unsigned int line_id = 0; + unsigned int line_num = 0; + + while ( ! in.eof() ) { + in.getline(tmp, 2048); + line = tmp; // string copy, ack + line_num++; + + if ( !line.size() || isspace(tmp[0])) { + continue; + } + + if (line.size() >= 3) { + char *p = (char *)memchr(tmp, ' ', 3); + if ( p ) + *p = 0; + } + + line_id = atoi(tmp); + if ( tmp[0] == 'I' ) { + // First line, indicates IBM (i.e. DOS line endings I + // believe.) + + // move past this line and read and discard the next line + // which is the version and copyright information + in.getline(tmp, 2048); + // vector vers_token = simgear::strutils::split( tmp ); + if ( strlen(tmp) > 4 ) { + char *p = (char *)memchr(tmp, ' ', 4); + if ( p ) + *p = 0; + } + SG_LOG( SG_GENERAL, SG_INFO, "Data file version = " << tmp ); + } else if ( line_id == 1 /* Airport */ || + line_id == 16 /* Seaplane base */ || + line_id == 17 /* Heliport */ ) { + parseAirportLine(simgear::strutils::split(line)); + } else if ( line_id == 10 ) { + parseRunwayLine(simgear::strutils::split(line)); + } else if ( line_id == 18 ) { + // beacon entry (ignore) + } else if ( line_id == 14 ) { + // control tower entry + vector token(simgear::strutils::split(line)); + + double lat = atof( token[1].c_str() ); + double lon = atof( token[2].c_str() ); + double elev = atof( token[3].c_str() ); + tower = SGGeod::fromDegFt(lon, lat, elev + last_apt_elev); + got_tower = true; + } else if ( line_id == 19 ) { + // windsock entry (ignore) + } else if ( line_id == 15 ) { + // custom startup locations (ignore) + } else if ( line_id == 0 ) { + // ?? + } else if ( line_id >= 50 && line_id <= 56 ) { + // frequency entries (ignore) + } else if ( line_id == 99 ) { + SG_LOG( SG_GENERAL, SG_DEBUG, "End of file reached" ); + } else { + SG_LOG( SG_GENERAL, SG_ALERT, + "Unknown line(#" << line_num << ") in file: " << line ); + exit(-1); + } + } + + addAirport(); + } + +private: + double rwy_lat_accum; + double rwy_lon_accum; + double last_rwy_heading; + int rwy_count; + bool got_tower; + string last_apt_id; + string last_apt_name; + double last_apt_elev; + SGGeod tower; + int last_apt_type; + + vector runways; + vector taxiways; + + void addAirport() + { + if (last_apt_id.empty()) { + return; + } if (!rwy_count) { - SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: No runways for " << apt_id + SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: No runways for " << last_apt_id << ", skipping." ); - return NULL; + return; } double lat = rwy_lat_accum / (double)rwy_count; @@ -79,196 +178,99 @@ FGAirport* addAirport(const string& apt_id, const string& apt_name, // make a little off the heading for 1 runway airports... float fudge_lon = fabs(sin(last_rwy_heading * SGD_DEGREES_TO_RADIANS)) * .003f; float fudge_lat = .003f - fudge_lon; - tower = SGGeod::fromDegFt(lon + fudge_lon, lat + fudge_lat, apt_elev + tower_height); + tower = SGGeod::fromDegFt(lon + fudge_lon, lat + fudge_lat, last_apt_elev + tower_height); } - return new FGAirport(apt_id, SGGeod::fromDegFt(lon, lat, apt_elev), tower, apt_name, false, - fptypeFromRobinType(type)); -} + SGGeod pos(SGGeod::fromDegFt(lon, lat, last_apt_elev)); + FGAirport* apt = new FGAirport(last_apt_id, pos, tower, last_apt_name, false, + fptypeFromRobinType(last_apt_type)); + + apt->setRunwaysAndTaxiways(runways, taxiways); + } + + void parseAirportLine(const vector& token) + { + const string& id(token[4]); + double elev = atof( token[1].c_str() ); + + addAirport(); + + last_apt_id = id; + last_apt_elev = elev; + last_apt_name = ""; + got_tower = false; + + // build the name + for ( unsigned int i = 5; i < token.size() - 1; ++i ) { + last_apt_name += token[i]; + last_apt_name += " "; + } + last_apt_name += token[token.size() - 1]; + last_apt_type = atoi( token[0].c_str() ); + + // clear runway list for start of next airport + rwy_lon_accum = 0.0; + rwy_lat_accum = 0.0; + rwy_count = 0; + } + + void parseRunwayLine(const vector& token) + { + double lat = atof( token[1].c_str() ); + double lon = atof( token[2].c_str() ); + rwy_lat_accum += lat; + rwy_lon_accum += lon; + rwy_count++; + + const string& rwy_no(token[3]); + + double heading = atof( token[4].c_str() ); + double length = atoi( token[5].c_str() ); + double width = atoi( token[8].c_str() ); + + last_rwy_heading = heading; + + int surface_code = atoi( token[10].c_str() ); + SGGeod pos(SGGeod::fromDegFt(lon, lat, 0.0)); + + if (rwy_no[0] == 'x') { + // taxiway + FGTaxiway* t = new FGTaxiway(rwy_no, pos, heading, length, width, surface_code); + taxiways.push_back(t); + } else { + // (pair of) runways + string rwy_displ_threshold = token[6]; + vector displ + = simgear::strutils::split( rwy_displ_threshold, "." ); + double displ_thresh1 = atof( displ[0].c_str() ); + double displ_thresh2 = atof( displ[1].c_str() ); + + string rwy_stopway = token[7]; + vector stop + = simgear::strutils::split( rwy_stopway, "." ); + double stopway1 = atof( stop[0].c_str() ); + double stopway2 = atof( stop[1].c_str() ); + + FGRunway* rwy = new FGRunway(NULL, rwy_no, pos, heading, length, + width, displ_thresh1, stopway1, surface_code, false); + runways.push_back(rwy); + + FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no), + pos, heading + 180.0, length, width, + displ_thresh2, stopway2, surface_code, true); + + runways.push_back(reciprocal); + } + } +}; // Load the airport data base from the specified aptdb file. The // metar file is used to mark the airports as having metar available // or not. bool fgAirportDBLoad( const string &aptdb_file, const string &metar_file ) { - // - // Load the apt.dat file - // - - sg_gzifstream in( aptdb_file ); - if ( !in.is_open() ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << aptdb_file ); - exit(-1); - } - - vector token; - string last_apt_id = ""; - double last_apt_elev = 0.0; - string last_apt_name = ""; - string last_apt_info = ""; - int last_apt_type = 0; - SGGeod last_tower; - bool got_tower = false; - string line; - char tmp[2049]; - tmp[2048] = 0; - vector runways; - - unsigned int line_id = 0; - unsigned int line_num = 0; - double rwy_lon_accum = 0.0; - double rwy_lat_accum = 0.0; - int rwy_count = 0; - double last_rwy_heading = 0.0; - - while ( ! in.eof() ) { - in.getline(tmp, 2048); - line = tmp; - line_num++; - - SG_LOG( SG_GENERAL, SG_BULK, "#" << line_num << " '" << line << "'" ); - if ( !line.size() || isspace(tmp[0])) - continue; - - if (line.size() >= 3) { - char *p = (char *)memchr(tmp, ' ', 3); - if ( p ) - *p = 0; - } - - line_id = atoi(tmp); - if ( tmp[0] == 'I' ) { - // First line, indicates IBM (i.e. DOS line endings I - // believe.) - - // move past this line and read and discard the next line - // which is the version and copyright information - in.getline(tmp, 2048); - // vector vers_token = simgear::strutils::split( tmp ); - if ( strlen(tmp) > 4 ) { - char *p = (char *)memchr(tmp, ' ', 4); - if ( p ) - *p = 0; - } - SG_LOG( SG_GENERAL, SG_INFO, "Data file version = " - << tmp ); - } else if ( line_id == 1 /* Airport */ || - line_id == 16 /* Seaplane base */ || - line_id == 17 /* Heliport */ ) { - - token.clear(); - token = simgear::strutils::split(line); - string id = token[4]; - double elev = atof( token[1].c_str() ); - SG_LOG( SG_GENERAL, SG_BULK, "Next airport = " << id << " " - << elev ); - - FGAirport* apt = addAirport(last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum, - last_rwy_heading, last_apt_elev, last_tower, got_tower, last_apt_type); - - for (unsigned int r=0; r< runways.size(); ++r) { - apt->addRunway(runways[r]); - } - - runways.clear(); - - last_apt_id = id; - last_apt_elev = elev; - last_apt_name = ""; - got_tower = false; - - // build the name - for ( unsigned int i = 5; i < token.size() - 1; ++i ) { - last_apt_name += token[i]; - last_apt_name += " "; - } - last_apt_name += token[token.size() - 1]; - - last_apt_info = line; - last_apt_type = atoi( token[0].c_str() ); - - // clear runway list for start of next airport - rwy_lon_accum = 0.0; - rwy_lat_accum = 0.0; - rwy_count = 0; - } else if ( line_id == 10 ) { - token.clear(); - token = simgear::strutils::split(line); - - // runway entry - double lat = atof( token[1].c_str() ); - double lon = atof( token[2].c_str() ); - rwy_lat_accum += lat; - rwy_lon_accum += lon; - rwy_count++; - - string rwy_no = token[3]; - - double heading = atof( token[4].c_str() ); - double length = atoi( token[5].c_str() ); - double width = atoi( token[8].c_str() ); - - last_rwy_heading = heading; - - string rwy_displ_threshold = token[6]; - vector displ - = simgear::strutils::split( rwy_displ_threshold, "." ); - double displ_thresh1 = atof( displ[0].c_str() ); - double displ_thresh2 = atof( displ[1].c_str() ); - - string rwy_stopway = token[7]; - vector stop - = simgear::strutils::split( rwy_stopway, "." ); - double stopway1 = atof( stop[0].c_str() ); - double stopway2 = atof( stop[1].c_str() ); - - int surface_code = atoi( token[10].c_str() ); - SGGeod pos(SGGeod::fromDegFt(lon, lat, 0.0)); - FGRunway* rwy = new FGRunway(NULL, rwy_no, pos, heading, length, - width, displ_thresh1, stopway1, surface_code, false); - runways.push_back(rwy); - - if (rwy_no[0] != 'x') { - // runways need a reciprocal, taxiways do not - FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no), - pos, heading + 180.0, length, width, - displ_thresh2, stopway2, surface_code, true); - - runways.push_back(reciprocal); - } - } else if ( line_id == 18 ) { - // beacon entry (ignore) - } else if ( line_id == 14 ) { - // control tower entry - token.clear(); - token = simgear::strutils::split(line); - - double lat = atof( token[1].c_str() ); - double lon = atof( token[2].c_str() ); - double elev = atof( token[3].c_str() ); - last_tower = SGGeod::fromDegFt(lon, lat, elev + last_apt_elev); - got_tower = true; - } else if ( line_id == 19 ) { - // windsock entry (ignore) - } else if ( line_id == 15 ) { - // custom startup locations (ignore) - } else if ( line_id == 0 ) { - // ?? - } else if ( line_id >= 50 && line_id <= 56 ) { - // frequency entries (ignore) - } else if ( line_id == 99 ) { - SG_LOG( SG_GENERAL, SG_DEBUG, "End of file reached" ); - } else { - SG_LOG( SG_GENERAL, SG_ALERT, - "Unknown line(#" << line_num << ") in file: " << line ); - exit(-1); - } - } - - // add the last airport being processed if any - addAirport( last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum, - last_rwy_heading, last_apt_elev, last_tower, got_tower, last_apt_type); - + APTLoader ld; + ld.parseAPT(aptdb_file); // // Load the metar.dat file and update apt db with stations that @@ -297,3 +299,4 @@ bool fgAirportDBLoad( const string &aptdb_file, const string &metar_file ) return true; } + diff --git a/src/Airports/runwaybase.cxx b/src/Airports/runwaybase.cxx new file mode 100644 index 000000000..fd82406ad --- /dev/null +++ b/src/Airports/runwaybase.cxx @@ -0,0 +1,86 @@ +// runwaybase.cxx -- a base class for runways and taxiways +// +// Written by James Turber, started December 2008. +// +// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "runwaybase.hxx" + +using std::string; + +/* + * surface codes + * 1 - asphalt + * 2 - concrete + * 3 - turf + * 4 - dirt + * 5 - gravel + * 6 - asphalt helipad + * 7 - concrete helipad + * 8 - turf helipad + * 9 - dirt helipad + * 12 - lakebed + */ + +FGRunwayBase::FGRunwayBase(Type aTy, const string& aIdent, + const SGGeod& aGeod, + const double heading, const double length, + const double width, + const int surface_code, + bool index) : + FGPositioned(aTy, aIdent, aGeod, index) +{ + _heading = heading; + _length = length; + _width = width; + _surface_code = surface_code; +} + +SGGeod FGRunwayBase::pointOnCenterline(double aOffset) const +{ + SGGeod result; + double dummyAz2; + double halfLengthMetres = lengthM() * 0.5; + + SGGeodesy::direct(mPosition, _heading, + aOffset - halfLengthMetres, + result, dummyAz2); + return result; +} + +bool FGRunwayBase::isHardSurface() const +{ + return ((_surface_code == 1) || (_surface_code == 2)); +} + +FGTaxiway::FGTaxiway(const string& aIdent, + const SGGeod& aGeod, + const double heading, const double length, + const double width, + const int surface_code) : + FGRunwayBase(TAXIWAY, aIdent, aGeod, heading, length, width, surface_code, false) +{ +} diff --git a/src/Airports/runwaybase.hxx b/src/Airports/runwaybase.hxx new file mode 100644 index 000000000..aa34df7a7 --- /dev/null +++ b/src/Airports/runwaybase.hxx @@ -0,0 +1,108 @@ +// runwaybase.hxx -- represent a runway or taxiway +// +// Written by James Turner, started December 2000. +// +// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#ifndef _FG_RUNWAY_BASE_HXX +#define _FG_RUNWAY_BASE_HXX + +#include + +#include + +#include "Navaids/positioned.hxx" + +#include + +/** + * @class The base class for runways and taxiways. At present, FGTaxiway is + * a direct instantiation of this class. + */ +class FGRunwayBase : public FGPositioned +{ +public: + FGRunwayBase(Type aTy, const std::string& aIdent, + const SGGeod& aGeod, + const double heading, const double length, + const double width, + const int surface_code, + bool index); + + /** + * Retrieve a position on the extended centerline. Positive values + * are in the direction of the runway heading, negative values are in the + * opposited direction. 0.0 corresponds to the (non-displaced) threshold + */ + SGGeod pointOnCenterline(double aOffset) const; + + double lengthFt() const + { return _length; } + + double lengthM() const + { return _length * SG_FEET_TO_METER; } + + double widthFt() const + { return _width; } + + double widthM() const + { return _width * SG_FEET_TO_METER; } + + /** + * Runway heading in degrees. + */ + double headingDeg() const + { return _heading; } + + /** + * Predicate to test if this runway has a hard surface. For the moment, this + * means concrete or asphalt + */ + bool isHardSurface() const; + + /** + * Retrieve runway surface code, as define in Robin Peel's data + */ + int surface() const + { return _surface_code; } + +protected: + double _heading; + double _length; + double _width; + + /** surface, as defined by: + * http://www.x-plane.org/home/robinp/Apt810.htm#RwySfcCodes + */ + int _surface_code; +}; + +// for the moment, taxiways are simply a concrete RunwayBase +class FGTaxiway : public FGRunwayBase +{ +public: + FGTaxiway(const std::string& aIdent, + const SGGeod& aGeod, + const double heading, const double length, + const double width, + const int surface_code); +}; + +#endif // _FG_RUNWAY_BASE_HXX diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index c38d1dc91..5adfba4f8 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -25,42 +25,17 @@ # include #endif -#include // fabs() #include // sprintf() #include // atoi() #include -#include -#include
#include -#include #include "runways.hxx" -using std::istream; -using std::multimap; using std::string; -/* - * surface codes - * 1 - asphalt - * 2 - concrete - * 3 - turf - * 4 - dirt - * 5 - gravel - * 6 - asphalt helipad - * 7 - concrete helipad - * 8 - turf helipad - * 9 - dirt helipad - * 12 - lakebed - */ - -static FGPositioned::Type runwayTypeFromNumber(const std::string& aRwyNo) -{ - return (aRwyNo[0] == 'x') ? FGPositioned::TAXIWAY : FGPositioned::RUNWAY; -} - static std::string cleanRunwayNo(const std::string& aRwyNo) { if (aRwyNo[0] == 'x') { @@ -84,7 +59,7 @@ static std::string cleanRunwayNo(const std::string& aRwyNo) return result; } -FGRunway::FGRunway(FGAirport* aAirport, const string& rwy_no, +FGRunway::FGRunway(FGAirport* aAirport, const string& aIdent, const SGGeod& aGeod, const double heading, const double length, const double width, @@ -92,18 +67,12 @@ FGRunway::FGRunway(FGAirport* aAirport, const string& rwy_no, const double stopway, const int surface_code, bool reciprocal) : - FGPositioned(runwayTypeFromNumber(rwy_no), cleanRunwayNo(rwy_no), aGeod, - (runwayTypeFromNumber(rwy_no) == FGPositioned::RUNWAY)), + FGRunwayBase(RUNWAY, cleanRunwayNo(aIdent), aGeod, heading, length, width, surface_code, true), _airport(aAirport), - _reciprocal(reciprocal) + _reciprocal(reciprocal), + _displ_thresh(displ_thresh), + _stopway(stopway) { - _heading = heading; - _length = length; - _width = width; - _displ_thresh = displ_thresh; - _stopway = stopway; - - _surface_code = surface_code; } string FGRunway::reverseIdent(const string& aRunwayIdent) @@ -151,11 +120,6 @@ double FGRunway::score(double aLengthWt, double aWidthWt, double aSurfaceWt) con return _length * aLengthWt + _width * aWidthWt + surface * aSurfaceWt + 1e-20; } -bool FGRunway::isTaxiway() const -{ - return (type() == TAXIWAY); -} - SGGeod FGRunway::threshold() const { return pointOnCenterline(0.0); @@ -171,20 +135,3 @@ SGGeod FGRunway::displacedThreshold() const return pointOnCenterline(_displ_thresh * SG_FEET_TO_METER); } -SGGeod FGRunway::pointOnCenterline(double aOffset) const -{ - SGGeod result; - double dummyAz2; - double halfLengthMetres = lengthM() * 0.5; - - SGGeodesy::direct(mPosition, _heading, - aOffset - halfLengthMetres, - result, dummyAz2); - return result; -} - -bool FGRunway::isHardSurface() const -{ - return ((_surface_code == 1) || (_surface_code == 2)); -} - diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index 8e40f9e76..ae2610c8b 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -26,30 +26,17 @@ #include -#include - -#include "Navaids/positioned.hxx" - -#include +#include "Airports/runwaybase.hxx" // forward decls class FGAirport; -class FGRunway : public FGPositioned -{ - FGAirport* _airport; ///< owning airport +class FGRunway : public FGRunwayBase +{ + FGAirport* _airport; bool _reciprocal; - double _heading; - double _length; - double _width; double _displ_thresh; double _stopway; - - /** surface, as defined by: - * http://www.x-plane.org/home/robinp/Apt810.htm#RwySfcCodes - */ - int _surface_code; - public: FGRunway(FGAirport* aAirport, const std::string& rwy_no, @@ -80,11 +67,6 @@ public: bool isReciprocal() const { return _reciprocal; } - /** - * Test if this is a taxiway or not - */ - bool isTaxiway() const; - /** * Get the runway threshold point - this is syntatic sugar, equivalent to * calling pointOnCenterline(0.0); @@ -102,41 +84,13 @@ public: */ SGGeod reverseThreshold() const; - /** - * Retrieve a position on the extended runway centerline. Positive values - * are in the direction of the runway heading, negative values are in the - * opposited direction. 0.0 corresponds to the (non-displaced) threshold - */ - SGGeod pointOnCenterline(double aOffset) const; - - /** - * Runway length in ft - */ - double lengthFt() const - { return _length; } - - double lengthM() const - { return _length * SG_FEET_TO_METER; } - - double widthFt() const - { return _width; } - - double widthM() const - { return _width * SG_FEET_TO_METER; } - double displacedThresholdM() const { return _displ_thresh * SG_FEET_TO_METER; } double stopwayM() const { return _stopway * SG_FEET_TO_METER; } - /** - * Runway heading in degrees. - */ - double headingDeg() const - { return _heading; } - - /** + /** * Airport this runway is located at */ FGAirport* airport() const @@ -145,18 +99,6 @@ public: // FIXME - should die once airport / runway creation is cleaned up void setAirport(FGAirport* aAirport) { _airport = aAirport; } - - /** - * Predicate to test if this runway has a hard surface. For the moment, this - * means concrete or asphalt - */ - bool isHardSurface() const; - - /** - * Retrieve runway surface code, as define in Robin Peel's data - */ - int surface() const - { return _surface_code; } }; #endif // _FG_RUNWAYS_HXX diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 0907030fb..356b8dcc2 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -192,21 +192,22 @@ unsigned int FGAirport::numTaxiways() const return mTaxiways.size(); } -FGRunway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const +FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const { assert(aIndex >= 0 && aIndex < mTaxiways.size()); return mTaxiways[aIndex]; } -void FGAirport::addRunway(FGRunway* aRunway) +void FGAirport::setRunwaysAndTaxiways(vector& rwys, + vector& txwys) { - aRunway->setAirport(this); - - if (aRunway->isTaxiway()) { - mTaxiways.push_back(aRunway); - } else { - mRunways.push_back(aRunway); + mRunways.swap(rwys); + Runway_iterator it = mRunways.begin(); + for (; it != mRunways.end(); ++it) { + (*it)->setAirport(this); } + + mTaxiways.swap(txwys); } FGRunway* FGAirport::getActiveRunwayForUsage() const diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index f79b6187b..0a25f8d46 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -37,8 +37,10 @@ // forward decls class FGAirportDynamics; class FGRunway; +class FGTaxiway; typedef SGSharedPtr FGRunwayPtr; +typedef SGSharedPtr FGTaxiwayPtr; /*************************************************************************************** * @@ -93,9 +95,10 @@ public: bool hasHardRunwayOfLengthFt(double aLengthFt) const; unsigned int numTaxiways() const; - FGRunway* getTaxiwayByIndex(unsigned int aIndex) const; + FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const; - void addRunway(FGRunway* aRunway); + void setRunwaysAndTaxiways(std::vector& rwys, + std::vector& txwys); class AirportFilter : public Filter { @@ -153,7 +156,7 @@ private: FGAirport(const FGAirport&); std::vector mRunways; - std::vector mTaxiways; + std::vector mTaxiways; }; // find basic airport location info from airport database diff --git a/src/Instrumentation/groundradar.cxx b/src/Instrumentation/groundradar.cxx index 219c1c32b..3b74bea9e 100644 --- a/src/Instrumentation/groundradar.cxx +++ b/src/Instrumentation/groundradar.cxx @@ -112,7 +112,7 @@ void GroundRadar::createTexture(const char* texture_name) FGTextureManager::addTexture(texture_name, getTexture()); } -void GroundRadar::addRunwayVertices(const FGRunway* aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices) +void GroundRadar::addRunwayVertices(const FGRunwayBase* aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices) { double az1, az2, dist_m; geo_inverse_wgs_84(aTowerLat, aTowerLon, aRunway->latitude(), aRunway->longitude(), &az1, &az2, &dist_m); @@ -159,8 +159,8 @@ void GroundRadar::updateTexture() for (unsigned int i=0; inumTaxiways(); ++i) { - FGRunway* runway(apt->getTaxiwayByIndex(i)); - addRunwayVertices(runway, tower_lat, tower_lon, scale, taxi_vertices.get()); + FGTaxiway* txwy(apt->getTaxiwayByIndex(i)); + addRunwayVertices(txwy, tower_lat, tower_lon, scale, taxi_vertices.get()); } osg::Vec3Array* vertices = new osg::Vec3Array(*taxi_vertices.get()); diff --git a/src/Instrumentation/groundradar.hxx b/src/Instrumentation/groundradar.hxx index 2a78cab59..64cbd04a6 100644 --- a/src/Instrumentation/groundradar.hxx +++ b/src/Instrumentation/groundradar.hxx @@ -26,7 +26,7 @@ #include "od_gauge.hxx" // forward decls -class FGRunway; +class FGRunwayBase; //////////////////////////////////////////////////////////////////////// // Built-in layer for the atc radar. @@ -43,7 +43,7 @@ public: protected: void createTexture(const char* texture_name); - void addRunwayVertices(const FGRunway* aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices); + void addRunwayVertices(const FGRunwayBase* aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices); osg::ref_ptr _geom; SGPropertyNode_ptr _airport_node; From 91bed7b6da018bda0b53123f08a2731c74ced201 Mon Sep 17 00:00:00 2001 From: jmt Date: Mon, 29 Dec 2008 22:27:36 +0000 Subject: [PATCH 2/2] Automake on Hardy Heron seems to be considerably more picky about white- space than previous versions. --- src/Airports/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Airports/Makefile.am b/src/Airports/Makefile.am index 09969cb2b..71a49a139 100644 --- a/src/Airports/Makefile.am +++ b/src/Airports/Makefile.am @@ -14,8 +14,8 @@ libAirports_a_SOURCES = \ dynamicloader.cxx dynamicloader.hxx \ runwayprefloader.cxx runwayprefloader.hxx \ xmlloader.cxx xmlloader.hxx \ - runwaybase.cxx runwaybase.hxx \ - + runwaybase.cxx runwaybase.hxx + calc_loc_SOURCES = calc_loc.cxx calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lsgstructure -lz $(base_LIBS)