]> git.mxchange.org Git - flightgear.git/commitdiff
Parse nav.dat DMEs and assign them to appropriate navaid, if applicable.
authorChristian Schmitt <chris@ilovelinux.de>
Thu, 7 Mar 2013 22:31:01 +0000 (23:31 +0100)
committerChristian Schmitt <chris@ilovelinux.de>
Fri, 15 Mar 2013 13:07:31 +0000 (14:07 +0100)
We can now detect whether a DME is colocated at a VOR/ILS/VORTAC/TACAN/NDB

src/Navaids/NavDataCache.cxx
src/Navaids/NavDataCache.hxx
src/Navaids/navdb.cxx
src/Navaids/navrecord.cxx
src/Navaids/navrecord.hxx

index 86f292662c8781156d7b42db9dfcf0ec6c087191..5928ddaa6a68a3b8f549c6354a5a8640744e24be 100644 (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);
index e0f8ed84cd5fdac6dcce2b0316f8fbac21aef9bb..31616769301fd2d79f4e0e45a95bcb0ff17d3bf0 100644 (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.
index 1a3613c15ad2ab0b6df1e34a46a8ec6812e05293..99453022a826c45185b2b48a032939adffd3ca1e 100644 (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;
 }
index d9b3a18d6765a615769cd39c33e28ff2cd847823..8700a577f5ec1bab04dcac85d3944d815b130749 100644 (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)
index cf9e695794387b65df04f52f8056304ab49b44da..e4f28c5f8598ad71555f1d92399d4aa6a662d937 100644 (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 {