}
}
+SGGeod FlightPlan::pointAlongRoute(int aIndex, double aOffsetNm) const
+{
+ if (aIndex >= (int) _legs.size()) {
+ throw sg_range_exception();
+ }
+
+ const int lastLeg = static_cast<int>(_legs.size()) - 1;
+// convert the relative offset and leg index into an absolute, positive
+// distance in nm from the route origin. This means we can simply walk
+// forwards to find the actual leg.
+ Leg* leg = _legs[(aIndex >= 0) ? aIndex : lastLeg];
+ double absolutePathDistance = leg->_distanceAlongPath + aOffsetNm;
+ if (absolutePathDistance < 0.0) {
+ return _legs[0]->waypoint()->position(); // begining of route
+ }
+
+ if (absolutePathDistance > _totalDistance) {
+ return _legs[lastLeg]->waypoint()->position(); // end of route
+ }
+
+// find the leg containing the absolute distance
+ for (int l=0; l<lastLeg; ++l) {
+ leg = _legs[l];
+ if (absolutePathDistance < leg->_pathDistance) {
+ break; // found our matching leg
+ }
+ absolutePathDistance -= leg->_pathDistance;
+ } // of forwards walk along route to find leg
+
+ return SGGeodesy::direct(leg->waypoint()->position(),
+ leg->_courseDeg, absolutePathDistance * SG_NM_TO_METER);
+}
+
void FlightPlan::lockDelegate()
{
if (_delegateLock == 0) {
double totalDistanceNm() const
{ return _totalDistance; }
+ /**
+ * given a waypoint index, and an offset in NM, find the geodetic
+ * position on the route path. I.e the point 10nm before or after
+ * a particular waypoint.
+ */
+ SGGeod pointAlongRoute(int aIndex, double aOffsetNm) const;
+
/**
* Create a WayPoint from a string in the following format:
* - simple identifier
return ghostForFlightPlan(c, fp->clone());
}
+static naRef f_flightplan_pathGeod(naContext c, naRef me, int argc, naRef* args)
+{
+ FlightPlan* fp = flightplanGhost(me);
+ if (!fp) {
+ naRuntimeError(c, "flightplan.clone called on non-flightplan object");
+ }
+
+ if ((argc < 1) || !naIsNum(args[0])) {
+ naRuntimeError(c, "bad argument to flightplan.pathGeod");
+ }
+
+ if ((argc > 1) && !naIsNum(args[1])) {
+ naRuntimeError(c, "bad argument to flightplan.pathGeod");
+ }
+
+ int index = (int) args[0].num;
+ double offset = (argc > 1) ? args[1].num : 0.0;
+ naRef result = naNewHash(c);
+ SGGeod g = fp->pointAlongRoute(index, offset);
+ hashset(c, result, "lat", naNum(g.getLatitudeDeg()));
+ hashset(c, result, "lon", naNum(g.getLongitudeDeg()));
+ return result;
+}
+
+
static naRef f_leg_setSpeed(naContext c, naRef me, int argc, naRef* args)
{
FlightPlan::Leg* leg = fpLegGhost(me);
hashset(c, flightplanPrototype, "cleanPlan", naNewFunc(c, naNewCCode(c, f_flightplan_clearPlan)));
hashset(c, flightplanPrototype, "clearWPType", naNewFunc(c, naNewCCode(c, f_flightplan_clearWPType)));
hashset(c, flightplanPrototype, "clone", naNewFunc(c, naNewCCode(c, f_flightplan_clone)));
-
+ hashset(c, flightplanPrototype, "pathGeod", naNewFunc(c, naNewCCode(c, f_flightplan_pathGeod)));
+
waypointPrototype = naNewHash(c);
hashset(c, gcSave, "wayptProto", waypointPrototype);