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
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;
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
// passing the filter
FGAirport* FGAirportList::search(double lon_deg, double lat_deg,
double max_range,
FGAirportSearchFilter& filter)
{
double min_dist = 360.0;
double min_dist = max_range;
airport_list_iterator it = airports_array.begin();
airport_list_iterator end = airports_array.end();
airport_list_iterator closest = end;

View file

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

View file

@ -652,6 +652,7 @@ FGMetarEnvironmentCtrl::init ()
const FGAirport* a = globals->get_airports()
->search( longitude->getDoubleValue(),
latitude->getDoubleValue(),
360.0,
metar_only );
if ( a ) {
FGMetarResult result = fetch_data( a->getId() );
@ -715,6 +716,7 @@ FGMetarEnvironmentCtrl::update(double delta_time_sec)
const FGAirport* a = globals->get_airports()
->search( longitude->getDoubleValue(),
latitude->getDoubleValue(),
360.0,
metar_only );
if ( a ) {
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.
// Get the nearest airport, and set it as waypoint 1.
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) {
_wp1_ID_node->setStringValue(a->getId().c_str());
wp1_longitude_deg = a->getLongitude();

View file

@ -168,35 +168,6 @@ get_reciprocal_heading (double h)
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 //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@ -4301,30 +4272,35 @@ MK_VIII::Mode6Handler::test_airport (const FGAirport *airport)
return false;
}
bool MK_VIII::Mode6Handler::AirportFilter::pass(FGAirport* a)
{
return self->test_airport(a);
}
void
MK_VIII::Mode6Handler::update_runway ()
{
if (! mk_data(gps_latitude).ncd && ! mk_data(gps_longitude).ncd)
{
// Search for the closest runway threshold in range 5
// 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.
if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
has_runway.unset();
return;
}
const FGAirport *airport = get_closest_airport(mk_data(gps_latitude).get(),
mk_data(gps_longitude).get(),
0.5,
*this,
&MK_VIII::Mode6Handler::test_airport);
// Search for the closest runway threshold in range 5
// 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.
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)
runway.elevation = airport->getElevation();
has_runway.set(airport != NULL);
}
else
has_runway.unset();
if (airport) {
runway.elevation = airport->getElevation();
}
has_runway.set(airport != NULL);
}
void
@ -4552,15 +4528,14 @@ MK_VIII::TCFHandler::select_runway (const FGAirport *airport,
} // of airport runways iteration
}
bool
MK_VIII::TCFHandler::test_airport (const FGAirport *airport)
bool MK_VIII::TCFHandler::AirportFilter::pass(FGAirport *a)
{
for (unsigned int r=0; r<airport->numRunways(); ++r) {
if (airport->getRunwayByIndex(r)._length >= mk->conf.runway_database) {
for (unsigned int r=0; r<a->numRunways(); ++r) {
if (a->getRunwayByIndex(r)._length >= mk->conf.runway_database) {
return true;
}
}
return false;
}
@ -4568,22 +4543,22 @@ void
MK_VIII::TCFHandler::update_runway ()
{
has_runway = false;
if (! mk_data(gps_latitude).ncd && ! mk_data(gps_longitude).ncd)
{
// 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.
if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
return;
}
const FGAirport *airport = get_closest_airport(mk_data(gps_latitude).get(),
mk_data(gps_longitude).get(),
0.5,
*this,
&MK_VIII::TCFHandler::test_airport);
// 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.
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;
FGRunway _runway;
@ -4644,8 +4619,6 @@ MK_VIII::TCFHandler::update_runway ()
half_width_m,
&runway.bias_area[2],
&runway.bias_area[3]);
}
}
}
void

View file

@ -1504,6 +1504,18 @@ private:
bool is_high_bank_angle ();
unsigned int get_bank_angle_alerts ();
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);
void select_runway (const FGAirport *airport, FGRunway *_runway);
bool test_airport (const FGAirport *airport);
void update_runway ();
void get_bias_area_edges (Position *edge,
@ -1567,6 +1578,17 @@ private:
bool is_tcf ();
bool is_rfcf ();
class AirportFilter : public FGAirportSearchFilter
{
public:
AirportFilter(MK_VIII *device)
: mk(device) {}
virtual bool pass(FGAirport *a);
private:
MK_VIII* mk;
};
public:
struct
{

View file

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