From d756f913ec88a912e5bf34a06538952cf378fed7 Mon Sep 17 00:00:00 2001 From: jmt Date: Sat, 3 Jan 2009 15:54:03 +0000 Subject: [PATCH] Refactor marker-beacons to be distinct from FGNavRecord. This is a big space saving for beacons, but since they're surprisingly few (in nav.dat), not a an enormous saving in real terms. The major motivation is that marker beacons don't behave like other NavRecords for radio interaction - they have no ident, frequency or range (in the sense that NavRecord means them). --- src/Navaids/Makefile.am | 5 +- src/Navaids/markerbeacon.cxx | 68 +++++++++++++++++++++++ src/Navaids/markerbeacon.hxx | 50 +++++++++++++++++ src/Navaids/navdb.cxx | 103 ++++++++++++++++++++++++++++------- src/Navaids/navdb.hxx | 6 ++ src/Navaids/navrecord.cxx | 86 ++--------------------------- src/Navaids/navrecord.hxx | 2 - 7 files changed, 214 insertions(+), 106 deletions(-) create mode 100644 src/Navaids/markerbeacon.cxx create mode 100644 src/Navaids/markerbeacon.hxx diff --git a/src/Navaids/Makefile.am b/src/Navaids/Makefile.am index a6201ae7f..a1f38ed14 100644 --- a/src/Navaids/Makefile.am +++ b/src/Navaids/Makefile.am @@ -8,10 +8,9 @@ libNavaids_a_SOURCES = \ awynet.hxx awynet.cxx \ navrecord.hxx navrecord.cxx \ navlist.hxx navlist.cxx \ - positioned.hxx positioned.cxx + positioned.hxx positioned.cxx \ + markerbeacon.hxx markerbeacon.cxx -# ils.hxx ilslist.hxx ilslist.cxx \ -# mkrbeacons.hxx mkrbeacons.cxx # # testnavs_SOURCES = testnavs.cxx # testnavs_LDADD = \ diff --git a/src/Navaids/markerbeacon.cxx b/src/Navaids/markerbeacon.cxx new file mode 100644 index 000000000..9eaeff2cd --- /dev/null +++ b/src/Navaids/markerbeacon.cxx @@ -0,0 +1,68 @@ +// markerbeacon.cxx -- marker beacon class +// +// Written by James Turner, started December 2008. +// +// Copyright (C) 2008 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 +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +#include "Navaids/markerbeacon.hxx" +#include "Airports/runways.hxx" +#include "Navaids/navdb.hxx" + +using std::string; + +FGPositioned::Type +FGMarkerBeacon::mapType(int aTy) +{ + switch (aTy) { + case 7: return FGPositioned::OM; + case 8: return FGPositioned::MM; + case 9: return FGPositioned::IM; + default: + throw sg_range_exception("Got a non-marker-beacon-type", + "FGMarkerBeacon::mapType"); + } +} + +FGMarkerBeacon* +FGMarkerBeacon::create(int aTy, const string& aName, const SGGeod& aPos) +{ + Type fgpTy = mapType(aTy); + FGRunway* runway = getRunwayFromName(aName); + SGGeod pos(aPos); + // fudge elevation to the runway elevation if it's not specified + if (fabs(pos.getElevationFt()) < 0.01) { + pos.setElevationFt(runway->elevation()); + } + + return new FGMarkerBeacon(fgpTy, runway, pos); +} + + +FGMarkerBeacon::FGMarkerBeacon(Type aTy, FGRunway* aRunway, const SGGeod& aPos) : + FGPositioned(aTy, string(), aPos), + _runway(aRunway) +{ +} diff --git a/src/Navaids/markerbeacon.hxx b/src/Navaids/markerbeacon.hxx new file mode 100644 index 000000000..198959c59 --- /dev/null +++ b/src/Navaids/markerbeacon.hxx @@ -0,0 +1,50 @@ +// markerbeacon.hxx -- marker beacon class +// +// Written by James Turner, started December 2008. +// +// Copyright (C) 2008 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 +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#ifndef _FG_MARKERBEACON_HXX +#define _FG_MARKERBEACON_HXX + +#include + +#include "positioned.hxx" + +// forward decls +class FGRunway; + +class FGMarkerBeacon : public FGPositioned +{ +public: + static FGMarkerBeacon* create(int aTy, const std::string& aName, const SGGeod& aPos); + +private: + FGMarkerBeacon(Type aTy, FGRunway* aRunway, const SGGeod& aPos); + + FGRunway* _runway; // should this be ref-ptr? + + /** + * Helper to map a 'Robin' integer type to an FGPositioned::Type + */ + static Type mapType(int aTy); +}; + +#endif // _FG_MARKERBEACON_HXX diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 40f487c5c..e6979ee96 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -39,9 +39,66 @@ #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()) { + 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 + FGMarkerBeacon::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, @@ -50,17 +107,6 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, 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" ); @@ -76,9 +122,9 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, in >> skipeol; while (!in.eof()) { - FGNavRecord *r = FGNavRecord::createFromStream(in); + FGNavRecord *r = createNavFromStream(in); if (!r) { - break; + continue; } switch (r->type()) { @@ -96,12 +142,6 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, gslist->add(r); break; - case FGPositioned::OM: - case FGPositioned::MM: - case FGPositioned::IM: - // no need to add this to a list, never searched by frequency - break; - case FGPositioned::DME: { dmelist->add(r); @@ -143,7 +183,7 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, //incarrier >> skipeol; while ( ! incarrier.eof() ) { - FGNavRecord *r = FGNavRecord::createFromStream(incarrier); + FGNavRecord *r = createNavFromStream(incarrier); if (!r) { continue; } @@ -185,3 +225,26 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, 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; +} diff --git a/src/Navaids/navdb.hxx b/src/Navaids/navdb.hxx index 87e510825..5c2aa117c 100644 --- a/src/Navaids/navdb.hxx +++ b/src/Navaids/navdb.hxx @@ -37,4 +37,10 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, FGTACANList *channellist ); +/** + * Helper to map a nav.data name (eg 'KBWI 33R GS') into a FGRunway reference. + * returns NULL, and complains loudly, if the airport/runway is not found. + */ +FGRunway* getRunwayFromName(const std::string& aName); + #endif // _FG_NAVDB_HXX diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx index 1e3800ae4..c2ab0e9a7 100644 --- a/src/Navaids/navrecord.cxx +++ b/src/Navaids/navrecord.cxx @@ -28,11 +28,10 @@ #include #include -#include #include #include "Navaids/navrecord.hxx" -#include "Airports/simple.hxx" +#include "Navaids/navdb.hxx" #include "Airports/runways.hxx" #include "Main/fg_props.hxx" @@ -77,91 +76,16 @@ FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent, } -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 7: return FGPositioned::OM; - case 8: return FGPositioned::MM; - case 9: return FGPositioned::IM; - 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"); - } -} - -FGNavRecord* FGNavRecord::createFromStream(std::istream& aStream) -{ - int rawType; - aStream >> rawType; - if (aStream.eof()) { - return NULL; // happens with, eg, carrier_nav.dat - } - - Type type = mapRobinTypeToFGPType(rawType); - if (type == INVALID) return NULL; - - 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); - - // silently multiply adf frequencies by 100 so that adf - // vs. nav/loc frequency lookups can use the same code. - if (type == NDB) { - freq *= 100; - } - - // ensure marker beacons are anonymous, so they don't get added to the - // name index - if ((type >= OM) && (type <= IM)) { - ident.clear(); - } - - FGNavRecord* result = new FGNavRecord(type, ident, - simgear::strutils::strip(name), SGGeod::fromDegFt(lon, lat, elev_ft), - freq, range, multiuse); - - return result; -} - void FGNavRecord::initAirportRelation() { - if ((type() < ILS) || (type() > IM)) { + if ((type() < ILS) || (type() > GS)) { return; // not airport-located } - vector parts = simgear::strutils::split(_name); - if (parts.size() < 2) { - SG_LOG(SG_GENERAL, SG_WARN, "navaid has malformed name:" << _name); - return; - } - - const FGAirport* apt = fgFindAirportID(parts[0]); - - if (!apt) { - SG_LOG(SG_GENERAL, SG_WARN, "navaid " << _name << " associated with bogus airport ID:" << parts[0]); - return; - } - - runway = apt->getRunwayByIdent(parts[1]); - if (!runway) { - SG_LOG(SG_GENERAL, SG_WARN, "navaid " << _name << " associated with bogus runway ID:" << parts[1]); - return; - } - - // fudge elevation to the field elevation if it's not specified + FGRunway* runway = getRunwayFromName(_name); + // fudge elevation to the runway elevation if it's not specified if (fabs(elevation()) < 0.01) { - mPosition.setElevationFt(apt->getElevation()); + mPosition.setElevationFt(runway->elevation()); } // align localizers with their runway diff --git a/src/Navaids/navrecord.hxx b/src/Navaids/navrecord.hxx index 57c199d6c..5d205d654 100644 --- a/src/Navaids/navrecord.hxx +++ b/src/Navaids/navrecord.hxx @@ -68,8 +68,6 @@ class FGNavRecord : public FGPositioned public: inline ~FGNavRecord(void) {} - static FGNavRecord* createFromStream(std::istream& aStream); - FGNavRecord(Type type, const std::string& ident, const std::string& name, const SGGeod& aPos, int freq, int range, double multiuse);