1
0
Fork 0

Parse nav.dat DMEs and assign them to appropriate navaid, if applicable.

We can now detect whether a DME is colocated at a VOR/ILS/VORTAC/TACAN/NDB
This commit is contained in:
Christian Schmitt 2013-03-07 23:31:01 +01:00
parent 46eadabf3a
commit 08bae40991
5 changed files with 81 additions and 11 deletions

View file

@ -557,6 +557,7 @@ public:
setRunwayReciprocal = prepare("UPDATE runway SET reciprocal=?2 WHERE rowid=?1");
setRunwayILS = prepare("UPDATE runway SET ils=?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 "
@ -789,12 +790,17 @@ public:
}
int rangeNm = sqlite3_column_int(loadNavaid, 0),
freq = sqlite3_column_int(loadNavaid, 1);
freq = sqlite3_column_int(loadNavaid, 1);
double mulituse = sqlite3_column_double(loadNavaid, 2);
//sqlite3_int64 colocated = sqlite3_column_int64(loadNavaid, 4);
PositionedID colocated = sqlite3_column_int64(loadNavaid, 4);
reset(loadNavaid);
return new FGNavRecord(rowId, ty, id, name, pos, freq, rangeNm, mulituse, runway);
FGNavRecord* n = new FGNavRecord(rowId, ty, id, name, pos, freq, rangeNm, mulituse, runway);
if (colocated) {
n->setColocatedDME(colocated);
}
return n;
}
FGPositioned* loadParking(sqlite3_int64 rowId,
@ -965,7 +971,7 @@ public:
sqlite3_stmt_ptr insertPositionedQuery, insertAirport, insertTower, insertRunway,
insertCommStation, insertNavaid;
sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS,
sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS, setNavaidColocated,
setAirportPos, updateRunwayThreshold, updateILS;
sqlite3_stmt_ptr removePOIQuery;
@ -1631,9 +1637,24 @@ NavDataCache::insertNavaid(FGPositioned::Type ty, const string& ident,
sqlite3_bind_int(d->insertNavaid, 3, range);
sqlite3_bind_double(d->insertNavaid, 4, multiuse);
sqlite3_bind_int64(d->insertNavaid, 5, runway);
sqlite3_bind_int64(d->insertNavaid, 6, 0);
return d->execInsert(d->insertNavaid);
}
void NavDataCache::setNavaidColocated(PositionedID navaid, PositionedID colocatedDME)
{
// Update DB entries...
sqlite3_bind_int64(d->setNavaidColocated, 1, navaid);
sqlite3_bind_int64(d->setNavaidColocated, 2, colocatedDME);
d->execUpdate(d->setNavaidColocated);
// ...and the in-memory copy of the navrecord
if (d->cache.find(navaid) != d->cache.end()) {
FGNavRecord* rec = (FGNavRecord*) d->cache[navaid].get();
rec->setColocatedDME(colocatedDME);
}
}
void NavDataCache::updateILS(PositionedID ils, const SGGeod& newPos, double aHdg)
{
sqlite3_bind_int64(d->updateILS, 1, ils);

View file

@ -110,6 +110,10 @@ public:
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);
PositionedID insertCommStation(FGPositioned::Type ty,
const std::string& name, const SGGeod& pos, int freq, int range,
@ -192,7 +196,7 @@ public:
* Given a runway and type, find the corresponding navaid (ILS / GS / OM)
*/
PositionedID findNavaidForRunway(PositionedID runway, FGPositioned::Type ty);
/**
* given a navaid name (or similar) from apt.dat / nav.dat, find the
* corresponding airport and runway IDs.

View file

@ -126,7 +126,7 @@ static double defaultNavRange(const string& ident, FGPositioned::Type type)
namespace flightgear
{
static PositionedID readNavFromStream(std::istream& aStream,
FGPositioned::Type type = FGPositioned::INVALID)
{
@ -175,9 +175,36 @@ static PositionedID readNavFromStream(std::istream& aStream,
AirportRunwayPair arp;
FGRunway* runway = NULL;
// FIXME - also relate DMEs, but only ILS/LOC DMEs - need a heuristic
// on the DME naming string
PositionedID navaid_dme = 0;
if (type == FGPositioned::DME) {
FGPositioned::TypeFilter f(FGPositioned::INVALID);
if ( name.find("VOR-DME") != std::string::npos ) {
f.addType(FGPositioned::VOR);
} else if ( name.find("DME-ILS") != std::string::npos ) {
f.addType(FGPositioned::ILS);
f.addType(FGPositioned::LOC);
} else if ( name.find("VORTAC") != std::string::npos ) {
f.addType(FGPositioned::VOR);
} else if ( name.find("NDB-DME") != std::string::npos ) {
f.addType(FGPositioned::NDB);
} else if ( name.find("TACAN") != std::string::npos ) {
f.addType(FGPositioned::VOR);
}
if (f.maxType() > 0) {
FGPositionedRef ref = FGPositioned::findClosestWithIdent(ident, pos, &f);
if (ref.valid()) {
string_list dme_part = simgear::strutils::split(name , 0 ,1);
string_list navaid_part = simgear::strutils::split(ref.get()->name(), 0 ,1);
if ( simgear::strutils::uppercase(navaid_part[0]) == simgear::strutils::uppercase(dme_part[0]) ) {
navaid_dme = ref.get()->guid();
}
}
}
}
if ((type >= FGPositioned::ILS) && (type <= FGPositioned::GS)) {
arp = cache->findAirportRunway(name);
if (arp.second) {
@ -211,6 +238,10 @@ static PositionedID readNavFromStream(std::istream& aStream,
if (isLoc) {
cache->setRunwayILS(arp.second, r);
}
if (navaid_dme) {
cache->setNavaidColocated(navaid_dme, r);
}
return r;
}

View file

@ -50,6 +50,7 @@ FGNavRecord::FGNavRecord(PositionedID aGuid, Type aTy, const std::string& aIdent
multiuse(aMultiuse),
mName(aName),
mRunway(aRunway),
mColocated(0),
serviceable(true)
{
}
@ -92,6 +93,16 @@ double FGNavRecord::localizerWidth() const
}
bool FGNavRecord::hasDME()
{
return (mColocated > 0);
}
void FGNavRecord::setColocatedDME(PositionedID other)
{
mColocated = other;
}
FGTACANRecord::FGTACANRecord(void) :
channel(""),
freq(0)

View file

@ -46,7 +46,7 @@ class FGNavRecord : public FGPositioned
std::string mName; // verbose name in nav database
PositionedID mRunway; // associated runway, if there is one
PositionedID mColocated; // Colocated DME at a navaid (ILS, VOR, TACAN, NDB)
bool serviceable; // for failure modeling
void processSceneryILS(SGPropertyNode* aILSNode);
@ -87,6 +87,9 @@ public:
void bindToNode(SGPropertyNode* nd) const;
void unbindFromNode(SGPropertyNode* nd) const;
void setColocatedDME(PositionedID other);
bool hasDME();
};
class FGTACANRecord : public SGReferenced {