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.
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!
}
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();
typedef std::map<std::string, FGAirport*> AirportCache;
}
+typedef std::vector<FGRunway*> FGRunwayList;
/***************************************************************************************
*/
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.
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),
const double width,
const int surface_code) :
FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod,
- heading, length, width, surface_code),
- _airport(aAirport)
+ heading, length, width, surface_code)
{
}
class FGRunway : public FGRunwayBase
{
PositionedID _airport;
- bool _isReciprocal;
PositionedID _reciprocal;
double _displ_thresh;
double _stopway;
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
*/
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);
class FGHelipad : public FGRunwayBase
{
- PositionedID _airport;
public:
FGHelipad(PositionedID aGuid,
PositionedID aAirport, const std::string& rwy_no,
}
pvt_geom->setVertexArray(pvt_vertices.get());
- for (unsigned int i=0; i<apt->numRunways(); ++i)
+ FGRunwayList rwys(apt->getRunwaysWithoutReciprocals());
+ for (unsigned int i=0; i<rwys.size(); ++i)
{
- FGRunway* runway(apt->getRunwayByIndex(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<osg::Geometry *>(_geode->getDrawable(2));
rwy_geom->setVertexArray(rwy_vertices.get());
return;
}
- for (unsigned int r=0; r<apt->numRunways(); ++r) {
- FGRunway* rwy = apt->getRunwayByIndex(r);
- if (!rwy->isReciprocal()) {
- drawRunwayPre(rwy);
- }
+ FGRunwayList runways(apt->getRunwaysWithoutReciprocals());
+
+ for (unsigned int r=0; r<runways.size(); ++r) {
+ drawRunwayPre(runways[r]);
}
- for (unsigned int r=0; r<apt->numRunways(); ++r) {
- FGRunway* rwy = apt->getRunwayByIndex(r);
- if (!rwy->isReciprocal()) {
- drawRunway(rwy);
- }
+ for (unsigned int r=0; r<runways.size(); ++r) {
+ FGRunway* rwy = runways[r];
+ drawRunway(rwy);
- if (rwy->ILS()) {
- 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; r<apt->numHelipads(); ++r) {
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; r<numRunways; ++r) {
- FGRunway* rwy = apt->getRunwayByIndex(r);
- if (rwy->isReciprocal()) {
- continue;
- }
+ FGRunwayList runways(apt->getRunwaysWithoutReciprocals());
+ int score = 0;
+ for (unsigned int r=0; r<runways.size(); ++r) {
+ FGRunway* rwy = runways[r];
if (needHardSurface && !rwy->isHardSurface()) {
continue;
}
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);