X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNavaids%2Fnavdb.cxx;h=f7a2761f3dc67ee64db562624c91c7990db9d086;hb=4022edc5ba91cfedec45f8a39ff8f41d20f3f34e;hp=5ca43646e73af8039657b438c6f043aa73043f74;hpb=b2b33f75820359670ca4d8b326370fc3771ee08c;p=flightgear.git diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 5ca43646e..f7a2761f3 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -2,7 +2,7 @@ // // Written by Curtis Olson, started May 2004. // -// Copyright (C) 2004 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 2004 Curtis L. Olson - http://www.flightgear.org/~curt // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -16,23 +16,36 @@ // // 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. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include STL_STRING #include +#include +#include #include
#include "navrecord.hxx" - #include "navdb.hxx" +SG_USING_STD( string ); + // load and initialize the navigational databases -bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, - FGNavList *dmelist, FGNavList *mkrlist ) +bool fgNavDBInit( FGAirportList *airports, + FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, + FGNavList *dmelist, FGNavList *mkrlist, + FGNavList *tacanlist, FGNavList *carrierlist, + FGTACANList *channellist) { SG_LOG(SG_GENERAL, SG_INFO, "Loading Navaid Databases"); // SG_LOG(SG_GENERAL, SG_INFO, " VOR/NDB"); @@ -62,8 +75,14 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, #ifdef __MWERKS__ + + FIXME -- Please report to the FlightGear mailing list, if you still use a + compiler identifying itself as __MWERKS__ that needs this hack. + There are 41 instances of it in the SimGear & FilghtGear code, + and they are scheduled for removal. + char c = 0; - while ( in.get(c) && c != '\0' ) { + while ( in.get(c) && c != '\0' ) { in.putback(c); #else while ( ! in.eof() ) { @@ -72,16 +91,29 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, FGNavRecord *r = new FGNavRecord; in >> (*r); if ( r->get_type() > 95 ) { + delete r; break; } - /* 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 << endl; */ + /*cout << "id = " << r->get_ident() << endl; + cout << " type = " << r->get_type() << endl; + cout << " lon = " << r->get_lon() << endl; + cout << " lat = " << r->get_lat() << endl; + cout << " elev = " <get_elev_ft() << endl; + cout << " freq = " << r->get_freq() << endl; + cout << " range = " << r->get_range() << endl; + cout << " name = " << r->get_name() << endl << endl; */ + + // fudge elevation to the field elevation if it's not specified + if ( fabs(r->get_elev_ft()) < 0.01 && r->get_apt_id().length() ) { + // cout << r->get_type() << " " << r->get_apt_id() << " zero elev" + // << endl; + const FGAirport* a = airports->search( r->get_apt_id() ); + if ( a ) { + r->set_elev_ft( a->getElevation() ); + // cout << " setting to " << a.elevation << endl; + } + } if ( r->get_type() == 2 || r->get_type() == 3 ) { // NDB=2, VOR=3 @@ -97,16 +129,196 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, { // Marker Beacon = 7,8,9 mkrlist->add( r ); - } else if ( r->get_type() == 12 ) { - // DME=12 + } else if ( r->get_type() == 12 || r->get_type() == 13) { + // DME with ILS=12; standalone DME=13 + string str1( r->get_name() ); + string::size_type loc1= str1.find( "TACAN", 0 ); + string::size_type loc2 = str1.find( "VORTAC", 0 ); + + if( loc1 != string::npos || loc2 != string::npos ){ + //cout << " name = " << r->get_name() ; + //cout << " freq = " << r->get_freq() ; + tacanlist->add( r ); + } + dmelist->add( r ); + } in >> skipcomment; } - // cout << "min freq = " << min << endl; - // cout << "max freq = " << max << endl; +// load the carrier navaids file + + string file, name; + path = ""; + path = globals->get_fg_root() ; + path.append( "Navaids/carrier_nav.dat" ); + + file = path.str(); + SG_LOG( SG_GENERAL, SG_INFO, "opening file: " << path.str() ); + + sg_gzifstream incarrier( path.str() ); + + if ( !incarrier.is_open() ) { + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() ); + exit(-1); + } + + // skip first two lines + //incarrier >> skipeol; + //incarrier >> skipeol; + +#ifdef __MWERKS__ + char c = 0; + while ( incarrier.get(c) && c != '\0' ) { + incarrier.putback(c); +#else + while ( ! incarrier.eof() ) { +#endif + + FGNavRecord *r = new FGNavRecord; + incarrier >> (*r); + carrierlist->add ( r ); + /*cout << " carrier lon: "<< r->get_lon() ; + cout << " carrier lat: "<< r->get_lat() ; + cout << " freq: " << r->get_freq() ; + cout << " carrier name: "<< r->get_name() << endl;*/ + + //if ( r->get_type() > 95 ) { + // break;} + } // end while + +// end loading the carrier navaids file + +// load the channel/freqency file + string channel, freq; + path=""; + path = globals->get_fg_root(); + path.append( "Navaids/TACAN_freq.dat" ); + + SG_LOG( SG_GENERAL, SG_INFO, "opening file: " << path.str() ); + + sg_gzifstream inchannel( path.str() ); + + if ( !inchannel.is_open() ) { + SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() ); + exit(-1); + } + + // skip first line + inchannel >> skipeol; + +#ifdef __MWERKS__ + char c = 0; + while ( inchannel.get(c) && c != '\0' ) { + in.putback(c); +#else + while ( ! inchannel.eof() ) { +#endif + + FGTACANRecord *r = new FGTACANRecord; + inchannel >> (*r); + channellist->add ( r ); + //cout << "channel = " << r->get_channel() ; + //cout << " freq = " << r->get_freq() << endl; + + } // end while + + + // end ReadChanFile + return true; } + + +// Given a localizer record and it's corresponding runway record, +// adjust the localizer position so it is in perfect alignment with +// the runway. +static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, + double threshold ) +{ + double hdg = rwy->_heading; + hdg += 180.0; + if ( hdg > 360.0 ) { + hdg -= 360.0; + } + + // calculate runway threshold point + double thresh_lat, thresh_lon, return_az; + geo_direct_wgs_84 ( 0.0, rwy->_lat, rwy->_lon, hdg, + rwy->_length/2.0 * SG_FEET_TO_METER, + &thresh_lat, &thresh_lon, &return_az ); + // cout << "Threshold = " << thresh_lat << "," << thresh_lon << endl; + + // calculate distance from threshold to localizer + double az1, az2, dist_m; + geo_inverse_wgs_84( 0.0, loc->get_lat(), loc->get_lon(), + thresh_lat, thresh_lon, + &az1, &az2, &dist_m ); + // cout << "Distance = " << dist_m << endl; + + // back project that distance along the runway center line + double nloc_lat, nloc_lon; + geo_direct_wgs_84 ( 0.0, thresh_lat, thresh_lon, hdg + 180.0, + dist_m, &nloc_lat, &nloc_lon, &return_az ); + // printf("New localizer = %.6f %.6f\n", nloc_lat, nloc_lon ); + + // sanity check, how far have we moved the localizer? + geo_inverse_wgs_84( 0.0, loc->get_lat(), loc->get_lon(), + nloc_lat, nloc_lon, + &az1, &az2, &dist_m ); + // cout << "Distance moved = " << dist_m << endl; + + // cout << "orig heading = " << loc->get_multiuse() << endl; + // cout << "new heading = " << rwy->_heading << endl; + + double hdg_diff = loc->get_multiuse() - rwy->_heading; + + // clamp to [-180.0 ... 180.0] + if ( hdg_diff < -180.0 ) { + hdg_diff += 360.0; + } else if ( hdg_diff > 180.0 ) { + hdg_diff -= 360.0; + } + + if ( fabs(hdg_diff) <= threshold ) { + loc->set_lat( nloc_lat ); + loc->set_lon( nloc_lon ); + loc->set_multiuse( rwy->_heading ); + } +} + + +// This routines traverses the localizer list and attempts to match +// each entry with it's corresponding runway. When it is successful, +// it then "moves" the localizer and updates it's heading so it +// *perfectly* aligns with the runway, but is still the same distance +// from the runway threshold. +void fgNavDBAlignLOCwithRunway( FGRunwayList *runways, FGNavList *loclist, + double threshold ) { + nav_map_type navmap = loclist->get_navaids(); + + nav_map_const_iterator freq = navmap.begin(); + while ( freq != navmap.end() ) { + nav_list_type locs = freq->second; + nav_list_const_iterator loc = locs.begin(); + while ( loc != locs.end() ) { + string name = (*loc)->get_name(); + string::size_type pos1 = name.find(" "); + string id = name.substr(0, pos1); + name = name.substr(pos1+1); + string::size_type pos2 = name.find(" "); + string rwy = name.substr(0, pos2); + + FGRunway r; + if ( runways->search(id, rwy, &r) ) { + update_loc_position( (*loc), &r, threshold ); + } + ++loc; + } + ++freq; + } +} +