1
0
Fork 0
flightgear/src/Navaids/nav.hxx
curt 8cc7b283d5 Refactored some of the navlist code and removed the built in "fail to find"
if the station is too far away.  Instead, simply return the closest station.
All the code that searches navaids does it's own range checking anyway.
This will make the navlist query functions a bit more useful for other
types of functionality where you may need to lookup a station without
consideration of range (i.e. presetting your position relative to a navaid.)
2003-01-25 20:45:39 +00:00

183 lines
4.8 KiB
C++

// nav.hxx -- vor/dme/ndb class
//
// Written by Curtis Olson, started April 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _FG_NAV_HXX
#define _FG_NAV_HXX
#include <stdio.h>
#include <simgear/compiler.h>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/magvar/magvar.hxx>
#include <simgear/timing/sg_time.hxx>
#ifdef SG_HAVE_STD_INCLUDES
# include <istream>
#elif defined( __BORLANDC__ ) || (__APPLE__)
# include <iostream>
#else
# include <istream.h>
#endif
SG_USING_STD(istream);
class FGNav {
char type;
double lon, lat;
double elev;
double x, y, z;
int freq;
int range;
bool has_dme;
string ident; // to avoid a core dump with corrupt data
double magvar; // magvar from true north (negative = W)
// for failure modeling
string trans_ident; // transmitted ident
bool nav_failed; // nav failed?
bool dme_failed; // dme failed?
public:
inline FGNav(void);
inline ~FGNav(void) {}
inline char get_type() const { return type; }
inline double get_lon() const { return lon; }
inline double get_lat() const { return lat; }
inline double get_elev() const { return elev; }
inline double get_x() const { return x; }
inline double get_y() const { return y; }
inline double get_z() const { return z; }
inline int get_freq() const { return freq; }
inline int get_range() const { return range; }
inline bool get_has_dme() const { return has_dme; }
inline const char *get_ident() { return ident.c_str(); }
inline string get_trans_ident() { return trans_ident; }
inline double get_magvar () const { return magvar; }
friend istream& operator>> ( istream&, FGNav& );
};
inline
FGNav::FGNav(void) :
type(0),
lon(0.0), lat(0.0),
elev(0.0),
x(0.0), y(0.0), z(0.0),
freq(0),
range(0),
has_dme(false),
ident(""),
magvar(0.0),
trans_ident(""),
nav_failed(false),
dme_failed(false)
{
}
inline istream&
operator >> ( istream& in, FGNav& n )
{
double f;
char c /* , magvar_dir */ ;
string magvar_s;
static bool first_time = true;
static double julian_date = 0;
static const double MJD0 = 2415020.0;
if ( first_time ) {
julian_date = sgTimeCurrentMJD(0,0) + MJD0;
first_time = false;
}
in >> n.type;
if ( n.type == '[' )
return in >> skipeol;
in >> n.lat >> n.lon >> n.elev >> f >> n.range
>> c >> n.ident >> magvar_s;
n.freq = (int)(f*100.0 + 0.5);
if ( c == 'Y' ) {
n.has_dme = true;
} else {
n.has_dme = false;
}
// Calculate the magvar from true north.
// cout << "Calculating magvar for navaid " << n.ident << endl;
if (magvar_s == "XXX") {
// default to mag var as of 1990-01-01 (Julian 2447892.5)
// cout << "lat = " << n.lat << " lon = " << n.lon << " elev = "
// << n.elev << " JD = "
// << julian_date << endl;
n.magvar = sgGetMagVar( n.lon * SGD_DEGREES_TO_RADIANS,
n.lat * SGD_DEGREES_TO_RADIANS,
n.elev * SG_FEET_TO_METER,
julian_date )
* SGD_RADIANS_TO_DEGREES;
// cout << "Default variation at " << n.lon << ',' << n.lat
// << " is " << var << endl;
#if 0
// I don't know what this is for - CLO 1 Feb 2001
if (var - int(var) >= 0.5)
n.magvar = int(var) + 1;
else if (var - int(var) <= -0.5)
n.magvar = int(var) - 1;
else
n.magvar = int(var);
#endif
// cout << "Defaulted to magvar of " << n.magvar << endl;
} else {
char direction;
int var;
sscanf(magvar_s.c_str(), "%d%c", &var, &direction);
n.magvar = var;
if (direction == 'W')
n.magvar = -n.magvar;
// cout << "Explicit magvar of " << n.magvar << endl;
}
// cout << n.ident << " " << n.magvar << endl;
// generate cartesian coordinates
Point3D geod( n.lon * SGD_DEGREES_TO_RADIANS, n.lat * SGD_DEGREES_TO_RADIANS, n.elev );
Point3D cart = sgGeodToCart( geod );
n.x = cart.x();
n.y = cart.y();
n.z = cart.z();
n.trans_ident = n.ident;
n.nav_failed = n.dme_failed = false;
return in >> skipeol;
}
#endif // _FG_NAV_HXX