1
0
Fork 0

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:
James Turner 2018-10-08 16:40:15 +01:00
parent b3bcfb084e
commit 1cbcae9795
6 changed files with 71 additions and 7 deletions

View file

@ -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
}

View file

@ -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)
{

View file

@ -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;

View file

@ -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;
}

View file

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

View file

@ -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