From 6434163e650ef1be340de596e87493264f72c6fc Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 27 Nov 2012 22:42:46 +0000 Subject: [PATCH] Bug #927 - flightplan XML loading. This bug was caused by the code not tolerating missing navaids / waypoints. Update logic so missing navaids degenerate to basic waypoints without problem. Also tolerate present, but empty, runway properties - don't throw an exception by looking up empty identifiers. --- src/Navaids/FlightPlan.cxx | 23 +++++++++++++++-------- src/Navaids/route.cxx | 12 +++++++++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Navaids/FlightPlan.cxx b/src/Navaids/FlightPlan.cxx index 3f3eff4f6..cb7e41c0d 100644 --- a/src/Navaids/FlightPlan.cxx +++ b/src/Navaids/FlightPlan.cxx @@ -612,8 +612,9 @@ void FlightPlan::loadXMLRouteHeader(SGPropertyNode_ptr routeData) string depIdent = dep->getStringValue("airport"); setDeparture((FGAirport*) fgFindAirportID(depIdent)); if (_departure) { - if (dep->hasChild("runway")) { - setDeparture(_departure->getRunwayByIdent(dep->getStringValue("runway"))); + string rwy(dep->getStringValue("runway")); + if (_departure->hasRunwayWithIdent(rwy)) { + setDeparture(_departure->getRunwayByIdent(rwy)); } if (dep->hasChild("sid")) { @@ -628,8 +629,9 @@ void FlightPlan::loadXMLRouteHeader(SGPropertyNode_ptr routeData) if (dst) { setDestination((FGAirport*) fgFindAirportID(dst->getStringValue("airport"))); if (_destination) { - if (dst->hasChild("runway")) { - setDestination(_destination->getRunwayByIdent(dst->getStringValue("runway"))); + string rwy(dst->getStringValue("runway")); + if (_destination->hasRunwayWithIdent(rwy)) { + setDestination(_destination->getRunwayByIdent(rwy)); } if (dst->hasChild("star")) { @@ -709,18 +711,23 @@ WayptRef FlightPlan::parseVersion1XMLWaypt(SGPropertyNode* aWP) } else { string nid = aWP->getStringValue("navid", ident.c_str()); FGPositionedRef p = FGPositioned::findClosestWithIdent(nid, lastPos); - if (!p) { - throw sg_io_exception("bad route file, unknown navid:" + nid); + SGGeod pos; + + if (p) { + pos = p->geod(); + } else { + SG_LOG(SG_GENERAL, SG_WARN, "unknown navaid in flightplan:" << nid); + pos = SGGeod::fromDeg(aWP->getDoubleValue("longitude-deg"), + aWP->getDoubleValue("latitude-deg")); } - SGGeod pos(p->geod()); if (aWP->hasChild("offset-nm") && aWP->hasChild("offset-radial")) { double radialDeg = aWP->getDoubleValue("offset-radial"); // convert magnetic radial to a true radial! radialDeg += magvarDegAt(pos); double offsetNm = aWP->getDoubleValue("offset-nm"); double az2; - SGGeodesy::direct(p->geod(), radialDeg, offsetNm * SG_NM_TO_METER, pos, az2); + SGGeodesy::direct(pos, radialDeg, offsetNm * SG_NM_TO_METER, pos, az2); } w = new BasicWaypt(pos, ident, NULL); diff --git a/src/Navaids/route.cxx b/src/Navaids/route.cxx index 952860c4d..9123d24c3 100644 --- a/src/Navaids/route.cxx +++ b/src/Navaids/route.cxx @@ -237,7 +237,17 @@ WayptRef Waypt::createFromProperties(RouteBase* aOwner, SGPropertyNode_ptr aProp "Waypt::createFromProperties"); } - WayptRef nd(createInstance(aOwner, aProp->getStringValue("type"))); + try { + WayptRef nd(createInstance(aOwner, aProp->getStringValue("type"))); + nd->initFromProperties(aProp); + return nd; + } catch (sg_exception& e) { + SG_LOG(SG_GENERAL, SG_WARN, "failed to create waypoint, trying basic:" << e.getMessage()); + } + +// 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 + WayptRef nd(new BasicWaypt(aOwner)); nd->initFromProperties(aProp); return nd; }