#include <simgear/misc/strutils.hxx>
#include <simgear/math/sg_geodesy.hxx>
+#include <cstdio>
#include <sstream>
#include <iomanip>
#include <iostream> // for cout, endl
#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"
_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);
}
}
_testModeNode->setBoolValue(false);
_viewHeadingNode = _Instrument->getChild("view-heading-deg", 0, true);
+ _userLatNode = _Instrument->getChild("user-latitude-deg", 0, true);
+ _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;
_projectMat = osg::Matrixf::scale(_scale, _scale, 1.0) *
degRotation(-_view_heading) * _centerTrans;
- _pos = globals->get_aircraft_position();
-
+ if (_userPositionEnable->getBoolValue()) {
+ _pos = SGGeod::fromDeg(_userLonNode->getDoubleValue(), _userLatNode->getDoubleValue());
+ } else {
+ _pos = globals->get_aircraft_position();
+ }
+
// invalidate the cache of positioned items, if we travelled more than 1nm
if (_cachedItemsValid) {
SGVec3d cartNow(SGVec3d::fromGeod(_pos));
processRoute();
processNavRadios();
processAI();
+ processCustomSymbols();
findItems();
limitDisplayedSymbols();
}
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
_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
+}
+
+