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:
parent
474df2414e
commit
78228d2734
5 changed files with 80 additions and 71 deletions
|
@ -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 ) {
|
||||||
|
@ -169,6 +189,8 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways,
|
||||||
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
|
||||||
= simgear::strutils::split( rwy_displ_threshold, "." );
|
= simgear::strutils::split( rwy_displ_threshold, "." );
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue