]> git.mxchange.org Git - flightgear.git/blobdiff - src/Airports/airport.cxx
Interim windows build fix
[flightgear.git] / src / Airports / airport.cxx
index e18b8b5f2b0ee742bd7eb1156d1123052b9d50a7..f284fb55ad50bc38874416311814665192ba10df 100644 (file)
 #include <Main/fg_props.hxx>
 #include <Airports/runways.hxx>
 #include <Airports/pavement.hxx>
-#include <Airports/dynamics.hxx>
 #include <Airports/xmlloader.hxx>
+#include <Airports/dynamics.hxx>
+#include <Airports/airportdynamicsmanager.hxx>
 #include <Navaids/procedure.hxx>
 #include <Navaids/waypoint.hxx>
 #include <ATC/CommStation.hxx>
 #include <Navaids/NavDataCache.hxx>
+#include <Navaids/navrecord.hxx>
 
 using std::vector;
 using std::pair;
@@ -73,20 +75,21 @@ FGAirport::FGAirport( PositionedID aGuid,
     FGPositioned(aGuid, aType, id, location),
     _name(name),
     _has_metar(has_metar),
-    _dynamics(0),
     mTowerDataLoaded(false),
+    mHasTower(false),
     mRunwaysLoaded(false),
     mHelipadsLoaded(false),
     mTaxiwaysLoaded(false),
     mProceduresLoaded(false),
+    mThresholdDataLoaded(false),
     mILSDataLoaded(false)
 {
+    mIsClosed = (name.find("[x]") != std::string::npos);
 }
 
 
 FGAirport::~FGAirport()
 {
-    delete _dynamics;
 }
 
 bool FGAirport::isAirport() const
@@ -113,23 +116,6 @@ bool FGAirport::isAirportType(FGPositioned* pos)
     return (pos->type() >= AIRPORT) && (pos->type() <= SEAPORT);
 }
 
-FGAirportDynamics * FGAirport::getDynamics()
-{
-    if (_dynamics) {
-        return _dynamics;
-    }
-    
-    _dynamics = new FGAirportDynamics(this);
-    XMLLoader::load(_dynamics);
-    _dynamics->init();
-  
-    FGRunwayPreference rwyPrefs(this);
-    XMLLoader::load(&rwyPrefs);
-    _dynamics->setRwyUse(rwyPrefs);
-    
-    return _dynamics;
-}
-
 //------------------------------------------------------------------------------
 unsigned int FGAirport::numRunways() const
 {
@@ -312,6 +298,28 @@ bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const
   return false;
 }
 
+FGRunwayRef FGAirport::longestRunway() const
+{
+    FGRunwayRef r;
+    loadRunways();
+
+    BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
+        if (!r || (r->lengthFt() < rwy->lengthFt())) {
+             r = rwy;
+        }
+    } // of runways iteration
+
+    return r;
+}
+
+//------------------------------------------------------------------------------
+FGRunwayList FGAirport::getRunways() const
+{
+  loadRunways();
+
+  return mRunways;
+}
+
 //------------------------------------------------------------------------------
 FGRunwayList FGAirport::getRunwaysWithoutReciprocals() const
 {
@@ -527,8 +535,6 @@ void FGAirport::loadHelipads() const
     return; // already loaded, great
   }
 
-  loadSceneryDefinitions();
-
   mHelipadsLoaded = true;
   mHelipads = itemsOfType(FGPositioned::HELIPAD);
 }
@@ -562,6 +568,12 @@ void FGAirport::loadProcedures() const
 
 void FGAirport::loadSceneryDefinitions() const
 {
+  if (mThresholdDataLoaded) {
+    return;
+  }
+  
+  mThresholdDataLoaded = true;
+  
   SGPath path;
   if (!XMLLoader::findAirportData(ident(), "threshold", path)) {
     return; // no XML threshold data
@@ -649,13 +661,25 @@ void FGAirport::validateTowerData() const
   NavDataCache* cache = NavDataCache::instance();
   PositionedIDVec towers = cache->airportItemsOfType(guid(), FGPositioned::TOWER);
   if (towers.empty()) {
-    SG_LOG(SG_GENERAL, SG_ALERT, "No towers defined for:" <<ident());
+    mHasTower = false;
     mTowerPosition = geod(); // use airport position
+
+    // offset the tower position away from the runway centerline, if
+    // airport has a single runway. Offset by eight times the runway width,
+    // an entirely guessed figure.
+    int runwayCount = numRunways();
+    if ((runwayCount > 0) && (runwayCount <= 2)) {
+        FGRunway* runway = getRunwayByIndex(0);
+        double hdg = runway->headingDeg() + 90;
+        mTowerPosition = SGGeodesy::direct(geod(), hdg, runway->widthM() * 8);
+    }
+
     // increase tower elevation by 20 metres above the field elevation
     mTowerPosition.setElevationM(geod().getElevationM() + 20.0);
   } else {
     FGPositionedRef tower = cache->loadById(towers.front());
     mTowerPosition = tower->geod();
+    mHasTower = true;
   }
   
   SGPath path;
@@ -667,6 +691,7 @@ void FGAirport::validateTowerData() const
     SGPropertyNode_ptr rootNode = new SGPropertyNode;
     readProperties(path.str(), rootNode);
     const_cast<FGAirport*>(this)->readTowerData(rootNode);
+    mHasTower = true;
   } catch (sg_exception& e){
     SG_LOG(SG_NAVAID, SG_WARN, ident() << "loading twr XML failed:" << e.getFormattedMessage());
   }
@@ -685,49 +710,39 @@ void FGAirport::readTowerData(SGPropertyNode* aRoot)
   mTowerPosition = SGGeod::fromDegM(lon, lat, fieldElevationM + elevM);
 }
 
