bool
MK_VIII::Mode6Handler::test_runway (const FGRunway *_runway)
{
- if (_runway->_length < mk->conf.runway_database)
+ if (_runway->lengthFt() < mk->conf.runway_database)
return false;
- // get position of threshold
- double latitude, longitude, az;
- geo_direct_wgs_84(0,
- _runway->_lat,
- _runway->_lon,
- get_reciprocal_heading(_runway->_heading),
- _runway->_length / 2 * SG_FEET_TO_METER,
- &latitude,
- &longitude,
- &az);
-
+ SGGeod pos(
+ SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()));
+
// get distance to threshold
double distance, az1, az2;
- geo_inverse_wgs_84(0,
- mk_data(gps_latitude).get(),
- mk_data(gps_longitude).get(),
- latitude,
- longitude,
- &az1, &az2, &distance);
-
+ SGGeodesy::inverse(pos, _runway->threshold(), az1, az2, distance);
return distance * SG_METER_TO_NM <= 5;
}
MK_VIII::Mode6Handler::test_airport (const FGAirport *airport)
{
for (unsigned int r=0; r<airport->numRunways(); ++r) {
- FGRunway rwy(airport->getRunwayByIndex(r));
-
- if (test_runway(&rwy)) return true;
+ FGRunway* rwy(airport->getRunwayByIndex(r));
- // reciprocal runway
- rwy._heading = get_reciprocal_heading(rwy._heading);
- if (test_runway(&rwy)) return true;
+ if (test_runway(rwy)) return true;
}
return false;
}
-bool MK_VIII::Mode6Handler::AirportFilter::pass(FGAirport* a)
+bool MK_VIII::Mode6Handler::AirportFilter::pass(FGPositioned* a) const
{
- return self->test_airport(a);
+ if (a->type() != FGPositioned::AIRPORT) {
+ return false;
+ }
+
+ bool ok = self->test_airport(static_cast<FGAirport*>(a));
+ return ok;
}
void
}
// Search for the closest runway threshold in range 5
- // nm. Passing 0.5 degrees (approximatively 30 nm) to
+ // nm. Passing 30nm 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();
+ FGPositionedRef apt = FGPositioned::findClosest(
+ SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()),
+ 30.0, &filter);
+ if (apt) {
+ runway.elevation = apt->elevation();
}
- has_runway.set(airport != NULL);
+ has_runway.set(apt != NULL);
}
void
{
return get_azimuth_difference(mk_data(gps_latitude).get(),
mk_data(gps_longitude).get(),
- _runway->_lat,
- _runway->_lon,
- _runway->_heading);
+ _runway->latitude(),
+ _runway->longitude(),
+ _runway->headingDeg());
}
// Selects the most likely intended destination runway of @airport,
// This selection algorithm is not specified in [SPEC], but
// http://www.egpws.com/general_information/description/runway_select.htm
// talks about automatic runway selection.
-void
-MK_VIII::TCFHandler::select_runway (const FGAirport *airport,
- FGRunway *_runway)
+FGRunway*
+MK_VIII::TCFHandler::select_runway (const FGAirport *airport)
{
-/*
- FGRunway r;
- bool status = globals->get_runways()->search(airport->getId(), &r);
- assert(status);
-
- }
- while (globals->get_runways()->next(&r) && r._id == airport->getId());
- */
-
+ FGRunway* _runway = 0;
double min_diff = 360;
for (unsigned int r=0; r<airport->numRunways(); ++r) {
- FGRunway rwy(airport->getRunwayByIndex(r));
- double diff = get_azimuth_difference(&rwy);
+ FGRunway* rwy(airport->getRunwayByIndex(r));
+ double diff = get_azimuth_difference(rwy);
if (diff < min_diff)
{
min_diff = diff;
- *_runway = rwy;
- }
-
- // reciprocal runway
- rwy._heading = get_reciprocal_heading(rwy._heading);
- diff = get_azimuth_difference(&rwy);
- if (diff < min_diff)
- {
- min_diff = diff;
- *_runway = rwy;
+ _runway = rwy;
}
} // of airport runways iteration
+ return _runway;
}
-bool MK_VIII::TCFHandler::AirportFilter::pass(FGAirport *a)
+bool MK_VIII::TCFHandler::AirportFilter::pass(FGPositioned* aPos) const
{
- for (unsigned int r=0; r<a->numRunways(); ++r) {
- if (a->getRunwayByIndex(r)._length >= mk->conf.runway_database) {
- return true;
- }
+ if (aPos->type() != FGPositioned::AIRPORT) {
+ return false;
}
-
- return false;
+
+ FGAirport* apt = static_cast<FGAirport*>(aPos);
+ return apt->hasHardRunwayOfLengthFt(mk->conf.runway_database);
}
-
+
void
MK_VIII::TCFHandler::update_runway ()
{
}
// 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
+ // airport in range 15 nm. Passing 30nm 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;
+ FGAirport* apt = FGAirport::findClosest(
+ SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()),
+ 30.0, &filter);
+
+ if (!apt) return;
has_runway = true;
- FGRunway _runway;
- select_runway(airport, &_runway);
-
- runway.center.latitude = _runway._lat;
- runway.center.longitude = _runway._lon;
+ FGRunway* _runway = select_runway(apt);
+
+ runway.center.latitude = _runway->latitude();
+ runway.center.longitude = _runway->longitude();
- runway.elevation = airport->getElevation();
+ runway.elevation = apt->elevation();
- 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,