X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNavaids%2Fnavlist.cxx;h=44c830166bf7937aebc0d31a52deb61fd87e8021;hb=bd3c57beee2c368b8947b35e627a4a82c0d9b637;hp=7c3c21d0424ce4a8c09c1702ea7c6a405069d157;hpb=cbaf01548180f2dcaafd04676c4832b7297abc27;p=flightgear.git diff --git a/src/Navaids/navlist.cxx b/src/Navaids/navlist.cxx index 7c3c21d04..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,8 +21,12 @@ // $Id$ +#ifdef HAVE_CONFIG_H +# include +#endif + #include -#include +#include #include #include "navlist.hxx" @@ -42,17 +46,13 @@ FGNavList::~FGNavList( void ) { // load the navaids and build the map -bool FGNavList::init( FGPath path ) { - FGNav n; - - SGTime time_params; - time_params.update( 0.0, 0.0, 0 ); +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); } @@ -61,85 +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 - double min = 100000; - double max = 0; + 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_type() != 'N' ) { if ( n.get_freq() < min ) { min = n.get_freq(); } if ( n.get_freq() > max ) { max = n.get_freq(); } - } + } */ } // cout << "min freq = " << min << endl; // cout << "max freq = " << max << endl; -#endif - 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 ) +// 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) ); + + return findNavFromList( aircraft, stations ); +} - nav_list_iterator current = stations.begin(); - nav_list_iterator last = stations.end(); - // double az1, az2, s; - Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) ); +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) ); + + 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 d; - for ( ; current != last ; ++current ) { + 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; - station = Point3D(current->get_x(), current->get_y(), current->get_z()); + station = Point3D( stations[i]->get_x(), + stations[i]->get_y(), + stations[i]->get_z() ); - d = aircraft.distance3Dsquared( station ); + d2 = aircraft.distance3Dsquared( station ); // cout << " dist = " << sqrt(d) - // << " range = " << current->get_range() * NM_TO_METER << endl; - if ( d < (current->get_range() * NM_TO_METER - * current->get_range() * NM_TO_METER * 5.0) ) { - // cout << "matched = " << current->get_ident() << endl; - *n = *current; - return true; - } + // << " range = " << current->get_range() * SG_NM_TO_METER + // << endl; + + if ( d2 < min_dist ) { + min_dist = d2; + nav = stations[i]; + } } - return false; + return nav; }