From 8d56b4664ac77597571dbc0a40459fecf2b4c44e Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Wed, 6 Mar 2013 01:04:18 +0100 Subject: [PATCH] Port more airport/navaid methods to cppbind --- src/Navaids/navaids_fwd.hxx | 27 +++++ src/Navaids/navlist.cxx | 25 +++- src/Navaids/navlist.hxx | 21 ++-- src/Navaids/navrecord.hxx | 6 +- src/Navaids/positioned.cxx | 3 +- src/Navaids/positioned.hxx | 3 + src/Scripting/NasalPositioned_cppbind.cxx | 132 ++++++++++++++++++++-- 7 files changed, 192 insertions(+), 25 deletions(-) create mode 100644 src/Navaids/navaids_fwd.hxx diff --git a/src/Navaids/navaids_fwd.hxx b/src/Navaids/navaids_fwd.hxx new file mode 100644 index 000000000..b40b62d47 --- /dev/null +++ b/src/Navaids/navaids_fwd.hxx @@ -0,0 +1,27 @@ +// Navaids forward declarations +// +// Copyright (C) 2013 Thomas Geymayer +// +// 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 + +class FGNavRecord; +typedef SGSharedPtr FGNavRecordRef; + +#endif /* NAVAIDS_FWD_HXX_ */ diff --git a/src/Navaids/navlist.cxx b/src/Navaids/navlist.cxx index eb6bac754..7d5e8c123 100644 --- a/src/Navaids/navlist.cxx +++ b/src/Navaids/navlist.cxx @@ -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 diff --git a/src/Navaids/navlist.hxx b/src/Navaids/navlist.hxx index e33697406..8f9204b71 100644 --- a/src/Navaids/navlist.hxx +++ b/src/Navaids/navlist.hxx @@ -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); - - virtual FGPositioned::Type minType() const { - return _mintype; - } + /** + * 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 maxType() const { - return _maxtype; - } + virtual FGPositioned::Type minType() const { return _mintype; } + virtual FGPositioned::Type maxType() const { return _maxtype; } protected: FGPositioned::Type _mintype; diff --git a/src/Navaids/navrecord.hxx b/src/Navaids/navrecord.hxx index aa4c1cb4e..8710b9aa3 100644 --- a/src/Navaids/navrecord.hxx +++ b/src/Navaids/navrecord.hxx @@ -26,17 +26,15 @@ #include +#include "navaids_fwd.hxx" #include "positioned.hxx" +#include 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 { diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index 29e0ee0a4..e5227a2cc 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -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"; diff --git a/src/Navaids/positioned.hxx b/src/Navaids/positioned.hxx index 8341c22f1..42476d854 100644 --- a/src/Navaids/positioned.hxx +++ b/src/Navaids/positioned.hxx @@ -98,6 +98,9 @@ public: Type type() const { return mType; } + const char* typeString() const + { return nameForType(mType); } + const std::string& ident() const { return mIdent; } diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx index f0eb9331d..aab7489ea 100644 --- a/src/Scripting/NasalPositioned_cppbind.cxx +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -41,12 +41,15 @@ #include #include
#include +#include +#include typedef nasal::Ghost NasalPositioned; typedef nasal::Ghost NasalRunway; typedef nasal::Ghost NasalParking; typedef nasal::Ghost NasalAirport; typedef nasal::Ghost NasalCommStation; +typedef nasal::Ghost 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 , 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(0, "airport"); + std::string ident("airport"); + if( ctx.isString(0) ) + ident = ctx.requireArg(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([,] [, 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(0); + + FGAirport::TypeRunwayFilter filter; // defaults to airports only + filter.fromTypeString( ctx.getArg(1) ); + + FGPositioned::List apts = + FGPositioned::findWithinRange(pos, range_nm, &filter); + FGPositioned::sortByRange(apts, pos); + + return ctx.to_nasal(apts); +} + +/** + * findAirportsByICAO( [, type]) + */ +static naRef f_findAirportsByICAO(naContext c, naRef me, int argc, naRef* args) +{ + nasal::CallContext ctx(c, argc, args); + std::string prefix = ctx.requireArg(0); + + FGAirport::TypeRunwayFilter filter; // defaults to airports only + filter.fromTypeString( ctx.getArg(1) ); + + return ctx.to_nasal( FGPositioned::findAllWithIdent(prefix, &filter, false) ); +} + +// Returns vector of data hash for navaid of a , nil on error +// navaids sorted by ascending distance +// navinfo([,],[],[]) +// 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(0); + + FGNavList::TypeFilter filter; + if( filter.fromTypeString(id) ) + id = ctx.getArg(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(0); + + FGNavList::TypeFilter filter; + filter.fromTypeString(ctx.getArg(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(); - NasalParking::init("FGParking") + NasalParking::init("Parking") .bases(); NasalCommStation::init("CommStation") .bases() .member("frequency", &flightgear::CommStation::freqMHz); + NasalNavRecord::init("Navaid") + .bases() + .member("frequency", &FGNavRecord::get_freq) + .member("range_nm", &FGNavRecord::get_range) + .member("course", &f_navaid_course); + NasalAirport::init("FGAirport") .bases() .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(); } -- 2.39.5