This has been split from Csaba's ATC ground radar contribution.
#include "apt_loader.hxx"
+static void addAirport(FGAirportList *airports, 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)
+{
+ if (!apt_id.empty()) {
+ if (rwy_count > 0) {
+ 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);
+ }
+
+ airports->add(apt_id, SGGeod::fromDegFt(lon, lat, apt_elev), tower, apt_name, false);
+ } else {
+ if ( apt_id.length() ) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: No runways for " << apt_id
+ << ", skipping." );
+ }
+ }
+ }
+}
// Load the airport data base from the specified aptdb file. The
// metar file is used to mark the airports as having metar available
string last_apt_name = "";
string last_apt_info = "";
string last_apt_type = "";
+ SGGeod last_tower;
+ bool got_tower = false;
string line;
char tmp[2049];
tmp[2048] = 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);
SG_LOG( SG_GENERAL, SG_BULK, "Next airport = " << id << " "
<< elev );
- if ( !last_apt_id.empty()) {
- if ( rwy_count > 0 ) {
- double lat = rwy_lat_accum / (double)rwy_count;
- double lon = rwy_lon_accum / (double)rwy_count;
- airports->add( last_apt_id, lon, lat, last_apt_elev,
- last_apt_name, false );
- } else {
- if ( !last_apt_id.length() ) {
- SG_LOG(SG_GENERAL, SG_ALERT,
- "ERROR: No runways for " << last_apt_id
- << " skipping." );
- }
- }
- }
+ addAirport(airports, 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_id = id;
- last_apt_elev = atof( token[1].c_str() );
+ last_apt_elev = elev;
last_apt_name = "";
+ got_tower = false;
// build the name
for ( unsigned int i = 5; i < token.size() - 1; ++i ) {
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
} else if ( line_id == 18 ) {
// beacon entry (ignore)
} else if ( line_id == 14 ) {
- // control tower entry (ignore)
+ // 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);
+ got_tower = true;
} else if ( line_id == 19 ) {
// windsock entry (ignore)
} else if ( line_id == 15 ) {
}
}
- if ( !last_apt_id.empty()) {
- if ( rwy_count > 0 ) {
- double lat = rwy_lat_accum / (double)rwy_count;
- double lon = rwy_lon_accum / (double)rwy_count;
- airports->add( last_apt_id, lon, lat, last_apt_elev,
- last_apt_name, false );
- } else {
- if ( !last_apt_id.length() ) {
- SG_LOG(SG_GENERAL, SG_ALERT,
- "ERROR: No runways for " << last_apt_id
- << " skipping." );
- }
- }
- }
+ // add the last airport being processed if any
+ addAirport(airports, last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum,
+ last_rwy_heading, last_apt_elev, last_tower, got_tower);
+
//
// Load the metar.dat file and update apt db with stations that
rwy._smoothness = smoothness;
rwy._dist_remaining = dist_remaining;
- if ( rwy_no == "xxx" ) {
+ if ( rwy_no[0] == 'x' ) {
rwy._type = "taxiway";
- // don't insert taxiways into the DB for now
} else {
rwy._type = "runway";
- runways.insert(pair<const string, FGRunway>(rwy._id, rwy));
}
+ runways.insert(pair<const string, FGRunway>(rwy._id, rwy));
}
// cout << "Original rwyno = " << rwyNo << '\n';
// Helipads don't have a seperate number per end
- if(rwyno.size() && (rwyno[0] == 'H' || rwyno[0] == 'h')) {
+ if(rwyno.size() && (rwyno[0] == 'H' || rwyno[0] == 'h' || rwyno[0] == 'x')) {
return rwyno;
}
/***************************************************************************
* FGAirport
***************************************************************************/
-FGAirport::FGAirport() : _longitude(0), _latitude(0), _elevation(0)
+FGAirport::FGAirport()
{
dynamics = 0;
}
-
-FGAirport::FGAirport(const string &id, double lon, double lat, double elev, const string &name, bool has_metar)
+FGAirport::FGAirport(const string &id, const SGGeod& location, const SGGeod& tower_location, const string &name, bool has_metar)
{
_id = id;
- _longitude = lon;
- _latitude = lat;
- _elevation = elev;
+ _location = location;
+ _tower_location = tower_location;
_name = name;
_has_metar = has_metar;
dynamics = 0;
// add an entry to the list
-void FGAirportList::add( const string &id, const double longitude,
- const double latitude, const double elevation,
+void FGAirportList::add( const string &id, const SGGeod& location, const SGGeod& tower_location,
const string &name, const bool has_metar )
{
- FGAirport* a = new FGAirport(id, longitude, latitude, elevation, name, has_metar);
-
+ FGAirport* a = new FGAirport(id, location, tower_location, name, has_metar);
+
airports_by_id[a->getId()] = a;
// try and read in an auxilary file
-
+
airports_array.push_back( a );
- SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << longitude
- << ", " << latitude << " elev = " << elevation );
+ SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << location.getLongitudeDeg()
+ << ", " << location.getLatitudeDeg() << " elev = " << location.getElevationFt() );
}
class FGAirport {
private:
string _id;
- double _longitude; // degrees
- double _latitude; // degrees
- double _elevation; // ft
+ SGGeod _location;
+ SGGeod _tower_location;
string _name;
bool _has_metar;
FGAirportDynamics *dynamics;
public:
FGAirport();
// FGAirport(const FGAirport &other);
- FGAirport(const string& id, double lon, double lat, double elev, const string& name, bool has_metar);
+ FGAirport(const string& id, const SGGeod& location, const SGGeod& tower, const string& name, bool has_metar);
~FGAirport();
const string& getId() const { return _id; }
const string& getName() const { return _name; }
- double getLongitude() const { return _longitude; }
+ double getLongitude() const { return _location.getLongitudeDeg(); }
// Returns degrees
- double getLatitude() const { return _latitude; }
+ double getLatitude() const { return _location.getLatitudeDeg(); }
// Returns ft
- double getElevation() const { return _elevation; }
+ double getElevation() const { return _location.getElevationFt(); }
bool getMetar() const { return _has_metar; }
+ const SGGeod& getTowerLocation() const { return _tower_location; }
+
void setId(const string& id) { _id = id; }
void setMetar(bool value) { _has_metar = value; }
~FGAirportList();
// add an entry to the list
- void add( const string& id, const double longitude, const double latitude,
- const double elevation, const string& name, const bool has_metar );
+ void add( const string& id, const SGGeod& location, const SGGeod& tower,
+ const string& name, const bool has_metar );
// search for the specified id.
// Returns NULL if unsucessfull.
// Set current tower position lon/lat given an airport id
-static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) {
-
- // tower height hard coded for now...
- float towerheight=50.0f;
-
- // make a little off the heading for 1 runway airports...
- float fudge_lon = fabs(sin(hdg)) * .003f;
- float fudge_lat = .003f - fudge_lon;
-
+static bool fgSetTowerPosFromAirportID( const string& id) {
const FGAirport *a = fgFindAirportID( id);
- if ( a) {
- fgSetDouble("/sim/tower/longitude-deg", a->getLongitude() + fudge_lon);
- fgSetDouble("/sim/tower/latitude-deg", a->getLatitude() + fudge_lat);
- fgSetDouble("/sim/tower/altitude-ft", a->getElevation() + towerheight);
+ if (a) {
+ SGGeod tower = a->getTowerLocation();
+ fgSetDouble("/sim/tower/longitude-deg", tower.getLongitudeDeg());
+ fgSetDouble("/sim/tower/latitude-deg", tower.getLatitudeDeg());
+ fgSetDouble("/sim/tower/altitude-ft", tower.getElevationFt());
return true;
} else {
return false;
struct FGTowerLocationListener : SGPropertyChangeListener {
void valueChanged(SGPropertyNode* node) {
- const double hdg = fgGetDouble( "/orientation/heading-deg", 0);
const string id(node->getStringValue());
- fgSetTowerPosFromAirportID(id, hdg);
+ fgSetTowerPosFromAirportID(id);
}
};