Bugfix: fix range/ident priority of loaded wpts
When the lat-lon of a waypoint disagrees with the discovered ident by more than a threshold, assume we have a DB mismatch, and just revert to a basic wpt specified by lat-lon. This avoids inserting huge legs by selecting a very distant navaid with matching ident https://sourceforge.net/p/flightgear/codetickets/1814/
This commit is contained in:
parent
b3bcfb084e
commit
1cbcae9795
6 changed files with 71 additions and 7 deletions
|
@ -1111,9 +1111,8 @@ void FlightPlan::loadVersion2XMLRoute(SGPropertyNode_ptr routeData)
|
|||
_legs.clear();
|
||||
SGPropertyNode_ptr routeNode = routeData->getChild("route", 0);
|
||||
if (routeNode.valid()) {
|
||||
for (int i=0; i<routeNode->nChildren(); ++i) {
|
||||
SGPropertyNode_ptr wpNode = routeNode->getChild("wp", i);
|
||||
Leg* l = new Leg(this, Waypt::createFromProperties(this, wpNode));
|
||||
for (auto wpNode : routeNode->getChildren("wp")) {
|
||||
Leg* l = new Leg{this, Waypt::createFromProperties(this, wpNode)};
|
||||
_legs.push_back(l);
|
||||
} // of route iteration
|
||||
}
|
||||
|
|
|
@ -369,6 +369,7 @@ AirwayRef Airway::findByIdentAndNavaid(const std::string& aIdent, const FGPositi
|
|||
|
||||
WayptRef Airway::findEnroute(const std::string &aIdent) const
|
||||
{
|
||||
loadWaypoints();
|
||||
auto it = std::find_if(_elements.begin(), _elements.end(),
|
||||
[&aIdent](WayptRef w)
|
||||
{
|
||||
|
|
|
@ -256,6 +256,9 @@ WayptRef Waypt::createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp
|
|||
|
||||
// if we failed to make the waypoint, try again making a basic waypoint.
|
||||
// this handles the case where a navaid waypoint is missing, for example
|
||||
// we also reject navaids that don't look correct (too far form the specified
|
||||
// lat-lon, eg see https://sourceforge.net/p/flightgear/codetickets/1814/ )
|
||||
// and again fallback to here.
|
||||
WayptRef nd(new BasicWaypt(aOwner));
|
||||
nd->initFromProperties(aProp);
|
||||
return nd;
|
||||
|
|
|
@ -119,11 +119,21 @@ void NavaidWaypoint::initFromProperties(SGPropertyNode_ptr aProp)
|
|||
|
||||
// FIXME - resolve co-located DME, etc
|
||||
// is it sufficent just to ignore DMEs, actually?
|
||||
FGPositionedRef nav = FGPositioned::findClosestWithIdent(idn, p, NULL);
|
||||
FGPositionedRef nav = FGPositioned::findClosestWithIdent(idn, p, nullptr);
|
||||
if (!nav) {
|
||||
throw sg_io_exception("unknown navaid ident:" + idn,
|
||||
"NavaidWaypoint::initFromProperties");
|
||||
}
|
||||
|
||||
if (p.isValid() && (SGGeodesy::distanceM(nav->geod(), p) > 4000)) {
|
||||
// the looked up navaid was more than 4000 metres from the lat/lon.
|
||||
// in this case, throw an exception here so we fall back to using
|
||||
// a basic waypoint
|
||||
// see https://sourceforge.net/p/flightgear/codetickets/1814/
|
||||
throw sg_io_exception("Waypoint navaid for ident:" + idn +
|
||||
" is too far from specified lat/lon in flight-plan",
|
||||
"NavaidWaypoint::initFromProperties");
|
||||
}
|
||||
|
||||
_navaid = nav;
|
||||
}
|
||||
|
|
|
@ -226,3 +226,51 @@ void FlightplanTests::testParseICANLowLevelRoute()
|
|||
bool ok = f->parseICAORouteString(route);
|
||||
CPPUNIT_ASSERT(ok);
|
||||
}
|
||||
|
||||
// https://sourceforge.net/p/flightgear/codetickets/1814/
|
||||
void FlightplanTests::testBug1814()
|
||||
{
|
||||
const std::string fpXML = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PropertyList>
|
||||
<version type="int">2</version>
|
||||
<departure>
|
||||
<airport type="string">SAWG</airport>
|
||||
<runway type="string">25</runway>
|
||||
</departure>
|
||||
<destination>
|
||||
<airport type="string">SUMU</airport>
|
||||
</destination>
|
||||
<route>
|
||||
<wp n="6">
|
||||
<type type="string">navaid</type>
|
||||
<ident type="string">PUGLI</ident>
|
||||
<lon type="double">-60.552200</lon>
|
||||
<lat type="double">-40.490000</lat>
|
||||
</wp>
|
||||
<wp n="7">
|
||||
<type type="string">navaid</type>
|
||||
<ident type="string">SIGUL</ident>
|
||||
<lon type="double">-59.655800</lon>
|
||||
<lat type="double">-38.312800</lat>
|
||||
</wp>
|
||||
<wp n="8">
|
||||
<type type="string">navaid</type>
|
||||
<ident type="string">MDP</ident>
|
||||
<lon type="double">-57.576400</lon>
|
||||
<lat type="double">-37.929800</lat>
|
||||
</wp>
|
||||
</route>
|
||||
</PropertyList>
|
||||
)";
|
||||
|
||||
std::istringstream stream(fpXML);
|
||||
FlightPlanRef f = new FlightPlan;
|
||||
bool ok = f->load(stream);
|
||||
CPPUNIT_ASSERT(ok);
|
||||
|
||||
auto leg = f->legAtIndex(1);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("SIGUL"), leg->waypoint()->ident());
|
||||
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(137, leg->distanceNm(), 0.5);
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL(101, f->legAtIndex(2)->distanceNm(), 0.5);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef _FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||
#define _FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||
#ifndef FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||
#define FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
@ -37,6 +37,8 @@ class FlightplanTests : public CppUnit::TestFixture
|
|||
CPPUNIT_TEST(testRoutePathTrivialFlightPlan);
|
||||
CPPUNIT_TEST(testBasicAirways);
|
||||
CPPUNIT_TEST(testAirwayNetworkRoute);
|
||||
CPPUNIT_TEST(testBug1814);
|
||||
|
||||
// CPPUNIT_TEST(testParseICAORoute);
|
||||
// CPPUNIT_TEST(testParseICANLowLevelRoute);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
@ -57,6 +59,7 @@ public:
|
|||
void testAirwayNetworkRoute();
|
||||
void testParseICAORoute();
|
||||
void testParseICANLowLevelRoute();
|
||||
void testBug1814();
|
||||
};
|
||||
|
||||
#endif // _FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||
#endif // FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||
|
|
Loading…
Reference in a new issue