From d2bbaa69e07aafb157d58a84f2eb8d83eea51b73 Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 7 Dec 2010 17:55:45 +0000 Subject: [PATCH] Change how ils.xml data is loaded, to reduce impact on startup time. --- src/Navaids/navdb.cxx | 61 +++++++++++++++++++++++++++++++++++++++ src/Navaids/navdb.hxx | 7 +++++ src/Navaids/navrecord.cxx | 37 ++++-------------------- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 4f7c10e7f..96d38c153 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -34,6 +34,7 @@ #include #include #include +#include #include "navrecord.hxx" #include "navlist.hxx" @@ -41,9 +42,16 @@ #include
#include #include +#include +#include +#include
using std::string; +typedef std::map 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 parts = simgear::strutils::split(aName); diff --git a/src/Navaids/navdb.hxx b/src/Navaids/navdb.hxx index 5c2aa117c..a4aa9be1b 100644 --- a/src/Navaids/navdb.hxx +++ b/src/Navaids/navdb.hxx @@ -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. diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx index a22bebb69..03317a57d 100644 --- a/src/Navaids/navrecord.cxx +++ b/src/Navaids/navrecord.cxx @@ -32,7 +32,7 @@ #include #include #include -#include + #include #include @@ -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"), -- 2.39.5