1
0
Fork 0

ICAO.threshold.xml works read-only.

This commit is contained in:
James Turner 2014-02-21 10:59:13 -08:00
parent 5f9c17bd69
commit ffa7854ed9
4 changed files with 68 additions and 81 deletions

View file

@ -148,7 +148,7 @@ unsigned int FGAirport::numHelipads() const
FGRunwayRef FGAirport::getRunwayByIndex(unsigned int aIndex) const FGRunwayRef FGAirport::getRunwayByIndex(unsigned int aIndex) const
{ {
loadRunways(); loadRunways();
return loadById<FGRunway>(mRunways, aIndex); return mRunways.at(aIndex);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -166,10 +166,8 @@ FGRunwayMap FGAirport::getRunwayMap() const
double minLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft"); double minLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft");
BOOST_FOREACH(PositionedID id, mRunways) BOOST_FOREACH(FGRunwayRef rwy, mRunways)
{ {
FGRunway* rwy = loadById<FGRunway>(id);
// ignore unusably short runways // ignore unusably short runways
// TODO other methods don't check this... // TODO other methods don't check this...
if( rwy->lengthFt() >= minLengthFt ) if( rwy->lengthFt() >= minLengthFt )
@ -197,8 +195,14 @@ FGHelipadMap FGAirport::getHelipadMap() const
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool FGAirport::hasRunwayWithIdent(const std::string& aIdent) const bool FGAirport::hasRunwayWithIdent(const std::string& aIdent) const
{ {
return flightgear::NavDataCache::instance() loadRunways();
->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent) != 0; BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
if (rwy->ident() == aIdent) {
return true;
}
}
return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -211,16 +215,15 @@ bool FGAirport::hasHelipadWithIdent(const std::string& aIdent) const
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
FGRunwayRef FGAirport::getRunwayByIdent(const std::string& aIdent) const FGRunwayRef FGAirport::getRunwayByIdent(const std::string& aIdent) const
{ {
PositionedID id = loadRunways();
flightgear::NavDataCache::instance() BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent); if (rwy->ident() == aIdent) {
return rwy;
if (id == 0) { }
SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident());
throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getRunwayByIdent");
} }
return loadById<FGRunway>(id); SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident());
throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getRunwayByIdent");
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -255,14 +258,7 @@ FGRunwayRef FGAirport::findBestRunwayForHeading(double aHeading, struct FindBest
fbrfhp.ilsWeight = searchNode->getDoubleValue("ils-weight", fbrfhp.ilsWeight ); fbrfhp.ilsWeight = searchNode->getDoubleValue("ils-weight", fbrfhp.ilsWeight );
} }
BOOST_FOREACH(PositionedID id, mRunways) { BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
FGRunway* rwy = loadById<FGRunway>(id);
// bug http://code.google.com/p/flightgear-bugs/issues/detail?id=1149
// (and probably some other issues besides).
if (rwy->type() == FGPositioned::HELIPAD) {
continue;
}
double good = rwy->score( fbrfhp.lengthWeight, fbrfhp.widthWeight, fbrfhp.surfaceWeight, fbrfhp.ilsWeight ); double good = rwy->score( fbrfhp.lengthWeight, fbrfhp.widthWeight, fbrfhp.surfaceWeight, fbrfhp.ilsWeight );
double dev = aHeading - rwy->headingDeg(); double dev = aHeading - rwy->headingDeg();
SG_NORMALIZE_RANGE(dev, -180.0, 180.0); SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
@ -286,9 +282,7 @@ FGRunwayRef FGAirport::findBestRunwayForPos(const SGGeod& aPos) const
FGRunway* result = NULL; FGRunway* result = NULL;
double currentLowestDev = 180.0; double currentLowestDev = 180.0;
BOOST_FOREACH(PositionedID id, mRunways) { BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
FGRunway* rwy = loadById<FGRunway>(id);
double inboundCourse = SGGeodesy::courseDeg(aPos, rwy->end()); double inboundCourse = SGGeodesy::courseDeg(aPos, rwy->end());
double dev = inboundCourse - rwy->headingDeg(); double dev = inboundCourse - rwy->headingDeg();
SG_NORMALIZE_RANGE(dev, -180.0, 180.0); SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
@ -309,8 +303,7 @@ bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const
{ {
loadRunways(); loadRunways();
BOOST_FOREACH(PositionedID id, mRunways) { BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
FGRunway* rwy = loadById<FGRunway>(id);
if (rwy->isHardSurface() && (rwy->lengthFt() >= aLengthFt)) { if (rwy->isHardSurface() && (rwy->lengthFt() >= aLengthFt)) {
return true; // we're done! return true; // we're done!
} }
@ -326,8 +319,7 @@ FGRunwayList FGAirport::getRunwaysWithoutReciprocals() const
FGRunwayList r; FGRunwayList r;
BOOST_FOREACH(PositionedID id, mRunways) { BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
FGRunway* rwy = loadById<FGRunway>(id);
FGRunway* recip = rwy->reciprocalRunway(); FGRunway* recip = rwy->reciprocalRunway();
if (recip) { if (recip) {
FGRunwayList::iterator it = std::find(r.begin(), r.end(), recip); FGRunwayList::iterator it = std::find(r.begin(), r.end(), recip);
@ -508,6 +500,12 @@ const FGAirport *fgFindAirportID( const std::string& id)
return FGAirport::findByIdent(id); return FGAirport::findByIdent(id);
} }
PositionedIDVec FGAirport::itemsOfType(FGPositioned::Type ty) const
{
flightgear::NavDataCache* cache = flightgear::NavDataCache::instance();
return cache->airportItemsOfType(guid(), ty);
}
void FGAirport::loadRunways() const void FGAirport::loadRunways() const
{ {
if (mRunwaysLoaded) { if (mRunwaysLoaded) {
@ -517,7 +515,10 @@ void FGAirport::loadRunways() const
loadSceneryDefinitions(); loadSceneryDefinitions();
mRunwaysLoaded = true; mRunwaysLoaded = true;
mRunways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::RUNWAY); PositionedIDVec rwys(itemsOfType(FGPositioned::RUNWAY));
BOOST_FOREACH(PositionedID id, rwys) {
mRunways.push_back(loadById<FGRunway>(id));
}
} }
void FGAirport::loadHelipads() const void FGAirport::loadHelipads() const
@ -529,7 +530,7 @@ void FGAirport::loadHelipads() const
loadSceneryDefinitions(); loadSceneryDefinitions();
mHelipadsLoaded = true; mHelipadsLoaded = true;
mHelipads = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::HELIPAD); mHelipads = itemsOfType(FGPositioned::HELIPAD);
} }
void FGAirport::loadTaxiways() const void FGAirport::loadTaxiways() const
@ -539,7 +540,7 @@ void FGAirport::loadTaxiways() const
} }
mTaxiwaysLoaded = true; mTaxiwaysLoaded = true;
mTaxiways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::TAXIWAY); mTaxiways = itemsOfType(FGPositioned::TAXIWAY);
} }
void FGAirport::loadProcedures() const void FGAirport::loadProcedures() const
@ -561,31 +562,18 @@ void FGAirport::loadProcedures() const
void FGAirport::loadSceneryDefinitions() const void FGAirport::loadSceneryDefinitions() const
{ {
NavDataCache* cache = NavDataCache::instance();
if (cache->isReadOnly()) {
return;
}
SGPath path; SGPath path;
if (!XMLLoader::findAirportData(ident(), "threshold", path)) { if (!XMLLoader::findAirportData(ident(), "threshold", path)) {
return; // no XML threshold data return; // no XML threshold data
} }
if (!cache->isCachedFileModified(path)) { try {
// cached values are correct, we're all done SGPropertyNode_ptr rootNode = new SGPropertyNode;
return; readProperties(path.str(), rootNode);
const_cast<FGAirport*>(this)->readThresholdData(rootNode);
} catch (sg_exception& e) {
SG_LOG(SG_NAVAID, SG_WARN, ident() << "loading threshold XML failed:" << e.getFormattedMessage());
} }
try {
flightgear::NavDataCache::Transaction txn(cache);
SGPropertyNode_ptr rootNode = new SGPropertyNode;
readProperties(path.str(), rootNode);
const_cast<FGAirport*>(this)->readThresholdData(rootNode);
cache->stampCacheFile(path);
txn.commit();
} catch (sg_exception& e) {
SG_LOG(SG_NAVAID, SG_WARN, ident() << "loading threshold XML failed:" << e.getFormattedMessage());
}
} }
void FGAirport::readThresholdData(SGPropertyNode* aRoot) void FGAirport::readThresholdData(SGPropertyNode* aRoot)
@ -609,11 +597,6 @@ void FGAirport::processThreshold(SGPropertyNode* aThreshold)
std::string rwyIdent(aThreshold->getStringValue("rwy")); std::string rwyIdent(aThreshold->getStringValue("rwy"));
NavDataCache* cache = NavDataCache::instance(); NavDataCache* cache = NavDataCache::instance();
PositionedID id = cache->airportItemWithIdent(guid(), FGPositioned::RUNWAY, rwyIdent); PositionedID id = cache->airportItemWithIdent(guid(), FGPositioned::RUNWAY, rwyIdent);
if (id == 0) {
SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: "
"found runway not defined in the global data:" << ident() << "/" << rwyIdent);
return;
}
double lon = aThreshold->getDoubleValue("lon"), double lon = aThreshold->getDoubleValue("lon"),
lat = aThreshold->getDoubleValue("lat"); lat = aThreshold->getDoubleValue("lat");
@ -623,8 +606,29 @@ void FGAirport::processThreshold(SGPropertyNode* aThreshold)
double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m"); double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m");
double newStopway = aThreshold->getDoubleValue("stopw-m"); double newStopway = aThreshold->getDoubleValue("stopw-m");
cache->updateRunwayThreshold(id, newThreshold, if (id == 0) {
newHeading, newDisplacedThreshold, newStopway); SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: "
"found runway not defined in the global data:" << ident() << "/" << rwyIdent);
// enable this code when threshold.xml contains sufficient data to
// fully specify a new runway, *and* we figure out how to assign runtime
// Positioned IDs and insert temporary items into the spatial map.
#if 0
double newLength = 0.0, newWidth = 0.0;
int surfaceCode = 0;
FGRunway* rwy = new FGRunway(id, guid(), rwyIdent, newThreshold,
newHeading,
newLength, newWidth,
newDisplacedThreshold, newStopway,
surfaceCode);
// insert into the spatial map too
mRunways.push_back(rwy);
#endif
} else {
FGRunway* rwy = loadById<FGRunway>(id);
rwy->updateThreshold(newThreshold, newHeading,
newDisplacedThreshold, newStopway);
}
} }
SGGeod FGAirport::getTowerLocation() const SGGeod FGAirport::getTowerLocation() const

