]> git.mxchange.org Git - flightgear.git/commitdiff
Change how ils.xml data is loaded, to reduce impact on startup time.
authorJames Turner <zakalawe@mac.com>
Tue, 7 Dec 2010 17:55:45 +0000 (17:55 +0000)
committerJames Turner <zakalawe@mac.com>
Tue, 7 Dec 2010 18:07:50 +0000 (18:07 +0000)
src/Navaids/navdb.cxx
src/Navaids/navdb.hxx
src/Navaids/navrecord.cxx

index 4f7c10e7f8e89241e3d67d532ee6d7cfac6e0856..96d38c153ed49077e5d4ecb47429431534bd60ca 100644 (file)
@@ -34,6 +34,7 @@
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/misc/sgstream.hxx>
+#include <simgear/props/props_io.hxx>
 
 #include "navrecord.hxx"
 #include "navlist.hxx"
 #include <Main/globals.hxx>
 #include <Navaids/markerbeacon.hxx>
 #include <Airports/simple.hxx>
+#include <Airports/runways.hxx>
+#include <Airports/xmlloader.hxx>
+#include <Main/fg_props.hxx>
 
 using std::string;
 
+typedef std::map<FGAirport*, SGPropertyNode_ptr> AirportPropertyMap;
+
+static AirportPropertyMap static_airportIlsData;
+
 static FGPositioned::Type
 mapRobinTypeToFGPType(int aTy)
 {
@@ -223,9 +231,62 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
  // end ReadChanFile
 
 
+  // flush all the parsed ils.xml data, we don't need it anymore,
+  // since it's been meregd into the FGNavRecords
+    static_airportIlsData.clear();
+
     return true;
 }
 
+SGPropertyNode* ilsDataForRunwayAndNavaid(FGRunway* aRunway, const std::string& aNavIdent)
+{
+  if (!fgGetBool("/sim/paths/use-custom-scenery-data")) {
+    return NULL; 
+  }
+  
+  if (!aRunway) {
+    return NULL;
+  }
+  
+  FGAirport* apt = aRunway->airport();
+// find (or load) the airprot ILS data
+  AirportPropertyMap::iterator it = static_airportIlsData.find(apt);
+  if (it == static_airportIlsData.end()) {
+    SGPath path;
+    if (!XMLLoader::findAirportData(apt->ident(), "ils", path)) {
+    // no ils.xml file for this airpot, insert a NULL entry so we don't
+    // check again
+      static_airportIlsData.insert(it, std::make_pair(apt, SGPropertyNode_ptr()));
+      return NULL;
+    }
+    
+    SGPropertyNode_ptr rootNode = new SGPropertyNode;
+    readProperties(path.str(), rootNode);
+    it = static_airportIlsData.insert(it, std::make_pair(apt, rootNode));
+  } // of ils.xml file not loaded
+  
+  if (!it->second) {
+    return NULL;
+  }
+  
+// find the entry matching the runway
+  SGPropertyNode* runwayNode, *ilsNode;
+  for (int i=0; (runwayNode = it->second->getChild("runway", i)) != NULL; ++i) {
+    for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) {
+      // must match on both nav-ident and runway ident, to support the following:
+      // - runways with multiple distinct ILS installations (KEWD, for example)
+      // - runways where both ends share the same nav ident (LFAT, for example)
+      if ((ilsNode->getStringValue("nav-id") == aNavIdent) &&
+          (ilsNode->getStringValue("rwy") == aRunway->ident())) 
+      {
+        return ilsNode;
+      }
+    } // of ILS iteration
+  } // of runway iteration
+
+  return NULL;
+}
+
 FGRunway* getRunwayFromName(const std::string& aName)
 {
   vector<string> parts = simgear::strutils::split(aName);
index 5c2aa117ce252120bb2a4208df3d14de07090a8a..a4aa9be1b77c8ab990a046b0ef74f5540e8f2fdb 100644 (file)
@@ -37,6 +37,13 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
                   FGTACANList *channellist );
 
 
+/**
+ * Return the property node corresponding to the runway ILS installation,
+ * from the Airports/I/C/A/ICAO.ils.xml file (loading it if necessary)
+ * returns NULL is no ILS data is defined for the runway.
+ */
+SGPropertyNode* ilsDataForRunwayAndNavaid(FGRunway* aRunway, const std::string& aNavIdent);
+
 /**
  * Helper to map a nav.data name (eg 'KBWI 33R GS') into a FGRunway reference.
  * returns NULL, and complains loudly, if the airport/runway is not found.
index a22bebb69b431f7f6dec13701adb0a6318531488..03317a57d3342f62cd68718c36d1cc88e910ae5c 100644 (file)
@@ -32,7 +32,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/sg_inlines.h>
 #include <simgear/props/props.hxx>
-#include <simgear/props/props_io.hxx>
+
 
 #include <Navaids/navrecord.hxx>
 #include <Navaids/navdb.hxx>
@@ -97,7 +97,10 @@ void FGNavRecord::initAirportRelation()
   }
   
   if (type() != GS) {
-    readAirportSceneryData();
+    SGPropertyNode* ilsData = ilsDataForRunwayAndNavaid(mRunway, ident());
+    if (ilsData) {
+      processSceneryILS(ilsData);
+    }
   }
         
   // fudge elevation to the runway elevation if it's not specified
@@ -121,36 +124,6 @@ void FGNavRecord::initAirportRelation()
   }
 }
 
-void FGNavRecord::readAirportSceneryData()
-{
-  // allow users to disable the scenery data in the short-term
-  // longer term, this option can probably disappear
-  if (!fgGetBool("/sim/use-scenery-airport-data")) {
-    return; 
-  }
-  
-  SGPath path;
-  SGPropertyNode_ptr rootNode = new SGPropertyNode;
-  if (!XMLLoader::findAirportData(mRunway->airport()->ident(), "ils", path)) {
-    return;
-  }
-  
-  readProperties(path.str(), rootNode);
-  SGPropertyNode* runwayNode, *ilsNode;
-  for (int i=0; (runwayNode = rootNode->getChild("runway", i)) != NULL; ++i) {
-    for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) {
-      // must match on both nav-ident and runway ident, to support the following:
-      // - runways with multiple distinct ILS installations (KEWD, for example)
-      // - runways where both ends share the same nav ident (LFAT, for example)
-      if ((ilsNode->getStringValue("nav-id") == ident()) &&
-          (ilsNode->getStringValue("rwy") == mRunway->ident())) {
-        processSceneryILS(ilsNode);
-        return;
-      }
-    } // of ILS iteration
-  } // of runway iteration
-}
-
 void FGNavRecord::processSceneryILS(SGPropertyNode* aILSNode)
 {
   double hdgDeg = aILSNode->getDoubleValue("hdg-deg"),