]> git.mxchange.org Git - flightgear.git/blobdiff - src/Airports/simple.cxx
Expose more things to Nasal for FMSs in particular - still work in progress.
[flightgear.git] / src / Airports / simple.cxx
index c7e486f45a56b95cd0ddac27e5179fe9d7a22fa7..1cf962607748d7ae775b7225645e6a7ead48c14c 100644 (file)
 #include <Airports/xmlloader.hxx>
 #include <Navaids/procedure.hxx>
 #include <Navaids/waypoint.hxx>
+#include <Navaids/PositionedBinding.hxx>
+#include <ATC/CommStation.hxx>
 
 using std::vector;
+using std::pair;
+
 using namespace flightgear;
 
 // magic import of a helper which uses FGPositioned internals
@@ -92,22 +96,29 @@ bool FGAirport::isHeliport() const
   return type() == HELIPORT;
 }
 
+bool FGAirport::isAirportType(FGPositioned* pos)
+{
+    if (!pos) {
+        return false;
+    }
+    
+    return (pos->type() >= AIRPORT) && (pos->type() <= SEAPORT);
+}
+
 FGAirportDynamics * FGAirport::getDynamics()
 {
-    if (_dynamics != 0) {
+    if (_dynamics) {
         return _dynamics;
-    } else {
-        //cerr << "Trying to load dynamics for " << _id << endl;
-        _dynamics = new FGAirportDynamics(this);
-        XMLLoader::load(_dynamics);
-
-        FGRunwayPreference rwyPrefs(this);
-        XMLLoader::load(&rwyPrefs);
-        _dynamics->setRwyUse(rwyPrefs);
+    }
+    
+    _dynamics = new FGAirportDynamics(this);
+    XMLLoader::load(_dynamics);
 
-        //FGSidStar SIDs(this);
-        XMLLoader::load(_dynamics->getSIDs());
-   }
+    FGRunwayPreference rwyPrefs(this);
+    XMLLoader::load(&rwyPrefs);
+    _dynamics->setRwyUse(rwyPrefs);
+    XMLLoader::load(_dynamics->getSIDs());
+    
     return _dynamics;
 }
 
@@ -143,7 +154,10 @@ FGRunway* FGAirport::getRunwayByIdent(const string& aIdent) const
 
 FGAirport::Runway_iterator
 FGAirport::getIteratorForRunwayIdent(const string& aIdent) const
-{ 
+{
+  if (aIdent.empty())
+    return mRunways.end();
+
   loadRunways();
   
   string ident(aIdent);
@@ -369,7 +383,7 @@ void FGAirport::loadRunways() const
   }
   
   mRunwaysLoaded = true;
-  loadSceneryDefintions();
+  loadSceneryDefinitions();
 }
 
 void FGAirport::loadTaxiways() const
@@ -396,14 +410,8 @@ void FGAirport::loadProcedures() const
   Route::loadAirportProcedures(path, const_cast<FGAirport*>(this));
 }
 
-void FGAirport::loadSceneryDefintions() const
+void FGAirport::loadSceneryDefinitions() const
 {  
-  // allow users to disable the scenery data in the short-term
-  // longer term, this option can probably disappear
-  if (!fgGetBool("/sim/paths/use-custom-scenery-data")) {
-    return; 
-  }
-  
   SGPath path;
   SGPropertyNode_ptr rootNode = new SGPropertyNode;
   if (XMLLoader::findAirportData(ident(), "threshold", path)) {
@@ -439,7 +447,7 @@ void FGAirport::processThreshold(SGPropertyNode* aThreshold)
   // first, let's identify the current runway
   string id(aThreshold->getStringValue("rwy"));
   if (!hasRunwayWithIdent(id)) {
-    SG_LOG(SG_GENERAL, SG_WARN, "FGAirport::processThreshold: "
+    SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: "
       "found runway not defined in the global data:" << ident() << "/" << id);
     return;
   }
@@ -453,9 +461,13 @@ void FGAirport::readTowerData(SGPropertyNode* aRoot)
   SGPropertyNode* twrNode = aRoot->getChild("tower")->getChild("twr");
   double lat = twrNode->getDoubleValue("lat"), 
     lon = twrNode->getDoubleValue("lon"), 
-    elevM = twrNode->getDoubleValue("elev-m");
-    
-  _tower_location = SGGeod::fromDegM(lon, lat, elevM);
+    elevM = twrNode->getDoubleValue("elev-m");  
+// tower elevation is AGL, not AMSL. Since we don't want to depend on the
+// scenery for a precise terrain elevation, we use the field elevation
+// (this is also what the apt.dat code does)
+  double fieldElevationM = geod().getElevationM();
+  
+  _tower_location = SGGeod::fromDegM(lon, lat, fieldElevationM + elevM);
 }
 
 bool FGAirport::buildApproach(Waypt* aEnroute, STAR* aSTAR, FGRunway* aRwy, WayptVec& aRoute)
@@ -544,7 +556,7 @@ FGAirport::selectSID(const SGGeod& aDest, FGRunway* aRwy)
       << (aRwy ? aRwy->ident() : "no runway preference"));
   }
   
-  return make_pair(sid, enroute);
+  return std::make_pair(sid, enroute);
 }
     
 pair<STAR*, WayptRef>
@@ -576,7 +588,7 @@ FGAirport::selectSTAR(const SGGeod& aOrigin, FGRunway* aRwy)
     }
   } // of STAR iteration
   
-  return make_pair(star, enroute);
+  return std::make_pair(star, enroute);
 }
 
 
@@ -655,6 +667,61 @@ Approach* FGAirport::getApproachByIndex(unsigned int aIndex) const
   return mApproaches[aIndex];
 }
 
+class AirportNodeListener : public SGPropertyChangeListener
+{
+public:
+    AirportNodeListener()
+    {
+        SGPropertyNode* airports = fgGetNode("/sim/airport");
+        airports->addChangeListener(this, false);
+    }
+
+    virtual void valueChanged(SGPropertyNode*)
+    {
+    }
+
+    virtual void childAdded(SGPropertyNode* pr, SGPropertyNode* child)
+    {
+       FGAirport* apt = FGAirport::findByIdent(child->getName());
+       if (!apt) {
+           return;
+       }
+       
+       flightgear::PositionedBinding::bind(apt, child);
+    }
+};
+    
+void FGAirport::installPropertyListener()
+{
+    new AirportNodeListener;  
+}
+
+flightgear::PositionedBinding*
+FGAirport::createBinding(SGPropertyNode* nd) const
+{
+    return new flightgear::AirportBinding(this, nd);
+}
+
+void FGAirport::setCommStations(CommStationList& comms)
+{
+    mCommStations.swap(comms);
+    for (unsigned int c=0; c<mCommStations.size(); ++c) {
+        mCommStations[c]->setAirport(this);
+    }
+}
+
+CommStationList
+FGAirport::commStationsOfType(FGPositioned::Type aTy) const
+{
+    CommStationList result;
+    for (unsigned int c=0; c<mCommStations.size(); ++c) {
+        if (mCommStations[c]->type() == aTy) {
+            result.push_back(mCommStations[c]);
+        }
+    }
+    return result;
+}
+
 // get airport elevation
 double fgGetAirportElev( const string& id )
 {