1
0
Fork 0

Merge branch 'jt/runway' into next

This commit is contained in:
Tim Moore 2009-01-04 00:14:09 +01:00
commit 18d1593c42
12 changed files with 421 additions and 330 deletions

View file

@ -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());

View file

@ -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);

View file

@ -13,8 +13,9 @@ 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)

View file

@ -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<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 */ ||
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 " << 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<string>& 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<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++;
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 )
{
//
// 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<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;
}
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 */ ||
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<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);
}
}
// 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;
}

View file

@ -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 <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)
{
}

108
src/Airports/runwaybase.hxx Normal file
View file

@ -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 <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

View file

@ -25,42 +25,17 @@
# 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') {
@ -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));
}

View file

@ -26,30 +26,17 @@
#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,
@ -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

View file

@ -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<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

View file

@ -37,8 +37,10 @@
// forward decls
class FGAirportDynamics;
class FGRunway;
class FGTaxiway;
typedef SGSharedPtr<FGRunway> FGRunwayPtr;
typedef SGSharedPtr<FGTaxiway> 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<FGRunwayPtr>& rwys,
std::vector<FGTaxiwayPtr>& txwys);
class AirportFilter : public Filter
{
@ -153,7 +156,7 @@ private:
FGAirport(const FGAirport&);
std::vector<FGRunwayPtr> mRunways;
std::vector<FGRunwayPtr> mTaxiways;
std::vector<FGTaxiwayPtr> mTaxiways;
};
// find basic airport location info from airport database

View file

@ -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; 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());

View file

@ -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<osg::Geometry> _geom;
SGPropertyNode_ptr _airport_node;