1
0
Fork 0

Port more airport/navaid methods to cppbind

This commit is contained in:
Thomas Geymayer 2013-03-06 01:04:18 +01:00
parent 1c905e5881
commit 8d56b4664a
7 changed files with 192 additions and 25 deletions

View file

@ -0,0 +1,27 @@
// Navaids forward declarations
//
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef NAVAIDS_FWD_HXX_
#define NAVAIDS_FWD_HXX_
#include <simgear/structure/SGSharedPtr.hxx>
class FGNavRecord;
typedef SGSharedPtr<FGNavRecord> FGNavRecordRef;
#endif /* NAVAIDS_FWD_HXX_ */

View file

@ -91,6 +91,7 @@ bool navidUsable(FGNavRecord* aNav, const SGGeod &aircraft)
// FGNavList ------------------------------------------------------------------
//------------------------------------------------------------------------------
FGNavList::TypeFilter::TypeFilter(const FGPositioned::Type type)
{
if (type == FGPositioned::INVALID) {
@ -101,14 +102,32 @@ FGNavList::TypeFilter::TypeFilter(const FGPositioned::Type type)
}
}
FGNavList::TypeFilter::TypeFilter(const FGPositioned::Type minType,
const FGPositioned::Type maxType) :
//------------------------------------------------------------------------------
FGNavList::TypeFilter::TypeFilter( const FGPositioned::Type minType,
const FGPositioned::Type maxType ):
_mintype(minType),
_maxtype(maxType)
{
}
//------------------------------------------------------------------------------
bool FGNavList::TypeFilter::fromTypeString(const std::string& type)
{
FGPositioned::Type t;
if( type == "any" ) t = FGPositioned::INVALID;
else if( type == "fix" ) t = FGPositioned::FIX;
else if( type == "vor" ) t = FGPositioned::VOR;
else if( type == "ndb" ) t = FGPositioned::NDB;
else if( type == "ils" ) t = FGPositioned::ILS;
else if( type == "dme" ) t = FGPositioned::DME;
else if( type == "tacan") t = FGPositioned::TACAN;
else return false;
_mintype = _maxtype = t;
return true;
}
/**
* Filter returning Tacan stations. Checks for both pure TACAN stations
* but also co-located VORTACs. This is done by searching for DMEs whose

View file

@ -49,18 +49,19 @@ public:
class TypeFilter : public FGPositioned::Filter
{
public:
TypeFilter(const FGPositioned::Type type);
TypeFilter( const FGPositioned::Type type = FGPositioned::INVALID );
TypeFilter( const FGPositioned::Type minType,
const FGPositioned::Type maxType );
TypeFilter(const FGPositioned::Type minType,
const FGPositioned::Type maxType);
/**
* Construct from string containing type
*
* @param type One of "fix"|"vor"|"ndb"|"ils"|"dme"|"tacan"|"any"
*/
bool fromTypeString(const std::string& type);
virtual FGPositioned::Type minType() const {
return _mintype;
}
virtual FGPositioned::Type maxType() const {
return _maxtype;
}
virtual FGPositioned::Type minType() const { return _mintype; }
virtual FGPositioned::Type maxType() const { return _maxtype; }
protected:
FGPositioned::Type _mintype;

View file

