X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNavaids%2Fnavlist.cxx;h=44c830166bf7937aebc0d31a52deb61fd87e8021;hb=bd3c57beee2c368b8947b35e627a4a82c0d9b637;hp=f439044b50cc18e97ddeae4fb69793375d82bfa2;hpb=8f1c10a746108369cbeb3aad9ac067b765974ce6;p=flightgear.git diff --git a/src/Navaids/navlist.cxx b/src/Navaids/navlist.cxx index f439044b5..44c830166 100644 --- a/src/Navaids/navlist.cxx +++ b/src/Navaids/navlist.cxx @@ -1,4 +1,4 @@ -// navaids.cxx -- navaids management class +// navlist.cxx -- navaids management class // // Written by Curtis Olson, started April 2000. // @@ -21,9 +21,13 @@ // $Id$ +#ifdef HAVE_CONFIG_H +# include +#endif + #include -#include -#include +#include +#include #include "navlist.hxx" @@ -42,14 +46,13 @@ FGNavList::~FGNavList( void ) { // load the navaids and build the map -bool FGNavList::init( FGPath path ) { - FGNav n; +bool FGNavList::init( SGPath path ) { navaids.erase( navaids.begin(), navaids.end() ); - fg_gzifstream in( path.str() ); + sg_gzifstream in( path.str() ); if ( !in.is_open() ) { - FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << path.str() ); + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() ); exit(-1); } @@ -58,65 +61,134 @@ bool FGNavList::init( FGPath path ) { in >> skipeol; in >> skipcomment; -#ifdef __MWERKS__ + // double min = 100000; + // double max = 0; +#ifdef __MWERKS__ char c = 0; - while ( in.get(c) && c != '\0' && n.get_type() != '[' ) { + while ( in.get(c) && c != '\0' ) { in.putback(c); - in >> n; - if ( n.get_type() != '[' ) { - navaids[n.get_freq()].push_back(n); - } - in >> skipcomment; - } - #else + while ( ! in.eof() ) { +#endif + + FGNav *n = new FGNav; + in >> (*n); + if ( n->get_type() == '[' ) { + break; + } - while ( ! in.eof() && n.get_type() != '[' ) { - in >> n; /* cout << "id = " << n.get_ident() << endl; cout << " type = " << n.get_type() << endl; cout << " lon = " << n.get_lon() << endl; cout << " lat = " << n.get_lat() << endl; cout << " elev = " << n.get_elev() << endl; cout << " freq = " << n.get_freq() << endl; - cout << " range = " << n.get_range() << endl; */ - if ( n.get_type() != '[' ) { - navaids[n.get_freq()].push_back(n); - } + cout << " range = " << n.get_range() << endl << endl; */ + + navaids [n->get_freq() ].push_back(n); + ident_navaids[n->get_ident()].push_back(n); + in >> skipcomment; + + /* if ( n.get_type() != 'N' ) { + if ( n.get_freq() < min ) { + min = n.get_freq(); + } + if ( n.get_freq() > max ) { + max = n.get_freq(); + } + } */ } -#endif + // cout << "min freq = " << min << endl; + // cout << "max freq = " << max << endl; return true; } -// query the database for the specified frequency, lon and lat are in -// degrees, elev is in meters -bool FGNavList::query( double lon, double lat, double elev, double freq, - FGNav *n, double *heading, double *dist ) +// Query the database for the specified frequency. It is assumed that +// there will be multiple stations with matching frequencies so a +// position must be specified. Lon and lat are in degrees, elev is in +// meters. +FGNav *FGNavList::findByFreq( double freq, double lon, double lat, double elev ) { nav_list_type stations = navaids[(int)(freq*100.0 + 0.5)]; + Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) ); - nav_list_iterator current = stations.begin(); - nav_list_iterator last = stations.end(); + return findNavFromList( aircraft, stations ); +} + + +FGNav *FGNavList::findByIdent( const char* ident, + const double lon, const double lat ) +{ + nav_list_type stations = ident_navaids[ident]; + Point3D aircraft = sgGeodToCart( Point3D(lon, lat, 0.0) ); - double az1, az2, s; - for ( ; current != last ; ++current ) { + return findNavFromList( aircraft, stations ); +} + + +// Given an Ident and optional freqency, return the first matching +// station. +FGNav *FGNavList::findByIdentAndFreq( const char* ident, const double freq ) +{ + nav_list_type stations = ident_navaids[ident]; + + if ( freq > 0.0 ) { + // sometimes there can be duplicated idents. If a freq is + // specified, use it to refine the search. + int f = (int)(freq*100.0 + 0.5); + for ( unsigned int i = 0; i < stations.size(); ++i ) { + if ( f == stations[i]->get_freq() ) { + return stations[i]; + } + } + } else { + return stations[0]; + } + + return NULL; +} + + +// Given a point and a list of stations, return the closest one to the +// specified point. +FGNav *FGNavList::findNavFromList( const Point3D &aircraft, + const nav_list_type &stations ) +{ + FGNav *nav = NULL; + Point3D station; + double d2; + double min_dist = 999999999.0; + + // prime the pump with info from stations[0] + if ( stations.size() > 0 ) { + nav = stations[0]; + station = Point3D( nav->get_x(), nav->get_y(), nav->get_z()); + min_dist = aircraft.distance3Dsquared( station ); + } + + // check if any of the remaining stations are closer + for ( unsigned int i = 1; i < stations.size(); ++i ) { // cout << "testing " << current->get_ident() << endl; - geo_inverse_wgs_84( elev, lat, lon, - current->get_lat(), current->get_lon(), - &az1, &az2, &s ); - // cout << " dist = " << s << endl; - if ( s < ( current->get_range() * NM_TO_METER ) ) { - *n = *current; - *heading = az2; - *dist = s; - return true; - } + station = Point3D( stations[i]->get_x(), + stations[i]->get_y(), + stations[i]->get_z() ); + + d2 = aircraft.distance3Dsquared( station ); + + // cout << " dist = " << sqrt(d) + // << " range = " << current->get_range() * SG_NM_TO_METER + // << endl; + + if ( d2 < min_dist ) { + min_dist = d2; + nav = stations[i]; + } } - return false; + return nav; }