ICAO.ils.xml data works read-only.
This commit is contained in:
parent
ffa7854ed9
commit
c00ab21fad
5 changed files with 42 additions and 70 deletions
|
@ -52,6 +52,7 @@
|
|||
#include <Navaids/waypoint.hxx>
|
||||
#include <ATC/CommStation.hxx>
|
||||
#include <Navaids/NavDataCache.hxx>
|
||||
#include <Navaids/navrecord.hxx>
|
||||
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
|
@ -79,6 +80,7 @@ FGAirport::FGAirport( PositionedID aGuid,
|
|||
mHelipadsLoaded(false),
|
||||
mTaxiwaysLoaded(false),
|
||||
mProceduresLoaded(false),
|
||||
mThresholdDataLoaded(false),
|
||||
mILSDataLoaded(false)
|
||||
{
|
||||
}
|
||||
|
@ -527,8 +529,6 @@ void FGAirport::loadHelipads() const
|
|||
return; // already loaded, great
|
||||
}
|
||||
|
||||
loadSceneryDefinitions();
|
||||
|
||||
mHelipadsLoaded = true;
|
||||
mHelipads = itemsOfType(FGPositioned::HELIPAD);
|
||||
}
|
||||
|
@ -562,6 +562,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
|
||||
|
@ -685,49 +691,33 @@ 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;
|
||||
}
|
||||
|
||||
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 +729,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 +740,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
|
||||
}
|
||||
|
|
|
@ -70,10 +70,8 @@ class FGAirport : public FGPositioned
|
|||
|
||||
/**
|
||||
* reload the ILS data from XML if required.
|
||||
* @result true if the data was refreshed, false if no data was loaded
|
||||
* or previously cached data is still correct.
|
||||
*/
|
||||
bool validateILSData();
|
||||
void validateILSData();
|
||||
|
||||
SGGeod getTowerLocation() const;
|
||||
|
||||
|
@ -322,6 +320,8 @@ private:
|
|||
mutable bool mHelipadsLoaded;
|
||||
mutable bool mTaxiwaysLoaded;
|
||||
mutable bool mProceduresLoaded;
|
||||
|
||||
mutable bool mThresholdDataLoaded;
|
||||
bool mILSDataLoaded;
|
||||
|
||||
mutable std::vector<FGRunwayRef> mRunways;
|
||||
|
|
|
@ -485,7 +485,6 @@ public:
|
|||
insertAirport = prepare("INSERT INTO airport (rowid, has_metar) VALUES (?, ?)");
|
||||
insertNavaid = prepare("INSERT INTO navaid (rowid, freq, range_nm, multiuse, runway, colocated)"
|
||||
" VALUES (?1, ?2, ?3, ?4, ?5, ?6)");
|
||||
updateILS = prepare("UPDATE navaid SET multiuse=?2 WHERE rowid=?1");
|
||||
|
||||
insertCommStation = prepare("INSERT INTO comm (rowid, freq_khz, range_nm)"
|
||||
" VALUES (?, ?, ?)");
|
||||
|
@ -624,7 +623,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
FGPositioned* loadById(sqlite_int64 rowId);
|
||||
FGPositioned* loadById(sqlite_int64 rowId, sqlite3_int64& aptId);
|
||||
|
||||
FGAirport* loadAirport(sqlite_int64 rowId,
|
||||
FGPositioned::Type ty,
|
||||
|
@ -898,7 +897,7 @@ public:
|
|||
sqlite3_stmt_ptr insertPositionedQuery, insertAirport, insertTower, insertRunway,
|
||||
insertCommStation, insertNavaid;
|
||||
sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS, setNavaidColocated,
|
||||
setAirportPos, updateILS;
|
||||
setAirportPos;
|
||||
sqlite3_stmt_ptr removePOIQuery;
|
||||
|
||||
sqlite3_stmt_ptr findClosestWithIdent;
|
||||
|
@ -942,7 +941,8 @@ public:
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGPositioned* NavDataCache::NavDataCachePrivate::loadById(sqlite3_int64 rowid)
|
||||
FGPositioned* NavDataCache::NavDataCachePrivate::loadById(sqlite3_int64 rowid,
|
||||
sqlite3_int64& aptId)
|
||||
{
|
||||
|
||||
sqlite3_bind_int64(loadPositioned, 1, rowid);
|
||||
|
@ -954,7 +954,7 @@ FGPositioned* NavDataCache::NavDataCachePrivate::loadById(sqlite3_int64 rowid)
|
|||
PositionedID prowid = static_cast<PositionedID>(rowid);
|
||||
string ident = (char*) sqlite3_column_text(loadPositioned, 2);
|
||||
string name = (char*) sqlite3_column_text(loadPositioned, 3);
|
||||
sqlite3_int64 aptId = sqlite3_column_int64(loadPositioned, 4);
|
||||
aptId = sqlite3_column_int64(loadPositioned, 4);
|
||||
double lon = sqlite3_column_double(loadPositioned, 5);
|
||||
double lat = sqlite3_column_double(loadPositioned, 6);
|
||||
double elev = sqlite3_column_double(loadPositioned, 7);
|
||||
|
@ -987,18 +987,7 @@ FGPositioned* NavDataCache::NavDataCachePrivate::loadById(sqlite3_int64 rowid)
|
|||
case FGPositioned::DME:
|
||||
case FGPositioned::TACAN:
|
||||
case FGPositioned::MOBILE_TACAN:
|
||||
{
|
||||
if (aptId > 0) {
|
||||
FGAirport* apt = FGPositioned::loadById<FGAirport>(aptId);
|
||||
if (apt->validateILSData()) {
|
||||
// queried data above is probably invalid, force us to go around again
|
||||
// (the next time through, validateILSData will return false)
|
||||
return outer->loadById(rowid);
|
||||
}
|
||||
}
|
||||
|
||||
return loadNav(rowid, ty, ident, name, pos);
|
||||
}
|
||||
|
||||
case FGPositioned::FIX:
|
||||
return new FGFix(rowid, ident, pos);
|
||||
|
@ -1456,9 +1445,17 @@ FGPositionedRef NavDataCache::loadById(PositionedID rowid)
|
|||
return it->second; // cache it
|
||||
}
|
||||
|
||||
FGPositioned* pos = d->loadById(rowid);
|
||||
PositionedID aptId;
|
||||
FGPositioned* pos = d->loadById(rowid, aptId);
|
||||
d->cache.insert(it, PositionedCache::value_type(rowid, pos));
|
||||
d->cacheMisses++;
|
||||
d->cacheMisses++;
|
||||
|
||||
// when we loaded an ILS, we must apply per-airport changes
|
||||
if ((pos->type() == FGPositioned::ILS) && (aptId > 0)) {
|
||||
FGAirport* apt = FGPositioned::loadById<FGAirport>(aptId);
|
||||
apt->validateILSData();
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
@ -1600,14 +1597,6 @@ void NavDataCache::setNavaidColocated(PositionedID navaid, PositionedID colocate
|
|||
rec->setColocatedDME(colocatedDME);
|
||||
}
|
||||
}
|
||||
|
||||
void NavDataCache::updateILS(PositionedID ils, const SGGeod& newPos, double aHdg)
|
||||
{
|
||||
sqlite3_bind_int64(d->updateILS, 1, ils);
|
||||
sqlite3_bind_double(d->updateILS, 2, aHdg);
|
||||
d->execUpdate(d->updateILS);
|
||||
updatePosition(ils, newPos);
|
||||
}
|
||||
|
||||
PositionedID NavDataCache::insertCommStation(FGPositioned::Type ty,
|
||||
const string& name, const SGGeod& pos, int freq, int range,
|
||||
|
|
|
@ -105,8 +105,6 @@ public:
|
|||
PositionedID insertNavaid(FGPositioned::Type ty, const std::string& ident,
|
||||
const std::string& name, const SGGeod& pos, int freq, int range, double multiuse,
|
||||
PositionedID apt, PositionedID runway);
|
||||
void updateILS(PositionedID ils, const SGGeod& newPos, double aHdg);
|
||||
|
||||
|
||||
// Assign colocated DME to a navaid
|
||||
void setNavaidColocated(PositionedID navaid, PositionedID colocatedDME);
|
||||
|
|
|
@ -44,13 +44,6 @@ bool loadCarrierNav(const SGPath& path);
|
|||
|
||||
bool loadTacan(const SGPath& path, 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);
|
||||
|
||||
} // of namespace flightgear
|
||||
|
||||
#endif // _FG_NAVDB_HXX
|
||||
|
|
Loading…
Add table
Reference in a new issue