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 = \
--- /dev/null
+// 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 <simgear/structure/exception.hxx>
+#include <simgear/debug/logstream.hxx>
+
+#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)
+{
+}
--- /dev/null
+// 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 <simgear/compiler.h>
+
+#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
#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,
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" );
in >> skipeol;
while (!in.eof()) {
- FGNavRecord *r = FGNavRecord::createFromStream(in);
+ FGNavRecord *r = createNavFromStream(in);
if (!r) {
- break;
+ continue;
}
switch (r->type()) {
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);
//incarrier >> skipeol;
while ( ! incarrier.eof() ) {
- FGNavRecord *r = FGNavRecord::createFromStream(incarrier);
+ FGNavRecord *r = createNavFromStream(incarrier);
if (!r) {
continue;
}
return true;
}
+
+FGRunway* getRunwayFromName(const std::string& aName)
+{
+ vector<string> 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;
+}
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
#include <simgear/misc/sgstream.hxx>
#include <simgear/structure/exception.hxx>
-#include <simgear/misc/strutils.hxx>
#include <simgear/debug/logstream.hxx>
#include "Navaids/navrecord.hxx"
-#include "Airports/simple.hxx"
+#include "Navaids/navdb.hxx"
#include "Airports/runways.hxx"
#include "Main/fg_props.hxx"
}
-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<string> 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
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);