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
src/Navaids
test_suite/unit_tests/Navaids
|
@ -1111,9 +1111,8 @@ void FlightPlan::loadVersion2XMLRoute(SGPropertyNode_ptr routeData)
|
||||||
_legs.clear();
|
_legs.clear();
|
||||||
SGPropertyNode_ptr routeNode = routeData->getChild("route", 0);
|
SGPropertyNode_ptr routeNode = routeData->getChild("route", 0);
|
||||||
if (routeNode.valid()) {
|
if (routeNode.valid()) {
|
||||||
for (int i=0; i<routeNode->nChildren(); ++i) {
|
for (auto wpNode : routeNode->getChildren("wp")) {
|
||||||
SGPropertyNode_ptr wpNode = routeNode->getChild("wp", i);
|
Leg* l = new Leg{this, Waypt::createFromProperties(this, wpNode)};
|
||||||
Leg* l = new Leg(this, Waypt::createFromProperties(this, wpNode));
|
|
||||||
_legs.push_back(l);
|
_legs.push_back(l);
|
||||||
} // of route iteration
|
} // of route iteration
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,6 +369,7 @@ AirwayRef Airway::findByIdentAndNavaid(const std::string& aIdent, const FGPositi
|
||||||
|
|
||||||
WayptRef Airway::findEnroute(const std::string &aIdent) const
|
WayptRef Airway::findEnroute(const std::string &aIdent) const
|
||||||
{
|
{
|
||||||
|
loadWaypoints();
|
||||||
auto it = std::find_if(_elements.begin(), _elements.end(),
|
auto it = std::find_if(_elements.begin(), _elements.end(),
|
||||||
[&aIdent](WayptRef w)
|
[&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.
|
// 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
|
// 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));
|
WayptRef nd(new BasicWaypt(aOwner));
|
||||||
nd->initFromProperties(aProp);
|
nd->initFromProperties(aProp);
|
||||||
return nd;
|
return nd;
|
||||||
|
|
|
@ -119,11 +119,21 @@ void NavaidWaypoint::initFromProperties(SGPropertyNode_ptr aProp)
|
||||||
|
|
||||||
// FIXME - resolve co-located DME, etc
|
// FIXME - resolve co-located DME, etc
|
||||||
// is it sufficent just to ignore DMEs, actually?
|
// is it sufficent just to ignore DMEs, actually?
|
||||||
FGPositionedRef nav = FGPositioned::findClosestWithIdent(idn, p, NULL);
|
FGPositionedRef nav = FGPositioned::findClosestWithIdent(idn, p, nullptr);
|
||||||
if (!nav) {
|
if (!nav) {
|
||||||
throw sg_io_exception("unknown navaid ident:" + idn,
|
throw sg_io_exception("unknown navaid ident:" + idn,
|
||||||
"NavaidWaypoint::initFromProperties");
|
"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;
|
_navaid = nav;
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,3 +226,51 @@ void FlightplanTests::testParseICANLowLevelRoute()
|
||||||
bool ok = f->parseICAORouteString(route);
|
bool ok = f->parseICAORouteString(route);
|
||||||
CPPUNIT_ASSERT(ok);
|
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
|
#ifndef FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||||
#define _FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
#define FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||||
|
|
||||||
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
@ -37,6 +37,8 @@ class FlightplanTests : public CppUnit::TestFixture
|
||||||
CPPUNIT_TEST(testRoutePathTrivialFlightPlan);
|
CPPUNIT_TEST(testRoutePathTrivialFlightPlan);
|
||||||
CPPUNIT_TEST(testBasicAirways);
|
CPPUNIT_TEST(testBasicAirways);
|
||||||
CPPUNIT_TEST(testAirwayNetworkRoute);
|
CPPUNIT_TEST(testAirwayNetworkRoute);
|
||||||
|
CPPUNIT_TEST(testBug1814);
|
||||||
|
|
||||||
// CPPUNIT_TEST(testParseICAORoute);
|
// CPPUNIT_TEST(testParseICAORoute);
|
||||||
// CPPUNIT_TEST(testParseICANLowLevelRoute);
|
// CPPUNIT_TEST(testParseICANLowLevelRoute);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
@ -57,6 +59,7 @@ public:
|
||||||
void testAirwayNetworkRoute();
|
void testAirwayNetworkRoute();
|
||||||
void testParseICAORoute();
|
void testParseICAORoute();
|
||||||
void testParseICANLowLevelRoute();
|
void testParseICANLowLevelRoute();
|
||||||
|
void testBug1814();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
#endif // FG_FLIGHTPLAN_UNIT_TESTS_HXX
|
||||||
|
|
Loading…
Add table
Reference in a new issue