static naRef airportPrototype;
static naRef routePrototype;
static naRef waypointPrototype;
+static naRef geoCoordClass;
naRef ghostForPositioned(naContext c, const FGPositioned* pos)
{
return navdata;
}
+static bool hashIsCoord(naRef h)
+{
+ naRef parents = naHash_cget(h, (char*) "parents");
+ if (!naIsVector(parents)) {
+ return false;
+ }
+
+ return naEqual(naVec_get(parents, 0), geoCoordClass);
+}
+
bool geodFromHash(naRef ref, SGGeod& result)
{
if (!naIsHash(ref)) {
naRef lat = naHash_cget(ref, (char*) "lat");
naRef lon = naHash_cget(ref, (char*) "lon");
if (naIsNum(lat) && naIsNum(lon)) {
- result = SGGeod::fromDeg(naNumValue(lat).num, naNumValue(lon).num);
+ result = SGGeod::fromDeg(naNumValue(lon).num, naNumValue(lat).num);
return true;
}
-// check for geo.Coord type
+ if (hashIsCoord(ref)) {
+ naRef lat = naHash_cget(ref, (char*) "_lat");
+ naRef lon = naHash_cget(ref, (char*) "_lon");
+ if (naIsNum(lat) && naIsNum(lon)) {
+ result = SGGeod::fromRad(naNumValue(lon).num, naNumValue(lat).num);
+ return true;
+ }
+ }
// check for any synonyms?
// latitude + longitude?
naRef sids = naNewVector(c);
- // if we have an explicit type, return a simple vector of frequencies
if (argc > 0 && naIsString(args[0])) {
if (!apt->hasRunwayWithIdent(naStr_data(args[0]))) {
return naNil();
naRef stars = naNewVector(c);
- // if we have an explicit type, return a simple vector of frequencies
if (argc > 0 && naIsString(args[0])) {
if (!apt->hasRunwayWithIdent(naStr_data(args[0]))) {
return naNil();
return result;
}
+static naRef f_greatCircleMove(naContext c, naRef me, int argc, naRef* args)
+{
+ SGGeod from = globals->get_aircraft_position(), to;
+ int argOffset = 0;
+
+ // complication - don't inerpret two doubles (as the only args)
+ // as a lat,lon pair - only do so if we have at least three args.
+ if (argc > 2) {
+ argOffset = geodFromArgs(args, 0, argc, from);
+ }
+
+ if ((argOffset + 1) >= argc) {
+ naRuntimeError(c, "isufficent arguments to greatCircleMove");
+ }
+
+ if (!naIsNum(args[argOffset]) || !naIsNum(args[argOffset+1])) {
+ naRuntimeError(c, "invalid arguments %d and %d to greatCircleMove",
+ argOffset, argOffset + 1);
+ }
+
+ double course = args[argOffset].num, course2;
+ double distanceNm = args[argOffset + 1].num;
+ SGGeodesy::direct(from, course, distanceNm * SG_NM_TO_METER, to, course2);
+
+ // return geo.Coord
+ naRef coord = naNewHash(c);
+ hashset(c, coord, "lat", naNum(to.getLatitudeDeg()));
+ hashset(c, coord, "lon", naNum(to.getLongitudeDeg()));
+ return coord;
+}
+
static naRef f_tilePath(naContext c, naRef me, int argc, naRef* args)
{
SGGeod pos = globals->get_aircraft_position();
{ "route", f_route },
{ "magvar", f_magvar },
{ "courseAndDistance", f_courseAndDistance },
+ { "greatCircleMove", f_greatCircleMove },
{ "bucketPath", f_tilePath },
{ 0, 0 }
};
return naNil();
}
+void postinitNasalPositioned(naRef globals, naContext c)
+{
+ naRef geoModule = naHash_cget(globals, (char*) "geo");
+ if (naIsNil(geoModule)) {
+ SG_LOG(SG_GENERAL, SG_WARN, "postinitNasalPositioned: geo.nas not loaded");
+ return;
+ }
+
+ geoCoordClass = naHash_cget(geoModule, (char*) "Coord");
+}
+
+