#include <simgear/sound/soundmgr_openal.hxx>
#include <simgear/structure/exception.hxx>
-SG_USING_STD(string);
+using std::string;
#include "Airports/runways.hxx"
#include "Airports/simple.hxx"
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 //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// [PILOT] page 20 specifies that the terrain clearance is equal to
// 75% of the radio altitude, averaged over the previous 15 seconds.
- deque< Sample<double> >::iterator iter;
+ samples_type::iterator iter;
// remove samples older than 15 seconds
for (iter = samples.begin(); iter != samples.end() && globals->get_sim_time_sec() - (*iter).timestamp >= 15; iter = samples.begin())
// Erase everything from the beginning of the list up to the sample
// preceding the most recent sample whose age is >= 1 second.
- deque< Sample< Parameter<double> > >::iterator erase_last = altitude_samples.begin();
- deque< Sample< Parameter<double> > >::iterator iter;
+ altitude_samples_type::iterator erase_last = altitude_samples.begin();
+ altitude_samples_type::iterator iter;
for (iter = altitude_samples.begin(); iter != altitude_samples.end(); iter++)
if (globals->get_sim_time_sec() - (*iter).timestamp >= 1)
bool
MK_VIII::Mode6Handler::test_airport (const FGAirport *airport)
{
- FGRunway r;
- if (globals->get_runways()->search(airport->getId(), &r))
- do
- {
- if (test_runway(&r))
- return true;
-
- // reciprocal runway
- r._heading = get_reciprocal_heading(r._heading);
- if (test_runway(&r))
- return true;
- }
- while (globals->get_runways()->next(&r) && r._id == airport->getId());
+ for (unsigned int r=0; r<airport->numRunways(); ++r) {
+ FGRunway* rwy(airport->getRunwayByIndex(r));
+
+ if (test_runway(rwy)) return true;
+ }
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();
-
- has_runway.set(airport != NULL);
- }
- else
- has_runway.unset();
+
+ if (mk_data(gps_latitude).ncd || mk_data(gps_longitude).ncd) {
+ has_runway.unset();
+ return;
+ }
+
+ // 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
MK_VIII::TCFHandler::select_runway (const FGAirport *airport,
FGRunway *_runway)
{
- FGRunway r;
- bool status = globals->get_runways()->search(airport->getId(), &r);
- assert(status);
-
double min_diff = 360;
- do
- {
- double diff;
-
- diff = get_azimuth_difference(&r);
- if (diff < min_diff)
- {
- min_diff = diff;
- *_runway = r;
- }
-
- // reciprocal runway
- r._heading = get_reciprocal_heading(r._heading);
- diff = get_azimuth_difference(&r);
- if (diff < min_diff)
- {
- min_diff = diff;
- *_runway = r;
- }
+
+ for (unsigned int r=0; r<airport->numRunways(); ++r) {
+ FGRunway* rwy(airport->getRunwayByIndex(r));
+ double diff = get_azimuth_difference(rwy);
+ if (diff < min_diff)
+ {
+ min_diff = diff;
+ _runway = rwy;
}
- while (globals->get_runways()->next(&r) && r._id == airport->getId());
+ } // of airport runways iteration
}
-bool
-MK_VIII::TCFHandler::test_airport (const FGAirport *airport)
+bool MK_VIII::TCFHandler::AirportFilter::pass(FGAirport *a)
{
- FGRunway r;
- if (globals->get_runways()->search(airport->getId(), &r))
- do
- {
- if (r._length >= mk->conf.runway_database)
- return true;
- }
- while (globals->get_runways()->next(&r) && r._id == airport->getId());
-
+ for (unsigned int r=0; r<a->numRunways(); ++r) {
+ if (a->getRunwayByIndex(r)->lengthFt() >= 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 (airport)
- {
+ 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.
+ 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;
- select_runway(airport, &_runway);
+ FGRunway* _runway;
+ select_runway(airport, _runway);
- runway.center.latitude = _runway._lat;
- runway.center.longitude = _runway._lon;
+ runway.center.latitude = _runway->latitude();
+ runway.center.longitude = _runway->longitude();
runway.elevation = airport->getElevation();
- double half_length_m = _runway._length / 2 * SG_FEET_TO_METER;
+ double half_length_m = _runway->lengthM() * 0.5;
runway.half_length = half_length_m * SG_METER_TO_NM;
// b3 ________________ b0
// b2 b1
// get heading to runway threshold (h0) and end (h1)
- runway.edges[0].heading = _runway._heading;
- runway.edges[1].heading = get_reciprocal_heading(_runway._heading);
+ runway.edges[0].heading = _runway->headingDeg();
+ runway.edges[1].heading = get_reciprocal_heading(_runway->headingDeg());
double az;
&runway.edges[1].position.longitude,
&az);
- double half_width_m = _runway._width / 2 * SG_FEET_TO_METER;
+ double half_width_m = _runway->widthM() * 0.5;
// get position of threshold bias area edges (b0 and b1)
get_bias_area_edges(&runway.edges[0].position,
half_width_m,
&runway.bias_area[2],
&runway.bias_area[3]);
- }
- }
}
void