1
0
Fork 0

Change tower location to an SGGeod. Include taxiways too.

This has been split from Csaba's ATC ground radar contribution.
This commit is contained in:
timoore 2007-09-09 23:21:48 +00:00
parent 474df2414e
commit 78228d2734
5 changed files with 80 additions and 71 deletions

View file

@ -44,6 +44,34 @@
#include "apt_loader.hxx" #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 // Load the airport data base from the specified aptdb file. The
// metar file is used to mark the airports as having metar available // 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_name = "";
string last_apt_info = ""; string last_apt_info = "";
string last_apt_type = ""; string last_apt_type = "";
SGGeod last_tower;
bool got_tower = false;
string line; string line;
char tmp[2049]; char tmp[2049];
tmp[2048] = 0; tmp[2048] = 0;
@ -76,6 +106,7 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
double rwy_lon_accum = 0.0; double rwy_lon_accum = 0.0;
double rwy_lat_accum = 0.0; double rwy_lat_accum = 0.0;
int rwy_count = 0; int rwy_count = 0;
double last_rwy_heading = 0.0;
while ( ! in.eof() ) { while ( ! in.eof() ) {
in.getline(tmp, 2048); in.getline(tmp, 2048);
@ -119,24 +150,13 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
SG_LOG( SG_GENERAL, SG_BULK, "Next airport = " << id << " " SG_LOG( SG_GENERAL, SG_BULK, "Next airport = " << id << " "
<< elev ); << elev );
if ( !last_apt_id.empty()) { addAirport(airports, last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum,
if ( rwy_count > 0 ) { last_rwy_heading, last_apt_elev, last_tower, got_tower);
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." );
}
}
}
last_apt_id = id; last_apt_id = id;
last_apt_elev = atof( token[1].c_str() ); last_apt_elev = elev;
last_apt_name = ""; last_apt_name = "";
got_tower = false;
// build the name // build the name
for ( unsigned int i = 5; i < token.size() - 1; ++i ) { 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 heading = atof( token[4].c_str() );
double length = atoi( token[5].c_str() ); double length = atoi( token[5].c_str() );
double width = atoi( token[8].c_str() ); double width = atoi( token[8].c_str() );
last_rwy_heading = heading;
string rwy_displ_threshold = token[6]; string rwy_displ_threshold = token[6];
vector<string> displ vector<string> displ
@ -196,7 +218,15 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
} else if ( line_id == 18 ) { } else if ( line_id == 18 ) {
// beacon entry (ignore) // beacon entry (ignore)
} else if ( line_id == 14 ) { } 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 ) { } else if ( line_id == 19 ) {
// windsock entry (ignore) // windsock entry (ignore)
} else if ( line_id == 15 ) { } else if ( line_id == 15 ) {
@ -212,20 +242,10 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
} }
} }
if ( !last_apt_id.empty()) { // add the last airport being processed if any
if ( rwy_count > 0 ) { addAirport(airports, last_apt_id, last_apt_name, rwy_count, rwy_lat_accum, rwy_lon_accum,
double lat = rwy_lat_accum / (double)rwy_count; last_rwy_heading, last_apt_elev, last_tower, got_tower);
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." );
}
}
}
// //
// Load the metar.dat file and update apt db with stations that // Load the metar.dat file and update apt db with stations that

View file

@ -80,13 +80,12 @@ void FGRunwayList::add( const string& id, const string& rwy_no,
rwy._smoothness = smoothness; rwy._smoothness = smoothness;
rwy._dist_remaining = dist_remaining; rwy._dist_remaining = dist_remaining;
if ( rwy_no == "xxx" ) { if ( rwy_no[0] == 'x' ) {
rwy._type = "taxiway"; rwy._type = "taxiway";
// don't insert taxiways into the DB for now
} else { } else {
rwy._type = "runway"; rwy._type = "runway";
runways.insert(pair<const string, FGRunway>(rwy._id, rwy));
} }
runways.insert(pair<const string, FGRunway>(rwy._id, rwy));
} }
@ -97,7 +96,7 @@ static string GetReverseRunwayNo(string& rwyno) {
// cout << "Original rwyno = " << rwyNo << '\n'; // cout << "Original rwyno = " << rwyNo << '\n';
// Helipads don't have a seperate number per end // 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; return rwyno;
} }

View file

