]> git.mxchange.org Git - flightgear.git/blobdiff - src/Navaids/procedure.cxx
Prepare and implement reinit methods for instruments
[flightgear.git] / src / Navaids / procedure.cxx
index 4080f0a75d99de5e031469e44ddda26ed98f1c4e..bb53a642929c8852d96f92ae861d1b4c268708d5 100644 (file)
@@ -19,6 +19,9 @@
 
 #include "procedure.hxx"
 
+#include <cassert>
+#include <algorithm> // for reverse_copy
+
 #include <simgear/structure/exception.hxx>
 
 #include <Navaids/waypoint.hxx>
@@ -27,14 +30,22 @@ using std::string;
 
 namespace flightgear
 {
+  
+static void markWaypoints(WayptVec& wps, WayptFlag f)
+{
+  for (unsigned int i=0; i<wps.size(); ++i) {
+    wps[i]->setFlag(f, true);
+  }
+}
 
 Procedure::Procedure(const string& aIdent) :
   _ident(aIdent)
 {
 }
 
-Approach::Approach(const string& aIdent) : 
-  Procedure(aIdent)
+Approach::Approach(const string& aIdent, ProcedureType ty) : 
+  Procedure(aIdent),
+  _type(ty)
 {
 
 }
@@ -44,22 +55,32 @@ void Approach::setRunway(FGRunwayRef aRwy)
   _runway = aRwy;
 }
 
+FGAirport* Approach::airport() const
+{
+  return _runway->airport();
+}
+
+RunwayVec Approach::runways() const
+{
+  RunwayVec r;
+  r.push_back(_runway);
+  return r;
+}
+  
 void Approach::setPrimaryAndMissed(const WayptVec& aPrimary, const WayptVec& aMissed)
 {
   _primary = aPrimary;
   _primary[0]->setFlag(WPT_IAF, true);
   _primary[_primary.size()-1]->setFlag(WPT_FAF, true);
+  markWaypoints(_primary, WPT_APPROACH);
   
   _missed = aMissed;
   
   if (!_missed.empty()) {
     // mark the first point as the published missed-approach point
     _missed[0]->setFlag(WPT_MAP, true);
-  
-    // mark all the points as being on the missed approach route
-    for (unsigned int i=0; i<_missed.size(); ++i) {
-      _missed[i]->setFlag(WPT_MISS, true);
-    }
+    markWaypoints(_missed, WPT_MISS);
+    markWaypoints(_missed, WPT_APPROACH);
   }
 }
 
