1
0
Fork 0

Change how ils.xml data is loaded, to reduce impact on startup time.

This commit is contained in:
James Turner 2010-12-07 17:55:45 +00:00
parent b847ca6026
commit d2bbaa69e0
3 changed files with 73 additions and 32 deletions

View 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"
@ -41,9 +42,16 @@
#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);

View 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.

View 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"),