# include <config.h>
#endif
-#include <cmath> // fabs()
#include <cstdio> // sprintf()
#include <cstdlib> // atoi()
+#include <cassert>
#include <simgear/compiler.h>
-#include <simgear/debug/logstream.hxx>
-#include <Main/fg_props.hxx>
+
+#include <simgear/props/props.hxx>
#include <string>
-#include <map>
#include "runways.hxx"
-using std::istream;
-using std::multimap;
-using std::string;
+#include <Airports/airport.hxx>
+#include <Navaids/procedure.hxx>
+#include <Navaids/navrecord.hxx>
+#include <Navaids/NavDataCache.hxx>
-FGRunway::FGRunway()
-{
-}
+using std::string;
-FGRunway::FGRunway( const string& id, const string& rwy_no,
- const double longitude, const double latitude,
+FGRunway::FGRunway(PositionedID aGuid,
+ PositionedID aAirport, const string& aIdent,
+ const SGGeod& aGeod,
const double heading, const double length,
const double width,
- const double displ_thresh1, const double displ_thresh2,
- const double stopway1, const double stopway2,
- const string& lighting_flags, const int surface_code,
- const string& shoulder_code, const int marking_code,
- const double smoothness, const bool dist_remaining )
+ const double displ_thresh,
+ const double stopway,
+ const int surface_code) :
+ FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod,
+ heading, length, width, surface_code),
+ _airport(aAirport),
+ _reciprocal(0),
+ _displ_thresh(displ_thresh),
+ _stopway(stopway),
+ _ils(0)
{
- _rwy_no = rwy_no;
- if (rwy_no[0] == 'x') {
- _type = "taxiway";
- } else {
- _type = "runway";
-
- // canonicalise runway ident
- if ((rwy_no.size() == 1) || !isdigit(rwy_no[1])) {
- _rwy_no = "0" + rwy_no;
- }
-
- if ((_rwy_no.size() > 2) && (_rwy_no[2] == 'x')) {
- _rwy_no = _rwy_no.substr(0, 2);
- }
- }
-
- _id = id;
- _lon = longitude;
- _lat = latitude;
- _heading = heading;
- _length = length;
- _width = width;
- _displ_thresh1 = displ_thresh1;
- _displ_thresh2 = displ_thresh2;
- _stopway1 = stopway1;
- _stopway2 = stopway2;
-
- _lighting_flags = lighting_flags;
- _surface_code = surface_code;
- _shoulder_code = shoulder_code;
- _marking_code = marking_code;
- _smoothness = smoothness;
- _dist_remaining = dist_remaining;
}
string FGRunway::reverseIdent(const string& aRunwayIdent)
sprintf(buf, "%02i", rn);
if(ident.size() == 3) {
- if(ident.substr(2,1) == "L") {
- buf[2] = 'R';
- buf[3] = '\0';
- } else if (ident.substr(2,1) == "R") {
- buf[2] = 'L';
- buf[3] = '\0';
- } else if (ident.substr(2,1) == "C") {
- buf[2] = 'C';
- buf[3] = '\0';
- } else if (ident.substr(2,1) == "T") {
- buf[2] = 'T';
- buf[3] = '\0';
+ char suffix = toupper(ident[2]);
+ if(suffix == 'L') {
+ buf[2] = 'R';
+ } else if (suffix == 'R') {
+ buf[2] = 'L';
} else {
- SG_LOG(SG_GENERAL, SG_ALERT, "Unknown runway code "
- << aRunwayIdent << " passed to FGRunway::reverseIdent");
+ // something else, just copy
+ buf[2] = suffix;
}
+
+ buf[3] = 0;
}
return buf;
return _length * aLengthWt + _width * aWidthWt + surface * aSurfaceWt + 1e-20;
}
-bool FGRunway::isTaxiway() const
+SGGeod FGRunway::begin() const
+{
+ return pointOnCenterline(0.0);
+}
+
+SGGeod FGRunway::end() const
+{
+ return pointOnCenterline(lengthM());
+}
+
+SGGeod FGRunway::threshold() const
+{
+ return pointOnCenterline(_displ_thresh);
+}
+
+void FGRunway::setReciprocalRunway(PositionedID other)
+{
+ assert(_reciprocal==0);
+ _reciprocal = other;
+}
+
+FGAirport* FGRunway::airport() const
+{
+ return loadById<FGAirport>(_airport);
+}
+
+FGRunway* FGRunway::reciprocalRunway() const
+{
+ return loadById<FGRunway>(_reciprocal);
+}
+
+FGNavRecord* FGRunway::ILS() const
+{
+ if (_ils == 0) {
+ return NULL;
+ }
+
+ return loadById<FGNavRecord>(_ils);
+}
+
+FGNavRecord* FGRunway::glideslope() const
+{
+ flightgear::NavDataCache* cache = flightgear::NavDataCache::instance();
+ PositionedID gsId = cache->findNavaidForRunway(guid(), FGPositioned::GS);
+ if (gsId == 0) {
+ return NULL;
+ }
+
+ return loadById<FGNavRecord>(gsId);
+}
+
+flightgear::SIDList FGRunway::getSIDs() const
+{
+ FGAirport* apt = airport();
+ flightgear::SIDList 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
+
+ return result;
+}
+
+flightgear::STARList FGRunway::getSTARs() const
+{
+ FGAirport* apt = airport();
+ flightgear::STARList 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
+
+ return result;
+}
+
+flightgear::ApproachList
+FGRunway::getApproaches(flightgear::ProcedureType type) const
+{
+ FGAirport* apt = airport();
+ flightgear::ApproachList result;
+ for (unsigned int i=0; i<apt->numApproaches(); ++i)
+ {
+ flightgear::Approach* s = apt->getApproachByIndex(i);
+ if( s->runway() == this
+ && (type == flightgear::PROCEDURE_INVALID || type == s->type()) )
+ {
+ result.push_back(s);
+ }
+ } // of approaches at the airport iteration
+
+ return result;
+}
+
+FGHelipad::FGHelipad(PositionedID aGuid,
+ PositionedID aAirport, const string& aIdent,
+ const SGGeod& aGeod,
+ const double heading, const double length,
+ const double width,
+ const int surface_code) :
+ FGRunwayBase(aGuid, RUNWAY, aIdent, aGeod,
+ heading, length, width, surface_code)
{
- return (_rwy_no[0] == 'x');
}