Another clean-up iteration: FGAirportList::search is gone, replaced by two
static FGAirport helpers. As a result, another global index goes away. Use the helpers to avoid ugly FGPositioned down-casts in various places. Also converts the environment/METAR code to deal with FGAirport pointers, instead of string identifiers, and contains work-in-progress code to implement the AirportList dialog using FGPositioned. This isn't enabled yet for various reasons, but is the final piece to allow FGAirportList to be removed.
This commit is contained in:
parent
b2d4612beb
commit
660d59a098
10 changed files with 163 additions and 104 deletions
|
@ -289,8 +289,10 @@ bool fgAirportDBLoad( FGAirportList *airports,
|
||||||
if ( ident == "#" || ident == "//" ) {
|
if ( ident == "#" || ident == "//" ) {
|
||||||
metar_in >> skipeol;
|
metar_in >> skipeol;
|
||||||
} else {
|
} else {
|
||||||
const FGAirport* a = airports->search( ident );
|
FGAirport* apt = FGAirport::findByIdent(ident);
|
||||||
if ( a ) const_cast<FGAirport*>(a)->setMetar(true);
|
if (apt) {
|
||||||
|
apt->setMetar(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
using std::sort;
|
using std::sort;
|
||||||
using std::random_shuffle;
|
using std::random_shuffle;
|
||||||
|
|
||||||
|
// magic import of a helper which uses FGPositioned internals
|
||||||
|
extern char** searchAirportNamesAndIdents(const std::string& aFilter);
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* FGAirport
|
* FGAirport
|
||||||
|
@ -279,32 +279,41 @@ bool FGAirport::HardSurfaceFilter::pass(FGPositioned* aPos) const
|
||||||
return static_cast<FGAirport*>(aPos)->hasHardRunwayOfLengthFt(mMinLengthFt);
|
return static_cast<FGAirport*>(aPos)->hasHardRunwayOfLengthFt(mMinLengthFt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGAirport* FGAirport::findByIdent(const std::string& aIdent)
|
||||||
|
{
|
||||||
|
FGPositionedRef r;
|
||||||
|
AirportFilter filter;
|
||||||
|
r = FGPositioned::findNextWithPartialId(r, aIdent, &filter);
|
||||||
|
if (!r) {
|
||||||
|
return NULL; // we don't warn here, let the caller do that
|
||||||
|
}
|
||||||
|
return static_cast<FGAirport*>(r.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
FGAirport* FGAirport::getByIdent(const std::string& aIdent)
|
||||||
|
{
|
||||||
|
FGPositionedRef r;
|
||||||
|
AirportFilter filter;
|
||||||
|
r = FGPositioned::findNextWithPartialId(r, aIdent, &filter);
|
||||||
|
if (!r) {
|
||||||
|
throw sg_range_exception("No such airport with ident: " + aIdent);
|
||||||
|
}
|
||||||
|
return static_cast<FGAirport*>(r.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
char** FGAirport::searchNamesAndIdents(const std::string& aFilter)
|
||||||
|
{
|
||||||
|
// we delegate all the work to a horrible helper in FGPositioned, which can
|
||||||
|
// access the (private) index data.
|
||||||
|
return searchAirportNamesAndIdents(aFilter);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FGAirportList
|
* FGAirportList
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
// Populates a list of subdirectories of $FG_ROOT/Airports/AI so that
|
|
||||||
// the add() method doesn't have to try opening 2 XML files in each of
|
|
||||||
// thousands of non-existent directories. FIXME: should probably add
|
|
||||||
// code to free this list after parsing of apt.dat is finished;
|
|
||||||
// non-issue at the moment, however, as there are no AI subdirectories
|
|
||||||
// in the base package.
|
|
||||||
//
|
|
||||||
// Note: 2005/12/23: This is probably not necessary anymore, because I'm
|
|
||||||
// Switching to runtime airport dynamics loading (DT).
|
|
||||||
FGAirportList::FGAirportList()
|
FGAirportList::FGAirportList()
|
||||||
{
|
{
|
||||||
// ulDir* d;
|
|
||||||
// ulDirEnt* dent;
|
|
||||||
// SGPath aid( globals->get_fg_root() );
|
|
||||||
// aid.append( "/Airports/AI" );
|
|
||||||
// if((d = ulOpenDir(aid.c_str())) == NULL)
|
|
||||||
// return;
|
|
||||||
// while((dent = ulReadDir(d)) != NULL) {
|
|
||||||
// SG_LOG( SG_GENERAL, SG_DEBUG, "Dent: " << dent->d_name );
|
|
||||||
// ai_dirs.insert(dent->d_name);
|
|
||||||
// }
|
|
||||||
// ulCloseDir(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -321,20 +330,11 @@ FGAirport* FGAirportList::add( const string &id, const SGGeod& location, const S
|
||||||
const string &name, bool has_metar, FGPositioned::Type aType)
|
const string &name, bool has_metar, FGPositioned::Type aType)
|
||||||
{
|
{
|
||||||
FGAirport* a = new FGAirport(id, location, tower_location, name, has_metar, aType);
|
FGAirport* a = new FGAirport(id, location, tower_location, name, has_metar, aType);
|
||||||
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 );
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// search for the specified 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
FGAirportList::size () const
|
FGAirportList::size () const
|
||||||
{
|
{
|
||||||
|
@ -354,26 +354,11 @@ const FGAirport *FGAirportList::getAirport( unsigned int index ) const
|
||||||
// find basic airport location info from airport database
|
// find basic airport location info from airport database
|
||||||
const FGAirport *fgFindAirportID( const string& id)
|
const FGAirport *fgFindAirportID( const string& id)
|
||||||
{
|
{
|
||||||
const FGAirport* result = NULL;
|
if ( id.empty() ) {
|
||||||
if ( id.length() ) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_BULK, "Searching for airport code = " << id );
|
|
||||||
|
|
||||||
result = globals->get_airports()->search( id );
|
|
||||||
|
|
||||||
if ( result == NULL ) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
||||||
"Failed to find " << id << " in apt.dat.gz" );
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
SG_LOG( SG_GENERAL, SG_BULK,
|
|
||||||
"Position for " << id << " is ("
|
|
||||||
<< result->getLongitude() << ", "
|
|
||||||
<< result->getLatitude() << ")" );
|
|
||||||
|
|
||||||
return result;
|
return FGAirport::findByIdent(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Navaids/positioned.hxx"
|
#include "Navaids/positioned.hxx"
|
||||||
|
@ -123,6 +122,26 @@ public:
|
||||||
* passes all airports, including seaports and heliports.
|
* passes all airports, including seaports and heliports.
|
||||||
*/
|
*/
|
||||||
static FGAirport* findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL);
|
static FGAirport* findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to look up an FGAirport instance by unique ident. Throws an
|
||||||
|
* exception if the airport could not be found - so callers can assume
|
||||||
|
* the result is non-NULL.
|
||||||
|
*/
|
||||||
|
static FGAirport* getByIdent(const std::string& aIdent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to look up an FGAirport instance by unique ident. Returns NULL
|
||||||
|
* if the airport could not be found.
|
||||||
|
*/
|
||||||
|
static FGAirport* findByIdent(const std::string& aIdent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialised helper to implement the AirportList dialog. Performs a
|
||||||
|
* case-insensitive search on airport names and ICAO codes, and returns
|
||||||
|
* matches in a format suitable for use by a puaList.
|
||||||
|
*/
|
||||||
|
static char** searchNamesAndIdents(const std::string& aFilter);
|
||||||
private:
|
private:
|
||||||
typedef std::vector<FGRunwayPtr>::const_iterator Runway_iterator;
|
typedef std::vector<FGRunwayPtr>::const_iterator Runway_iterator;
|
||||||
/**
|
/**
|
||||||
|
@ -137,10 +156,6 @@ private:
|
||||||
std::vector<FGRunwayPtr> mTaxiways;
|
std::vector<FGRunwayPtr> mTaxiways;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map < std::string, FGAirport* > airport_map;
|
|
||||||
typedef airport_map::iterator airport_map_iterator;
|
|
||||||
typedef airport_map::const_iterator const_airport_map_iterator;
|
|
||||||
|
|
||||||
typedef std::vector < FGAirport * > airport_list;
|
typedef std::vector < FGAirport * > airport_list;
|
||||||
typedef airport_list::iterator airport_list_iterator;
|
typedef airport_list::iterator airport_list_iterator;
|
||||||
typedef airport_list::const_iterator const_airport_list_iterator;
|
typedef airport_list::const_iterator const_airport_list_iterator;
|
||||||
|
@ -150,7 +165,6 @@ typedef airport_list::const_iterator const_airport_list_iterator;
|
||||||
class FGAirportList {
|
class FGAirportList {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
airport_map airports_by_id;
|
|
||||||
airport_list airports_array;
|
airport_list airports_array;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -164,10 +178,6 @@ public:
|
||||||
FGAirport* add( const std::string& id, const SGGeod& location, const SGGeod& tower,
|
FGAirport* add( const std::string& id, const SGGeod& location, const SGGeod& tower,
|
||||||
const std::string& name, bool has_metar, FGPositioned::Type aType);
|
const std::string& name, bool has_metar, FGPositioned::Type aType);
|
||||||
|
|
||||||
// search for the specified id.
|
|
||||||
// Returns NULL if unsucessfull.
|
|
||||||
FGAirport* search( const std::string& id );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of airports in the list.
|
* Return the number of airports in the list.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -336,7 +336,6 @@ FGInterpolateEnvironmentCtrl::bucket::lessThan(bucket *a, bucket *b)
|
||||||
|
|
||||||
FGMetarEnvironmentCtrl::FGMetarEnvironmentCtrl ()
|
FGMetarEnvironmentCtrl::FGMetarEnvironmentCtrl ()
|
||||||
: env( new FGInterpolateEnvironmentCtrl ),
|
: env( new FGInterpolateEnvironmentCtrl ),
|
||||||
_icao( "" ),
|
|
||||||
metar_loaded( false ),
|
metar_loaded( false ),
|
||||||
search_interval_sec( 60.0 ), // 1 minute
|
search_interval_sec( 60.0 ), // 1 minute
|
||||||
same_station_interval_sec( 900.0 ), // 15 minutes
|
same_station_interval_sec( 900.0 ), // 15 minutes
|
||||||
|
@ -667,17 +666,16 @@ FGMetarEnvironmentCtrl::init ()
|
||||||
|
|
||||||
while ( !found_metar && (_error_count < 3) ) {
|
while ( !found_metar && (_error_count < 3) ) {
|
||||||
AirportWithMetar filter;
|
AirportWithMetar filter;
|
||||||
FGPositionedRef a = FGPositioned::findClosest(pos, 10000.0, &filter);
|
FGAirport* a = FGAirport::findClosest(pos, 10000.0, &filter);
|
||||||
if (!a) {
|
if (!a) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGMetarResult result = fetch_data(a->ident());
|
FGMetarResult result = fetch_data(a);
|
||||||
if ( result.m != NULL ) {
|
if ( result.m != NULL ) {
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
|
SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
|
||||||
<< a->ident());
|
<< a->ident());
|
||||||
last_apt = a;
|
last_apt = a;
|
||||||
_icao = a->ident();
|
|
||||||
search_elapsed = 0.0;
|
search_elapsed = 0.0;
|
||||||
fetch_elapsed = 0.0;
|
fetch_elapsed = 0.0;
|
||||||
update_metar_properties( result.m );
|
update_metar_properties( result.m );
|
||||||
|
@ -688,7 +686,7 @@ FGMetarEnvironmentCtrl::init ()
|
||||||
// mark as no metar so it doesn't show up in subsequent
|
// mark as no metar so it doesn't show up in subsequent
|
||||||
// searches.
|
// searches.
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = " << a->ident() );
|
SG_LOG( SG_GENERAL, SG_INFO, "no metar at metar = " << a->ident() );
|
||||||
static_cast<FGAirport*>(a.ptr())->setMetar(false);
|
a->setMetar(false);
|
||||||
}
|
}
|
||||||
} // of airprot-with-metar search iteration
|
} // of airprot-with-metar search iteration
|
||||||
|
|
||||||
|
@ -729,16 +727,15 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
|
||||||
// queue
|
// queue
|
||||||
if ( search_elapsed > search_interval_sec ) {
|
if ( search_elapsed > search_interval_sec ) {
|
||||||
AirportWithMetar filter;
|
AirportWithMetar filter;
|
||||||
FGPositionedRef a = FGPositioned::findClosest(pos, 10000.0, &filter);
|
FGAirport* a = FGAirport::findClosest(pos, 10000.0, &filter);
|
||||||
if (a) {
|
if (a) {
|
||||||
if ( !last_apt || last_apt->ident() != a->ident()
|
if ( !last_apt || last_apt->ident() != a->ident()
|
||||||
|| fetch_elapsed > same_station_interval_sec )
|
|| fetch_elapsed > same_station_interval_sec )
|
||||||
{
|
{
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
|
SG_LOG( SG_GENERAL, SG_INFO, "closest station w/ metar = "
|
||||||
<< a->ident());
|
<< a->ident());
|
||||||
request_queue.push( a->ident() );
|
request_queue.push(a);
|
||||||
last_apt = a;
|
last_apt = a;
|
||||||
_icao = a->ident();
|
|
||||||
search_elapsed = 0.0;
|
search_elapsed = 0.0;
|
||||||
fetch_elapsed = 0.0;
|
fetch_elapsed = 0.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -760,15 +757,15 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
|
||||||
|
|
||||||
#if !defined(ENABLE_THREADS)
|
#if !defined(ENABLE_THREADS)
|
||||||
// No loader thread running so manually fetch the data
|
// No loader thread running so manually fetch the data
|
||||||
string id = "";
|
FGAirport* apt = NULL;
|
||||||
while ( !request_queue.empty() ) {
|
while ( !request_queue.empty() ) {
|
||||||
id = request_queue.front();
|
apt = request_queue.front();
|
||||||
request_queue.pop();
|
request_queue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !id.empty() ) {
|
if (apt) {
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "inline fetching = " << id );
|
SG_LOG( SG_GENERAL, SG_INFO, "inline fetching = " << apt->ident() );
|
||||||
result = fetch_data( id );
|
result = fetch_data( apt );
|
||||||
result_queue.push( result );
|
result_queue.push( result );
|
||||||
}
|
}
|
||||||
#endif // ENABLE_THREADS
|
#endif // ENABLE_THREADS
|
||||||
|
@ -786,9 +783,8 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
|
||||||
// mark as no metar so it doesn't show up in subsequent
|
// mark as no metar so it doesn't show up in subsequent
|
||||||
// searches, and signal an immediate re-search.
|
// searches, and signal an immediate re-search.
|
||||||
SG_LOG( SG_GENERAL, SG_WARN,
|
SG_LOG( SG_GENERAL, SG_WARN,
|
||||||
"no metar at station = " << result.icao );
|
"no metar at station = " << result.airport->ident() );
|
||||||
const FGAirport* apt = globals->get_airports()->search(result.icao);
|
result.airport->setMetar(false);
|
||||||
const_cast<FGAirport*>(apt)->setMetar(false);
|
|
||||||
search_elapsed = 9999.0;
|
search_elapsed = 9999.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,10 +800,10 @@ FGMetarEnvironmentCtrl::setEnvironment (FGEnvironment * environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
FGMetarResult
|
FGMetarResult
|
||||||
FGMetarEnvironmentCtrl::fetch_data( const string &icao )
|
FGMetarEnvironmentCtrl::fetch_data(FGAirport* apt)
|
||||||
{
|
{
|
||||||
FGMetarResult result;
|
FGMetarResult result;
|
||||||
result.icao = icao;
|
result.airport = apt;
|
||||||
|
|
||||||
// if the last error was more than three seconds ago,
|
// if the last error was more than three seconds ago,
|
||||||
// then pretent nothing happened.
|
// then pretent nothing happened.
|
||||||
|
@ -819,18 +815,14 @@ FGMetarEnvironmentCtrl::fetch_data( const string &icao )
|
||||||
_error_count = 0;
|
_error_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch station elevation if exists
|
station_elevation_ft = apt->getElevation();
|
||||||
const FGAirport* a = globals->get_airports()->search( icao );
|
|
||||||
if ( a ) {
|
|
||||||
station_elevation_ft = a->getElevation();
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch current metar data
|
// fetch current metar data
|
||||||
try {
|
try {
|
||||||
string host = proxy_host->getStringValue();
|
string host = proxy_host->getStringValue();
|
||||||
string auth = proxy_auth->getStringValue();
|
string auth = proxy_auth->getStringValue();
|
||||||
string port = proxy_port->getStringValue();
|
string port = proxy_port->getStringValue();
|
||||||
result.m = new FGMetar( icao, host, port, auth);
|
result.m = new FGMetar( apt->ident(), host, port, auth);
|
||||||
|
|
||||||
long max_age = metar_max_age->getLongValue();
|
long max_age = metar_max_age->getLongValue();
|
||||||
long age = result.m->getAge_min();
|
long age = result.m->getAge_min();
|
||||||
|
|
|
@ -137,7 +137,7 @@ private:
|
||||||
|
|
||||||
// A convenience wrapper around FGMetar
|
// A convenience wrapper around FGMetar
|
||||||
struct FGMetarResult {
|
struct FGMetarResult {
|
||||||
std::string icao;
|
FGAirport* airport;
|
||||||
FGMetar *m;
|
FGMetar *m;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -160,7 +160,6 @@ public:
|
||||||
private:
|
private:
|
||||||
FGInterpolateEnvironmentCtrl *env;
|
FGInterpolateEnvironmentCtrl *env;
|
||||||
|
|
||||||
std::string _icao;
|
|
||||||
bool metar_loaded;
|
bool metar_loaded;
|
||||||
float station_elevation_ft;
|
float station_elevation_ft;
|
||||||
float search_interval_sec;
|
float search_interval_sec;
|
||||||
|
@ -174,7 +173,7 @@ private:
|
||||||
SGPropertyNode_ptr proxy_auth;
|
SGPropertyNode_ptr proxy_auth;
|
||||||
SGPropertyNode_ptr metar_max_age;
|
SGPropertyNode_ptr metar_max_age;
|
||||||
|
|
||||||
FGMetarResult fetch_data( const string &icao );
|
FGMetarResult fetch_data(FGAirport* apt);
|
||||||
virtual void update_metar_properties( const FGMetar *m );
|
virtual void update_metar_properties( const FGMetar *m );
|
||||||
void update_env_config();
|
void update_env_config();
|
||||||
double interpolate_prop(const char * currentname, const char * requiredname, double dvalue);
|
double interpolate_prop(const char * currentname, const char * requiredname, double dvalue);
|
||||||
|
@ -200,7 +199,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* FIFO queue which holds a pointer to the fetched metar data.
|
* FIFO queue which holds a pointer to the fetched metar data.
|
||||||
*/
|
*/
|
||||||
SGBlockingQueue <std::string > request_queue;
|
SGBlockingQueue <FGAirport*> request_queue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIFO queue which holds a pointer to the fetched metar data.
|
* FIFO queue which holds a pointer to the fetched metar data.
|
||||||
|
@ -210,7 +209,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* FIFO queue which holds a pointer to the fetched metar data.
|
* FIFO queue which holds a pointer to the fetched metar data.
|
||||||
*/
|
*/
|
||||||
std::queue <std::string > request_queue;
|
std::queue <FGAirport*> request_queue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIFO queue which holds a pointer to the fetched metar data.
|
* FIFO queue which holds a pointer to the fetched metar data.
|
||||||
|
|
|
@ -464,7 +464,7 @@ void FGClouds::buildScenario( const string& scenario ) {
|
||||||
if( station == "XXXX" )
|
if( station == "XXXX" )
|
||||||
station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0);
|
station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0);
|
||||||
else {
|
else {
|
||||||
const FGAirport* a = globals->get_airports()->search( station );
|
const FGAirport* a = FGAirport::findByIdent(station);
|
||||||
station_elevation_ft = (a ? a->getElevation() : 0.0);
|
station_elevation_ft = (a ? a->getElevation() : 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4521,7 +4521,7 @@ MK_VIII::TCFHandler::update_runway ()
|
||||||
// large airports, which may have a runway located far away from
|
// large airports, which may have a runway located far away from
|
||||||
// the airport's reference point.
|
// the airport's reference point.
|
||||||
AirportFilter filter(mk);
|
AirportFilter filter(mk);
|
||||||
FGPositionedRef apt = FGPositioned::findClosest(
|
FGAirport* apt = FGAirport::findClosest(
|
||||||
SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()),
|
SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()),
|
||||||
30.0, &filter);
|
30.0, &filter);
|
||||||
|
|
||||||
|
@ -4529,7 +4529,7 @@ MK_VIII::TCFHandler::update_runway ()
|
||||||
|
|
||||||
has_runway = true;
|
has_runway = true;
|
||||||
|
|
||||||
FGRunway* _runway = select_runway(static_cast<FGAirport*>(apt.ptr()));
|
FGRunway* _runway = select_runway(apt);
|
||||||
|
|
||||||
runway.center.latitude = _runway->latitude();
|
runway.center.latitude = _runway->latitude();
|
||||||
runway.center.longitude = _runway->longitude();
|
runway.center.longitude = _runway->longitude();
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm> // for sort
|
||||||
|
#include <locale> // for char-traits toupper
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -336,6 +337,78 @@ spatialGetClosest(const SGGeod& aPos, unsigned int aN, double aCutoffNm, FGPosit
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
|
||||||
|
* implement the AirportList dialog. It's unfortunate that it needs to reside
|
||||||
|
* here, but for now it's least ugly solution.
|
||||||
|
*/
|
||||||
|
char** searchAirportNamesAndIdents(const std::string& aFilter)
|
||||||
|
{
|
||||||
|
const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(std::locale());
|
||||||
|
std::string filter(aFilter);
|
||||||
|
if (!filter.empty()) {
|
||||||
|
ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
NamedPositionedIndex::const_iterator it = global_namedIndex.begin();
|
||||||
|
NamedPositionedIndex::const_iterator end = global_namedIndex.end();
|
||||||
|
|
||||||
|
FGPositioned::List matches;
|
||||||
|
if (aFilter.empty()) {
|
||||||
|
matches.reserve(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
FGPositioned::Type ty = it->second->type();
|
||||||
|
if ((ty < FGPositioned::AIRPORT) || (ty > FGPositioned::SEAPORT)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aFilter.empty()) {
|
||||||
|
matches.push_back(it->second);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((it->second->name().find(aFilter) == std::string::npos) &&
|
||||||
|
(it->second->ident().find(aFilter) == std::string::npos)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
matches.push_back(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert results to format comptible with puaList
|
||||||
|
unsigned int numMatches = matches.size();
|
||||||
|
char** result = new char*[numMatches + 1];
|
||||||
|
result[numMatches] = NULL; // end-of-list marker
|
||||||
|
|
||||||
|
// nasty code to avoid excessive string copying and allocations.
|
||||||
|
// We format results as follows (note whitespace!):
|
||||||
|
// ' name-of-airport-chars (icao)'
|
||||||
|
// so the total length is:
|
||||||
|
// 1 + strlen(name) + 4 + 4 (for the ICAO) + 1 + 1 (for the null)
|
||||||
|
// which gives a grand total of 11 + the length of the name.
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<numMatches; ++i) {
|
||||||
|
int nameLength = matches[i]->name().size();
|
||||||
|
char* entry = new char[nameLength + 11];
|
||||||
|
entry[0] = ' ';
|
||||||
|
memcpy(entry + 1, matches[i]->name().c_str(), nameLength);
|
||||||
|
entry[nameLength + 1] = ' ';
|
||||||
|
entry[nameLength + 2] = ' ';
|
||||||
|
entry[nameLength + 3] = ' ';
|
||||||
|
entry[nameLength + 4] = '(';
|
||||||
|
memcpy(entry + nameLength + 5, matches[i]->ident().c_str(), 4);
|
||||||
|
entry[nameLength + 9] = ')';
|
||||||
|
entry[nameLength + 10] = 0;
|
||||||
|
result[i] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndexed) :
|
FGPositioned::FGPositioned(Type ty, const std::string& aIdent, const SGGeod& aPos, bool aIndexed) :
|
||||||
|
|
|
@ -524,7 +524,7 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
|
||||||
static SGConstPropertyNode_ptr latn = fgGetNode("/position/latitude-deg", true);
|
static SGConstPropertyNode_ptr latn = fgGetNode("/position/latitude-deg", true);
|
||||||
static SGConstPropertyNode_ptr lonn = fgGetNode("/position/longitude-deg", true);
|
static SGConstPropertyNode_ptr lonn = fgGetNode("/position/longitude-deg", true);
|
||||||
SGGeod pos;
|
SGGeod pos;
|
||||||
FGPositionedRef ref;
|
FGAirport* apt = NULL;
|
||||||
|
|
||||||
if(argc >= 2 && naIsNum(args[0]) && naIsNum(args[1])) {
|
if(argc >= 2 && naIsNum(args[0]) && naIsNum(args[1])) {
|
||||||
pos = SGGeod::fromDeg(args[1].num, args[0].num);
|
pos = SGGeod::fromDeg(args[1].num, args[0].num);
|
||||||
|
@ -547,8 +547,8 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
|
||||||
else if(!strcmp(s, "heliport")) filter.type = FGPositioned::HELIPORT;
|
else if(!strcmp(s, "heliport")) filter.type = FGPositioned::HELIPORT;
|
||||||
else {
|
else {
|
||||||
// user provided an <id>, hopefully
|
// user provided an <id>, hopefully
|
||||||
ref = globals->get_airports()->search(s);
|
apt = FGAirport::findByIdent(s);
|
||||||
if (!ref) {
|
if (!apt) {
|
||||||
naRuntimeError(c, "airportinfo() couldn't find airport:%s", s);
|
naRuntimeError(c, "airportinfo() couldn't find airport:%s", s);
|
||||||
return naNil();
|
return naNil();
|
||||||
}
|
}
|
||||||
|
@ -558,13 +558,11 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
|
||||||
return naNil();
|
return naNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ref) {
|
if (!apt) {
|
||||||
ref = FGPositioned::findClosest(pos, maxRange, &filter);
|
apt = FGAirport::findClosest(pos, maxRange, &filter);
|
||||||
|
if(!apt) return naNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ref) return naNil();
|
|
||||||
FGAirport *apt = static_cast<FGAirport*>(ref.ptr());
|
|
||||||
|
|
||||||
string id = apt->ident();
|
string id = apt->ident();
|
||||||
string name = apt->name();
|
string name = apt->name();
|
||||||
|
|
||||||
|
|
|
@ -271,13 +271,13 @@ FGAirport * FGScheduledFlight::getArrivalAirport ()
|
||||||
bool FGScheduledFlight::initializeAirports()
|
bool FGScheduledFlight::initializeAirports()
|
||||||
{
|
{
|
||||||
//cerr << "Initializing using : " << depId << " " << arrId << endl;
|
//cerr << "Initializing using : " << depId << " " << arrId << endl;
|
||||||
departurePort = globals->get_airports()->search(depId);
|
departurePort = FGAirport::findByIdent(depId);
|
||||||
if(departurePort == NULL)
|
if(departurePort == NULL)
|
||||||
{
|
{
|
||||||
SG_LOG( SG_GENERAL, SG_WARN, "Traffic manager could not find departure airport : " << depId);
|
SG_LOG( SG_GENERAL, SG_WARN, "Traffic manager could not find departure airport : " << depId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
arrivalPort = globals->get_airports()->search(arrId);
|
arrivalPort = FGAirport::findByIdent(arrId);
|
||||||
if(arrivalPort == NULL)
|
if(arrivalPort == NULL)
|
||||||
{
|
{
|
||||||
SG_LOG( SG_GENERAL, SG_WARN, "Traffic manager could not find arrival airport : " << arrId);
|
SG_LOG( SG_GENERAL, SG_WARN, "Traffic manager could not find arrival airport : " << arrId);
|
||||||
|
|
Loading…
Add table
Reference in a new issue