+
+
+// returns the closest entry to the give lon/lat/elev
+FGNavRecord *FGNavList::findClosest( double lon_rad, double lat_rad,
+ double elev_m, fg_nav_types type)
+{
+ FGNavRecord *result = NULL;
+ double diff;
+
+ double lon_deg = lon_rad * SG_RADIANS_TO_DEGREES;
+ double lat_deg = lat_rad * SG_RADIANS_TO_DEGREES;
+ int lonidx = (int)lon_deg;
+ diff = lon_deg - (double)lonidx;
+ if ( (lon_deg < 0.0) && (fabs(diff) > SG_EPSILON) ) {
+ lonidx -= 1;
+ }
+ lonidx += 180;
+
+ int latidx = (int)lat_deg;
+ diff = lat_deg - (double)latidx;
+ if ( (lat_deg < 0.0) && (fabs(diff) > SG_EPSILON) ) {
+ latidx -= 1;
+ }
+ latidx += 90;
+
+ int master_index = lonidx * 1000 + latidx;
+
+ const nav_list_type& navs = navaids_by_tile[ master_index ];
+ // cout << "Master index = " << master_index << endl;
+ // cout << "beacon search length = " << beacons.size() << endl;
+
+ nav_list_const_iterator current = navs.begin();
+ nav_list_const_iterator last = navs.end();
+
+ SGGeod geod = SGGeod::fromRadM(lon_rad, lat_rad, elev_m);
+ SGVec3d aircraft = SGVec3d::fromGeod(geod);
+
+ double min_dist = 999999999.0;
+
+ for ( ; current != last ; ++current ) {
+ if(isTypeMatch(*current, type)) {
+ // cout << " testing " << (*current)->get_ident() << endl;
+
+ double d = distSqr((*current)->get_cart(), aircraft);
+ // cout << " distance = " << d << " ("
+ // << FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
+ // * FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER
+ // << ")" << endl;
+
+ // cout << " range = " << sqrt(d) << endl;
+
+ if ( d < min_dist ) {
+ min_dist = d;
+ result = (*current);
+ }
+ }
+ }
+
+ // cout << "lon = " << lon << " lat = " << lat
+ // << " closest beacon = " << sqrt( min_dist ) << endl;
+
+ return result;
+}
+
+// Given a frequency, return the first matching station.
+FGNavRecord *FGNavList::findStationByFreq( double freq )
+{
+ const nav_list_type& stations = navaids[(int)(freq*100.0 + 0.5)];
+
+ SG_LOG( SG_INSTR, SG_DEBUG, "findStationByFreq " << freq << " size " << stations.size() );
+
+ if (!stations.empty()) {
+ return stations[0];
+ }
+ return NULL;
+}
+
+
+
+// FGTACANList ----------------------------------------------------------------
+
+FGTACANList::FGTACANList( void )
+{
+}
+
+
+FGTACANList::~FGTACANList( void )
+{
+}
+
+
+bool FGTACANList::init()
+{
+ return true;
+}
+
+
+// add an entry to the lists
+bool FGTACANList::add( FGTACANRecord *c )
+{
+ ident_channels[c->get_channel()].push_back(c);
+ return true;
+}
+
+
+// Given a TACAN Channel return the first matching frequency
+FGTACANRecord *FGTACANList::findByChannel( const string& channel )
+{
+ const tacan_list_type& stations = ident_channels[channel];
+ SG_LOG( SG_INSTR, SG_DEBUG, "findByChannel " << channel<< " size " << stations.size() );
+
+ if (!stations.empty()) {
+ return stations[0];
+ }
+ return NULL;
+}
+
+