X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNavaids%2Fnavdb.cxx;h=95f7f77eef15f1b72d1e4f32cefc360fa9331230;hb=76958a038251a697ad798bce630e7d793797cf78;hp=5ca43646e73af8039657b438c6f043aa73043f74;hpb=b2b33f75820359670ca4d8b326370fc3771ee08c;p=flightgear.git diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 5ca43646e..95f7f77ee 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,36 +16,97 @@ // // 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 -#include
+#include -#include "navrecord.hxx" +#include +#include +#include +#include +#include +#include +#include "navrecord.hxx" +#include "navlist.hxx" #include "navdb.hxx" +#include "Main/globals.hxx" +#include "Navaids/markerbeacon.hxx" +#include "Airports/simple.hxx" +using std::string; + +static FGPositioned::Type +mapRobinTypeToFGPType(int aTy) +{ + switch (aTy) { + // case 1: + case 2: return FGPositioned::NDB; + case 3: return FGPositioned::VOR; + case 4: return FGPositioned::LOC; + case 5: return FGPositioned::ILS; + case 6: return FGPositioned::GS; + case 12: + case 13: return FGPositioned::DME; + case 99: return FGPositioned::INVALID; // end-of-file code + default: + throw sg_range_exception("Got a nav.dat type we don't recognize", "FGNavRecord::createFromStream"); + } +} + +static FGNavRecord* createNavFromStream(std::istream& aStream) +{ + int rawType; + aStream >> rawType; + if (aStream.eof() || (rawType == 99)) { + return NULL; // happens with, eg, carrier_nav.dat + } + + double lat, lon, elev_ft, multiuse; + int freq, range; + std::string name, ident; + aStream >> lat >> lon >> elev_ft >> freq >> range >> multiuse >> ident; + getline(aStream, name); + + SGGeod pos(SGGeod::fromDegFt(lon, lat, elev_ft)); + name = simgear::strutils::strip(name); + + if ((rawType >= 7) && (rawType <= 9)) { + // marker beacons use a different run-time class now + FGMarkerBeaconRecord::create(rawType, name, pos); + return NULL; // not a nav-record, but that's okay + } + + FGPositioned::Type type = mapRobinTypeToFGPType(rawType); + if (type == FGPositioned::INVALID) { + return NULL; + } + + // silently multiply adf frequencies by 100 so that adf + // vs. nav/loc frequency lookups can use the same code. + if (type == FGPositioned::NDB) { + freq *= 100; + } + + return new FGNavRecord(type, ident, name, pos, + freq, range, multiuse); +} // load and initialize the navigational databases bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, - FGNavList *dmelist, FGNavList *mkrlist ) + FGNavList *dmelist, + FGNavList *tacanlist, FGNavList *carrierlist, + FGTACANList *channellist) { SG_LOG(SG_GENERAL, SG_INFO, "Loading Navaid Databases"); - // SG_LOG(SG_GENERAL, SG_INFO, " VOR/NDB"); - // SGPath p_nav( globals->get_fg_root() ); - // p_nav.append( "Navaids/default.nav" ); - // navlist->init( p_nav ); - - // SG_LOG(SG_GENERAL, SG_INFO, " ILS and Marker Beacons"); - // beacons->init(); - // SGPath p_ils( globals->get_fg_root() ); - // p_ils.append( "Navaids/default.ils" ); - // ilslist->init( p_ils ); - SGPath path( globals->get_fg_root() ); path.append( "Navaids/nav.dat" ); @@ -60,53 +121,130 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, in >> skipeol; in >> skipeol; - -#ifdef __MWERKS__ - char c = 0; - while ( in.get(c) && c != '\0' ) { - in.putback(c); -#else - while ( ! in.eof() ) { -#endif - - FGNavRecord *r = new FGNavRecord; - in >> (*r); - if ( r->get_type() > 95 ) { - break; + while (!in.eof()) { + FGNavRecord *r = createNavFromStream(in); + if (!r) { + continue; + } + + switch (r->type()) { + case FGPositioned::NDB: + case FGPositioned::VOR: + navlist->add(r); + break; + + case FGPositioned::ILS: + case FGPositioned::LOC: + loclist->add(r); + break; + + case FGPositioned::GS: + gslist->add(r); + break; + + case FGPositioned::DME: + { + dmelist->add(r); + string::size_type loc1= r->name().find( "TACAN", 0 ); + string::size_type loc2 = r->name().find( "VORTAC", 0 ); + + if( loc1 != string::npos || loc2 != string::npos) { + tacanlist->add(r); } - /* 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; */ - - if ( r->get_type() == 2 || r->get_type() == 3 ) { - // NDB=2, VOR=3 - navlist->add( r ); - } else if ( r->get_type() == 4 || r->get_type() == 5 ) { - // ILS=4, LOC(only)=5 - loclist->add( r ); - } else if ( r->get_type() == 6 ) { - // GS=6 - gslist->add( r ); - } else if ( r->get_type() == 7 || r->get_type() == 8 - || r->get_type() == 9 ) - { - // Marker Beacon = 7,8,9 - mkrlist->add( r ); - } else if ( r->get_type() == 12 ) { - // DME=12 - dmelist->add( r ); - } - - in >> skipcomment; + break; + } + + default: + throw sg_range_exception("got unsupported NavRecord type", "fgNavDBInit"); + } + + in >> skipcomment; + } // of stream data loop + +// load the carrier navaids file + + string file, name; + 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; + + while ( ! incarrier.eof() ) { + FGNavRecord *r = createNavFromStream(incarrier); + if (!r) { + continue; + } + + carrierlist->add (r); + } // 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; + while ( ! inchannel.eof() ) { + FGTACANRecord *r = new FGTACANRecord; + inchannel >> (*r); + channellist->add ( r ); + //cout << "channel = " << r->get_channel() ; + //cout << " freq = " << r->get_freq() << endl; + + } // end while + + + // end ReadChanFile - // cout << "min freq = " << min << endl; - // cout << "max freq = " << max << endl; return true; } + +FGRunway* getRunwayFromName(const std::string& aName) +{ + vector parts = simgear::strutils::split(aName); + if (parts.size() < 2) { + SG_LOG(SG_GENERAL, SG_WARN, "getRunwayFromName: malformed name:" << aName); + return NULL; + } + + const FGAirport* apt = fgFindAirportID(parts[0]); + if (!apt) { + SG_LOG(SG_GENERAL, SG_WARN, "navaid " << aName << " associated with bogus airport ID:" << parts[0]); + return NULL; + } + + FGRunway* runway = apt->getRunwayByIdent(parts[1]); + if (!runway) { + SG_LOG(SG_GENERAL, SG_WARN, "navaid " << aName << " associated with bogus runway ID:" << parts[1]); + return NULL; + } + + return runway; +}