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"); 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");
updateRunwayThreshold = prepare("UPDATE runway SET heading=?2, displaced_threshold=?3, stopway=?4 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 "
@ -789,12 +790,17 @@ public:
} }
int rangeNm = sqlite3_column_int(loadNavaid, 0), 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); double mulituse = sqlite3_column_double(loadNavaid, 2);
//sqlite3_int64 colocated = sqlite3_column_int64(loadNavaid, 4); PositionedID colocated = sqlite3_column_int64(loadNavaid, 4);
reset(loadNavaid); 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, FGPositioned* loadParking(sqlite3_int64 rowId,
@ -965,7 +971,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, sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS, setNavaidColocated,
setAirportPos, updateRunwayThreshold, updateILS; setAirportPos, updateRunwayThreshold, updateILS;
sqlite3_stmt_ptr removePOIQuery; 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_int(d->insertNavaid, 3, range);
sqlite3_bind_double(d->insertNavaid, 4, multiuse); sqlite3_bind_double(d->insertNavaid, 4, multiuse);
sqlite3_bind_int64(d->insertNavaid, 5, runway); sqlite3_bind_int64(d->insertNavaid, 5, runway);
sqlite3_bind_int64(d->insertNavaid, 6, 0);
return d->execInsert(d->insertNavaid); 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) void NavDataCache::updateILS(PositionedID ils, const SGGeod& newPos, double aHdg)
{ {
sqlite3_bind_int64(d->updateILS, 1, ils); sqlite3_bind_int64(d->updateILS, 1, ils);

View file

@ -111,6 +111,10 @@ public:
PositionedID apt, PositionedID runway); PositionedID apt, PositionedID runway);
void updateILS(PositionedID ils, const SGGeod& newPos, double aHdg); 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, PositionedID insertCommStation(FGPositioned::Type ty,
const std::string& name, const SGGeod& pos, int freq, int range, const std::string& name, const SGGeod& pos, int freq, int range,
PositionedID apt); PositionedID apt);

View file

@ -175,9 +175,36 @@ static PositionedID readNavFromStream(std::istream& aStream,
AirportRunwayPair arp; AirportRunwayPair arp;
FGRunway* runway = NULL; FGRunway* runway = NULL;
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();
}
}
}
}
// FIXME - also relate DMEs, but only ILS/LOC DMEs - need a heuristic
// on the DME naming string
if ((type >= FGPositioned::ILS) && (type <= FGPositioned::GS)) { if ((type >= FGPositioned::ILS) && (type <= FGPositioned::GS)) {
arp = cache->findAirportRunway(name); arp = cache->findAirportRunway(name);
if (arp.second) { if (arp.second) {
@ -212,6 +239,10 @@ static PositionedID readNavFromStream(std::istream& aStream,
cache->setRunwayILS(arp.second, r); cache->setRunwayILS(arp.second, r);
} }
if (navaid_dme) {
cache->setNavaidColocated(navaid_dme, r);
}
return r; return r;
} }

View file

@ -50,6 +50,7 @@ FGNavRecord::FGNavRecord(PositionedID aGuid, Type aTy, const std::string& aIdent
multiuse(aMultiuse), multiuse(aMultiuse),
mName(aName), mName(aName),
mRunway(aRunway), mRunway(aRunway),
mColocated(0),
serviceable(true) 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) : FGTACANRecord::FGTACANRecord(void) :
channel(""), channel(""),
freq(0) freq(0)

View file

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