@@ -67,68 +88,101 @@ void Approach::addTransition(Transition* aTrans)
 {
   WayptRef entry = aTrans->enroute();
   _transitions[entry] = aTrans;
+  aTrans->mark(WPT_APPROACH);
 }
 
 bool Approach::route(WayptRef aIAF, WayptVec& aWps)
 {
-  WptTransitionMap::iterator it;
-  bool haveTrans = false;
-  for (it = _transitions.begin(); it != _transitions.end(); ++it) {
-    Transition* t= it->second;
-    if (t->route(aIAF, aWps)) {
-    haveTrans = true;
-      break;
+  if (aIAF.valid()) {
+    WptTransitionMap::iterator it;
+    bool haveTrans = false;
+    for (it = _transitions.begin(); it != _transitions.end(); ++it) {
+      Transition* t= it->second;
+      if (t->enroute()->matches(aIAF)) {
+        t->route(aWps);
+        haveTrans = true;
+        break;
+      }
+    } // of transitions iteration
+    
+    if (!haveTrans) {
+      SG_LOG(SG_GENERAL, SG_INFO, "approach " << ident() << " has no transition " <<
+        "for IAF: " << aIAF->ident());
+      return false;
     }
-  } // of transitions iteration
-  
-  if (!haveTrans) {
-    SG_LOG(SG_GENERAL, SG_INFO, "approach " << ident() << " has no transition " <<
-      "for IAF: " << aIAF->ident());
-    return false;
   }
   
-  aWps.insert(aWps.end(), _primary.begin(), _primary.end());
-  aWps.push_back(new RunwayWaypt(_runway, NULL));
-  aWps.insert(aWps.end(), _missed.begin(), _missed.end());
-  return true;
+  return routeFromVectors(aWps);
 }
 
 bool Approach::routeFromVectors(WayptVec& aWps)
 {
   aWps.insert(aWps.end(), _primary.begin(), _primary.end());
-  aWps.push_back(new RunwayWaypt(_runway, NULL));
+  RunwayWaypt* rwy = new RunwayWaypt(_runway, NULL);
+  rwy->setFlag(WPT_APPROACH);
+  aWps.push_back(rwy);
   aWps.insert(aWps.end(), _missed.begin(), _missed.end());
   return true;
 }
 
+bool Approach::isApproach(ProcedureType ty)
+{
+  return (ty >= PROCEDURE_APPROACH_ILS) && (ty <= PROCEDURE_APPROACH_RNAV);
+}
+  
 //////////////////////////////////////////////////////////////////////////////
 
-ArrivalDeparture::ArrivalDeparture(const string& aIdent) :
-    Procedure(aIdent)
+ArrivalDeparture::ArrivalDeparture(const string& aIdent, FGAirport* apt) :
+  Procedure(aIdent),
+  _airport(apt)
 {
 }
 
 void ArrivalDeparture::addRunway(FGRunwayRef aWay)
 {
+  assert(aWay->airport() == _airport);
   _runways[aWay] = NULL;
 }
 
-bool ArrivalDeparture::isForRunway(FGRunwayRef aWay) const
+bool ArrivalDeparture::isForRunway(const FGRunway* aWay) const
 {
   // null runway always passes
   if (!aWay) {
     return true;
   }
   
-  return (_runways.count(aWay));
+  FGRunwayRef r(const_cast<FGRunway*>(aWay));
+  return (_runways.count(r));
 }
 
+RunwayVec ArrivalDeparture::runways() const
+{
+  RunwayVec r;
+  RunwayTransitionMap::const_iterator it = _runways.begin();
+  for (; it != _runways.end(); ++it) {
+    r.push_back(it->first);
+  }
+  
+  return r;
+}
+    
 void ArrivalDeparture::addTransition(Transition* aTrans)
 {
   WayptRef entry = aTrans->enroute();
+  aTrans->mark(flagType());
   _enrouteTransitions[entry] = aTrans;
 }
 
+string_list ArrivalDeparture::transitionIdents() const
+{
+  string_list r;
+  WptTransitionMap::const_iterator eit;
+  for (eit = _enrouteTransitions.begin(); eit != _enrouteTransitions.end(); ++eit) {
+    r.push_back(eit->second->ident());
+  }
+  return r;
+}
+  
 void ArrivalDeparture::addRunwayTransition(FGRunwayRef aWay, Transition* aTrans)
 {
   assert(aWay->ident() == aTrans->ident());
@@ -136,23 +190,24 @@ void ArrivalDeparture::addRunwayTransition(FGRunwayRef aWay, Transition* aTrans)
     throw sg_io_exception("adding transition for unspecified runway:" + aWay->ident(), ident());
   }
   
+  aTrans->mark(flagType());
   _runways[aWay] = aTrans;
 }
 
 void ArrivalDeparture::setCommon(const WayptVec& aWps)
 {
   _common = aWps;
+  markWaypoints(_common, flagType());
 }
 
-bool ArrivalDeparture::commonRoute(Waypt* aEnroute, WayptVec& aPath, FGRunwayRef aRwy)
+bool ArrivalDeparture::commonRoute(Transition* t, WayptVec& aPath, FGRunwayRef aRwy)
 {
   // assume we're routing from enroute, to the runway.
   // for departures, we'll flip the result points
 
-  Transition* t = findTransitionByEnroute(aEnroute);
   WayptVec::iterator firstCommon = _common.begin();
   if (t) {
-    t->route(aEnroute, aPath);
+    t->route(aPath);
 
     Waypt* transEnd = t->procedureEnd();
     for (; firstCommon != _common.end(); ++firstCommon) {
@@ -167,9 +222,7 @@ bool ArrivalDeparture::commonRoute(Waypt* aEnroute, WayptVec& aPath, FGRunwayRef
     // common section after the transition.
     firstCommon = _common.begin();
   } else {
-    if (aEnroute && !(*firstCommon)->matches(aEnroute)) {
-      return false;
-    }
+    // no tranasition
   } // of not using a transition
   
   // append (some) common points
@@ -190,7 +243,7 @@ bool ArrivalDeparture::commonRoute(Waypt* aEnroute, WayptVec& aPath, FGRunwayRef
   }
   
   SG_LOG(SG_GENERAL, SG_INFO, ident() << " using runway transition for " << r->first->ident());
-  r->second->route(NULL, aPath);
+  r->second->route(aPath);
   return true;
 }
 
@@ -238,13 +291,12 @@ WayptRef ArrivalDeparture::findBestTransition(const SGGeod& aPos) const
   return w;
 }
 
-WayptRef ArrivalDeparture::findTransitionByName(const string& aIdent) const
+Transition* ArrivalDeparture::findTransitionByName(const string& aIdent) const
 {
   WptTransitionMap::const_iterator eit;
   for (eit = _enrouteTransitions.begin(); eit != _enrouteTransitions.end(); ++eit) {
-    WayptRef c = eit->second->enroute();
-    if (c->ident() == aIdent) {
-      return c;
+    if (eit->second->ident() == aIdent) {
+      return eit->second;
     }
   }
   
@@ -253,12 +305,12 @@ WayptRef ArrivalDeparture::findTransitionByName(const string& aIdent) const
 
 ////////////////////////////////////////////////////////////////////////////
 
-SID::SID(const string& aIdent) :
-    ArrivalDeparture(aIdent)
+SID::SID(const string& aIdent, FGAirport* apt) :
+    ArrivalDeparture(aIdent, apt)
 {
 }
 
-bool SID::route(FGRunwayRef aWay, Waypt* aEnroute, WayptVec& aPath)
+bool SID::route(FGRunwayRef aWay, Transition* trans, WayptVec& aPath)
 {
   if (!isForRunway(aWay)) {
     SG_LOG(SG_GENERAL, SG_WARN, "SID " << ident() << " not for runway " << aWay->ident());
@@ -266,7 +318,7 @@ bool SID::route(FGRunwayRef aWay, Waypt* aEnroute, WayptVec& aPath)
   }
   
   WayptVec path;
-  if (!commonRoute(aEnroute, path, aWay)) {
+  if (!commonRoute(trans, path, aWay)) {
     return false;
   }
   
@@ -280,31 +332,34 @@ bool SID::route(FGRunwayRef aWay, Waypt* aEnroute, WayptVec& aPath)
 
 ////////////////////////////////////////////////////////////////////////////
 
-STAR::STAR(const string& aIdent) :
-    ArrivalDeparture(aIdent)
+STAR::STAR(const string& aIdent, FGAirport* apt) :
+    ArrivalDeparture(aIdent, apt)
 {
 }
 
-bool STAR::route(FGRunwayRef aWay, Waypt* aEnroute, WayptVec& aPath)
+bool STAR::route(FGRunwayRef aWay, Transition* trans, WayptVec& aPath)
 {
   if (aWay && !isForRunway(aWay)) {
     return false;
   }
     
-  return commonRoute(aEnroute, aPath, aWay);
+  return commonRoute(trans, aPath, aWay);
 }
 
 /////////////////////////////////////////////////////////////////////////////
 
-Transition::Transition(const std::string& aIdent, Procedure* aPr, 
-    const WayptVec& aWps) :
-  _ident(aIdent),
-  _parent(aPr),
-  _primary(aWps)
+Transition::Transition(const std::string& aIdent, ProcedureType ty, Procedure* aPr) :
+  Procedure(aIdent),
+  _type(ty),
+  _parent(aPr)
 {
   assert(aPr);
-  assert(!_primary.empty());
+}
   
+void Transition::setPrimary(const WayptVec& aWps)
+{
+  _primary = aWps;
+  assert(!_primary.empty());
   _primary[0]->setFlag(WPT_TRANSITION, true);
 }
 
@@ -320,14 +375,20 @@ WayptRef Transition::procedureEnd() const
   return _primary[_primary.size() - 1];
 }
 
-bool Transition::route(Waypt* aEnroute, WayptVec& aPath)
+bool Transition::route(WayptVec& aPath)
 {
-  if (aEnroute && !enroute()->matches(aEnroute)) {
-    return false;
-  }
-  
   aPath.insert(aPath.end(), _primary.begin(), _primary.end());
   return true;
 }
 
+FGAirport* Transition::airport() const
+{
+  return _parent->airport();
+}
+  
+void Transition::mark(WayptFlag f)
+{
+  markWaypoints(_primary, f);
+}
+  
 } // of namespace