+ if (arg->hasChild("navaid", 1)) {
+ // intersection of two radials
+ FGPositionedRef p2 = FGPositioned::findClosestWithIdent(arg->getStringValue("navaid[1]"), pos);
+ if (!p2) {
+ SG_LOG( SG_AUTOPILOT, SG_INFO, "Unable to find FGPositioned with ident:" << arg->getStringValue("navaid[1]"));
+ return false;
+ }
+
+ double r1 = arg->getDoubleValue("radial"),
+ r2 = arg->getDoubleValue("radial[1]");
+
+ SGGeod intersection;
+ bool ok = SGGeodesy::radialIntersection(p->geod(), r1, p2->geod(), r2, intersection);
+ if (!ok) {
+ SG_LOG(SG_AUTOPILOT, SG_INFO, "no valid intersection for:" << p->ident()
+ << "," << p2->ident());
+ return false;
+ }
+
+ std::string name = p->ident() + "-" + p2->ident();
+ wp = new BasicWaypt(intersection, name, NULL);
+ } else if (arg->hasChild("offset-nm") && arg->hasChild("radial")) {
+ // offset radial from navaid
+ double radial = arg->getDoubleValue("radial");
+ double distanceNm = arg->getDoubleValue("offset-nm");
+ //radial += magvar->getDoubleValue(); // convert to true bearing
+ wp = new OffsetNavaidWaypoint(p, NULL, radial, distanceNm);
+ } else {
+ wp = new NavaidWaypoint(p, NULL);
+ }
+ } else if (arg->hasChild("airport")) {
+ const FGAirport* apt = fgFindAirportID(arg->getStringValue("airport"));
+ if (!apt) {
+ SG_LOG(SG_AUTOPILOT, SG_INFO, "no such airport" << arg->getStringValue("airport"));
+ return false;
+ }
+
+ if (arg->hasChild("runway")) {
+ if (!apt->hasRunwayWithIdent(arg->getStringValue("runway"))) {
+ SG_LOG(SG_AUTOPILOT, SG_INFO, "No runway: " << arg->getStringValue("runway") << " at " << apt->ident());
+ return false;
+ }
+
+ FGRunway* runway = apt->getRunwayByIdent(arg->getStringValue("runway"));
+ wp = new RunwayWaypt(runway, NULL);
+ } else {
+ wp = new NavaidWaypoint((FGAirport*) apt, NULL);
+ }
+ } else if (arg->hasChild("text")) {
+ wp = self->waypointFromString(arg->getStringValue("text"));
+ } else if (!(pos == SGGeod())) {
+ // just a raw lat/lon
+ wp = new BasicWaypt(pos, ident, NULL);
+ } else {
+ return false; // failed to build waypoint
+ }
+
+ FlightPlan::Leg* leg = self->flightPlan()->insertWayptAtIndex(wp, index);
+ if (alt >= 0) {
+ leg->setAltitude(RESTRICT_AT, alt);
+ }
+
+ if (ias > 0) {
+ leg->setSpeed(RESTRICT_AT, ias);
+ }
+
+ return true;
+}
+
+static bool commandDeleteWaypt(const SGPropertyNode* arg)
+{
+ FGRouteMgr* self = (FGRouteMgr*) globals->get_subsystem("route-manager");
+ int index = arg->getIntValue("index");
+ self->removeLegAtIndex(index);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+FGRouteMgr::FGRouteMgr() :
+ _plan(NULL),
+ input(fgGetNode( RM "input", true )),
+ mirror(fgGetNode( RM "route", true ))
+{
+ listener = new InputListener(this);
+ input->setStringValue("");
+ input->addChangeListener(listener);
+
+ SGCommandMgr::instance()->addCommand("load-flightplan", commandLoadFlightPlan);
+ SGCommandMgr::instance()->addCommand("save-flightplan", commandSaveFlightPlan);
+ SGCommandMgr::instance()->addCommand("activate-flightplan", commandActivateFlightPlan);
+ SGCommandMgr::instance()->addCommand("clear-flightplan", commandClearFlightPlan);
+ SGCommandMgr::instance()->addCommand("set-active-waypt", commandSetActiveWaypt);
+ SGCommandMgr::instance()->addCommand("insert-waypt", commandInsertWaypt);
+ SGCommandMgr::instance()->addCommand("delete-waypt", commandDeleteWaypt);
+}
+
+
+FGRouteMgr::~FGRouteMgr()
+{
+ input->removeChangeListener(listener);
+ delete listener;