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:
parent
301054204e
commit
a1426a812a
7 changed files with 82 additions and 80 deletions
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Reference in a new issue