]> git.mxchange.org Git - flightgear.git/blobdiff - src/Instrumentation/mk_viii.cxx
Merge branch 'maint2' into next
[flightgear.git] / src / Instrumentation / mk_viii.cxx
index 401af8a5bd968a907d52cd74f103f2547acda17c..50e1df1a75ec323c32597bd2166098ff9ccb593a 100755 (executable)
@@ -4230,29 +4230,15 @@ MK_VIII::Mode6Handler::update_altitude_callouts ()
 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;
 }
 
@@ -4260,21 +4246,22 @@ bool
 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
@@ -4287,20 +4274,19 @@ MK_VIII::Mode6Handler::update_runway ()
   }
 
   // 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
@@ -4479,9 +4465,9 @@ MK_VIII::TCFHandler::get_azimuth_difference (const FGRunway *_runway)
 {
   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,
@@ -4493,52 +4479,34 @@ MK_VIII::TCFHandler::get_azimuth_difference (const FGRunway *_runway)
 // 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 ()
 {
@@ -4548,28 +4516,27 @@ 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
@@ -4579,8 +4546,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;
 
@@ -4604,7 +4571,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,