// in fg_init.cxx, and are just here temporarily until some rationalisation occurs.
// find basic airport location info from airport database
bool dclFindAirportID( const string& id, FGAirport *a ) {
- FGAirport result;
+ const FGAirport* result;
if ( id.length() ) {
SG_LOG( SG_GENERAL, SG_INFO, "Searching for airport code = " << id );
- result = globals->get_airports()->search( id );
- if ( result.getId().empty() ) {
+ result = globals->get_airports()->search(id);
+ if ( result == NULL ) {
SG_LOG( SG_GENERAL, SG_WARN,
- "Failed to find " << id << " in basic.dat.gz" );
+ "Failed to find " << id << " in apt.dat.gz" );
return false;
}
} else {
return false;
}
- *a = result;
+ *a = *result;
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << " is ("
if ( ident == "#" || ident == "//" ) {
metar_in >> skipeol;
} else {
- const FGAirport &a = airports->search( ident );
- if ( a.getId() == ident ) {
- airports->has_metar( ident );
- }
+ const FGAirport* a = airports->search( ident );
+ if ( a ) airports->has_metar( ident );
}
}
ulCloseDir(d);
}
+
+FGAirportList::~FGAirportList( void ) {
+ for(unsigned int i = 0; i < airports_array.size(); ++i) {
+ delete airports_array[i];
+ }
+}
+
+
// add an entry to the list
void FGAirportList::add( const string id, const double longitude,
const double latitude, const double elevation,
const string name, const bool has_metar )
{
- FGRunwayPreference rwyPrefs;
- FGAirport a(id, longitude, latitude, elevation, name, has_metar);
- //a._id = id;
- //a._longitude = longitude;
- //a._latitude = latitude;
- //a._elevation = elevation;
- //a._name = name;
- //a._has_metar = has_metar;
+ FGRunwayPreference rwyPrefs;
+ FGAirport* a = new FGAirport(id, longitude, latitude, elevation, name, has_metar);
SGPath parkpath( globals->get_fg_root() );
parkpath.append( "/Airports/AI/" );
parkpath.append(id);
rwyPrefPath.append("rwyuse.xml");
if (ai_dirs.find(id.c_str()) != ai_dirs.end()
&& parkpath.exists())
- {
- try {
- readXML(parkpath.str(),a);
- }
- catch (const sg_exception &e) {
- //cerr << "unable to read " << parkpath.str() << endl;
- }
- }
+ {
+ try {
+ readXML(parkpath.str(),*a);
+ }
+ catch (const sg_exception &e) {
+ //cerr << "unable to read " << parkpath.str() << endl;
+ }
+ }
if (ai_dirs.find(id.c_str()) != ai_dirs.end()
&& rwyPrefPath.exists())
- {
- try {
- readXML(rwyPrefPath.str(), rwyPrefs);
- a.setRwyUse(rwyPrefs);
- }
- catch (const sg_exception &e) {
- //cerr << "unable to read " << rwyPrefPath.str() << endl;
- //exit(1);
- }
- }
+ {
+ try {
+ readXML(rwyPrefPath.str(), rwyPrefs);
+ a->setRwyUse(rwyPrefs);
+ }
+ catch (const sg_exception &e) {
+ //cerr << "unable to read " << rwyPrefPath.str() << endl;
+ //exit(1);
+ }
+ }
- airports_by_id[a.getId()] = a;
+ airports_by_id[a->getId()] = a;
// try and read in an auxilary file
-
- airports_array.push_back( &airports_by_id[a.getId()] );
+
+ airports_array.push_back( a );
SG_LOG( SG_GENERAL, SG_BULK, "Adding " << id << " pos = " << longitude
<< ", " << latitude << " elev = " << elevation );
}
// search for the specified id
-FGAirport FGAirportList::search( const string& id) {
- return airports_by_id[id];
+FGAirport* FGAirportList::search( const string& id) {
+ airport_map_iterator itr = airports_by_id.find(id);
+ return(itr == airports_by_id.end() ? NULL : itr->second);
}
-// search for the specified id and return a pointer
-FGAirport* FGAirportList::search( const string& id, FGAirport *result) {
- FGAirport* retval = airports_by_id[id].getAddress();
- //cerr << "Returning Airport of string " << id << " results in " << retval->getId();
- return retval;
+
+// search for first subsequent alphabetically to supplied id
+const FGAirport* FGAirportList::findFirstById( const string& id, bool exact ) {
+ airport_map_iterator itr;
+ if(exact) {
+ itr = airports_by_id.find(id);
+ } else {
+ itr = airports_by_id.lower_bound(id);
+ }
+ if(itr == airports_by_id.end()) {
+ return(NULL);
+ } else {
+ return(itr->second);
+ }
}
+
// search for the airport nearest the specified position
-FGAirport FGAirportList::search( double lon_deg, double lat_deg,
+FGAirport* FGAirportList::search( double lon_deg, double lat_deg,
bool with_metar ) {
- int closest = 0;
+ int closest = -1;
double min_dist = 360.0;
unsigned int i;
for ( i = 0; i < airports_array.size(); ++i ) {
}
}
- return *airports_array[closest];
+ return ( closest > -1 ? airports_array[closest] : NULL );
}
-// Destructor
-FGAirportList::~FGAirportList( void ) {
-}
-
int
FGAirportList::size () const
{
return airports_array.size();
}
-const FGAirport *FGAirportList::getAirport( int index ) const
+const FGAirport *FGAirportList::getAirport( unsigned int index ) const
{
- return airports_array[index];
+ if(index < airports_array.size()) {
+ return(airports_array[index]);
+ } else {
+ return(NULL);
+ }
}
* Mark the specified airport record as not having metar
*/
void FGAirportList::no_metar( const string &id ) {
- airports_by_id[id].setMetar(false);
+ if(airports_by_id.find(id) != airports_by_id.end()) {
+ airports_by_id[id]->setMetar(false);
+ }
}
* Mark the specified airport record as (yes) having metar
*/
void FGAirportList::has_metar( const string &id ) {
- airports_by_id[id].setMetar(true);
+ if(airports_by_id.find(id) != airports_by_id.end()) {
+ airports_by_id[id]->setMetar(true);
+ }
}
class FGAirport : public XMLVisitor{
private:
string _id;
- double _longitude;
- double _latitude;
- double _elevation;
+ double _longitude; // degrees
+ double _latitude; // degrees
+ double _elevation; // ft
string _code; // depricated and can be removed
string _name;
bool _has_metar;
FGParkingVec parkings;
FGRunwayPreference rwyPrefs;
- time_t lastUpdate;
+ time_t lastUpdate;
string prevTrafficType;
stringVec landing;
stringVec takeoff;
FGParking *getParking(int i); // { if (i < parkings.size()) return parkings[i]; else return 0;};
void releaseParking(int id);
string getParkingName(int i);
- const string getId() const { return _id;};
+ string getId() const { return _id;};
const string &getName() const { return _name;};
- FGAirport *getAddress() { return this; };
- double getLongitude() { return _longitude;};
- double getLatitude() { return _latitude; };
- double getElevation() { return _elevation;};
- bool getMetar() { return _has_metar;};
+ // Returns degrees
+ double getLongitude() const { return _longitude;};
+ // Returns degrees
+ double getLatitude() const { return _latitude; };
+ // Returns ft
+ double getElevation() const { return _elevation;};
+ bool getMetar() const { return _has_metar;};
void setId(string id) { _id = id;};
virtual void error (const char * message, int line, int column);
};
-typedef map < string, FGAirport > airport_map;
+typedef map < string, FGAirport* > airport_map;
typedef airport_map::iterator airport_map_iterator;
typedef airport_map::const_iterator const_airport_map_iterator;
const double elevation, const string name, const bool has_metar );
// search for the specified id.
- // Returns true if successful, otherwise returns false.
- // On success, airport data is returned thru "airport" pointer.
- // "airport" is not changed if "apt" is not found.
- FGAirport search( const string& id );
+ // Returns NULL if unsucessfull.
+ FGAirport* search( const string& id );
+
+ // Search for the next airport in ASCII sequence to the supplied id.
+ // eg. id = "KDC" or "KDCA" would both return "KDCA".
+ // If exact = true then only exact matches are returned.
+ // NOTE: Numbers come prior to A-Z in ASCII sequence so id = "LD" would return "LD57", not "LDDP"
+ // Implementation assumes airport codes are unique.
+ // Returns NULL if unsucessfull.
+ const FGAirport* findFirstById( const string& id, bool exact = false );
// search for the airport closest to the specified position
// (currently a linear inefficient search so it's probably not
// best to use this at runtime.) If with_metar is true, then only
// return station id's marked as having metar data.
- FGAirport search( double lon_deg, double lat_deg, bool with_metar );
-
- // search and return a pointer;
- FGAirport* search( const string& id, FGAirport *result);
+ // Returns NULL if fails (unlikely unless none have metar and with_metar spec'd!)
+ FGAirport* search( double lon_deg, double lat_deg, bool with_metar );
/**
* Return the number of airports in the list.
*/
int size() const;
-
/**
* Return a specific airport, by position.
*/
- const FGAirport *getAirport( int index ) const;
-
+ const FGAirport *getAirport( unsigned int index ) const;
/**
* Mark the specified airport record as not having metar
metar_max_age->setLongValue(60 * 24 * 7);
while ( !found_metar && (_error_count < 3) ) {
- FGAirport a = globals->get_airports()
- ->search( longitude->getDoubleValue(),
- latitude->getDoubleValue(),
- true );
- FGMetarResult result = fetch_data( a.getId() );
- if ( result.m != NULL ) {
- SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = " << a.getId());
- last_apt = a;
- _icao = a.getId();
- search_elapsed = 0.0;
- fetch_elapsed = 0.0;
- update_metar_properties( result.m );
- update_env_config();
- env->init();
- found_metar = true;
- } else {
- // mark as no metar so it doesn't show up in subsequent
- // searches.
- SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = " << a.getId() );
- globals->get_airports()->no_metar( a.getId() );
+ const FGAirport* a = globals->get_airports()
+ ->search( longitude->getDoubleValue(),
+ latitude->getDoubleValue(),
+ true );
+ if ( a ) {
+ FGMetarResult result = fetch_data( a->getId() );
+ if ( result.m != NULL ) {
+ SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
+ << a->getId());
+ last_apt = *a;
+ _icao = a->getId();
+ search_elapsed = 0.0;
+ fetch_elapsed = 0.0;
+ update_metar_properties( result.m );
+ update_env_config();
+ env->init();
+ found_metar = true;
+ } else {
+ // mark as no metar so it doesn't show up in subsequent
+ // searches.
+ SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = "
+ << a->getId() );
+ globals->get_airports()->no_metar( a->getId() );
+ }
}
}
metar_max_age->setLongValue(max_age);
// if time for a new search request, push it onto the request
// queue
if ( search_elapsed > search_interval_sec ) {
- FGAirport a = globals->get_airports()
- ->search( longitude->getDoubleValue(),
- latitude->getDoubleValue(),
- true );
- if ( last_apt.getId() != a.getId()
- || fetch_elapsed > same_station_interval_sec )
- {
- SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = " << a.getId());
- request_queue.push( a.getId() );
- last_apt = a;
- _icao = a.getId();
- search_elapsed = 0.0;
- fetch_elapsed = 0.0;
+ const FGAirport* a = globals->get_airports()
+ ->search( longitude->getDoubleValue(),
+ latitude->getDoubleValue(),
+ true );
+ if ( a ) {
+ if ( last_apt.getId() != a->getId()
+ || fetch_elapsed > same_station_interval_sec )
+ {
+ SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
+ << a->getId());
+ request_queue.push( a->getId() );
+ last_apt = *a;
+ _icao = a->getId();
+ search_elapsed = 0.0;
+ fetch_elapsed = 0.0;
+ } else {
+ search_elapsed = 0.0;
+ SG_LOG( SG_GENERAL, SG_INFO, "same station, waiting = "
+ << same_station_interval_sec - fetch_elapsed );
+ }
} else {
- search_elapsed = 0.0;
- SG_LOG( SG_GENERAL, SG_INFO, "same station, waiting = "
- << same_station_interval_sec - fetch_elapsed );
+ SG_LOG( SG_GENERAL, SG_WARN,
+ "Unable to find any airports with metar" );
}
}
}
// fetch station elevation if exists
- FGAirport a = globals->get_airports()->search( icao );
- station_elevation_ft = a.getElevation();
+ const FGAirport* a = globals->get_airports()->search( icao );
+ if ( a ) {
+ station_elevation_ft = a->getElevation();
+ }
// fetch current metar data
try {
if( station == "XXXX" )
station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0);
else {
- FGAirport a = globals->get_airports()->search( station );
- station_elevation_ft = a.getElevation();
+ const FGAirport* a = globals->get_airports()->search( station );
+ station_elevation_ft = (a ? a->getElevation() : 0.0);
}
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
_nAirports = _airports->size();
_content = new char *[_nAirports+1];
- for (int i = 0; i < _nAirports; i++) {
+ for (unsigned int i = 0; i < _nAirports; i++) {
const FGAirport *airport = _airports->getAirport(i);
snprintf(buf, 1023, "%s %s",
airport->getId().c_str(),
AirportList::~AirportList ()
{
- for (int i = 0; i < _nAirports; i++) {
+ for (unsigned int i = 0; i < _nAirports; i++) {
delete _content[i];
_content[i] = 0;
}
// If the get-nearest-airport-node is true.
// Get the nearest airport, and set it as waypoint 1.
if (_get_nearest_airport_node->getBoolValue()) {
- FGAirport a;
- //cout << "Airport found" << endl;
- a = globals->get_airports()->search(longitude_deg, latitude_deg, false);
- _wp1_ID_node->setStringValue(a.getId().c_str());
- wp1_longitude_deg = a.getLongitude();
- wp1_latitude_deg = a.getLatitude();
- _wp1_name_node->setStringValue(a.getName().c_str());
- _get_nearest_airport_node->setBoolValue(false);
- _last_wp1_ID = wp1_ID = a.getId().c_str();
+ const FGAirport* a = globals->get_airports()->search(longitude_deg, latitude_deg, false);
+ if(a) {
+ _wp1_ID_node->setStringValue(a->getId().c_str());
+ wp1_longitude_deg = a->getLongitude();
+ wp1_latitude_deg = a->getLatitude();
+ _wp1_name_node->setStringValue(a->getName().c_str());
+ _get_nearest_airport_node->setBoolValue(false);
+ _last_wp1_ID = wp1_ID = a->getId().c_str();
+ }
}
// If the waypoint 0 ID has changed, try to find the new ID
string waypont_type =
_wp0_waypoint_type_node->getStringValue();
if (waypont_type == "airport") {
- FGAirport a;
- a = globals->get_airports()->search( wp0_ID );
- if ( a.getId() == wp0_ID ) {
- //cout << "Airport found" << endl;
- wp0_longitude_deg = a.getLongitude();
- wp0_latitude_deg = a.getLatitude();
- _wp0_name_node->setStringValue(a.getName().c_str());
+ const FGAirport* a = globals->get_airports()->search( wp0_ID );
+ if ( a ) {
+ wp0_longitude_deg = a->getLongitude();
+ wp0_latitude_deg = a->getLatitude();
+ _wp0_name_node->setStringValue(a->getName().c_str());
}
}
else if (waypont_type == "nav") {
string waypont_type =
_wp1_waypoint_type_node->getStringValue();
if (waypont_type == "airport") {
- FGAirport a;
- a = globals->get_airports()->search( wp1_ID );
- if ( a.getId() == wp1_ID ) {
- //cout << "Airport found" << endl;
- wp1_longitude_deg = a.getLongitude();
- wp1_latitude_deg = a.getLatitude();
- _wp1_name_node->setStringValue(a.getName().c_str());
+ const FGAirport* a = globals->get_airports()->search( wp1_ID );
+ if ( a ) {
+ wp1_longitude_deg = a->getLongitude();
+ wp1_latitude_deg = a->getLatitude();
+ _wp1_name_node->setStringValue(a->getName().c_str());
}
}
else if (waypont_type == "nav") {
// find basic airport location info from airport database
bool fgFindAirportID( const string& id, FGAirport *a ) {
- FGAirport result;
+ const FGAirport* result;
if ( id.length() ) {
SG_LOG( SG_GENERAL, SG_INFO, "Searching for airport code = " << id );
result = globals->get_airports()->search( id );
- if ( result.getId().empty() ) {
+ if ( result == NULL ) {
SG_LOG( SG_GENERAL, SG_ALERT,
- "Failed to find " << id << " in basic.dat.gz" );
+ "Failed to find " << id << " in apt.dat.gz" );
return false;
}
} else {
return false;
}
- *a = result;
+ *a = *result;
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << " is ("
if ( fabs(r->get_elev_ft()) < 0.01 && r->get_apt_id().length() ) {
// cout << r->get_type() << " " << r->get_apt_id() << " zero elev"
// << endl;
- FGAirport a = airports->search( r->get_apt_id() );
- if ( a.getId() == r->get_apt_id() ) {
- r->set_elev_ft( a.getElevation() );
+ const FGAirport* a = airports->search( r->get_apt_id() );
+ if ( a ) {
+ r->set_elev_ft( a->getElevation() );
// cout << " setting to " << a.elevation << endl;
}
}
bool FGScheduledFlight::initializeAirports()
{
//cerr << "Initializing using : " << depId << " " << arrId << endl;
- departurePort = globals->get_airports()->search( depId, departurePort );
- if(departurePort->getId().empty())
+ departurePort = globals->get_airports()->search(depId);
+ if(departurePort == NULL)
{
cerr << "Could not find " << depId << endl;
return false;
}
- arrivalPort = globals->get_airports()->search(arrId, arrivalPort);
- if(arrivalPort->getId().empty())
+ arrivalPort = globals->get_airports()->search(arrId);
+ if(arrivalPort == NULL)
{
cerr << "Could not find " << arrId << endl;
return false;