View file

@ -303,7 +303,9 @@ private:
* Helper to parse property data loaded from an ICAO.twr.xml file * Helper to parse property data loaded from an ICAO.twr.xml file
*/ */
void readTowerData(SGPropertyNode* aRoot); void readTowerData(SGPropertyNode* aRoot);
PositionedIDVec itemsOfType(FGPositioned::Type ty) const;
std::string _name; std::string _name;
bool _has_metar; bool _has_metar;
FGAirportDynamics *_dynamics; FGAirportDynamics *_dynamics;
@ -321,8 +323,9 @@ private:
mutable bool mTaxiwaysLoaded; mutable bool mTaxiwaysLoaded;
mutable bool mProceduresLoaded; mutable bool mProceduresLoaded;
bool mILSDataLoaded; bool mILSDataLoaded;
mutable std::vector<FGRunwayRef> mRunways;
mutable PositionedIDVec mRunways;
mutable PositionedIDVec mHelipads; mutable PositionedIDVec mHelipads;
mutable PositionedIDVec mTaxiways; mutable PositionedIDVec mTaxiways;
PositionedIDVec mPavements; PositionedIDVec mPavements;

View file

@ -474,7 +474,6 @@ public:
setRunwayReciprocal = prepare("UPDATE runway SET reciprocal=?2 WHERE rowid=?1"); setRunwayReciprocal = prepare("UPDATE runway SET reciprocal=?2 WHERE rowid=?1");
setRunwayILS = prepare("UPDATE runway SET ils=?2 WHERE rowid=?1"); setRunwayILS = prepare("UPDATE runway SET ils=?2 WHERE rowid=?1");
setNavaidColocated = prepare("UPDATE navaid SET colocated=?2 WHERE rowid=?1"); setNavaidColocated = prepare("UPDATE navaid SET colocated=?2 WHERE rowid=?1");
updateRunwayThreshold = prepare("UPDATE runway SET heading=?2, displaced_threshold=?3, stopway=?4 WHERE rowid=?1");
insertPositionedQuery = prepare("INSERT INTO positioned " insertPositionedQuery = prepare("INSERT INTO positioned "
"(type, ident, name, airport, lon, lat, elev_m, octree_node, " "(type, ident, name, airport, lon, lat, elev_m, octree_node, "
@ -899,7 +898,7 @@ public:
sqlite3_stmt_ptr insertPositionedQuery, insertAirport, insertTower, insertRunway, sqlite3_stmt_ptr insertPositionedQuery, insertAirport, insertTower, insertRunway,
insertCommStation, insertNavaid; insertCommStation, insertNavaid;
sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS, setNavaidColocated, sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS, setNavaidColocated,
setAirportPos, updateRunwayThreshold, updateILS; setAirportPos, updateILS;
sqlite3_stmt_ptr removePOIQuery; sqlite3_stmt_ptr removePOIQuery;
sqlite3_stmt_ptr findClosestWithIdent; sqlite3_stmt_ptr findClosestWithIdent;
@ -1566,21 +1565,6 @@ void NavDataCache::setRunwayILS(PositionedID runway, PositionedID ils)
} }
} }
void NavDataCache::updateRunwayThreshold(PositionedID runwayID, const SGGeod &aThreshold,
double aHeading, double aDisplacedThreshold,
double aStopway)
{
// update the runway information
sqlite3_bind_int64(d->updateRunwayThreshold, 1, runwayID);
sqlite3_bind_double(d->updateRunwayThreshold, 2, aHeading);
sqlite3_bind_double(d->updateRunwayThreshold, 3, aDisplacedThreshold);
sqlite3_bind_double(d->updateRunwayThreshold, 4, aStopway);
d->execUpdate(d->updateRunwayThreshold);
// now update the positional data
updatePosition(runwayID, aThreshold);
}
PositionedID PositionedID
NavDataCache::insertNavaid(FGPositioned::Type ty, const string& ident, NavDataCache::insertNavaid(FGPositioned::Type ty, const string& ident,
const string& name, const SGGeod& pos, const string& name, const SGGeod& pos,

View file

@ -102,10 +102,6 @@ public:
void setRunwayReciprocal(PositionedID runway, PositionedID recip); void setRunwayReciprocal(PositionedID runway, PositionedID recip);
void setRunwayILS(PositionedID runway, PositionedID ils); void setRunwayILS(PositionedID runway, PositionedID ils);
void updateRunwayThreshold(PositionedID runwayID, const SGGeod &aThreshold,
double aHeading, double aDisplacedThreshold,
double aStopway);
PositionedID insertNavaid(FGPositioned::Type ty, const std::string& ident, PositionedID insertNavaid(FGPositioned::Type ty, const std::string& ident,
const std::string& name, const SGGeod& pos, int freq, int range, double multiuse, const std::string& name, const SGGeod& pos, int freq, int range, double multiuse,
PositionedID apt, PositionedID runway); PositionedID apt, PositionedID runway);