From d6277068f50c661144c6ae183225a48e7c37028d Mon Sep 17 00:00:00 2001 From: jmt <jmt> Date: Tue, 23 Dec 2008 12:37:59 +0000 Subject: [PATCH] (first commit, partly a low-risk thing to sanity check my setup) Add a helper predicate to FGAirport to encapsulate the common 'does this airport have a suitable runway of at least xxxx ft?' query. Also add a FGPositioned filter built on the predicate, and a 'closest airport' helper. --- src/Airports/runways.hxx | 3 +++ src/Airports/simple.cxx | 51 ++++++++++++++++++++++++++++++++++++++++ src/Airports/simple.hxx | 34 +++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index a2cc2ae62..9289e3404 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -129,6 +129,9 @@ public: void setAirport(FGAirport* aAirport) { _airport = aAirport; } + int surface() const + { return _surface_code; } + std::string _rwy_no; double _lon; diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 354cff448..1dc6b7d76 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -192,6 +192,28 @@ FGRunway* FGAirport::findBestRunwayForHeading(double aHeading) const return result; } +bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const +{ + unsigned int numRunways(mRunways.size()); + for (unsigned int r=0; r<numRunways; ++r) { + FGRunway* rwy = mRunways[r]; + if (rwy->isReciprocal()) { + continue; // we only care about lengths, so don't do work twice + } + + int surface = rwy->surface(); + if ((surface != 1) && (surface != 2)) { + continue; // no hard surface + } + + if (rwy->lengthFt() >= aLengthFt) { + return true; // we're done! + } + } // of runways iteration + + return false; +} + unsigned int FGAirport::numTaxiways() const { return mTaxiways.size(); @@ -233,6 +255,35 @@ FGRunway* FGAirport::getActiveRunwayForUsage() const 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) +{ +} + +bool FGAirport::HardSurfaceFilter::pass(FGPositioned* aPos) const +{ + if (aPos->type() != AIRPORT) { + return false; // exclude seaports and heliports as well, we need a runways + } + + return static_cast<FGAirport*>(aPos)->hasHardRunwayOfLengthFt(mMinLengthFt); +} + /****************************************************************************** * FGAirportList *****************************************************************************/ diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index 2ec8a9173..a37524318 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -86,10 +86,44 @@ public: FGRunway* getRunwayByIdent(const std::string& aIdent) const; FGRunway* findBestRunwayForHeading(double aHeading) 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. + * For the moment, hard means asphalt or concrete, not gravel or a + * lake bed. + */ + bool hasHardRunwayOfLengthFt(double aLengthFt) const; + unsigned int numTaxiways() const; FGRunway* getTaxiwayByIndex(unsigned int aIndex) const; void addRunway(FGRunway* aRunway); + + class AirportFilter : public Filter + { + public: + virtual bool pass(FGPositioned* aPos) const { + Type ty(aPos->type()); + return (ty >= AIRPORT) && (ty <= SEAPORT); + } + }; + + class HardSurfaceFilter : public Filter + { + public: + HardSurfaceFilter(double minLengthFt); + + virtual bool pass(FGPositioned* aPos) const; + private: + double mMinLengthFt; + }; + + /** + * Syntactic wrapper around FGPositioned::findClosest - find the closest + * match for filter, and return it cast to FGAirport. The default filter + * passes all airports, including seaports and heliports. + */ + static FGAirport* findClosest(const SGGeod& aPos, double aCuttofNm, Filter* filter = NULL); private: typedef std::vector<FGRunwayPtr>::const_iterator Runway_iterator; /**