diff --git a/src/ATC/ATCutils.cxx b/src/ATC/ATCutils.cxx index b209a57ff..14442917e 100644 --- a/src/ATC/ATCutils.cxx +++ b/src/ATC/ATCutils.cxx @@ -292,22 +292,22 @@ double GetAngleDiff_deg( const double &a1, const double &a2) { // 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 (" diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index f0ab3afab..4ea968d73 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -243,10 +243,8 @@ bool fgAirportDBLoad( FGAirportList *airports, FGRunwayList *runways, 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 ); } } diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 1964ce667..4a9a8837c 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -1170,19 +1170,21 @@ FGAirportList::FGAirportList() 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); @@ -1194,52 +1196,63 @@ void FGAirportList::add( const string id, const double longitude, 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 ) { @@ -1254,23 +1267,23 @@ FGAirport FGAirportList::search( double lon_deg, double lat_deg, } } - 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); + } } @@ -1278,7 +1291,9 @@ const FGAirport *FGAirportList::getAirport( int index ) const * 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); + } } @@ -1286,5 +1301,7 @@ void FGAirportList::no_metar( const string &id ) { * 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); + } } diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index 9fe38fdbe..901cb06d1 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -236,16 +236,16 @@ typedef vector::const_iterator FGParkingVecConstIterator; 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; @@ -270,13 +270,15 @@ public: 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;}; @@ -295,7 +297,7 @@ public: 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; @@ -323,31 +325,33 @@ public: 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 diff --git a/src/Environment/environment_ctrl.cxx b/src/Environment/environment_ctrl.cxx index d41f50b9b..551df9aa5 100644 --- a/src/Environment/environment_ctrl.cxx +++ b/src/Environment/environment_ctrl.cxx @@ -402,26 +402,30 @@ FGMetarEnvironmentCtrl::init () 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); @@ -460,23 +464,29 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec) // 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" ); } } @@ -541,8 +551,10 @@ FGMetarEnvironmentCtrl::fetch_data( const string &icao ) } // 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 { diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index 9821a92b6..b00ee64a9 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -401,8 +401,8 @@ void FGClouds::buildScenario( string scenario ) { 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++) { diff --git a/src/GUI/AirportList.cxx b/src/GUI/AirportList.cxx index 16f9785d0..fd6a72da5 100644 --- a/src/GUI/AirportList.cxx +++ b/src/GUI/AirportList.cxx @@ -15,7 +15,7 @@ AirportList::AirportList (int x, int y, int width, int height) _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(), @@ -33,7 +33,7 @@ AirportList::AirportList (int x, int y, int width, int height) AirportList::~AirportList () { - for (int i = 0; i < _nAirports; i++) { + for (unsigned int i = 0; i < _nAirports; i++) { delete _content[i]; _content[i] = 0; } diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx index 26aad8dcf..53cd82ec9 100644 --- a/src/Instrumentation/gps.cxx +++ b/src/Instrumentation/gps.cxx @@ -340,15 +340,15 @@ GPS::update (double delta_time_sec) // 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 @@ -357,13 +357,11 @@ GPS::update (double delta_time_sec) 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") { @@ -396,13 +394,11 @@ GPS::update (double delta_time_sec) 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") { diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 66a0f327b..9fb7cee02 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -620,22 +620,22 @@ bool fgInitConfig ( int argc, char **argv ) { // 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 (" diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 22cac4f03..4c3347912 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -95,9 +95,9 @@ bool fgNavDBInit( FGAirportList *airports, 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; } } diff --git a/src/Traffic/SchedFlight.cxx b/src/Traffic/SchedFlight.cxx index e02f54f87..4a86c98c4 100644 --- a/src/Traffic/SchedFlight.cxx +++ b/src/Traffic/SchedFlight.cxx @@ -257,14 +257,14 @@ FGAirport * FGScheduledFlight::getArrivalAirport () 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;