From: Christian Schmitt Date: Thu, 7 Mar 2013 22:31:01 +0000 (+0100) Subject: Parse nav.dat DMEs and assign them to appropriate navaid, if applicable. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=08bae4099129a047fd9081e71d06e7130feb3115;p=flightgear.git 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 --- diff --git a/src/Navaids/NavDataCache.cxx b/src/Navaids/NavDataCache.cxx index 86f292662..5928ddaa6 100644 --- a/src/Navaids/NavDataCache.cxx +++ b/src/Navaids/NavDataCache.cxx @@ -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); diff --git a/src/Navaids/NavDataCache.hxx b/src/Navaids/NavDataCache.hxx index e0f8ed84c..316167693 100644 --- a/src/Navaids/NavDataCache.hxx +++ b/src/Navaids/NavDataCache.hxx @@ -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. diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 1a3613c15..99453022a 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -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; } diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx index d9b3a18d6..8700a577f 100644 --- a/src/Navaids/navrecord.cxx +++ b/src/Navaids/navrecord.cxx @@ -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) diff --git a/src/Navaids/navrecord.hxx b/src/Navaids/navrecord.hxx index cf9e69579..e4f28c5f8 100644 --- a/src/Navaids/navrecord.hxx +++ b/src/Navaids/navrecord.hxx @@ -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 {