From 78228d2734a44b4061be96ecda943f732f0a68cc Mon Sep 17 00:00:00 2001 From: timoore Date: Sun, 9 Sep 2007 23:21:48 +0000 Subject: [PATCH] Change tower location to an SGGeod. Include taxiways too. This has been split from Csaba's ATC ground radar contribution. --- src/Airports/apt_loader.cxx | 80 +++++++++++++++++++++++-------------- src/Airports/runways.cxx | 7 ++-- src/Airports/simple.cxx | 23 +++++------ src/Airports/simple.hxx | 19 ++++----- src/Main/fg_init.cxx | 22 ++++------ 5 files changed, 80 insertions(+), 71 deletions(-) diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index 0c62ea31d..a7475c708 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -44,6 +44,34 @@ #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 @@ -67,6 +95,8 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, 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; @@ -76,6 +106,7 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, 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); @@ -119,24 +150,13 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, 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 ) { @@ -168,6 +188,8 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, 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 @@ -196,7 +218,15 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, } 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 ) { @@ -212,20 +242,10 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, } } - 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 diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index c38c9fef2..4018cc5bc 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -80,13 +80,12 @@ void FGRunwayList::add( const string& id, const string& rwy_no, 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(rwy._id, rwy)); } + runways.insert(pair(rwy._id, rwy)); } @@ -97,7 +96,7 @@ static string GetReverseRunwayNo(string& rwyno) { // 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; } diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 64c2109b1..0b9c39097 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -61,18 +61,16 @@ SG_USING_STD(random_shuffle); /*************************************************************************** * 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; @@ -143,18 +141,17 @@ FGAirportList::~FGAirportList( void ) // 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() ); } diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index 0e79c8675..cb003e3d9 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -65,9 +65,8 @@ SG_USING_STD(vector); 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; @@ -75,18 +74,20 @@ private: 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; } @@ -124,8 +125,8 @@ public: ~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. diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index ef838b7e5..54d9b743e 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -722,20 +722,13 @@ static bool fgSetPosFromAirportID( const string& id ) { // 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; @@ -745,9 +738,8 @@ static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) { 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); } }; -- 2.39.5