#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <Airports/dynamics.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Main/util.hxx>
#include <string>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Main/fg_init.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <Airports/runways.hxx>
#include <Airports/groundnetwork.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <Airports/dynamics.hxx>
#include "AIAircraft.hxx"
#include <fstream>
#include <iostream>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <Airports/dynamics.hxx>
#include <simgear/math/sg_geodesy.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <Airports/dynamics.hxx>
#include <boost/foreach.hpp>
#include <Main/globals.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include "AIManager.hxx"
#include "AIAircraft.hxx"
#include <iostream>
#include <Airports/dynamics.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Scenery/scenery.hxx>
#include "atc_mgr.hxx"
#include <Main/fg_props.hxx>
#include <GUI/gui.h> // mkDialog
#include <GUI/new_gui.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <ATC/CommStation.hxx>
using std::string;
#include <Traffic/TrafficMgr.hxx>
#include <Airports/groundnetwork.hxx>
#include <Airports/dynamics.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Radio/radio.hxx>
#include <signal.h>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <ATC/CommStation.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
FGATC::FGATC() :
freq(0),
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <math.h>
runwayprefs.cxx
runways.cxx
sidstar.cxx
- simple.cxx
+ airport.cxx
xmlloader.cxx
)
runwayprefs.hxx
runways.hxx
sidstar.hxx
- simple.hxx
+ airport.hxx
xmlloader.hxx
)
--- /dev/null
+//
+// simple.cxx -- a really simplistic class to manage airport ID,
+// lat, lon of the center of one of it's runways, and
+// elevation in feet.
+//
+// Written by Curtis Olson, started April 1998.
+// Updated by Durk Talsma, started December, 2004.
+//
+// Copyright (C) 1998 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 "airport.hxx"
+
+#include <cassert>
+#include <boost/foreach.hpp>
+
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/sg_inlines.h>
+#include <simgear/structure/exception.hxx>
+
+#include <Environment/environment_mgr.hxx>
+#include <Environment/environment.hxx>
+#include <Main/fg_props.hxx>
+#include <Airports/runways.hxx>
+#include <Airports/pavement.hxx>
+#include <Airports/dynamics.hxx>
+#include <Airports/xmlloader.hxx>
+#include <Navaids/procedure.hxx>
+#include <Navaids/waypoint.hxx>
+#include <ATC/CommStation.hxx>
+#include <Navaids/NavDataCache.hxx>
+
+using std::vector;
+using std::pair;
+
+using namespace flightgear;
+
+
+/***************************************************************************
+ * FGAirport
+ ***************************************************************************/
+
+AirportCache FGAirport::airportCache;
+
+FGAirport::FGAirport(PositionedID aGuid, const string &id, const SGGeod& location,
+ const string &name, bool has_metar, Type aType) :
+ FGPositioned(aGuid, aType, id, location),
+ _name(name),
+ _has_metar(has_metar),
+ _dynamics(0),
+ mTowerDataLoaded(false),
+ mRunwaysLoaded(false),
+ mTaxiwaysLoaded(false),
+ mProceduresLoaded(false),
+ mILSDataLoaded(false)
+{
+}
+
+
+FGAirport::~FGAirport()
+{
+ delete _dynamics;
+}
+
+bool FGAirport::isAirport() const
+{
+ return type() == AIRPORT;
+}
+
+bool FGAirport::isSeaport() const
+{
+ return type() == SEAPORT;
+}
+
+bool FGAirport::isHeliport() const
+{
+ return type() == HELIPORT;
+}
+
+bool FGAirport::isAirportType(FGPositioned* pos)
+{
+ if (!pos) {
+ return false;
+ }
+
+ return (pos->type() >= AIRPORT) && (pos->type() <= SEAPORT);
+}
+
+FGAirportDynamics * FGAirport::getDynamics()
+{
+ if (_dynamics) {
+ return _dynamics;
+ }
+
+ _dynamics = new FGAirportDynamics(this);
+ XMLLoader::load(_dynamics);
+ _dynamics->init();
+
+ FGRunwayPreference rwyPrefs(this);
+ XMLLoader::load(&rwyPrefs);
+ _dynamics->setRwyUse(rwyPrefs);
+
+ return _dynamics;
+}
+
+unsigned int FGAirport::numRunways() const
+{
+ loadRunways();
+ return mRunways.size();
+}
+
+unsigned int FGAirport::numHelipads() const
+{
+ loadHelipads();
+ return mHelipads.size();
+}
+
+FGRunway* FGAirport::getRunwayByIndex(unsigned int aIndex) const
+{
+ loadRunways();
+
+ assert(aIndex >= 0 && aIndex < mRunways.size());
+ return (FGRunway*) flightgear::NavDataCache::instance()->loadById(mRunways[aIndex]);
+}
+
+FGHelipad* FGAirport::getHelipadByIndex(unsigned int aIndex) const
+{
+ loadHelipads();
+
+ assert(aIndex >= 0 && aIndex < mHelipads.size());
+ return (FGHelipad*) flightgear::NavDataCache::instance()->loadById(mHelipads[aIndex]);
+}
+
+bool FGAirport::hasRunwayWithIdent(const string& aIdent) const
+{
+ return flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent) != 0;
+}
+
+FGRunway* FGAirport::getRunwayByIdent(const string& aIdent) const
+{
+ PositionedID id = flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent);
+ if (id == 0) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident());
+ throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getRunwayByIdent");
+ }
+
+ return (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
+}
+
+
+FGRunway* FGAirport::findBestRunwayForHeading(double aHeading) const
+{
+ loadRunways();
+
+ FGRunway* result = NULL;
+ double currentBestQuality = 0.0;
+
+ SGPropertyNode *param = fgGetNode("/sim/airport/runways/search", true);
+ double lengthWeight = param->getDoubleValue("length-weight", 0.01);
+ double widthWeight = param->getDoubleValue("width-weight", 0.01);
+ double surfaceWeight = param->getDoubleValue("surface-weight", 10);
+ double deviationWeight = param->getDoubleValue("deviation-weight", 1);
+
+ BOOST_FOREACH(PositionedID id, mRunways) {
+ FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
+ double good = rwy->score(lengthWeight, widthWeight, surfaceWeight);
+ double dev = aHeading - rwy->headingDeg();
+ SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
+ double bad = fabs(deviationWeight * dev) + 1e-20;
+ double quality = good / bad;
+
+ if (quality > currentBestQuality) {
+ currentBestQuality = quality;
+ result = rwy;
+ }
+ }
+
+ return result;
+}
+
+FGRunway* FGAirport::findBestRunwayForPos(const SGGeod& aPos) const
+{
+ loadRunways();
+
+ FGRunway* result = NULL;
+ double currentLowestDev = 180.0;
+
+ BOOST_FOREACH(PositionedID id, mRunways) {
+ FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
+
+ double inboundCourse = SGGeodesy::courseDeg(aPos, rwy->end());
+ double dev = inboundCourse - rwy->headingDeg();
+ SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
+
+ dev = fabs(dev);
+ if (dev < currentLowestDev) { // new best match
+ currentLowestDev = dev;
+ result = rwy;
+ }
+ } // of runway iteration
+
+ return result;
+
+}
+
+bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const
+{
+ loadRunways();
+
+ BOOST_FOREACH(PositionedID id, mRunways) {
+ FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
+
+ if (rwy->isReciprocal()) {
+ continue; // we only care about lengths, so don't do work twice
+ }
+
+ if (rwy->isHardSurface() && (rwy->lengthFt() >= aLengthFt)) {
+ return true; // we're done!
+ }
+ } // of runways iteration
+
+ return false;
+}
+
+unsigned int FGAirport::numTaxiways() const
+{
+ loadTaxiways();
+ return mTaxiways.size();
+}
+
+FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const
+{
+ loadTaxiways();
+
+ assert(aIndex >= 0 && aIndex < mTaxiways.size());
+ return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(mTaxiways[aIndex]);
+}
+
+unsigned int FGAirport::numPavements() const
+{
+ loadTaxiways();
+ return mPavements.size();
+}
+
+FGPavement* FGAirport::getPavementByIndex(unsigned int aIndex) const
+{
+ loadTaxiways();
+ assert(aIndex >= 0 && aIndex < mPavements.size());
+ return (FGPavement*) flightgear::NavDataCache::instance()->loadById(mPavements[aIndex]);
+}
+
+FGRunway* FGAirport::getActiveRunwayForUsage() const
+{
+ FGEnvironmentMgr* envMgr = (FGEnvironmentMgr *) globals->get_subsystem("environment");
+
+ // This forces West-facing rwys to be used in no-wind situations
+ // which is consistent with Flightgear's initial setup.
+ double hdg = 270;
+
+ if (envMgr) {
+ FGEnvironment stationWeather(envMgr->getEnvironment(mPosition));
+
+ double windSpeed = stationWeather.get_wind_speed_kt();
+ if (windSpeed > 0.0) {
+ hdg = stationWeather.get_wind_from_heading_deg();
+ }
+ }
+
+ return findBestRunwayForHeading(hdg);
+}
+
+FGAirport* FGAirport::findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter)
+{
+ AirportFilter aptFilter;
+ if (filter == NULL) {
+ filter = &aptFilter;
+ }
+
+ FGPositionedRef r = FGPositioned::findClosest(aPos, aCuttofNm, filter);
+ if (!r) {
+ return NULL;
+ }
+
+ return static_cast<FGAirport*>(r.ptr());
+}
+
+FGAirport::HardSurfaceFilter::HardSurfaceFilter(double minLengthFt) :
+ mMinLengthFt(minLengthFt)
+{
+ if (minLengthFt < 0.0) {
+ mMinLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft", 0.0);
+ }
+}
+
+bool FGAirport::HardSurfaceFilter::passAirport(FGAirport* aApt) const
+{
+ return aApt->hasHardRunwayOfLengthFt(mMinLengthFt);
+}
+
+FGAirport* FGAirport::findByIdent(const std::string& aIdent)
+{
+ AirportCache::iterator it = airportCache.find(aIdent);
+ if (it != airportCache.end())
+ return it->second;
+
+ PortsFilter filter;
+ FGAirport* r = static_cast<FGAirport*> (FGPositioned::findFirstWithIdent(aIdent, &filter).get());
+
+ // add airport to the cache (even when it's NULL, so we don't need to search in vain again)
+ airportCache[aIdent] = r;
+
+ // we don't warn here when r==NULL, let the caller do that
+ return r;
+}
+
+FGAirport* FGAirport::getByIdent(const std::string& aIdent)
+{
+ FGAirport* r = findByIdent(aIdent);
+ if (!r)
+ throw sg_range_exception("No such airport with ident: " + aIdent);
+ return r;
+}
+
+char** FGAirport::searchNamesAndIdents(const std::string& aFilter)
+{
+ return NavDataCache::instance()->searchAirportNamesAndIdents(aFilter);
+}
+
+// find basic airport location info from airport database
+const FGAirport *fgFindAirportID( const string& id)
+{
+ if ( id.empty() ) {
+ return NULL;
+ }
+
+ return FGAirport::findByIdent(id);
+}
+
+void FGAirport::loadRunways() const
+{
+ if (mRunwaysLoaded) {
+ return; // already loaded, great
+ }
+
+ loadSceneryDefinitions();
+
+ mRunwaysLoaded = true;
+ mRunways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::RUNWAY);
+}
+
+void FGAirport::loadHelipads() const
+{
+ if (mHelipadsLoaded) {
+ return; // already loaded, great
+ }
+
+ loadSceneryDefinitions();
+
+ mHelipadsLoaded = true;
+ mHelipads = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::HELIPAD);
+}
+
+void FGAirport::loadTaxiways() const
+{
+ if (mTaxiwaysLoaded) {
+ return; // already loaded, great
+ }
+
+ mTaxiwaysLoaded = true;
+ mTaxiways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::TAXIWAY);
+}
+
+void FGAirport::loadProcedures() const
+{
+ if (mProceduresLoaded) {
+ return;
+ }
+
+ mProceduresLoaded = true;
+ SGPath path;
+ if (!XMLLoader::findAirportData(ident(), "procedures", path)) {
+ SG_LOG(SG_GENERAL, SG_INFO, "no procedures data available for " << ident());
+ return;
+ }
+
+ SG_LOG(SG_GENERAL, SG_INFO, ident() << ": loading procedures from " << path.str());
+ RouteBase::loadAirportProcedures(path, const_cast<FGAirport*>(this));
+}
+
+void FGAirport::loadSceneryDefinitions() const
+{
+ NavDataCache* cache = NavDataCache::instance();
+ SGPath path;
+ if (!XMLLoader::findAirportData(ident(), "threshold", path)) {
+ return; // no XML threshold data
+ }
+
+ if (!cache->isCachedFileModified(path)) {
+ // cached values are correct, we're all done
+ return;
+ }
+
+ flightgear::NavDataCache::Transaction txn(cache);
+ SGPropertyNode_ptr rootNode = new SGPropertyNode;
+ readProperties(path.str(), rootNode);
+ const_cast<FGAirport*>(this)->readThresholdData(rootNode);
+ cache->stampCacheFile(path);
+ txn.commit();
+}
+
+void FGAirport::readThresholdData(SGPropertyNode* aRoot)
+{
+ SGPropertyNode* runway;
+ int runwayIndex = 0;
+ for (; (runway = aRoot->getChild("runway", runwayIndex)) != NULL; ++runwayIndex) {
+ SGPropertyNode* t0 = runway->getChild("threshold", 0),
+ *t1 = runway->getChild("threshold", 1);
+ assert(t0);
+ assert(t1); // too strict? maybe we should finally allow single-ended runways
+
+ processThreshold(t0);
+ processThreshold(t1);
+ } // of runways iteration
+}
+
+void FGAirport::processThreshold(SGPropertyNode* aThreshold)
+{
+ // first, let's identify the current runway
+ string rwyIdent(aThreshold->getStringValue("rwy"));
+ NavDataCache* cache = NavDataCache::instance();
+ PositionedID id = cache->airportItemWithIdent(guid(), FGPositioned::RUNWAY, rwyIdent);
+ if (id == 0) {
+ SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: "
+ "found runway not defined in the global data:" << ident() << "/" << rwyIdent);
+ return;
+ }
+
+ double lon = aThreshold->getDoubleValue("lon"),
+ lat = aThreshold->getDoubleValue("lat");
+ SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM()));
+
+ double newHeading = aThreshold->getDoubleValue("hdg-deg");
+ double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m") * SG_METER_TO_FEET;
+ double newStopway = aThreshold->getDoubleValue("stopw-m") * SG_METER_TO_FEET;
+
+ cache->updateRunwayThreshold(id, newThreshold,
+ newHeading, newDisplacedThreshold, newStopway);
+}
+
+SGGeod FGAirport::getTowerLocation() const
+{
+ validateTowerData();
+
+ NavDataCache* cache = NavDataCache::instance();
+ PositionedIDVec towers = cache->airportItemsOfType(guid(), FGPositioned::TOWER);
+ if (towers.empty()) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "No towers defined for:" <<ident());
+ return SGGeod();
+ }
+
+ FGPositionedRef tower = cache->loadById(towers.front());
+ return tower->geod();
+}
+
+void FGAirport::validateTowerData() const
+{
+ if (mTowerDataLoaded) {
+ return;
+ }
+
+ mTowerDataLoaded = true;
+ NavDataCache* cache = NavDataCache::instance();
+ SGPath path;
+ if (!XMLLoader::findAirportData(ident(), "twr", path)) {
+ return; // no XML tower data
+ }
+
+ if (!cache->isCachedFileModified(path)) {
+ // cached values are correct, we're all done
+ return;
+ }
+
+ flightgear::NavDataCache::Transaction txn(cache);
+ SGPropertyNode_ptr rootNode = new SGPropertyNode;
+ readProperties(path.str(), rootNode);
+ const_cast<FGAirport*>(this)->readTowerData(rootNode);
+ cache->stampCacheFile(path);
+ txn.commit();
+}
+
+void FGAirport::readTowerData(SGPropertyNode* aRoot)
+{
+ SGPropertyNode* twrNode = aRoot->getChild("tower")->getChild("twr");
+ double lat = twrNode->getDoubleValue("lat"),
+ lon = twrNode->getDoubleValue("lon"),
+ elevM = twrNode->getDoubleValue("elev-m");
+// tower elevation is AGL, not AMSL. Since we don't want to depend on the
+// scenery for a precise terrain elevation, we use the field elevation
+// (this is also what the apt.dat code does)
+ double fieldElevationM = geod().getElevationM();
+ SGGeod towerLocation(SGGeod::fromDegM(lon, lat, fieldElevationM + elevM));
+
+ NavDataCache* cache = NavDataCache::instance();
+ PositionedIDVec towers = cache->airportItemsOfType(guid(), FGPositioned::TOWER);
+ if (towers.empty()) {
+ cache->insertTower(guid(), towerLocation);
+ } else {
+ // update the position
+ cache->updatePosition(towers.front(), towerLocation);
+ }
+}
+
+bool FGAirport::validateILSData()
+{
+ if (mILSDataLoaded) {
+ return false;
+ }
+
+ mILSDataLoaded = true;
+ NavDataCache* cache = NavDataCache::instance();
+ SGPath path;
+ if (!XMLLoader::findAirportData(ident(), "ils", path)) {
+ return false; // no XML tower data
+ }
+
+ if (!cache->isCachedFileModified(path)) {
+ // cached values are correct, we're all done
+ return false;
+ }
+
+ SGPropertyNode_ptr rootNode = new SGPropertyNode;
+ readProperties(path.str(), rootNode);
+
+ flightgear::NavDataCache::Transaction txn(cache);
+ readILSData(rootNode);
+ cache->stampCacheFile(path);
+ txn.commit();
+
+// we loaded data, tell the caller it might need to reload things
+ return true;
+}
+
+void FGAirport::readILSData(SGPropertyNode* aRoot)
+{
+ NavDataCache* cache = NavDataCache::instance();
+
+ // find the entry matching the runway
+ SGPropertyNode* runwayNode, *ilsNode;
+ for (int i=0; (runwayNode = aRoot->getChild("runway", i)) != NULL; ++i) {
+ for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) {
+ // must match on both nav-ident and runway ident, to support the following:
+ // - runways with multiple distinct ILS installations (KEWD, for example)
+ // - runways where both ends share the same nav ident (LFAT, for example)
+ PositionedID ils = cache->findILS(guid(), ilsNode->getStringValue("rwy"),
+ ilsNode->getStringValue("nav-id"));
+ if (ils == 0) {
+ SG_LOG(SG_GENERAL, SG_INFO, "reading ILS data for " << ident() <<
+ ", couldn;t find runway/navaid for:" <<
+ ilsNode->getStringValue("rwy") << "/" <<
+ ilsNode->getStringValue("nav-id"));
+ continue;
+ }
+
+ double hdgDeg = ilsNode->getDoubleValue("hdg-deg"),
+ lon = ilsNode->getDoubleValue("lon"),
+ lat = ilsNode->getDoubleValue("lat"),
+ elevM = ilsNode->getDoubleValue("elev-m");
+
+ cache->updateILS(ils, SGGeod::fromDegM(lon, lat, elevM), hdgDeg);
+ } // of ILS iteration
+ } // of runway iteration
+}
+
+void FGAirport::addSID(flightgear::SID* aSid)
+{
+ mSIDs.push_back(aSid);
+}
+
+void FGAirport::addSTAR(STAR* aStar)
+{
+ mSTARs.push_back(aStar);
+}
+
+void FGAirport::addApproach(Approach* aApp)
+{
+ mApproaches.push_back(aApp);
+}
+
+unsigned int FGAirport::numSIDs() const
+{
+ loadProcedures();
+ return mSIDs.size();
+}
+
+flightgear::SID* FGAirport::getSIDByIndex(unsigned int aIndex) const
+{
+ loadProcedures();
+ return mSIDs[aIndex];
+}
+
+flightgear::SID* FGAirport::findSIDWithIdent(const std::string& aIdent) const
+{
+ loadProcedures();
+ for (unsigned int i=0; i<mSIDs.size(); ++i) {
+ if (mSIDs[i]->ident() == aIdent) {
+ return mSIDs[i];
+ }
+ }
+
+ return NULL;
+}
+
+unsigned int FGAirport::numSTARs() const
+{
+ loadProcedures();
+ return mSTARs.size();
+}
+
+STAR* FGAirport::getSTARByIndex(unsigned int aIndex) const
+{
+ loadProcedures();
+ return mSTARs[aIndex];
+}
+
+STAR* FGAirport::findSTARWithIdent(const std::string& aIdent) const
+{
+ loadProcedures();
+ for (unsigned int i=0; i<mSTARs.size(); ++i) {
+ if (mSTARs[i]->ident() == aIdent) {
+ return mSTARs[i];
+ }
+ }
+
+ return NULL;
+}
+
+unsigned int FGAirport::numApproaches() const
+{
+ loadProcedures();
+ return mApproaches.size();
+}
+
+Approach* FGAirport::getApproachByIndex(unsigned int aIndex) const
+{
+ loadProcedures();
+ return mApproaches[aIndex];
+}
+
+Approach* FGAirport::findApproachWithIdent(const std::string& aIdent) const
+{
+ loadProcedures();
+ for (unsigned int i=0; i<mApproaches.size(); ++i) {
+ if (mApproaches[i]->ident() == aIdent) {
+ return mApproaches[i];
+ }
+ }
+
+ return NULL;
+}
+
+CommStationList
+FGAirport::commStations() const
+{
+ NavDataCache* cache = NavDataCache::instance();
+ CommStationList result;
+ BOOST_FOREACH(PositionedID pos, cache->airportItemsOfType(guid(),
+ FGPositioned::FREQ_GROUND,
+ FGPositioned::FREQ_UNICOM))
+ {
+ result.push_back((CommStation*) cache->loadById(pos));
+ }
+
+ return result;
+}
+
+CommStationList
+FGAirport::commStationsOfType(FGPositioned::Type aTy) const
+{
+ NavDataCache* cache = NavDataCache::instance();
+ CommStationList result;
+ BOOST_FOREACH(PositionedID pos, cache->airportItemsOfType(guid(), aTy)) {
+ result.push_back((CommStation*) cache->loadById(pos));
+ }
+
+ return result;
+}
+
+// get airport elevation
+double fgGetAirportElev( const string& id )
+{
+ const FGAirport *a=fgFindAirportID( id);
+ if (a) {
+ return a->getElevation();
+ } else {
+ return -9999.0;
+ }
+}
+
+
+// get airport position
+SGGeod fgGetAirportPos( const string& id )
+{
+ const FGAirport *a = fgFindAirportID( id);
+
+ if (a) {
+ return SGGeod::fromDegM(a->getLongitude(), a->getLatitude(), a->getElevation());
+ } else {
+ return SGGeod::fromDegM(0.0, 0.0, -9999.0);
+ }
+}
--- /dev/null
+// airport.hxx -- a really simplistic class to manage airport ID,
+// lat, lon of the center of one of it's runways, and
+// elevation in feet.
+//
+// Written by Curtis Olson, started April 1998.
+// Updated by Durk Talsma, started December 2004.
+//
+// Copyright (C) 1998 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_SIMPLE_HXX
+#define _FG_SIMPLE_HXX
+
+#include <simgear/compiler.h>
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include <Navaids/positioned.hxx>
+
+// forward decls
+class FGAirportDynamics;
+class FGRunway;
+class FGHelipad;
+class FGTaxiway;
+class FGPavement;
+class SGPropertyNode;
+class FGAirport;
+
+namespace flightgear {
+ class SID;
+ class STAR;
+ class Approach;
+ class Waypt;
+ class CommStation;
+
+ typedef SGSharedPtr<Waypt> WayptRef;
+ typedef std::vector<WayptRef> WayptVec;
+
+ typedef std::vector<CommStation*> CommStationList;
+ typedef std::map<std::string, FGAirport*> AirportCache;
+}
+
+
+
+/***************************************************************************************
+ *
+ **************************************************************************************/
+class FGAirport : public FGPositioned
+{
+public:
+ FGAirport(PositionedID aGuid, const std::string& id, const SGGeod& location,
+ const std::string& name, bool has_metar, Type aType);
+ ~FGAirport();
+
+ const std::string& getId() const { return ident(); }
+ const std::string& getName() const { return _name; }
+ double getLongitude() const { return longitude(); }
+ // Returns degrees
+ double getLatitude() const { return latitude(); }
+ // Returns ft
+ double getElevation() const { return elevation(); }
+ bool getMetar() const { return _has_metar; }
+ bool isAirport() const;
+ bool isSeaport() const;
+ bool isHeliport() const;
+
+ static bool isAirportType(FGPositioned* pos);
+
+ virtual const std::string& name() const
+ { return _name; }
+
+ /**
+ * reload the ILS data from XML if required.
+ * @result true if the data was refreshed, false if no data was loaded
+ * or previously cached data is still correct.
+ */
+ bool validateILSData();
+
+ SGGeod getTowerLocation() const;
+
+ void setMetar(bool value) { _has_metar = value; }
+
+ FGRunway* getActiveRunwayForUsage() const;
+
+ FGAirportDynamics *getDynamics();
+
+ unsigned int numRunways() const;
+ unsigned int numHelipads() const;
+ FGRunway* getRunwayByIndex(unsigned int aIndex) const;
+ FGHelipad* getHelipadByIndex(unsigned int aIndex) const;
+
+ bool hasRunwayWithIdent(const std::string& aIdent) const;
+ FGRunway* getRunwayByIdent(const std::string& aIdent) const;
+ FGRunway* findBestRunwayForHeading(double aHeading) const;
+
+ /**
+ * return the most likely target runway based on a position.
+ * Specifically, return the runway for which the course from aPos
+ * to the runway end, mostly closely matches the runway heading.
+ * This is a good approximation of which runway the position is on or
+ * aiming towards.
+ */
+ FGRunway* findBestRunwayForPos(const SGGeod& aPos) const;
+
+ /**
+ * Useful predicate for FMS/GPS/NAV displays and similar - check if this
+ * aiport has a hard-surfaced runway of at least the specified length.
+ */
+ bool hasHardRunwayOfLengthFt(double aLengthFt) const;
+
+ unsigned int numTaxiways() const;
+ FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const;
+
+ unsigned int numPavements() const;
+ FGPavement* getPavementByIndex(unsigned int aIndex) const;
+
+ class AirportFilter : public Filter
+ {
+ public:
+ virtual bool pass(FGPositioned* aPos) const {
+ return passAirport(static_cast<FGAirport*>(aPos));
+ }
+
+ virtual Type minType() const {
+ return AIRPORT;
+ }
+
+ virtual Type maxType() const {
+ return AIRPORT;
+ }
+
+ virtual bool passAirport(FGAirport* aApt) const {
+ return true;
+ }
+ };
+
+ /**
+ * Filter which passes heliports and seaports in addition to airports
+ */
+ class PortsFilter : public AirportFilter
+ {
+ public:
+ virtual Type maxType() const {
+ return SEAPORT;
+ }
+ };
+
+ class HardSurfaceFilter : public AirportFilter
+ {
+ public:
+ HardSurfaceFilter(double minLengthFt = -1);
+
+ virtual bool passAirport(FGAirport* aApt) const;
+
+ private:
+ double mMinLengthFt;
+ };
+
+
+ void setProcedures(const std::vector<flightgear::SID*>& aSids,
+ const std::vector<flightgear::STAR*>& aStars,
+ const std::vector<flightgear::Approach*>& aApproaches);
+
+ void addSID(flightgear::SID* aSid);
+ void addSTAR(flightgear::STAR* aStar);
+ void addApproach(flightgear::Approach* aApp);
+
+ unsigned int numSIDs() const;
+ flightgear::SID* getSIDByIndex(unsigned int aIndex) const;
+ flightgear::SID* findSIDWithIdent(const std::string& aIdent) const;
+
+ unsigned int numSTARs() const;
+ flightgear::STAR* getSTARByIndex(unsigned int aIndex) const;
+ flightgear::STAR* findSTARWithIdent(const std::string& aIdent) const;
+
+ unsigned int numApproaches() const;
+ flightgear::Approach* getApproachByIndex(unsigned int aIndex) const;
+ flightgear::Approach* findApproachWithIdent(const std::string& aIdent) const;
+
+ /**
+ * Syntactic wrapper around FGPositioned::findClosest - find the closest
+ * match for filter, and return it cast to FGAirport. The default filter
+ * passes airports, but not seaports or heliports
+ */
+ static FGAirport* findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL);
+
+ /**
+ * Helper to look up an FGAirport instance by unique ident. Throws an
+ * exception if the airport could not be found - so callers can assume
+ * the result is non-NULL.
+ */
+ static FGAirport* getByIdent(const std::string& aIdent);
+
+ /**
+ * Helper to look up an FGAirport instance by unique ident. Returns NULL
+ * if the airport could not be found.
+ */
+ static FGAirport* findByIdent(const std::string& aIdent);
+
+ /**
+ * Specialised helper to implement the AirportList dialog. Performs a
+ * case-insensitive search on airport names and ICAO codes, and returns
+ * matches in a format suitable for use by a puaList.
+ */
+ static char** searchNamesAndIdents(const std::string& aFilter);
+
+ flightgear::CommStationList commStationsOfType(FGPositioned::Type aTy) const;
+
+ flightgear::CommStationList commStations() const;
+private:
+ static flightgear::AirportCache airportCache;
+
+ // disable these
+ FGAirport operator=(FGAirport &other);
+ FGAirport(const FGAirport&);
+
+ /**
+ * helper to read airport data from the scenery XML files.
+ */
+ void loadSceneryDefinitions() const;
+
+ /**
+ * Helpers to process property data loaded from an ICAO.threshold.xml file
+ */
+ void readThresholdData(SGPropertyNode* aRoot);
+ void processThreshold(SGPropertyNode* aThreshold);
+
+ void readILSData(SGPropertyNode* aRoot);
+
+ void validateTowerData() const;
+
+ /**
+ * Helper to parse property data loaded from an ICAO.twr.xml file
+ */
+ void readTowerData(SGPropertyNode* aRoot);
+
+ std::string _name;
+ bool _has_metar;
+ FGAirportDynamics *_dynamics;
+
+ void loadRunways() const;
+ void loadHelipads() const;
+ void loadTaxiways() const;
+ void loadProcedures() const;
+
+ mutable bool mTowerDataLoaded;
+ mutable bool mRunwaysLoaded;
+ mutable bool mHelipadsLoaded;
+ mutable bool mTaxiwaysLoaded;
+ mutable bool mProceduresLoaded;
+ bool mILSDataLoaded;
+
+ mutable PositionedIDVec mRunways;
+ mutable PositionedIDVec mHelipads;
+ mutable PositionedIDVec mTaxiways;
+ PositionedIDVec mPavements;
+
+ typedef SGSharedPtr<flightgear::SID> SIDRef;
+ typedef SGSharedPtr<flightgear::STAR> STARRef;
+ typedef SGSharedPtr<flightgear::Approach> ApproachRef;
+
+ std::vector<SIDRef> mSIDs;
+ std::vector<STARRef> mSTARs;
+ std::vector<ApproachRef> mApproaches;
+ };
+
+// find basic airport location info from airport database
+const FGAirport *fgFindAirportID( const std::string& id);
+
+// get airport elevation
+double fgGetAirportElev( const std::string& id );
+
+#endif // _FG_SIMPLE_HXX
+
+
#include <string>
-#include "simple.hxx"
+#include "airport.hxx"
#include "runways.hxx"
#include "pavement.hxx"
#include <Navaids/NavDataCache.hxx>
#include <Navaids/NavDataCache.hxx>
#include <Airports/dynamics.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
/*****************************************************************************
* Helper function for parsing position string
#include <ATCDCL/ATCutils.hxx>
#include <Navaids/NavDataCache.hxx>
-#include "simple.hxx"
+#include "airport.hxx"
#include "dynamics.hxx"
using std::string;
#include <simgear/structure/exception.hxx>
#include <simgear/timing/timestamp.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <Airports/runways.hxx>
#include <Airports/runways.hxx>
#include "runwayprefs.hxx"
-#include "simple.hxx"
+#include "airport.hxx"
/******************************************************************************
* ScheduleTime
#include "runways.hxx"
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Navaids/procedure.hxx>
#include <Navaids/navrecord.hxx>
#include <Navaids/NavDataCache.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include "sidstar.hxx"
+++ /dev/null
-//
-// simple.cxx -- a really simplistic class to manage airport ID,
-// lat, lon of the center of one of it's runways, and
-// elevation in feet.
-//
-// Written by Curtis Olson, started April 1998.
-// Updated by Durk Talsma, started December, 2004.
-//
-// Copyright (C) 1998 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 "simple.hxx"
-
-#include <cassert>
-#include <boost/foreach.hpp>
-
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/props/props.hxx>
-#include <simgear/props/props_io.hxx>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/sg_inlines.h>
-#include <simgear/structure/exception.hxx>
-
-#include <Environment/environment_mgr.hxx>
-#include <Environment/environment.hxx>
-#include <Main/fg_props.hxx>
-#include <Airports/runways.hxx>
-#include <Airports/pavement.hxx>
-#include <Airports/dynamics.hxx>
-#include <Airports/xmlloader.hxx>
-#include <Navaids/procedure.hxx>
-#include <Navaids/waypoint.hxx>
-#include <ATC/CommStation.hxx>
-#include <Navaids/NavDataCache.hxx>
-
-using std::vector;
-using std::pair;
-
-using namespace flightgear;
-
-
-/***************************************************************************
- * FGAirport
- ***************************************************************************/
-
-AirportCache FGAirport::airportCache;
-
-FGAirport::FGAirport(PositionedID aGuid, const string &id, const SGGeod& location,
- const string &name, bool has_metar, Type aType) :
- FGPositioned(aGuid, aType, id, location),
- _name(name),
- _has_metar(has_metar),
- _dynamics(0),
- mTowerDataLoaded(false),
- mRunwaysLoaded(false),
- mTaxiwaysLoaded(false),
- mProceduresLoaded(false),
- mILSDataLoaded(false)
-{
-}
-
-
-FGAirport::~FGAirport()
-{
- delete _dynamics;
-}
-
-bool FGAirport::isAirport() const
-{
- return type() == AIRPORT;
-}
-
-bool FGAirport::isSeaport() const
-{
- return type() == SEAPORT;
-}
-
-bool FGAirport::isHeliport() const
-{
- return type() == HELIPORT;
-}
-
-bool FGAirport::isAirportType(FGPositioned* pos)
-{
- if (!pos) {
- return false;
- }
-
- return (pos->type() >= AIRPORT) && (pos->type() <= SEAPORT);
-}
-
-FGAirportDynamics * FGAirport::getDynamics()
-{
- if (_dynamics) {
- return _dynamics;
- }
-
- _dynamics = new FGAirportDynamics(this);
- XMLLoader::load(_dynamics);
- _dynamics->init();
-
- FGRunwayPreference rwyPrefs(this);
- XMLLoader::load(&rwyPrefs);
- _dynamics->setRwyUse(rwyPrefs);
-
- return _dynamics;
-}
-
-unsigned int FGAirport::numRunways() const
-{
- loadRunways();
- return mRunways.size();
-}
-
-unsigned int FGAirport::numHelipads() const
-{
- loadHelipads();
- return mHelipads.size();
-}
-
-FGRunway* FGAirport::getRunwayByIndex(unsigned int aIndex) const
-{
- loadRunways();
-
- assert(aIndex >= 0 && aIndex < mRunways.size());
- return (FGRunway*) flightgear::NavDataCache::instance()->loadById(mRunways[aIndex]);
-}
-
-FGHelipad* FGAirport::getHelipadByIndex(unsigned int aIndex) const
-{
- loadHelipads();
-
- assert(aIndex >= 0 && aIndex < mHelipads.size());
- return (FGHelipad*) flightgear::NavDataCache::instance()->loadById(mHelipads[aIndex]);
-}
-
-bool FGAirport::hasRunwayWithIdent(const string& aIdent) const
-{
- return flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent) != 0;
-}
-
-FGRunway* FGAirport::getRunwayByIdent(const string& aIdent) const
-{
- PositionedID id = flightgear::NavDataCache::instance()->airportItemWithIdent(guid(), FGPositioned::RUNWAY, aIdent);
- if (id == 0) {
- SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << ident());
- throw sg_range_exception("unknown runway " + aIdent + " at airport:" + ident(), "FGAirport::getRunwayByIdent");
- }
-
- return (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
-}
-
-
-FGRunway* FGAirport::findBestRunwayForHeading(double aHeading) const
-{
- loadRunways();
-
- FGRunway* result = NULL;
- double currentBestQuality = 0.0;
-
- SGPropertyNode *param = fgGetNode("/sim/airport/runways/search", true);
- double lengthWeight = param->getDoubleValue("length-weight", 0.01);
- double widthWeight = param->getDoubleValue("width-weight", 0.01);
- double surfaceWeight = param->getDoubleValue("surface-weight", 10);
- double deviationWeight = param->getDoubleValue("deviation-weight", 1);
-
- BOOST_FOREACH(PositionedID id, mRunways) {
- FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
- double good = rwy->score(lengthWeight, widthWeight, surfaceWeight);
- double dev = aHeading - rwy->headingDeg();
- SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
- double bad = fabs(deviationWeight * dev) + 1e-20;
- double quality = good / bad;
-
- if (quality > currentBestQuality) {
- currentBestQuality = quality;
- result = rwy;
- }
- }
-
- return result;
-}
-
-FGRunway* FGAirport::findBestRunwayForPos(const SGGeod& aPos) const
-{
- loadRunways();
-
- FGRunway* result = NULL;
- double currentLowestDev = 180.0;
-
- BOOST_FOREACH(PositionedID id, mRunways) {
- FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
-
- double inboundCourse = SGGeodesy::courseDeg(aPos, rwy->end());
- double dev = inboundCourse - rwy->headingDeg();
- SG_NORMALIZE_RANGE(dev, -180.0, 180.0);
-
- dev = fabs(dev);
- if (dev < currentLowestDev) { // new best match
- currentLowestDev = dev;
- result = rwy;
- }
- } // of runway iteration
-
- return result;
-
-}
-
-bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const
-{
- loadRunways();
-
- BOOST_FOREACH(PositionedID id, mRunways) {
- FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id);
-
- if (rwy->isReciprocal()) {
- continue; // we only care about lengths, so don't do work twice
- }
-
- if (rwy->isHardSurface() && (rwy->lengthFt() >= aLengthFt)) {
- return true; // we're done!
- }
- } // of runways iteration
-
- return false;
-}
-
-unsigned int FGAirport::numTaxiways() const
-{
- loadTaxiways();
- return mTaxiways.size();
-}
-
-FGTaxiway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const
-{
- loadTaxiways();
-
- assert(aIndex >= 0 && aIndex < mTaxiways.size());
- return (FGTaxiway*) flightgear::NavDataCache::instance()->loadById(mTaxiways[aIndex]);
-}
-
-unsigned int FGAirport::numPavements() const
-{
- loadTaxiways();
- return mPavements.size();
-}
-
-FGPavement* FGAirport::getPavementByIndex(unsigned int aIndex) const
-{
- loadTaxiways();
- assert(aIndex >= 0 && aIndex < mPavements.size());
- return (FGPavement*) flightgear::NavDataCache::instance()->loadById(mPavements[aIndex]);
-}
-
-FGRunway* FGAirport::getActiveRunwayForUsage() const
-{
- FGEnvironmentMgr* envMgr = (FGEnvironmentMgr *) globals->get_subsystem("environment");
-
- // This forces West-facing rwys to be used in no-wind situations
- // which is consistent with Flightgear's initial setup.
- double hdg = 270;
-
- if (envMgr) {
- FGEnvironment stationWeather(envMgr->getEnvironment(mPosition));
-
- double windSpeed = stationWeather.get_wind_speed_kt();
- if (windSpeed > 0.0) {
- hdg = stationWeather.get_wind_from_heading_deg();
- }
- }
-
- return findBestRunwayForHeading(hdg);
-}
-
-FGAirport* FGAirport::findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter)
-{
- AirportFilter aptFilter;
- if (filter == NULL) {
- filter = &aptFilter;
- }
-
- FGPositionedRef r = FGPositioned::findClosest(aPos, aCuttofNm, filter);
- if (!r) {
- return NULL;
- }
-
- return static_cast<FGAirport*>(r.ptr());
-}
-
-FGAirport::HardSurfaceFilter::HardSurfaceFilter(double minLengthFt) :
- mMinLengthFt(minLengthFt)
-{
- if (minLengthFt < 0.0) {
- mMinLengthFt = fgGetDouble("/sim/navdb/min-runway-length-ft", 0.0);
- }
-}
-
-bool FGAirport::HardSurfaceFilter::passAirport(FGAirport* aApt) const
-{
- return aApt->hasHardRunwayOfLengthFt(mMinLengthFt);
-}
-
-FGAirport* FGAirport::findByIdent(const std::string& aIdent)
-{
- AirportCache::iterator it = airportCache.find(aIdent);
- if (it != airportCache.end())
- return it->second;
-
- PortsFilter filter;
- FGAirport* r = static_cast<FGAirport*> (FGPositioned::findFirstWithIdent(aIdent, &filter).get());
-
- // add airport to the cache (even when it's NULL, so we don't need to search in vain again)
- airportCache[aIdent] = r;
-
- // we don't warn here when r==NULL, let the caller do that
- return r;
-}
-
-FGAirport* FGAirport::getByIdent(const std::string& aIdent)
-{
- FGAirport* r = findByIdent(aIdent);
- if (!r)
- throw sg_range_exception("No such airport with ident: " + aIdent);
- return r;
-}
-
-char** FGAirport::searchNamesAndIdents(const std::string& aFilter)
-{
- return NavDataCache::instance()->searchAirportNamesAndIdents(aFilter);
-}
-
-// find basic airport location info from airport database
-const FGAirport *fgFindAirportID( const string& id)
-{
- if ( id.empty() ) {
- return NULL;
- }
-
- return FGAirport::findByIdent(id);
-}
-
-void FGAirport::loadRunways() const
-{
- if (mRunwaysLoaded) {
- return; // already loaded, great
- }
-
- loadSceneryDefinitions();
-
- mRunwaysLoaded = true;
- mRunways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::RUNWAY);
-}
-
-void FGAirport::loadHelipads() const
-{
- if (mHelipadsLoaded) {
- return; // already loaded, great
- }
-
- loadSceneryDefinitions();
-
- mHelipadsLoaded = true;
- mHelipads = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::HELIPAD);
-}
-
-void FGAirport::loadTaxiways() const
-{
- if (mTaxiwaysLoaded) {
- return; // already loaded, great
- }
-
- mTaxiwaysLoaded = true;
- mTaxiways = flightgear::NavDataCache::instance()->airportItemsOfType(guid(), FGPositioned::TAXIWAY);
-}
-
-void FGAirport::loadProcedures() const
-{
- if (mProceduresLoaded) {
- return;
- }
-
- mProceduresLoaded = true;
- SGPath path;
- if (!XMLLoader::findAirportData(ident(), "procedures", path)) {
- SG_LOG(SG_GENERAL, SG_INFO, "no procedures data available for " << ident());
- return;
- }
-
- SG_LOG(SG_GENERAL, SG_INFO, ident() << ": loading procedures from " << path.str());
- RouteBase::loadAirportProcedures(path, const_cast<FGAirport*>(this));
-}
-
-void FGAirport::loadSceneryDefinitions() const
-{
- NavDataCache* cache = NavDataCache::instance();
- SGPath path;
- if (!XMLLoader::findAirportData(ident(), "threshold", path)) {
- return; // no XML threshold data
- }
-
- if (!cache->isCachedFileModified(path)) {
- // cached values are correct, we're all done
- return;
- }
-
- flightgear::NavDataCache::Transaction txn(cache);
- SGPropertyNode_ptr rootNode = new SGPropertyNode;
- readProperties(path.str(), rootNode);
- const_cast<FGAirport*>(this)->readThresholdData(rootNode);
- cache->stampCacheFile(path);
- txn.commit();
-}
-
-void FGAirport::readThresholdData(SGPropertyNode* aRoot)
-{
- SGPropertyNode* runway;
- int runwayIndex = 0;
- for (; (runway = aRoot->getChild("runway", runwayIndex)) != NULL; ++runwayIndex) {
- SGPropertyNode* t0 = runway->getChild("threshold", 0),
- *t1 = runway->getChild("threshold", 1);
- assert(t0);
- assert(t1); // too strict? maybe we should finally allow single-ended runways
-
- processThreshold(t0);
- processThreshold(t1);
- } // of runways iteration
-}
-
-void FGAirport::processThreshold(SGPropertyNode* aThreshold)
-{
- // first, let's identify the current runway
- string rwyIdent(aThreshold->getStringValue("rwy"));
- NavDataCache* cache = NavDataCache::instance();
- PositionedID id = cache->airportItemWithIdent(guid(), FGPositioned::RUNWAY, rwyIdent);
- if (id == 0) {
- SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: "
- "found runway not defined in the global data:" << ident() << "/" << rwyIdent);
- return;
- }
-
- double lon = aThreshold->getDoubleValue("lon"),
- lat = aThreshold->getDoubleValue("lat");
- SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM()));
-
- double newHeading = aThreshold->getDoubleValue("hdg-deg");
- double newDisplacedThreshold = aThreshold->getDoubleValue("displ-m") * SG_METER_TO_FEET;
- double newStopway = aThreshold->getDoubleValue("stopw-m") * SG_METER_TO_FEET;
-
- cache->updateRunwayThreshold(id, newThreshold,
- newHeading, newDisplacedThreshold, newStopway);
-}
-
-SGGeod FGAirport::getTowerLocation() const
-{
- validateTowerData();
-
- NavDataCache* cache = NavDataCache::instance();
- PositionedIDVec towers = cache->airportItemsOfType(guid(), FGPositioned::TOWER);
- if (towers.empty()) {
- SG_LOG(SG_GENERAL, SG_ALERT, "No towers defined for:" <<ident());
- return SGGeod();
- }
-
- FGPositionedRef tower = cache->loadById(towers.front());
- return tower->geod();
-}
-
-void FGAirport::validateTowerData() const
-{
- if (mTowerDataLoaded) {
- return;
- }
-
- mTowerDataLoaded = true;
- NavDataCache* cache = NavDataCache::instance();
- SGPath path;
- if (!XMLLoader::findAirportData(ident(), "twr", path)) {
- return; // no XML tower data
- }
-
- if (!cache->isCachedFileModified(path)) {
- // cached values are correct, we're all done
- return;
- }
-
- flightgear::NavDataCache::Transaction txn(cache);
- SGPropertyNode_ptr rootNode = new SGPropertyNode;
- readProperties(path.str(), rootNode);
- const_cast<FGAirport*>(this)->readTowerData(rootNode);
- cache->stampCacheFile(path);
- txn.commit();
-}
-
-void FGAirport::readTowerData(SGPropertyNode* aRoot)
-{
- SGPropertyNode* twrNode = aRoot->getChild("tower")->getChild("twr");
- double lat = twrNode->getDoubleValue("lat"),
- lon = twrNode->getDoubleValue("lon"),
- elevM = twrNode->getDoubleValue("elev-m");
-// tower elevation is AGL, not AMSL. Since we don't want to depend on the
-// scenery for a precise terrain elevation, we use the field elevation
-// (this is also what the apt.dat code does)
- double fieldElevationM = geod().getElevationM();
- SGGeod towerLocation(SGGeod::fromDegM(lon, lat, fieldElevationM + elevM));
-
- NavDataCache* cache = NavDataCache::instance();
- PositionedIDVec towers = cache->airportItemsOfType(guid(), FGPositioned::TOWER);
- if (towers.empty()) {
- cache->insertTower(guid(), towerLocation);
- } else {
- // update the position
- cache->updatePosition(towers.front(), towerLocation);
- }
-}
-
-bool FGAirport::validateILSData()
-{
- if (mILSDataLoaded) {
- return false;
- }
-
- mILSDataLoaded = true;
- NavDataCache* cache = NavDataCache::instance();
- SGPath path;
- if (!XMLLoader::findAirportData(ident(), "ils", path)) {
- return false; // no XML tower data
- }
-
- if (!cache->isCachedFileModified(path)) {
- // cached values are correct, we're all done
- return false;
- }
-
- SGPropertyNode_ptr rootNode = new SGPropertyNode;
- readProperties(path.str(), rootNode);
-
- flightgear::NavDataCache::Transaction txn(cache);
- readILSData(rootNode);
- cache->stampCacheFile(path);
- txn.commit();
-
-// we loaded data, tell the caller it might need to reload things
- return true;
-}
-
-void FGAirport::readILSData(SGPropertyNode* aRoot)
-{
- NavDataCache* cache = NavDataCache::instance();
-
- // find the entry matching the runway
- SGPropertyNode* runwayNode, *ilsNode;
- for (int i=0; (runwayNode = aRoot->getChild("runway", i)) != NULL; ++i) {
- for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) {
- // must match on both nav-ident and runway ident, to support the following:
- // - runways with multiple distinct ILS installations (KEWD, for example)
- // - runways where both ends share the same nav ident (LFAT, for example)
- PositionedID ils = cache->findILS(guid(), ilsNode->getStringValue("rwy"),
- ilsNode->getStringValue("nav-id"));
- if (ils == 0) {
- SG_LOG(SG_GENERAL, SG_INFO, "reading ILS data for " << ident() <<
- ", couldn;t find runway/navaid for:" <<
- ilsNode->getStringValue("rwy") << "/" <<
- ilsNode->getStringValue("nav-id"));
- continue;
- }
-
- double hdgDeg = ilsNode->getDoubleValue("hdg-deg"),
- lon = ilsNode->getDoubleValue("lon"),
- lat = ilsNode->getDoubleValue("lat"),
- elevM = ilsNode->getDoubleValue("elev-m");
-
- cache->updateILS(ils, SGGeod::fromDegM(lon, lat, elevM), hdgDeg);
- } // of ILS iteration
- } // of runway iteration
-}
-
-void FGAirport::addSID(flightgear::SID* aSid)
-{
- mSIDs.push_back(aSid);
-}
-
-void FGAirport::addSTAR(STAR* aStar)
-{
- mSTARs.push_back(aStar);
-}
-
-void FGAirport::addApproach(Approach* aApp)
-{
- mApproaches.push_back(aApp);
-}
-
-unsigned int FGAirport::numSIDs() const
-{
- loadProcedures();
- return mSIDs.size();
-}
-
-flightgear::SID* FGAirport::getSIDByIndex(unsigned int aIndex) const
-{
- loadProcedures();
- return mSIDs[aIndex];
-}
-
-flightgear::SID* FGAirport::findSIDWithIdent(const std::string& aIdent) const
-{
- loadProcedures();
- for (unsigned int i=0; i<mSIDs.size(); ++i) {
- if (mSIDs[i]->ident() == aIdent) {
- return mSIDs[i];
- }
- }
-
- return NULL;
-}
-
-unsigned int FGAirport::numSTARs() const
-{
- loadProcedures();
- return mSTARs.size();
-}
-
-STAR* FGAirport::getSTARByIndex(unsigned int aIndex) const
-{
- loadProcedures();
- return mSTARs[aIndex];
-}
-
-STAR* FGAirport::findSTARWithIdent(const std::string& aIdent) const
-{
- loadProcedures();
- for (unsigned int i=0; i<mSTARs.size(); ++i) {
- if (mSTARs[i]->ident() == aIdent) {
- return mSTARs[i];
- }
- }
-
- return NULL;
-}
-
-unsigned int FGAirport::numApproaches() const
-{
- loadProcedures();
- return mApproaches.size();
-}
-
-Approach* FGAirport::getApproachByIndex(unsigned int aIndex) const
-{
- loadProcedures();
- return mApproaches[aIndex];
-}
-
-Approach* FGAirport::findApproachWithIdent(const std::string& aIdent) const
-{
- loadProcedures();
- for (unsigned int i=0; i<mApproaches.size(); ++i) {
- if (mApproaches[i]->ident() == aIdent) {
- return mApproaches[i];
- }
- }
-
- return NULL;
-}
-
-CommStationList
-FGAirport::commStations() const
-{
- NavDataCache* cache = NavDataCache::instance();
- CommStationList result;
- BOOST_FOREACH(PositionedID pos, cache->airportItemsOfType(guid(),
- FGPositioned::FREQ_GROUND,
- FGPositioned::FREQ_UNICOM))
- {
- result.push_back((CommStation*) cache->loadById(pos));
- }
-
- return result;
-}
-
-CommStationList
-FGAirport::commStationsOfType(FGPositioned::Type aTy) const
-{
- NavDataCache* cache = NavDataCache::instance();
- CommStationList result;
- BOOST_FOREACH(PositionedID pos, cache->airportItemsOfType(guid(), aTy)) {
- result.push_back((CommStation*) cache->loadById(pos));
- }
-
- return result;
-}
-
-// get airport elevation
-double fgGetAirportElev( const string& id )
-{
- const FGAirport *a=fgFindAirportID( id);
- if (a) {
- return a->getElevation();
- } else {
- return -9999.0;
- }
-}
-
-
-// get airport position
-SGGeod fgGetAirportPos( const string& id )
-{
- const FGAirport *a = fgFindAirportID( id);
-
- if (a) {
- return SGGeod::fromDegM(a->getLongitude(), a->getLatitude(), a->getElevation());
- } else {
- return SGGeod::fromDegM(0.0, 0.0, -9999.0);
- }
-}
+++ /dev/null
-// simple.hxx -- a really simplistic class to manage airport ID,
-// lat, lon of the center of one of it's runways, and
-// elevation in feet.
-//
-// Written by Curtis Olson, started April 1998.
-// Updated by Durk Talsma, started December 2004.
-//
-// Copyright (C) 1998 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_SIMPLE_HXX
-#define _FG_SIMPLE_HXX
-
-#include <simgear/compiler.h>
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include <Navaids/positioned.hxx>
-
-// forward decls
-class FGAirportDynamics;
-class FGRunway;
-class FGHelipad;
-class FGTaxiway;
-class FGPavement;
-class SGPropertyNode;
-class FGAirport;
-
-namespace flightgear {
- class SID;
- class STAR;
- class Approach;
- class Waypt;
- class CommStation;
-
- typedef SGSharedPtr<Waypt> WayptRef;
- typedef std::vector<WayptRef> WayptVec;
-
- typedef std::vector<CommStation*> CommStationList;
- typedef std::map<std::string, FGAirport*> AirportCache;
-}
-
-
-
-/***************************************************************************************
- *
- **************************************************************************************/
-class FGAirport : public FGPositioned
-{
-public:
- FGAirport(PositionedID aGuid, const std::string& id, const SGGeod& location,
- const std::string& name, bool has_metar, Type aType);
- ~FGAirport();
-
- const std::string& getId() const { return ident(); }
- const std::string& getName() const { return _name; }
- double getLongitude() const { return longitude(); }
- // Returns degrees
- double getLatitude() const { return latitude(); }
- // Returns ft
- double getElevation() const { return elevation(); }
- bool getMetar() const { return _has_metar; }
- bool isAirport() const;
- bool isSeaport() const;
- bool isHeliport() const;
-
- static bool isAirportType(FGPositioned* pos);
-
- virtual const std::string& name() const
- { return _name; }
-
- /**
- * reload the ILS data from XML if required.
- * @result true if the data was refreshed, false if no data was loaded
- * or previously cached data is still correct.
- */
- bool validateILSData();
-
- SGGeod getTowerLocation() const;
-
- void setMetar(bool value) { _has_metar = value; }
-
- FGRunway* getActiveRunwayForUsage() const;
-
- FGAirportDynamics *getDynamics();
-
- unsigned int numRunways() const;
- unsigned int numHelipads() const;
- FGRunway* getRunwayByIndex(unsigned int aIndex) const;
- FGHelipad* getHelipadByIndex(unsigned int aIndex) const;
-
- bool hasRunwayWithIdent(const std::string& aIdent) const;
- FGRunway* getRunwayByIdent(const std::string& aIdent) const;
- FGRunway* findBestRunwayForHeading(double aHeading) const;
-
- /**
- * return the most likely target runway based on a position.
- * Specifically, return the runway for which the course from aPos
- * to the runway end, mostly closely matches the runway heading.
- * This is a good approximation of which runway the position is on or
- * aiming towards.
- */
- FGRunway* findBestRunwayForPos(const SGGeod& aPos) const;
-
- /**
- * Useful predicate for FMS/GPS/NAV displays and similar - check if this
- * aiport has a hard-surfaced runway of at least the specified length.
- */
- bool hasHardRunwayOfLengthFt(double aLengthFt) const;
-
- unsigned int numTaxiways() const;
- FGTaxiway* getTaxiwayByIndex(unsigned int aIndex) const;
-
- unsigned int numPavements() const;
- FGPavement* getPavementByIndex(unsigned int aIndex) const;
-
- class AirportFilter : public Filter
- {
- public:
- virtual bool pass(FGPositioned* aPos) const {
- return passAirport(static_cast<FGAirport*>(aPos));
- }
-
- virtual Type minType() const {
- return AIRPORT;
- }
-
- virtual Type maxType() const {
- return AIRPORT;
- }
-
- virtual bool passAirport(FGAirport* aApt) const {
- return true;
- }
- };
-
- /**
- * Filter which passes heliports and seaports in addition to airports
- */
- class PortsFilter : public AirportFilter
- {
- public:
- virtual Type maxType() const {
- return SEAPORT;
- }
- };
-
- class HardSurfaceFilter : public AirportFilter
- {
- public:
- HardSurfaceFilter(double minLengthFt = -1);
-
- virtual bool passAirport(FGAirport* aApt) const;
-
- private:
- double mMinLengthFt;
- };
-
-
- void setProcedures(const std::vector<flightgear::SID*>& aSids,
- const std::vector<flightgear::STAR*>& aStars,
- const std::vector<flightgear::Approach*>& aApproaches);
-
- void addSID(flightgear::SID* aSid);
- void addSTAR(flightgear::STAR* aStar);
- void addApproach(flightgear::Approach* aApp);
-
- unsigned int numSIDs() const;
- flightgear::SID* getSIDByIndex(unsigned int aIndex) const;
- flightgear::SID* findSIDWithIdent(const std::string& aIdent) const;
-
- unsigned int numSTARs() const;
- flightgear::STAR* getSTARByIndex(unsigned int aIndex) const;
- flightgear::STAR* findSTARWithIdent(const std::string& aIdent) const;
-
- unsigned int numApproaches() const;
- flightgear::Approach* getApproachByIndex(unsigned int aIndex) const;
- flightgear::Approach* findApproachWithIdent(const std::string& aIdent) const;
-
- /**
- * Syntactic wrapper around FGPositioned::findClosest - find the closest
- * match for filter, and return it cast to FGAirport. The default filter
- * passes airports, but not seaports or heliports
- */
- static FGAirport* findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL);
-
- /**
- * Helper to look up an FGAirport instance by unique ident. Throws an
- * exception if the airport could not be found - so callers can assume
- * the result is non-NULL.
- */
- static FGAirport* getByIdent(const std::string& aIdent);
-
- /**
- * Helper to look up an FGAirport instance by unique ident. Returns NULL
- * if the airport could not be found.
- */
- static FGAirport* findByIdent(const std::string& aIdent);
-
- /**
- * Specialised helper to implement the AirportList dialog. Performs a
- * case-insensitive search on airport names and ICAO codes, and returns
- * matches in a format suitable for use by a puaList.
- */
- static char** searchNamesAndIdents(const std::string& aFilter);
-
- flightgear::CommStationList commStationsOfType(FGPositioned::Type aTy) const;
-
- flightgear::CommStationList commStations() const;
-private:
- static flightgear::AirportCache airportCache;
-
- // disable these
- FGAirport operator=(FGAirport &other);
- FGAirport(const FGAirport&);
-
- /**
- * helper to read airport data from the scenery XML files.
- */
- void loadSceneryDefinitions() const;
-
- /**
- * Helpers to process property data loaded from an ICAO.threshold.xml file
- */
- void readThresholdData(SGPropertyNode* aRoot);
- void processThreshold(SGPropertyNode* aThreshold);
-
- void readILSData(SGPropertyNode* aRoot);
-
- void validateTowerData() const;
-
- /**
- * Helper to parse property data loaded from an ICAO.twr.xml file
- */
- void readTowerData(SGPropertyNode* aRoot);
-
- std::string _name;
- bool _has_metar;
- FGAirportDynamics *_dynamics;
-
- void loadRunways() const;
- void loadHelipads() const;
- void loadTaxiways() const;
- void loadProcedures() const;
-
- mutable bool mTowerDataLoaded;
- mutable bool mRunwaysLoaded;
- mutable bool mHelipadsLoaded;
- mutable bool mTaxiwaysLoaded;
- mutable bool mProceduresLoaded;
- bool mILSDataLoaded;
-
- mutable PositionedIDVec mRunways;
- mutable PositionedIDVec mHelipads;
- mutable PositionedIDVec mTaxiways;
- PositionedIDVec mPavements;
-
- typedef SGSharedPtr<flightgear::SID> SIDRef;
- typedef SGSharedPtr<flightgear::STAR> STARRef;
- typedef SGSharedPtr<flightgear::Approach> ApproachRef;
-
- std::vector<SIDRef> mSIDs;
- std::vector<STARRef> mSTARs;
- std::vector<ApproachRef> mApproaches;
- };
-
-// find basic airport location info from airport database
-const FGAirport *fgFindAirportID( const std::string& id);
-
-// get airport elevation
-double fgGetAirportElev( const std::string& id );
-
-#endif // _FG_SIMPLE_HXX
-
-
#include "runwayprefloader.hxx"
#include "dynamics.hxx"
-#include "simple.hxx"
+#include "airport.hxx"
#include "runwayprefs.hxx"
#include <Navaids/NavDataCache.hxx>
#include "Navaids/positioned.hxx"
#include <Navaids/waypoint.hxx>
#include <Navaids/procedure.hxx>
-#include "Airports/simple.hxx"
+#include "Airports/airport.hxx"
#include "Airports/runways.hxx"
#include <GUI/new_gui.hxx>
#include <GUI/dialog.hxx>
#include <Navaids/navrecord.hxx>
#include <Navaids/navlist.hxx>
#include <Navaids/fix.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include "od_gauge.hxx"
#include <Main/globals.hxx>
#include <Viewer/renderer.hxx>
#include <Cockpit/panel.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <Airports/pavement.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include "precipitation_mgr.hxx"
#include "ridge_lift.hxx"
#include "terrainsampler.hxx"
-#include "Airports/simple.hxx"
+#include "Airports/airport.hxx"
#include "gravity.hxx"
#include "magvarmanager.hxx"
#include <Main/globals.hxx>
#include <Main/util.hxx>
#include <Viewer/renderer.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include "fgclouds.hxx"
#ifndef __METARAIRPORTFILTER_HXX
#define __METARAIRPORTFILTER_HXX
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <simgear/props/props.hxx>
namespace Environment {
#ifndef __METARPROPERTIES_HXX
#define __METARPROPERTIES_HXX
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/tiedpropertylist.hxx>
#endif
#include <Main/globals.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include "AirportList.hxx"
#include <Navaids/navrecord.hxx>
#include <Navaids/navlist.hxx>
#include <Navaids/fix.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <Main/fg_os.hxx> // fgGetKeyModifiers()
#include <Navaids/routePath.hxx>
#include <Main/fg_props.hxx>
#include <simgear/structure/commands.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <cstdio>
#include <ATC/CommStation.hxx>
#include <Main/globals.hxx>
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
using std::string;
#include <Main/fg_props.hxx>
#include <Navaids/fix.hxx>
#include <Navaids/navrecord.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <fstream>
#include "Navaids/positioned.hxx"
#include <Navaids/waypoint.hxx>
#include "Navaids/navrecord.hxx"
-#include "Airports/simple.hxx"
+#include "Airports/airport.hxx"
#include "Airports/runways.hxx"
#include "Autopilot/route_mgr.hxx"
using std::string;
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#if defined( HAVE_VERSION_H ) && HAVE_VERSION_H
# include <Include/version.h>
class SGSampleGroup;
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Main/globals.hxx>
#include <Sound/voiceplayer.hxx>
#include <Aircraft/replay.hxx>
#include <Aircraft/FlightHistory.hxx>
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <AIModel/AIManager.hxx>
#include <Navaids/navlist.hxx>
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <AIModel/AIManager.hxx>
#define FG_FLIGHTPLAN_HXX
#include <Navaids/route.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
typedef SGSharedPtr<FGAirport> FGAirportRef;
#include <simgear/misc/sg_path.hxx>
#include <Navaids/waypoint.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
using std::string;
using std::vector;
#include <Main/globals.hxx>
#include "markerbeacon.hxx"
#include "navrecord.hxx"
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <ATC/CommStation.hxx>
#include "fix.hxx"
#include "navlist.hxx"
#include <Main/globals.hxx>
#include <Navaids/markerbeacon.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
#include <Airports/xmlloader.hxx>
#include <Main/fg_props.hxx>
#include <Navaids/navrecord.hxx>
#include <Navaids/navdb.hxx>
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/xmlloader.hxx>
#include <Main/fg_props.hxx>
#include <Navaids/NavDataCache.hxx>
#include <Navaids/procedure.hxx>
#include <Navaids/waypoint.hxx>
#include <Navaids/LevelDXML.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
using std::string;
using std::vector;
#include <simgear/structure/exception.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/runways.hxx>
using std::string;
#include <simgear/bucket/newbucket.hxx>
#include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <Airports/parking.hxx>
#include <Scripting/NasalSys.hxx>
#include <AIModel/AIFlightPlan.hxx>
#include <AIModel/AIManager.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Main/fg_init.hxx> // That's pretty ugly, but I need fgFindAirportID
#include <AIModel/AIFlightPlan.hxx>
#include <AIModel/AIManager.hxx>
#include <AIModel/AIAircraft.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Main/fg_init.hxx> // That's pretty ugly, but I need fgFindAirportID
#include <AIModel/AIAircraft.hxx>
#include <AIModel/AIFlightPlan.hxx>
#include <AIModel/AIBase.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
#include <Main/fg_init.hxx>
#include "TrafficMgr.hxx"