1
0
Fork 0

James Turner:

Switches the MkVIII code to use the same 'closest airport' logic as everything
else, instead of its own special version.
This commit is contained in:
ehofman 2008-08-15 18:48:11 +00:00
parent 301054204e
commit a1426a812a
7 changed files with 82 additions and 80 deletions

View file

@ -340,19 +340,20 @@ const FGAirport* FGAirportList::findFirstById( const string& id, bool exact )
// search for the airport nearest the specified position // 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, double max_range)
{ {
static FGAirportSearchFilter accept_any; static FGAirportSearchFilter accept_any;
return search(lon_deg, lat_deg, accept_any); return search(lon_deg, lat_deg, max_range, accept_any);
} }
// search for the airport nearest the specified position and // search for the airport nearest the specified position and
// passing the filter // passing the filter
FGAirport* FGAirportList::search(double lon_deg, double lat_deg, FGAirport* FGAirportList::search(double lon_deg, double lat_deg,
double max_range,
FGAirportSearchFilter& filter) FGAirportSearchFilter& filter)
{ {
double min_dist = 360.0; double min_dist = max_range;
airport_list_iterator it = airports_array.begin(); airport_list_iterator it = airports_array.begin();
airport_list_iterator end = airports_array.end(); airport_list_iterator end = airports_array.end();
airport_list_iterator closest = end; airport_list_iterator closest = end;

View file

@ -162,8 +162,9 @@ public:
// (currently a linear inefficient search so it's probably not // (currently a linear inefficient search so it's probably not
// best to use this at runtime.) An FGAirportSearchFilter class // best to use this at runtime.) An FGAirportSearchFilter class
// can be used to restrict the possible choices to a subtype. // can be used to restrict the possible choices to a subtype.
FGAirport* search( double lon_deg, double lat_deg ); // max_range limits search - specified as an arc distance, in degrees
FGAirport* search( double lon_deg, double lat_deg, FGAirportSearchFilter& ); FGAirport* search( double lon_deg, double lat_deg, double max_range );
FGAirport* search( double lon_deg, double lat_deg, double max_range, FGAirportSearchFilter& );
/** /**
* Return the number of airports in the list. * Return the number of airports in the list.

View file

@ -652,6 +652,7 @@ FGMetarEnvironmentCtrl::init ()
const FGAirport* a = globals->get_airports() const FGAirport* a = globals->get_airports()
->search( longitude->getDoubleValue(), ->search( longitude->getDoubleValue(),
latitude->getDoubleValue(), latitude->getDoubleValue(),
360.0,
metar_only ); metar_only );
if ( a ) { if ( a ) {
FGMetarResult result = fetch_data( a->getId() ); FGMetarResult result = fetch_data( a->getId() );
@ -715,6 +716,7 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
const FGAirport* a = globals->get_airports() const FGAirport* a = globals->get_airports()
->search( longitude->getDoubleValue(), ->search( longitude->getDoubleValue(),
latitude->getDoubleValue(), latitude->getDoubleValue(),
360.0,
metar_only ); metar_only );
if ( a ) { if ( a ) {
if ( !last_apt || last_apt->getId() != a->getId() if ( !last_apt || last_apt->getId() != a->getId()

View file

@ -313,7 +313,7 @@ GPS::update (double delta_time_sec)
// If the get-nearest-airport-node is true. // If the get-nearest-airport-node is true.
// Get the nearest airport, and set it as waypoint 1. // Get the nearest airport, and set it as waypoint 1.
if (_get_nearest_airport_node->getBoolValue()) { if (_get_nearest_airport_node->getBoolValue()) {
const FGAirport* a = globals->get_airports()->search(longitude_deg, latitude_deg); const FGAirport* a = globals->get_airports()->search(longitude_deg, latitude_deg, 360.0);
if(a) { if(a) {
_wp1_ID_node->setStringValue(a->getId().c_str()); _wp1_ID_node->setStringValue(a->getId().c_str());
wp1_longitude_deg = a->getLongitude(); wp1_longitude_deg = a->getLongitude();

View file

@ -168,35 +168,6 @@ get_reciprocal_heading (double h)
return heading_add(h, 180); return heading_add(h, 180);
} }
// Searches for the closest airport whose Manhattan distance to
// @lat,@lon is inferior to @min_manhattan_distance (expressed in
// degrees) and for which @test_airport returns true. Returns NULL if
// no airport was found.
template <class C>
static const FGAirport *
get_closest_airport (double lat,
double lon,
double min_manhattan_distance,
C &obj,
bool (C::*test_airport) (const FGAirport *))
{
const FGAirport *airport = NULL;
const airport_list *airport_list = globals->get_airports()->getAirportList();
for (size_t i = 0; i < airport_list->size(); i++)
{
const FGAirport *a = (*airport_list)[i];
double dist = fabs(lat - a->getLatitude()) + fabs(lon - a->getLongitude());
if (dist < min_manhattan_distance && (obj.*test_airport)(a))
{
airport = a;
min_manhattan_distance = dist;
}
}
return airport;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// PropertiesHandler ////////////////////////////////////////////////////////// // PropertiesHandler //////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -4301,30 +4272,35 @@ MK_VIII::Mode6Handler::test_airport (const FGAirport *airport)
return false; return false;
} }
bool MK_VIII::Mode6Handler::AirportFilter::pass(FGAirport* a)
{
return self->test_airport(a);
}
void void
MK_VIII::Mode6Handler::update_runway () MK_VIII::Mode6Handler::update_runway ()
{ {
if (! mk_data(gps_latitude).ncd && ! mk_data(gps_longitude).ncd)
{ if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
// Search for the closest runway threshold in range 5 has_runway.unset();
// nm. Passing 0.5 degrees (approximatively 30 nm) to return;
// get_closest_airport() provides enough margin for large }
// airports, which may have a runway located far away from the
// airport's reference point.
const FGAirport *airport = get_closest_airport(mk_data(gps_latitude).get(), // Search for the closest runway threshold in range 5
mk_data(gps_longitude).get(), // nm. Passing 0.5 degrees (approximatively 30 nm) to
0.5, // get_closest_airport() provides enough margin for large
*this, // airports, which may have a runway located far away from the
&MK_VIII::Mode6Handler::test_airport); // airport's reference point.
AirportFilter filter(this);
const FGAirport *airport = globals->get_airports()->search(
mk_data(gps_latitude).get(), mk_data(gps_longitude).get(),
0.5, filter);
if (airport) if (airport) {
runway.elevation = airport->getElevation(); runway.elevation = airport->getElevation();
}
has_runway.set(airport != NULL);
} has_runway.set(airport != NULL);
else
has_runway.unset();
} }
void void
@ -4552,15 +4528,14 @@ MK_VIII::TCFHandler::select_runway (const FGAirport *airport,
} // of airport runways iteration } // of airport runways iteration
} }
bool bool MK_VIII::TCFHandler::AirportFilter::pass(FGAirport *a)
MK_VIII::TCFHandler::test_airport (const FGAirport *airport)
{ {
for (unsigned int r=0; r<airport->numRunways(); ++r) { for (unsigned int r=0; r<a->numRunways(); ++r) {
if (airport->getRunwayByIndex(r)._length >= mk->conf.runway_database) { if (a->getRunwayByIndex(r)._length >= mk->conf.runway_database) {
return true; return true;
} }
} }
return false; return false;
} }
@ -4568,22 +4543,22 @@ void
MK_VIII::TCFHandler::update_runway () MK_VIII::TCFHandler::update_runway ()
{ {
has_runway = false; has_runway = false;
if (! mk_data(gps_latitude).ncd && ! mk_data(gps_longitude).ncd) if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
{ return;
// Search for the intended destination runway of the closest }
// airport in range 15 nm. Passing 0.5 degrees (approximatively
// 30 nm) to get_closest_airport() provides enough margin for
// large airports, which may have a runway located far away from
// the airport's reference point.
const FGAirport *airport = get_closest_airport(mk_data(gps_latitude).get(), // Search for the intended destination runway of the closest
mk_data(gps_longitude).get(), // airport in range 15 nm. Passing 0.5 degrees (approximatively
0.5, // 30 nm) to get_closest_airport() provides enough margin for
*this, // large airports, which may have a runway located far away from
&MK_VIII::TCFHandler::test_airport); // the airport's reference point.
AirportFilter filter(mk);
const FGAirport *airport = globals->get_airports()->search(
mk_data(gps_latitude).get(), mk_data(gps_longitude).get(),
0.5, filter);
if (airport) if (!airport) return;
{
has_runway = true; has_runway = true;
FGRunway _runway; FGRunway _runway;
@ -4644,8 +4619,6 @@ MK_VIII::TCFHandler::update_runway ()
half_width_m, half_width_m,
&runway.bias_area[2], &runway.bias_area[2],
&runway.bias_area[3]); &runway.bias_area[3]);
}
}
} }
void void

View file

@ -1504,6 +1504,18 @@ private:
bool is_high_bank_angle (); bool is_high_bank_angle ();
unsigned int get_bank_angle_alerts (); unsigned int get_bank_angle_alerts ();
void update_bank_angle (); void update_bank_angle ();
class AirportFilter : public FGAirportSearchFilter
{
public:
AirportFilter(Mode6Handler *s)
: self(s) {}
virtual bool pass(FGAirport *a);
private:
Mode6Handler* self;
};
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -1552,7 +1564,6 @@ private:
double get_azimuth_difference (const FGRunway *_runway); double get_azimuth_difference (const FGRunway *_runway);
void select_runway (const FGAirport *airport, FGRunway *_runway); void select_runway (const FGAirport *airport, FGRunway *_runway);
bool test_airport (const FGAirport *airport);
void update_runway (); void update_runway ();
void get_bias_area_edges (Position *edge, void get_bias_area_edges (Position *edge,
@ -1567,6 +1578,17 @@ private:
bool is_tcf (); bool is_tcf ();
bool is_rfcf (); bool is_rfcf ();
class AirportFilter : public FGAirportSearchFilter
{
public:
AirportFilter(MK_VIII *device)
: mk(device) {}
virtual bool pass(FGAirport *a);
private:
MK_VIII* mk;
};
public: public:
struct struct
{ {

View file

@ -532,13 +532,16 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
lat = latn->getDoubleValue(); lat = latn->getDoubleValue();
lon = lonn->getDoubleValue(); lon = lonn->getDoubleValue();
} }
double maxRange = 360.0; // expose this? or pick a smaller value?
if(argc == 0) { if(argc == 0) {
apt = aptlst->search(lon, lat, airport); apt = aptlst->search(lon, lat, maxRange, airport);
} else if(argc == 1 && naIsString(args[0])) { } else if(argc == 1 && naIsString(args[0])) {
const char *s = naStr_data(args[0]); const char *s = naStr_data(args[0]);
if(!strcmp(s, "airport")) apt = aptlst->search(lon, lat, airport); if(!strcmp(s, "airport")) apt = aptlst->search(lon, lat, maxRange, airport);
else if(!strcmp(s, "seaport")) apt = aptlst->search(lon, lat, seaport); else if(!strcmp(s, "seaport")) apt = aptlst->search(lon, lat, maxRange, seaport);
else if(!strcmp(s, "heliport")) apt = aptlst->search(lon, lat, heliport); else if(!strcmp(s, "heliport")) apt = aptlst->search(lon, lat, maxRange, heliport);
else apt = aptlst->search(s); else apt = aptlst->search(s);
} else { } else {
naRuntimeError(c, "airportinfo() with invalid function arguments"); naRuntimeError(c, "airportinfo() with invalid function arguments");