-bool FGAirport::validateILSData()
+void FGAirport::validateILSData()
 {
   if (mILSDataLoaded) {
-    return false;
+    return;
   }
   
+  // to avoid re-entrancy on this code-path, ensure we set loaded
+  // immediately.
   mILSDataLoaded = true;
-  NavDataCache* cache = NavDataCache::instance();
-    if (cache->isReadOnly()) {
-        return false;
-    }
     
   SGPath path;
   if (!XMLLoader::findAirportData(ident(), "ils", path)) {
-    return false; // no XML tower data
+    return; // no XML tower data
   }
   
-  if (!cache->isCachedFileModified(path)) {
-    // cached values are correct, we're all done
-    return false;
+  try {
+      SGPropertyNode_ptr rootNode = new SGPropertyNode;
+      readProperties(path.str(), rootNode);
+      readILSData(rootNode);
+  } catch (sg_exception& e){
+      SG_LOG(SG_NAVAID, SG_WARN, ident() << "loading ils XML failed:" << e.getFormattedMessage());
   }
-  
-    try {
-        SGPropertyNode_ptr rootNode = new SGPropertyNode;
-        readProperties(path.str(), rootNode);
+}
 
-        flightgear::NavDataCache::Transaction txn(cache);
-        readILSData(rootNode);
-        cache->stampCacheFile(path);
-        txn.commit();
-// we loaded data, tell the caller it might need to reload things
-        return true;
-    } catch (sg_exception& e){
-        SG_LOG(SG_NAVAID, SG_WARN, ident() << "loading ils XML failed:" << e.getFormattedMessage());
-    }
-    
-    return false;
+bool FGAirport::hasTower() const
+{
+    validateTowerData();
+    return mHasTower;
 }
 
 void FGAirport::readILSData(SGPropertyNode* aRoot)
-{
+{  
   NavDataCache* cache = NavDataCache::instance();
-  
   // find the entry matching the runway
   SGPropertyNode* runwayNode, *ilsNode;
   for (int i=0; (runwayNode = aRoot->getChild("runway", i)) != NULL; ++i) {
@@ -739,7 +754,7 @@ void FGAirport::readILSData(SGPropertyNode* aRoot)
                                         ilsNode->getStringValue("nav-id"));
       if (ils == 0) {
         SG_LOG(SG_GENERAL, SG_INFO, "reading ILS data for " << ident() <<
-               ", couldn;t find runway/navaid for:" <<
+               ", couldn't find runway/navaid for:" <<
                ilsNode->getStringValue("rwy") << "/" <<
                ilsNode->getStringValue("nav-id"));
         continue;
@@ -750,7 +765,9 @@ void FGAirport::readILSData(SGPropertyNode* aRoot)
         lat = ilsNode->getDoubleValue("lat"),
         elevM = ilsNode->getDoubleValue("elev-m");
  
-      cache->updateILS(ils, SGGeod::fromDegM(lon, lat, elevM), hdgDeg);
+      FGNavRecordRef nav(FGPositioned::loadById<FGNavRecord>(ils));
+      assert(nav.valid());
+      nav->updateFromXML(SGGeod::fromDegM(lon, lat, elevM), hdgDeg);
     } // of ILS iteration
   } // of runway iteration
 }
@@ -947,6 +964,11 @@ void FGAirport::sortBySize(FGPositionedList& airportList)
     }
 }
 
+FGAirportDynamicsRef FGAirport::getDynamics() const
+{
+    return flightgear::AirportDynamicsManager::find(const_cast<FGAirport*>(this));
+}
+
 // get airport elevation
 double fgGetAirportElev( const std::string& id )
 {