#include <cstdio> // sprintf()
#include <cstdlib> // atoi()
+#include <cassert>
#include <simgear/compiler.h>
#include "runways.hxx"
-using std::string;
-
-static std::string cleanRunwayNo(const std::string& aRwyNo)
-{
- if (aRwyNo[0] == 'x') {
- return std::string(); // no ident for taxiways
- }
-
- string result(aRwyNo);
- // canonicalise runway ident
- if ((aRwyNo.size() == 1) || !isdigit(aRwyNo[1])) {
- result = "0" + aRwyNo;
- }
+#include <Airports/simple.hxx>
+#include <Navaids/procedure.hxx>
+#include <Navaids/navrecord.hxx>
+#include <Navaids/NavDataCache.hxx>
- // trim off trailing garbage
- if (result.size() > 2) {
- char suffix = toupper(result[2]);
- if (suffix == 'X') {
- result = result.substr(0, 2);
- }
- }
-
- return result;
-}
+using std::string;
-FGRunway::FGRunway(FGAirport* aAirport, const string& aIdent,
+FGRunway::FGRunway(PositionedID aGuid,
+ PositionedID aAirport, const string& aIdent,
const SGGeod& aGeod,
const double heading, const double length,
const double width,
const double stopway,
const int surface_code,
bool reciprocal) :
- FGRunwayBase(RUNWAY, cleanRunwayNo(aIdent), aGeod, heading, length, width, surface_code, true),
+ FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod,
+ heading, length, width, surface_code),
_airport(aAirport),
_isReciprocal(reciprocal),
- _reciprocal(NULL),
+ _reciprocal(0),
_displ_thresh(displ_thresh),
_stopway(stopway),
- _ils(NULL)
+ _ils(0)
{
}
return pointOnCenterline(_displ_thresh * SG_FEET_TO_METER);
}
-void FGRunway::processThreshold(SGPropertyNode* aThreshold)
+void FGRunway::setReciprocalRunway(PositionedID other)
+{
+ assert(_reciprocal==0);
+ _reciprocal = other;
+}
+
+FGAirport* FGRunway::airport() const
+{
+ return (FGAirport*) flightgear::NavDataCache::instance()->loadById(_airport);
+}
+
+FGRunway* FGRunway::reciprocalRunway() const
+{
+ return (FGRunway*) flightgear::NavDataCache::instance()->loadById(_reciprocal);
+}
+
+FGNavRecord* FGRunway::ILS() const
{
- assert(ident() == aThreshold->getStringValue("rwy"));
+ if (_ils == 0) {
+ return NULL;
+ }
- double lon = aThreshold->getDoubleValue("lon"),
- lat = aThreshold->getDoubleValue("lat");
- SGGeod newThreshold(SGGeod::fromDegM(lon, lat, mPosition.getElevationM()));
+ return (FGNavRecord*) flightgear::NavDataCache::instance()->loadById(_ils);
+}
+
+FGNavRecord* FGRunway::glideslope() const
+{
+ flightgear::NavDataCache* cache = flightgear::NavDataCache::instance();
+ PositionedID gsId = cache->findNavaidForRunway(guid(), FGPositioned::GS);
+ if (gsId == 0) {
+ return NULL;
+ }
- _heading = aThreshold->getDoubleValue("hdg-deg");
- _displ_thresh = aThreshold->getDoubleValue("displ-m") * SG_METER_TO_FEET;
- _stopway = aThreshold->getDoubleValue("stopw-m") * SG_METER_TO_FEET;
+ return (FGNavRecord*) cache->loadById(gsId);
+}
+
+std::vector<flightgear::SID*> FGRunway::getSIDs() const
+{
+ FGAirport* apt = airport();
+ std::vector<flightgear::SID*> result;
+ for (unsigned int i=0; i<apt->numSIDs(); ++i) {
+ flightgear::SID* s = apt->getSIDByIndex(i);
+ if (s->isForRunway(this)) {
+ result.push_back(s);
+ }
+ } // of SIDs at the airport iteration
- // compute the new runway center, based on the threshold lat/lon, length,
- // and any displaced threshold.
- double offsetFt = (0.5 * _length) - _displ_thresh;
- SGGeod newCenter;
- double dummy;
- SGGeodesy::direct(newThreshold, _heading, offsetFt * SG_FEET_TO_METER, newCenter, dummy);
- mPosition = newCenter;
-}
-
-void FGRunway::setReciprocalRunway(FGRunway* other)
+ return result;
+}
+
+std::vector<flightgear::STAR*> FGRunway::getSTARs() const
{
- assert(_reciprocal==NULL);
- assert((other->_reciprocal == NULL) || (other->_reciprocal == this));
+ FGAirport* apt = airport();
+ std::vector<flightgear::STAR*> result;
+ for (unsigned int i=0; i<apt->numSTARs(); ++i) {
+ flightgear::STAR* s = apt->getSTARByIndex(i);
+ if (s->isForRunway(this)) {
+ result.push_back(s);
+ }
+ } // of STARs at the airport iteration
- _reciprocal = other;
+ return result;
+}
+
+std::vector<flightgear::Approach*> FGRunway::getApproaches() const
+{
+ FGAirport* apt = airport();
+ std::vector<flightgear::Approach*> result;
+ for (unsigned int i=0; i<apt->numApproaches(); ++i) {
+ flightgear::Approach* s = apt->getApproachByIndex(i);
+ if (s->runway() == this) {
+ result.push_back(s);
+ }
+ } // of approaches at the airport iteration
+
+ return result;
}