1
0
Fork 0

Support PBD waypoints in procedures files.

http://code.google.com/p/flightgear-bugs/issues/detail?id=635
This commit is contained in:
James Turner 2012-05-02 22:09:41 +01:00
parent efee6ad968
commit ea73373109
3 changed files with 47 additions and 29 deletions

View file

@ -299,15 +299,17 @@ bool STAR::route(FGRunwayRef aWay, Waypt* aEnroute, WayptVec& aPath)
/////////////////////////////////////////////////////////////////////////////
Transition::Transition(const std::string& aIdent, Procedure* aPr,
const WayptVec& aWps) :
Transition::Transition(const std::string& aIdent, Procedure* aPr) :
_ident(aIdent),
_parent(aPr),
_primary(aWps)
_parent(aPr)
{
assert(aPr);
assert(!_primary.empty());
}
void Transition::setPrimary(const WayptVec& aWps)
{
_primary = aWps;
assert(!_primary.empty());
_primary[0]->setFlag(WPT_TRANSITION, true);
}

View file

@ -70,8 +70,10 @@ public:
private:
friend class NavdataVisitor;
Transition(const std::string& aIdent, Procedure* aPr, const WayptVec& aWps);
Transition(const std::string& aIdent, Procedure* aPr);
void setPrimary(const WayptVec& aWps);
std::string _ident;
Procedure* _parent;
WayptVec _primary;

View file

