From 0931fe332ea14196c6041221f2bcafc00cfd9999 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 19 Dec 2010 16:18:12 +0000 Subject: [PATCH 1/1] Guard against NaN SGGeods in FGPositioned spatial queries, and in the GPS lat/lon reading code. --- src/Instrumentation/gps.cxx | 9 ++++++++- src/Navaids/positioned.cxx | 35 ++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx index 7e4b2b398..853d49d46 100644 --- a/src/Instrumentation/gps.cxx +++ b/src/Instrumentation/gps.cxx @@ -72,6 +72,13 @@ SGGeod SGGeodProperty::get() const { double lon = _lon->getDoubleValue(), lat = _lat->getDoubleValue(); + + if (osg::isNaN(lon) || osg::isNaN(lat)) { + SG_LOG(SG_INSTR, SG_WARN, "read NaN for lon/lat:" << _lon->getPath() + << ", " << _lat->getPath()); + return SGGeod(); + } + if (_alt) { return SGGeod::fromDegFt(lon, lat, _alt->getDoubleValue()); } else { @@ -490,7 +497,7 @@ GPS::update (double delta_time_sec) } // of init mode check _last_pos = _indicated_pos; - _lastPosValid = true; + _lastPosValid = !(_last_pos == SGGeod()); } /////////////////////////////////////////////////////////////////////////// diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index fcf5ec848..b74e4e877 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -32,6 +32,8 @@ #include #include +#include // for osg::isNaN + #include #include #include @@ -500,6 +502,15 @@ char** searchAirportNamesAndIdents(const std::string& aFilter) return result; } +static void validateSGGeod(const SGGeod& geod) +{ + if (osg::isNaN(geod.getLatitudeDeg()) || + osg::isNaN(geod.getLongitudeDeg())) + { + throw sg_range_exception("position is invalid, NaNs"); + } +} + /////////////////////////////////////////////////////////////////////////////// bool @@ -672,6 +683,8 @@ const char* FGPositioned::nameForType(Type aTy) FGPositionedRef FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter) { + validateSGGeod(aPos); + FGPositioned::List r(findAll(global_identIndex, aIdent, aFilter, true)); if (r.empty()) { return FGPositionedRef(); @@ -684,6 +697,8 @@ FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos FGPositioned::List FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter) { + validateSGGeod(aPos); + List result; Octree::findAllWithinRange(SGVec3d::fromGeod(aPos), aRangeNm * SG_NM_TO_METER, aFilter, result); @@ -705,18 +720,22 @@ FGPositioned::findAllWithName(const std::string& aName, Filter* aFilter, bool aE FGPositionedRef FGPositioned::findClosest(const SGGeod& aPos, double aCutoffNm, Filter* aFilter) { - List l(findClosestN(aPos, 1, aCutoffNm, aFilter)); - if (l.empty()) { - return NULL; - } - - assert(l.size() == 1); - return l.front(); + validateSGGeod(aPos); + + List l(findClosestN(aPos, 1, aCutoffNm, aFilter)); + if (l.empty()) { + return NULL; + } + + assert(l.size() == 1); + return l.front(); } FGPositioned::List FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter) { + validateSGGeod(aPos); + List result; Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result); return result; @@ -772,6 +791,8 @@ FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId void FGPositioned::sortByRange(List& aResult, const SGGeod& aPos) { + validateSGGeod(aPos); + SGVec3d cartPos(SGVec3d::fromGeod(aPos)); // computer ordering values Octree::FindNearestResults r; -- 2.39.5