@ -26,17 +26,15 @@
#include <iosfwd>
#include "navaids_fwd.hxx"
#include "positioned.hxx"
#include <Airports/airports_fwd.hxx>
const double FG_NAV_DEFAULT_RANGE = 50; // nm
const double FG_LOC_DEFAULT_RANGE = 18; // nm
const double FG_DME_DEFAULT_RANGE = 50; // nm
const double FG_NAV_MAX_RANGE = 300; // nm
// forward decls
class FGRunway;
class SGPropertyNode;
class FGNavRecord : public FGPositioned
{

View file

@ -134,6 +134,7 @@ FGPositioned::Type FGPositioned::typeFromName(const std::string& aName)
{"village", VILLAGE},
// aliases
{"localizer", LOC},
{"gnd", FREQ_GROUND},
{"twr", FREQ_TOWER},
{"waypoint", WAYPOINT},
@ -170,7 +171,7 @@ const char* FGPositioned::nameForType(Type aTy)
case VOR: return "VOR";
case NDB: return "NDB";
case ILS: return "ILS";
case LOC: return "localiser";
case LOC: return "localizer";
case GS: return "glideslope";
case OM: return "outer-marker";
case MM: return "middle-marker";

View file

@ -98,6 +98,9 @@ public:
Type type() const
{ return mType; }
const char* typeString() const
{ return nameForType(mType); }
const std::string& ident() const
{ return mIdent; }

View file

@ -41,12 +41,15 @@
#include <ATC/CommStation.hxx>
#include <Main/globals.hxx>
#include <Navaids/NavDataCache.hxx>
#include <Navaids/navlist.hxx>
#include <Navaids/navrecord.hxx>
typedef nasal::Ghost<FGPositionedRef> NasalPositioned;
typedef nasal::Ghost<FGRunwayRef> NasalRunway;
typedef nasal::Ghost<FGParkingRef> NasalParking;
typedef nasal::Ghost<FGAirportRef> NasalAirport;
typedef nasal::Ghost<flightgear::CommStationRef> NasalCommStation;
typedef nasal::Ghost<FGNavRecordRef> NasalNavRecord;
//------------------------------------------------------------------------------
naRef to_nasal_helper(naContext c, FGPositioned* positioned)
@ -109,6 +112,18 @@ naRef to_nasal_helper(naContext c, const SGGeod& pos)
return hash.get_naRef();
}
//------------------------------------------------------------------------------
static naRef f_navaid_course(naContext, FGNavRecord& nav)
{
if( !( nav.type() == FGPositioned::ILS
|| nav.type() == FGPositioned::LOC
) )
return naNil();
double radial = nav.get_multiuse();
return naNum(SGMiscd::normalizePeriodic(0.5, 360.5, radial));
}
//------------------------------------------------------------------------------
static FGRunwayBase* f_airport_runway(FGAirport& apt, std::string ident)
{
@ -314,6 +329,18 @@ static bool extractGeod(nasal::CallContext& ctx, SGGeod& result)
return false;
}
/**
* Extract position from ctx or return current aircraft position if not given.
*/
static SGGeod getPosition(nasal::CallContext& ctx)
{
SGGeod pos;
if( !extractGeod(ctx, pos) )
pos = globals->get_aircraft_position();
return pos;
}
//------------------------------------------------------------------------------
// Returns Nasal ghost for particular or nearest airport of a <type>, or nil
// on error.
@ -326,15 +353,15 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
{
nasal::CallContext ctx(c, argc, args);
SGGeod pos;
if( !extractGeod(ctx, pos) )
pos = globals->get_aircraft_position();
SGGeod pos = getPosition(ctx);
if( ctx.argc > 1 )
naRuntimeError(ctx.c, "airportinfo() with invalid function arguments");
// optional type/ident
std::string ident = ctx.getArg<std::string>(0, "airport");
std::string ident("airport");
if( ctx.isString(0) )
ident = ctx.requireArg<std::string>(0);
FGAirport::TypeRunwayFilter filter;
if( !filter.fromTypeString(ident) )
@ -345,23 +372,110 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
return ctx.to_nasal( FGAirport::findClosest(pos, maxRange, &filter) );
}
/**
* findAirportsWithinRange([<position>,] <range-nm> [, type])
*/
static naRef f_findAirportsWithinRange(naContext c, naRef me, int argc, naRef* args)
{
nasal::CallContext ctx(c, argc, args);
SGGeod pos = getPosition(ctx);
double range_nm = ctx.requireArg<double>(0);
FGAirport::TypeRunwayFilter filter; // defaults to airports only
filter.fromTypeString( ctx.getArg<std::string>(1) );
FGPositioned::List apts =
FGPositioned::findWithinRange(pos, range_nm, &filter);
FGPositioned::sortByRange(apts, pos);
return ctx.to_nasal(apts);
}
/**
* findAirportsByICAO(<ident/prefix> [, type])
*/
static naRef f_findAirportsByICAO(naContext c, naRef me, int argc, naRef* args)
{
nasal::CallContext ctx(c, argc, args);
std::string prefix = ctx.requireArg<std::string>(0);
FGAirport::TypeRunwayFilter filter; // defaults to airports only
filter.fromTypeString( ctx.getArg<std::string>(1) );
return ctx.to_nasal( FGPositioned::findAllWithIdent(prefix, &filter, false) );
}
// Returns vector of data hash for navaid of a <type>, nil on error
// navaids sorted by ascending distance
// navinfo([<lat>,<lon>],[<type>],[<id>])
// lat/lon (numeric): use latitude/longitude instead of ac position
// type: ("fix"|"vor"|"ndb"|"ils"|"dme"|"tacan"|"any")
// id: (partial) id of the fix
// examples:
// navinfo("vor") returns all vors
// navinfo("HAM") return all navaids who's name start with "HAM"
// navinfo("vor", "HAM") return all vor who's name start with "HAM"
//navinfo(34,48,"vor","HAM") return all vor who's name start with "HAM"
// sorted by distance relative to lat=34, lon=48
static naRef f_navinfo(naContext c, naRef me, int argc, naRef* args)
{
nasal::CallContext ctx(c, argc, args);
SGGeod pos = getPosition(ctx);
std::string id = ctx.getArg<std::string>(0);
FGNavList::TypeFilter filter;
if( filter.fromTypeString(id) )
id = ctx.getArg<std::string>(1);
else if( ctx.argc > 1 )
naRuntimeError(c, "navinfo() already got an ident");
return ctx.to_nasal( FGNavList::findByIdentAndFreq(pos, id, 0.0, &filter) );
}
//------------------------------------------------------------------------------
static naRef f_findNavaidsWithinRange(naContext c, naRef me, int argc, naRef* args)
{
nasal::CallContext ctx(c, argc, args);
SGGeod pos = getPosition(ctx);
double range_nm = ctx.requireArg<double>(0);
FGNavList::TypeFilter filter;
filter.fromTypeString(ctx.getArg<std::string>(0));
FGPositioned::List navs =
FGPositioned::findWithinRange(pos, range_nm, &filter);
FGPositioned::sortByRange(navs, pos);
return ctx.to_nasal(navs);
}
//------------------------------------------------------------------------------
naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave)
{
NasalPositioned::init("FGPositioned")
NasalPositioned::init("Positioned")
.member("id", &FGPositioned::ident)
.member("ident", &FGPositioned::ident) // TODO to we really need id and ident?
.member("name", &FGPositioned::name)
.member("type", &FGPositioned::typeString)
.member("lat", &FGPositioned::latitude)
.member("lon", &FGPositioned::longitude)
.member("elevation", &FGPositioned::elevationM);
NasalRunway::init("FGRunway")
NasalRunway::init("Runway")
.bases<NasalPositioned>();
NasalParking::init("FGParking")
NasalParking::init("Parking")
.bases<NasalPositioned>();
NasalCommStation::init("CommStation")
.bases<NasalPositioned>()
.member("frequency", &flightgear::CommStation::freqMHz);
NasalNavRecord::init("Navaid")
.bases<NasalPositioned>()
.member("frequency", &FGNavRecord::get_freq)
.member("range_nm", &FGNavRecord::get_range)
.member("course", &f_navaid_course);
NasalAirport::init("FGAirport")
.bases<NasalPositioned>()
.member("has_metar", &FGAirport::getMetar)
@ -386,6 +500,10 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c, naRef gcSave)
positioned( globals.createHash("positioned") );
positioned.set("airportinfo", &f_airportinfo);
positioned.set("findAirportsWithinRange", f_findAirportsWithinRange);
positioned.set("findAirportsByICAO", &f_findAirportsByICAO);
positioned.set("navinfo", &f_navinfo);
positioned.set("findNavaidsWithinRange", &f_findNavaidsWithinRange);
return naNil();
}