@ -368,7 +368,7 @@ protected:
virtual void error (const char * message, int line, int column);
private:
Waypt* buildWaypoint();
Waypt* buildWaypoint(Route* owner);
void processRunways(ArrivalDeparture* aProc, const XMLAttributes &atts);
void finishApproach();
@ -382,7 +382,9 @@ private:
SID* _sid;
STAR* _star;
Approach* _approach;
Transition* _transition;
Procedure* _procedure;
WayptVec _waypoints; ///< waypoint list for current approach/sid/star
WayptVec _transWaypts; ///< waypoint list for current transition
@ -408,10 +410,10 @@ void Route::loadAirportProcedures(const SGPath& aPath, FGAirport* aApt)
NavdataVisitor visitor(aApt, aPath);
readXML(aPath.str(), visitor);
} catch (sg_io_exception& ex) {
SG_LOG(SG_GENERAL, SG_WARN, "failured parsing procedures: " << aPath.str() <<
SG_LOG(SG_GENERAL, SG_WARN, "failure parsing procedures: " << aPath.str() <<
"\n\t" << ex.getMessage() << "\n\tat:" << ex.getLocation().asString());
} catch (sg_exception& ex) {
SG_LOG(SG_GENERAL, SG_WARN, "failured parsing procedures: " << aPath.str() <<
SG_LOG(SG_GENERAL, SG_WARN, "failure parsing procedures: " << aPath.str() <<
"\n\t" << ex.getMessage());
}
}
@ -421,7 +423,9 @@ NavdataVisitor::NavdataVisitor(FGAirport* aApt, const SGPath& aPath):
_path(aPath),
_sid(NULL),
_star(NULL),
_approach(NULL)
_approach(NULL),
_transition(NULL),
_procedure(NULL)
{
}
@ -445,11 +449,13 @@ void NavdataVisitor::startElement(const char* name, const XMLAttributes &atts)
} else if (tag == "Sid") {
string ident(atts.getValue("Name"));
_sid = new SID(ident);
_procedure = _sid;
_waypoints.clear();
processRunways(_sid, atts);
} else if (tag == "Star") {
string ident(atts.getValue("Name"));
_star = new STAR(ident);
_procedure = _star;
_waypoints.clear();
processRunways(_star, atts);
} else if ((tag == "Sid_Waypoint") ||
@ -467,13 +473,16 @@ void NavdataVisitor::startElement(const char* name, const XMLAttributes &atts)
_ident = atts.getValue("Name");
_waypoints.clear();
_approach = new Approach(_ident);
_procedure = _approach;
} else if ((tag == "Sid_Transition") ||
(tag == "App_Transition") ||
(tag == "Star_Transition")) {
_transIdent = atts.getValue("Name");
_transition = new Transition(_transIdent, _procedure);
_transWaypts.clear();
} else if (tag == "RunwayTransition") {
_transIdent = atts.getValue("Runway");
_transition = new Transition(_transIdent, _procedure);
_transWaypts.clear();
} else {
@ -509,27 +518,27 @@ void NavdataVisitor::endElement(const char* name)
(tag == "App_Waypoint") ||
(tag == "Star_Waypoint"))
{
_waypoints.push_back(buildWaypoint());
_waypoints.push_back(buildWaypoint(_procedure));
} else if ((tag == "AppTr_Waypoint") ||
(tag == "SidTr_Waypoint") ||
(tag == "RwyTr_Waypoint") ||
(tag == "StarTr_Waypoint"))
{
_transWaypts.push_back(buildWaypoint());
_transWaypts.push_back(buildWaypoint(_transition));
} else if (tag == "Sid_Transition") {
assert(_sid);
// SID waypoints are stored backwards, to share code with STARs
std::reverse(_transWaypts.begin(), _transWaypts.end());
Transition* t = new Transition(_transIdent, _sid, _transWaypts);
_sid->addTransition(t);
_transition->setPrimary(_transWaypts);
_sid->addTransition(_transition);
} else if (tag == "Star_Transition") {
assert(_star);
Transition* t = new Transition(_transIdent, _star, _transWaypts);
_star->addTransition(t);
_transition->setPrimary(_transWaypts);
_star->addTransition(_transition);
} else if (tag == "App_Transition") {
assert(_approach);
Transition* t = new Transition(_transIdent, _approach, _transWaypts);
_approach->addTransition(t);
_transition->setPrimary(_transWaypts);
_approach->addTransition(_transition);
} else if (tag == "RunwayTransition") {
ArrivalDeparture* ad;
if (_sid) {
@ -540,9 +549,9 @@ void NavdataVisitor::endElement(const char* name)
ad = _star;
}
Transition* t = new Transition(_transIdent, ad, _transWaypts);
_transition->setPrimary(_transWaypts);
FGRunwayRef rwy = _airport->getRunwayByIdent(_transIdent);
ad->addRunwayTransition(rwy, t);
ad->addRunwayTransition(rwy, _transition);
} else if (tag == "Approach") {
finishApproach();
} else if (tag == "Sid") {
@ -594,20 +603,20 @@ void NavdataVisitor::endElement(const char* name)
}
}
Waypt* NavdataVisitor::buildWaypoint()
Waypt* NavdataVisitor::buildWaypoint(Route* owner)
{
Waypt* wp = NULL;
if (_wayptType == "Normal") {
// new LatLonWaypoint
SGGeod pos(SGGeod::fromDeg(_longitude, _latitude));
wp = new BasicWaypt(pos, _wayptName, NULL);
wp = new BasicWaypt(pos, _wayptName, owner);
} else if (_wayptType == "Runway") {
string ident = _wayptName.substr(2);
FGRunwayRef rwy = _airport->getRunwayByIdent(ident);
wp = new RunwayWaypt(rwy, NULL);
wp = new RunwayWaypt(rwy, owner);
} else if (_wayptType == "Hold") {
SGGeod pos(SGGeod::fromDeg(_longitude, _latitude));
Hold* h = new Hold(pos, _wayptName, NULL);
Hold* h = new Hold(pos, _wayptName, owner);
wp = h;
if (_holdRighthanded) {
h->setRightHanded();
@ -625,15 +634,20 @@ Waypt* NavdataVisitor::buildWaypoint()
h->setHoldRadial(_holdRadial);
}
} else if (_wayptType == "Vectors") {
wp = new ATCVectors(NULL, _airport);
wp = new ATCVectors(owner, _airport);
} else if ((_wayptType == "Intc") || (_wayptType == "VorRadialIntc")) {
SGGeod pos(SGGeod::fromDeg(_longitude, _latitude));
wp = new RadialIntercept(NULL, _wayptName, pos, _course, _radial);
wp = new RadialIntercept(owner, _wayptName, pos, _course, _radial);
} else if (_wayptType == "DmeIntc") {
SGGeod pos(SGGeod::fromDeg(_longitude, _latitude));
wp = new DMEIntercept(NULL, _wayptName, pos, _course, _dmeDistance);
wp = new DMEIntercept(owner, _wayptName, pos, _course, _dmeDistance);
} else if (_wayptType == "ConstHdgtoAlt") {
wp = new HeadingToAltitude(NULL, _wayptName, _course);
wp = new HeadingToAltitude(owner, _wayptName, _course);
} else if (_wayptType == "PBD") {
SGGeod pos(SGGeod::fromDeg(_longitude, _latitude)), pos2;
double az2;
SGGeodesy::direct(pos, _course, _dmeDistance, pos2, az2);
wp = new BasicWaypt(pos2, _wayptName, owner);
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "implement waypoint type:" << _wayptType);
throw sg_format_exception("Unrecognized waypt type", _wayptType);