]> git.mxchange.org Git - flightgear.git/blobdiff - src/Instrumentation/mk_viii.cxx
James Turner:
[flightgear.git] / src / Instrumentation / mk_viii.cxx
index fc34f0b792ed98c11b50348c13387b6a79142020..1deabde7c5ccd1f385a014c742c6a946bfa6f534 100755 (executable)
@@ -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 //////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
@@ -4288,47 +4259,44 @@ MK_VIII::Mode6Handler::test_runway (const FGRunway *_runway)
 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
@@ -4525,46 +4493,27 @@ 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;
 }
 
@@ -4572,33 +4521,33 @@ 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.
-
-      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
@@ -4608,8 +4557,8 @@ MK_VIII::TCFHandler::update_runway ()
          //        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;
 
@@ -4633,7 +4582,7 @@ MK_VIII::TCFHandler::update_runway ()
                            &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,
@@ -4648,8 +4597,6 @@ MK_VIII::TCFHandler::update_runway ()
                              half_width_m,
                              &runway.bias_area[2],
                              &runway.bias_area[3]);
-       }
-    }
 }
 
 void