Guard against NaN SGGeods in FGPositioned spatial queries, and in the GPS lat/lon reading code.
This commit is contained in:
parent
099d6475fd
commit
0931fe332e
2 changed files with 36 additions and 8 deletions
src
|
@ -72,6 +72,13 @@ SGGeod SGGeodProperty::get() const
|
||||||
{
|
{
|
||||||
double lon = _lon->getDoubleValue(),
|
double lon = _lon->getDoubleValue(),
|
||||||
lat = _lat->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) {
|
if (_alt) {
|
||||||
return SGGeod::fromDegFt(lon, lat, _alt->getDoubleValue());
|
return SGGeod::fromDegFt(lon, lat, _alt->getDoubleValue());
|
||||||
} else {
|
} else {
|
||||||
|
@ -490,7 +497,7 @@ GPS::update (double delta_time_sec)
|
||||||
} // of init mode check
|
} // of init mode check
|
||||||
|
|
||||||
_last_pos = _indicated_pos;
|
_last_pos = _indicated_pos;
|
||||||
_lastPosValid = true;
|
_lastPosValid = !(_last_pos == SGGeod());
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
|
#include <osg/Math> // for osg::isNaN
|
||||||
|
|
||||||
#include <simgear/timing/timestamp.hxx>
|
#include <simgear/timing/timestamp.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
|
@ -500,6 +502,15 @@ char** searchAirportNamesAndIdents(const std::string& aFilter)
|
||||||
return result;
|
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
|
bool
|
||||||
|
@ -672,6 +683,8 @@ const char* FGPositioned::nameForType(Type aTy)
|
||||||
FGPositionedRef
|
FGPositionedRef
|
||||||
FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter)
|
FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter)
|
||||||
{
|
{
|
||||||
|
validateSGGeod(aPos);
|
||||||
|
|
||||||
FGPositioned::List r(findAll(global_identIndex, aIdent, aFilter, true));
|
FGPositioned::List r(findAll(global_identIndex, aIdent, aFilter, true));
|
||||||
if (r.empty()) {
|
if (r.empty()) {
|
||||||
return FGPositionedRef();
|
return FGPositionedRef();
|
||||||
|
@ -684,6 +697,8 @@ FGPositioned::findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos
|
||||||
FGPositioned::List
|
FGPositioned::List
|
||||||
FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter)
|
FGPositioned::findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter)
|
||||||
{
|
{
|
||||||
|
validateSGGeod(aPos);
|
||||||
|
|
||||||
List result;
|
List result;
|
||||||
Octree::findAllWithinRange(SGVec3d::fromGeod(aPos),
|
Octree::findAllWithinRange(SGVec3d::fromGeod(aPos),
|
||||||
aRangeNm * SG_NM_TO_METER, aFilter, result);
|
aRangeNm * SG_NM_TO_METER, aFilter, result);
|
||||||
|
@ -705,18 +720,22 @@ FGPositioned::findAllWithName(const std::string& aName, Filter* aFilter, bool aE
|
||||||
FGPositionedRef
|
FGPositionedRef
|
||||||
FGPositioned::findClosest(const SGGeod& aPos, double aCutoffNm, Filter* aFilter)
|
FGPositioned::findClosest(const SGGeod& aPos, double aCutoffNm, Filter* aFilter)
|
||||||
{
|
{
|
||||||
List l(findClosestN(aPos, 1, aCutoffNm, aFilter));
|
validateSGGeod(aPos);
|
||||||
if (l.empty()) {
|
|
||||||
return NULL;
|
List l(findClosestN(aPos, 1, aCutoffNm, aFilter));
|
||||||
}
|
if (l.empty()) {
|
||||||
|
return NULL;
|
||||||
assert(l.size() == 1);
|
}
|
||||||
return l.front();
|
|
||||||
|
assert(l.size() == 1);
|
||||||
|
return l.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
FGPositioned::List
|
FGPositioned::List
|
||||||
FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter)
|
FGPositioned::findClosestN(const SGGeod& aPos, unsigned int aN, double aCutoffNm, Filter* aFilter)
|
||||||
{
|
{
|
||||||
|
validateSGGeod(aPos);
|
||||||
|
|
||||||
List result;
|
List result;
|
||||||
Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result);
|
Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -772,6 +791,8 @@ FGPositioned::findNextWithPartialId(FGPositionedRef aCur, const std::string& aId
|
||||||
void
|
void
|
||||||
FGPositioned::sortByRange(List& aResult, const SGGeod& aPos)
|
FGPositioned::sortByRange(List& aResult, const SGGeod& aPos)
|
||||||
{
|
{
|
||||||
|
validateSGGeod(aPos);
|
||||||
|
|
||||||
SGVec3d cartPos(SGVec3d::fromGeod(aPos));
|
SGVec3d cartPos(SGVec3d::fromGeod(aPos));
|
||||||
// computer ordering values
|
// computer ordering values
|
||||||
Octree::FindNearestResults r;
|
Octree::FindNearestResults r;
|
||||||
|
|
Loading…
Add table
Reference in a new issue