diff --git a/src/Navaids/FlightPlan.cxx b/src/Navaids/FlightPlan.cxx index 2cd97607a..7da7e09d5 100644 --- a/src/Navaids/FlightPlan.cxx +++ b/src/Navaids/FlightPlan.cxx @@ -766,41 +766,45 @@ void FlightPlan::saveToProperties(SGPropertyNode* d) const bool FlightPlan::load(const SGPath& path) { - if (!path.exists()) - { - SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load flight-plan '" << path - << "'. The file does not exist."); - return false; - } - - SG_LOG(SG_NAVAID, SG_INFO, "going to read flight-plan from:" << path); - - bool Status = false; - lockDelegates(); - - // try different file formats - if (loadGpxFormat(path)) // GPX format - Status = true; - else - if (loadXmlFormat(path)) // XML property data - Status = true; - else - if (loadPlainTextFormat(path)) // simple textual list of waypoints - Status = true; - - - if (Status == true) { - setIdent(path.file_base()); - } - - // mark data as unchanged since this is a clean plan - _arrivalChanged = false; - _departureChanged = false; - _cruiseDataChanged = true; - _waypointsChanged = true; - unlockDelegates(); - - return Status; + if (!path.exists()) { + SG_LOG(SG_NAVAID, SG_ALERT, "Failed to load flight-plan '" << path + << "'. The file does not exist."); + return false; + } + + SG_LOG(SG_NAVAID, SG_INFO, "going to read flight-plan from:" << path); + + bool Status = false; + lockDelegates(); + + // try different file formats + if (loadGpxFormat(path)) { // GPX format + _arrivalChanged = true; + _departureChanged = true; + Status = true; + } else if (loadXmlFormat(path)) { // XML property data + // we don't want to re-compute the arrival / departure after + // a load, since we assume the flight-plan had it specified already + // especially, the XML might have a SID/STAR embedded, which we don't + // want to lose + _arrivalChanged = false; + _departureChanged = false; + Status = true; + } else if (loadPlainTextFormat(path)) { // simple textual list of waypoints + _arrivalChanged = true; + _departureChanged = true; + Status = true; + } + + if (Status == true) { + setIdent(path.file_base()); + } + + _cruiseDataChanged = true; + _waypointsChanged = true; + unlockDelegates(); + + return Status; } bool FlightPlan::load(std::istream &stream) diff --git a/test_suite/unit_tests/Navaids/test_routeManager.cxx b/test_suite/unit_tests/Navaids/test_routeManager.cxx index fe8be0ed6..4c9e29312 100644 --- a/test_suite/unit_tests/Navaids/test_routeManager.cxx +++ b/test_suite/unit_tests/Navaids/test_routeManager.cxx @@ -3,6 +3,9 @@ #include #include +#include +#include + #include "test_suite/FGTestApi/testGlobals.hxx" #include "test_suite/FGTestApi/NavDataCache.hxx" #include "test_suite/FGTestApi/TestPilot.hxx" @@ -544,3 +547,53 @@ void RouteManagerTests::testHoldFromNasal() // get back on course FGTestApi::runForTime(60.0); } + +// check that when loading a GPX, airport waypoints are created +// by the default delegate +// https://sourceforge.net/p/flightgear/codetickets/2227/ +void RouteManagerTests::loadGPX() +{ + auto rm = globals->get_subsystem(); + + FlightPlanRef f = new FlightPlan; + rm->setFlightPlan(f); + + SGPath gpxPath = simgear::Dir::current().path() / "test_gpx.gpx"; + { + sg_ofstream s(gpxPath); + s << R"( + + + KJFK-KBOS + + KJFK + false + + + HFD + false + + + KBOS + false + + + + + )"; + } + + CPPUNIT_ASSERT(f->load(gpxPath)); + + auto kbos = FGAirport::getByIdent("KBOS"); + auto kjfk = FGAirport::getByIdent("KJFK"); + CPPUNIT_ASSERT_EQUAL(kjfk, f->departureAirport()); + CPPUNIT_ASSERT_EQUAL(static_cast(nullptr), f->departureRunway()); + CPPUNIT_ASSERT_EQUAL(3, f->numLegs()); + CPPUNIT_ASSERT_EQUAL(kbos, f->destinationAirport()); + + auto wp1 = f->legAtIndex(1); + CPPUNIT_ASSERT_EQUAL(std::string{"HFD"}, wp1->waypoint()->ident()); + + +} diff --git a/test_suite/unit_tests/Navaids/test_routeManager.hxx b/test_suite/unit_tests/Navaids/test_routeManager.hxx index e0ecf7c44..e66f36cc6 100644 --- a/test_suite/unit_tests/Navaids/test_routeManager.hxx +++ b/test_suite/unit_tests/Navaids/test_routeManager.hxx @@ -40,6 +40,7 @@ class RouteManagerTests : public CppUnit::TestFixture CPPUNIT_TEST(testHoldFromNasal); CPPUNIT_TEST(testSequenceDiscontinuityAndResume); CPPUNIT_TEST(testHiddenWaypoints); + CPPUNIT_TEST(loadGPX); CPPUNIT_TEST_SUITE_END(); @@ -62,6 +63,7 @@ public: void testHoldFromNasal(); void testSequenceDiscontinuityAndResume(); void testHiddenWaypoints(); + void loadGPX(); private: GPS* m_gps = nullptr; };