]> git.mxchange.org Git - flightgear.git/blobdiff - src/Cockpit/NavDisplay.cxx
Use new SGBucket API in tile-manager
[flightgear.git] / src / Cockpit / NavDisplay.cxx
index caf70b0ff1528ff3ee9d38570099efd0cf2fcb54..4c96c3ddea44e28b78e390634ea4a5cf20b5ec20 100644 (file)
@@ -46,6 +46,7 @@
 #include <simgear/misc/strutils.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 
+#include <cstdio>
 #include <sstream>
 #include <iomanip>
 #include <iostream>             // for cout, endl
@@ -69,7 +70,7 @@ using std::string;
 #include <Navaids/navrecord.hxx>
 #include <Navaids/navlist.hxx>
 #include <Navaids/fix.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
 #include <Airports/runways.hxx>
 #include "od_gauge.hxx"
 
@@ -476,28 +477,23 @@ NavDisplay::NavDisplay(SGPropertyNode *node) :
         _definitions.push_back(def);
     } // of symbol definition parsing
     
-    SGPropertyNode* rulesNode = node->getNode("rules");
-    if (rulesNode) {
-        SGPropertyNode* rule;
+    BOOST_FOREACH(SGPropertyNode* rule, symbolsNode->getChildren("rule")) {
+        SymbolRule* r = new SymbolRule;
+        if (!r->initFromNode(rule, this)) {
+            delete r;
+            continue;
+        }
         
-        for (int i = 0; (rule = rulesNode->getChild("rule", i)) != NULL; ++i) {
-            SymbolRule* r = new SymbolRule;
-            if (!r->initFromNode(rule, this)) {
-                delete r;
-                continue;
-            }
-            
-            const char* id = symbol->getStringValue("symbol");
-            if (id && strlen(id) && (definitionDict.find(id) != definitionDict.end())) {
-                r->setDefinition(definitionDict[id]);
-            } else {
-                SG_LOG(SG_INSTR, SG_WARN, "symbol rule has missing/unknown definition id:" << id);
-                delete r;
-                continue;
-            }
-            
-            addRule(r);
-        } // of symbol rule parsing
+        const char* id = rule->getStringValue("symbol");
+        if (id && strlen(id) && (definitionDict.find(id) != definitionDict.end())) {
+            r->setDefinition(definitionDict[id]);
+        } else {
+            SG_LOG(SG_INSTR, SG_WARN, "symbol rule has missing/unknown definition id:" << id);
+            delete r;
+            continue;
+        }
+        
+        addRule(r);
     }
     
 }
@@ -566,6 +562,8 @@ NavDisplay::init ()
     _userLonNode = _Instrument->getChild("user-longitude-deg", 0, true);
     _userPositionEnable = _Instrument->getChild("user-position", 0, true);
     
+    _customSymbols = _Instrument->getChild("symbols", 0, true);
+    
 // OSG geometry setup
     _radarGeode = new osg::Geode;
 
@@ -745,6 +743,7 @@ NavDisplay::update (double delta_time_sec)
     processRoute();
     processNavRadios();
     processAI();
+    processCustomSymbols();
     findItems();
     limitDisplayedSymbols();
   }
@@ -995,9 +994,16 @@ void NavDisplay::findItems()
     if (!_cachedItemsValid) {
         Filter filt(this);
         filt.minRunwayLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft", 2000);
-        _itemsInRange = FGPositioned::findClosestN(_pos, _maxSymbols, _rangeNm, &filt);
+        bool wasTimeLimited;
+        _itemsInRange = FGPositioned::findClosestNPartial(_pos, _maxSymbols, _rangeNm,
+                                                          &filt, wasTimeLimited);
         _cachedItemsValid = true;
         _cachedPos = SGVec3d::fromGeod(_pos);
+        
+        if (wasTimeLimited) {
+            // re-query next frame, to load incrementally
+            _cachedItemsValid = false;
+        }
     }
     
   // sort by distance from pos, so symbol limits are accurate
@@ -1439,3 +1445,39 @@ void NavDisplay::addRule(SymbolRule* r)
     _rules.push_back(r);
 }
 
+void NavDisplay::computeCustomSymbolStates(const SGPropertyNode* sym, string_set& states)
+{
+  BOOST_FOREACH(SGPropertyNode* st, sym->getChildren("state")) {
+    states.insert(st->getStringValue());
+  }
+}
+
+void NavDisplay::processCustomSymbols()
+{
+  for (int i = _customSymbols->nChildren() - 1; i >= 0; i--) {
+    SGPropertyNode *symNode = _customSymbols->getChild(i);
+    if (!symNode->nChildren()) {
+      continue;
+    }
+    string_set ss;
+    computeCustomSymbolStates(symNode, ss);
+    SymbolRuleVector rules;
+    findRules(symNode->getName(), ss, rules);
+    if (rules.empty()) {
+      return; // no rules matched, we can skip this item
+    }
+    
+    double heading = symNode->getDoubleValue("true-heading-deg", 0.0);
+    SGGeod pos = SGGeod::fromDegFt(symNode->getDoubleValue("longitude-deg"),
+                                          symNode->getDoubleValue("latitude-deg"),
+                                          symNode->getDoubleValue("altitude-ft"));
+    
+    osg::Vec2 projected = projectGeod(pos);
+    BOOST_FOREACH(SymbolRule* r, rules) {
+      addSymbolInstance(projected, heading, r->getDefinition(), symNode);
+    }
+  } // of custom symbols iteration
+}
+
+