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.
// 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());
****************/
// 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);
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)
}
}
-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;
-
- if (!rwy_count) {
- SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: No runways for " << apt_id
- << ", skipping." );
- return NULL;
- }
-
- double lat = rwy_lat_accum / (double)rwy_count;
- double lon = rwy_lon_accum / (double)rwy_count;
-
- if (!got_tower) {
- // tower height hard coded for now...
- const float tower_height = 50.0f;
- // 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);
- }
-
- return new FGAirport(apt_id, SGGeod::fromDegFt(lon, lat, apt_elev), tower, apt_name, false,
- fptypeFromRobinType(type));
-}
-
-// 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
- //
-
+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);
}
- vector<string> 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<FGRunwayPtr> 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;
+ 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<string> vers_token = simgear::strutils::split( tmp );
+ if ( strlen(tmp) > 4 ) {
+ char *p = (char *)memchr(tmp, ' ', 4);
+ 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<string> 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 */ ||
+ 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<string> 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<FGRunwayPtr> runways;
+ vector<FGTaxiwayPtr> taxiways;
+
+ void addAirport()
+ {
+ if (last_apt_id.empty()) {
+ return;
+ }
+
+ if (!rwy_count) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: No runways for " << last_apt_id
+ << ", skipping." );
+ return;
+ }
- 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 );
+ double lat = rwy_lat_accum / (double)rwy_count;
+ double lon = rwy_lon_accum / (double)rwy_count;
- 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);
+ if (!got_tower) {
+ // tower height hard coded for now...
+ const float tower_height = 50.0f;
+ // 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, last_apt_elev + tower_height);
+ }
- for (unsigned int r=0; r< runways.size(); ++r) {
- apt->addRunway(runways[r]);
- }
+ 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<string>& token)
+ {
+ const string& id(token[4]);
+ double elev = atof( token[1].c_str() );
- runways.clear();
+ 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_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<string> 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<string> 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);
- }
+ 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<string>& 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++;
- // 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);
+ 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<string> 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<string> 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 )
+{
+ APTLoader ld;
+ ld.parseAPT(aptdb_file);
//
// Load the metar.dat file and update apt db with stations that
return true;
}
+
--- /dev/null
+// 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 <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#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)
+{
+}
--- /dev/null
+// 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 <simgear/compiler.h>
+
+#include <simgear/math/sg_geodesy.hxx>
+
+#include "Navaids/positioned.hxx"
+
+#include <string>
+
+/**
+ * @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
# include <config.h>
#endif
-#include <cmath> // fabs()
#include <cstdio> // sprintf()
#include <cstdlib> // atoi()
#include <simgear/compiler.h>
-#include <simgear/debug/logstream.hxx>
-#include <Main/fg_props.hxx>
#include <string>
-#include <map>
#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') {
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,
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)
return _length * aLengthWt + _width * aWidthWt + surface * aSurfaceWt + 1e-20;
}
-bool FGRunway::isTaxiway() const
-{
- return (type() == TAXIWAY);
-}
-
SGGeod FGRunway::threshold() const
{
return pointOnCenterline(0.0);
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));
-}
-
#include <simgear/compiler.h>
-#include <simgear/math/sg_geodesy.hxx>
-
-#include "Navaids/positioned.hxx"
-
-#include <string>
+#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,
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);
*/
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
// 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
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<FGRunwayPtr>& rwys,
+ vector<FGTaxiwayPtr>& 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
// forward decls
class FGAirportDynamics;
class FGRunway;
+class FGTaxiway;
typedef SGSharedPtr<FGRunway> FGRunwayPtr;
+typedef SGSharedPtr<FGTaxiway> FGTaxiwayPtr;
/***************************************************************************************
*
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<FGRunwayPtr>& rwys,
+ std::vector<FGTaxiwayPtr>& txwys);
class AirportFilter : public Filter
{
FGAirport(const FGAirport&);
std::vector<FGRunwayPtr> mRunways;
- std::vector<FGRunwayPtr> mTaxiways;
+ std::vector<FGTaxiwayPtr> mTaxiways;
};
// find basic airport location info from airport database
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);
for (unsigned int i=0; i<apt->numTaxiways(); ++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());
#include "od_gauge.hxx"
// forward decls
-class FGRunway;
+class FGRunwayBase;
////////////////////////////////////////////////////////////////////////
// Built-in layer for the atc radar.
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<osg::Geometry> _geom;
SGPropertyNode_ptr _airport_node;