1
0
Fork 0

Guard against NaN SGGeods in FGPositioned spatial queries, and in the GPS lat/lon reading code.

This commit is contained in:
James Turner 2010-12-19 16:18:12 +00:00
parent 099d6475fd
commit 0931fe332e
2 changed files with 36 additions and 8 deletions

View file

@ -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());
}
///////////////////////////////////////////////////////////////////////////

View file

@ -32,6 +32,8 @@
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <osg/Math> // for osg::isNaN
#include <simgear/timing/timestamp.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
@ -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;