From 88a4435cef38450fff9804c304c9132af79f854c Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 28 Feb 2013 18:21:23 +0000 Subject: [PATCH] Remove isReciprocal from FGRunway. This was a bogus concept, either runways have a reciprocal or not (if singled-ended), really this was simply exposing an artefact of the apt.dat encoding. Change to an API which gives what is actually wanted - the ability to extract an airport's runways without any reciprocals included. --- src/Airports/airport.cxx | 27 ++++++++++++++++++++----- src/Airports/airport.hxx | 14 +++++++++++++ src/Airports/runways.cxx | 7 ++----- src/Airports/runways.hxx | 12 +---------- src/Cockpit/groundradar.cxx | 8 +++----- src/GUI/MapWidget.cxx | 39 ++++++++++++++++++------------------ src/Navaids/NavDataCache.cxx | 2 +- 7 files changed, 63 insertions(+), 46 deletions(-) diff --git a/src/Airports/airport.cxx b/src/Airports/airport.cxx index 2f8dc1197..5bfdb18e2 100644 --- a/src/Airports/airport.cxx +++ b/src/Airports/airport.cxx @@ -247,11 +247,6 @@ bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const 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! } @@ -260,6 +255,28 @@ bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const return false; } +FGRunwayList FGAirport::getRunwaysWithoutReciprocals() const +{ + loadRunways(); + + FGRunwayList r; + + BOOST_FOREACH(PositionedID id, mRunways) { + FGRunway* rwy = (FGRunway*) flightgear::NavDataCache::instance()->loadById(id); + FGRunway* recip = rwy->reciprocalRunway(); + if (recip) { + FGRunwayList::iterator it = std::find(r.begin(), r.end(), recip); + if (it != r.end()) { + continue; // reciprocal already in result set, don't include us + } + } + + r.push_back(rwy); + } + + return r; +} + unsigned int FGAirport::numTaxiways() const { loadTaxiways(); diff --git a/src/Airports/airport.hxx b/src/Airports/airport.hxx index 8c0c49297..2d2ca7138 100644 --- a/src/Airports/airport.hxx +++ b/src/Airports/airport.hxx @@ -58,6 +58,7 @@ namespace flightgear { typedef std::map AirportCache; } +typedef std::vector FGRunwayList; /*************************************************************************************** @@ -122,6 +123,19 @@ public: */ FGRunway* findBestRunwayForPos(const SGGeod& aPos) const; + /** + * Retrieve all runways at the airport, but excluding the reciprocal + * runways. For example at KSFO this might return 1L, 1R, 28L and 28R, + * but would not then include 19L/R or 10L/R. + * + * Exactly which runways you get, is undefined (i.e, dont assumes it's + * runways with heading < 180 degrees) - it depends on order in apt.dat. + * + * This is useful for code that wants to process each piece of tarmac at + * an airport *once*, not *twice* - eg mapping and nav-display code. + */ + FGRunwayList getRunwaysWithoutReciprocals() 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. diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index 8abed46ca..66f2407a2 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -51,12 +51,10 @@ FGRunway::FGRunway(PositionedID aGuid, const double width, const double displ_thresh, const double stopway, - const int surface_code, - bool reciprocal) : + const int surface_code) : FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod, heading, length, width, surface_code), _airport(aAirport), - _isReciprocal(reciprocal), _reciprocal(0), _displ_thresh(displ_thresh), _stopway(stopway), @@ -209,7 +207,6 @@ FGHelipad::FGHelipad(PositionedID aGuid, const double width, const int surface_code) : FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod, - heading, length, width, surface_code), - _airport(aAirport) + heading, length, width, surface_code) { } diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index b5109de4f..216875c41 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -42,7 +42,6 @@ namespace flightgear { class FGRunway : public FGRunwayBase { PositionedID _airport; - bool _isReciprocal; PositionedID _reciprocal; double _displ_thresh; double _stopway; @@ -56,8 +55,7 @@ public: const double width, const double displ_thresh, const double stopway, - const int surface_code, - const bool reciprocal); + const int surface_code); /** * given a runway identifier (06, 18L, 31R) compute the identifier for the @@ -71,13 +69,6 @@ public: */ double score(double aLengthWt, double aWidthWt, double aSurfaceWt) const; - /** - * Test if this runway is the reciprocal. This allows users who iterate - * over runways to avoid counting runways twice, if desired. - */ - bool isReciprocal() const - { return _isReciprocal; } - /** * Get the runway beginning point - this is syntatic sugar, equivalent to * calling pointOnCenterline(0.0); @@ -136,7 +127,6 @@ public: class FGHelipad : public FGRunwayBase { - PositionedID _airport; public: FGHelipad(PositionedID aGuid, PositionedID aAirport, const std::string& rwy_no, diff --git a/src/Cockpit/groundradar.cxx b/src/Cockpit/groundradar.cxx index 7a2af9b62..702ba6d5a 100644 --- a/src/Cockpit/groundradar.cxx +++ b/src/Cockpit/groundradar.cxx @@ -336,12 +336,10 @@ void GroundRadar::updateTexture() } pvt_geom->setVertexArray(pvt_vertices.get()); - for (unsigned int i=0; inumRunways(); ++i) + FGRunwayList rwys(apt->getRunwaysWithoutReciprocals()); + for (unsigned int i=0; igetRunwayByIndex(i)); - if (runway->isReciprocal()) continue; - - addRunwayVertices(runway, tower_lat, tower_lon, scale, rwy_vertices.get()); + addRunwayVertices(rwys[i], tower_lat, tower_lon, scale, rwy_vertices.get()); } osg::Geometry *rwy_geom = dynamic_cast(_geode->getDrawable(2)); rwy_geom->setVertexArray(rwy_vertices.get()); diff --git a/src/GUI/MapWidget.cxx b/src/GUI/MapWidget.cxx index b8bac7236..249605c6b 100644 --- a/src/GUI/MapWidget.cxx +++ b/src/GUI/MapWidget.cxx @@ -1194,22 +1194,26 @@ void MapWidget::drawAirport(FGAirport* apt) return; } - for (unsigned int r=0; rnumRunways(); ++r) { - FGRunway* rwy = apt->getRunwayByIndex(r); - if (!rwy->isReciprocal()) { - drawRunwayPre(rwy); - } + FGRunwayList runways(apt->getRunwaysWithoutReciprocals()); + + for (unsigned int r=0; rnumRunways(); ++r) { - FGRunway* rwy = apt->getRunwayByIndex(r); - if (!rwy->isReciprocal()) { - drawRunway(rwy); - } + for (unsigned int r=0; rILS()) { - drawILS(false, rwy); + if (rwy->ILS()) { + drawILS(false, rwy); + } + + if (rwy->reciprocalRunway()) { + FGRunway* recip = rwy->reciprocalRunway(); + if (recip->ILS()) { + drawILS(false, recip); } + } } for (unsigned int r=0; rnumHelipads(); ++r) { @@ -1224,14 +1228,11 @@ int MapWidget::scoreAirportRunways(FGAirport* apt) bool needHardSurface = _root->getBoolValue("hard-surfaced-airports", true); double minLength = _root->getDoubleValue("min-runway-length-ft", 2000.0); - int score = 0; - unsigned int numRunways(apt->numRunways()); - for (unsigned int r=0; rgetRunwayByIndex(r); - if (rwy->isReciprocal()) { - continue; - } + FGRunwayList runways(apt->getRunwaysWithoutReciprocals()); + int score = 0; + for (unsigned int r=0; risHardSurface()) { continue; } diff --git a/src/Navaids/NavDataCache.cxx b/src/Navaids/NavDataCache.cxx index b27736d1b..ee7b90d95 100644 --- a/src/Navaids/NavDataCache.cxx +++ b/src/Navaids/NavDataCache.cxx @@ -733,7 +733,7 @@ public: PositionedID reciprocal = sqlite3_column_int64(loadRunwayStmt, 6); PositionedID ils = sqlite3_column_int64(loadRunwayStmt, 7); FGRunway* r = new FGRunway(rowId, apt, id, pos, heading, lengthM, widthM, - displacedThreshold, stopway, surface, false); + displacedThreshold, stopway, surface); if (reciprocal > 0) { r->setReciprocalRunway(reciprocal);