@ -61,18 +61,16 @@ SG_USING_STD(random_shuffle);
/*************************************************************************** /***************************************************************************
* FGAirport * FGAirport
***************************************************************************/ ***************************************************************************/
FGAirport::FGAirport() : _longitude(0), _latitude(0), _elevation(0) FGAirport::FGAirport()
{ {
dynamics = 0; dynamics = 0;
} }
FGAirport::FGAirport(const string &id, const SGGeod& location, const SGGeod& tower_location, const string &name, bool has_metar)
FGAirport::FGAirport(const string &id, double lon, double lat, double elev, const string &name, bool has_metar)
{ {
_id = id; _id = id;
_longitude = lon; _location = location;
_latitude = lat; _tower_location = tower_location;
_elevation = elev;
_name = name; _name = name;
_has_metar = has_metar; _has_metar = has_metar;
dynamics = 0; dynamics = 0;
@ -143,18 +141,17 @@ FGAirportList::~FGAirportList( void )
// add an entry to the list // add an entry to the list
void FGAirportList::add( const string &id, const double longitude, void FGAirportList::add( const string &id, const SGGeod& location, const SGGeod& tower_location,
const double latitude, const double elevation,
const string &name, const bool has_metar ) 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; airports_by_id[a->getId()] = a;
// try and read in an auxilary file // try and read in an auxilary file
airports_array.push_back( a ); airports_array.push_back( a );
SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << longitude SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << location.getLongitudeDeg()
<< ", " << latitude << " elev = " << elevation ); << ", " << location.getLatitudeDeg() << " elev = " << location.getElevationFt() );
} }

View file

@ -65,9 +65,8 @@ SG_USING_STD(vector);
class FGAirport { class FGAirport {
private: private:
string _id; string _id;
double _longitude; // degrees SGGeod _location;
double _latitude; // degrees SGGeod _tower_location;
double _elevation; // ft
string _name; string _name;
bool _has_metar; bool _has_metar;
FGAirportDynamics *dynamics; FGAirportDynamics *dynamics;
@ -75,18 +74,20 @@ private:
public: public:
FGAirport(); FGAirport();
// FGAirport(const FGAirport &other); // 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(); ~FGAirport();
const string& getId() const { return _id; } const string& getId() const { return _id; }
const string& getName() const { return _name; } const string& getName() const { return _name; }
double getLongitude() const { return _longitude; } double getLongitude() const { return _location.getLongitudeDeg(); }
// Returns degrees // Returns degrees
double getLatitude() const { return _latitude; } double getLatitude() const { return _location.getLatitudeDeg(); }
// Returns ft // Returns ft
double getElevation() const { return _elevation; } double getElevation() const { return _location.getElevationFt(); }
bool getMetar() const { return _has_metar; } bool getMetar() const { return _has_metar; }
const SGGeod& getTowerLocation() const { return _tower_location; }
void setId(const string& id) { _id = id; } void setId(const string& id) { _id = id; }
void setMetar(bool value) { _has_metar = value; } void setMetar(bool value) { _has_metar = value; }
@ -124,8 +125,8 @@ public:
~FGAirportList(); ~FGAirportList();
// add an entry to the list // add an entry to the list
void add( const string& id, const double longitude, const double latitude, void add( const string& id, const SGGeod& location, const SGGeod& tower,
const double elevation, const string& name, const bool has_metar ); const string& name, const bool has_metar );
// search for the specified id. // search for the specified id.
// Returns NULL if unsucessfull. // Returns NULL if unsucessfull.

View file

@ -722,20 +722,13 @@ static bool fgSetPosFromAirportID( const string& id ) {
// Set current tower position lon/lat given an airport id // Set current tower position lon/lat given an airport id
static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) { static bool fgSetTowerPosFromAirportID( const string& id) {
// 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;
const FGAirport *a = fgFindAirportID( id); const FGAirport *a = fgFindAirportID( id);
if ( a) { if (a) {
fgSetDouble("/sim/tower/longitude-deg", a->getLongitude() + fudge_lon); SGGeod tower = a->getTowerLocation();
fgSetDouble("/sim/tower/latitude-deg", a->getLatitude() + fudge_lat); fgSetDouble("/sim/tower/longitude-deg", tower.getLongitudeDeg());
fgSetDouble("/sim/tower/altitude-ft", a->getElevation() + towerheight); fgSetDouble("/sim/tower/latitude-deg", tower.getLatitudeDeg());
fgSetDouble("/sim/tower/altitude-ft", tower.getElevationFt());
return true; return true;
} else { } else {
return false; return false;
@ -745,9 +738,8 @@ static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) {
struct FGTowerLocationListener : SGPropertyChangeListener { struct FGTowerLocationListener : SGPropertyChangeListener {
void valueChanged(SGPropertyNode* node) { void valueChanged(SGPropertyNode* node) {
const double hdg = fgGetDouble( "/orientation/heading-deg", 0);
const string id(node->getStringValue()); const string id(node->getStringValue());
fgSetTowerPosFromAirportID(id, hdg); fgSetTowerPosFromAirportID(id);
} }
}; };