// 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;
// (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.
const FGAirport* a = globals->get_airports()
->search( longitude->getDoubleValue(),
latitude->getDoubleValue(),
+ 360.0,
metar_only );
if ( a ) {
FGMetarResult result = fetch_data( a->getId() );
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()
// 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();
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 //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
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.
-
- const FGAirport *airport = get_closest_airport(mk_data(gps_latitude).get(),
- mk_data(gps_longitude).get(),
- 0.5,
- *this,
- &MK_VIII::Mode6Handler::test_airport);
-
- if (airport)
- runway.elevation = airport->getElevation();
+
+ if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
+ has_runway.unset();
+ return;
+ }
- has_runway.set(airport != NULL);
- }
- else
- has_runway.unset();
+ // 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);
}
void
} // 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;
}
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.
-
- const FGAirport *airport = get_closest_airport(mk_data(gps_latitude).get(),
- mk_data(gps_longitude).get(),
- 0.5,
- *this,
- &MK_VIII::TCFHandler::test_airport);
+ if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
+ return;
+ }
- if (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) return;
+
has_runway = true;
FGRunway _runway;
half_width_m,
&runway.bias_area[2],
&runway.bias_area[3]);
- }
- }
}
void
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;
+ };
};
/////////////////////////////////////////////////////////////////////////////
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,
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
{
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");