X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FAirports%2Frunways.cxx;h=9f2291f7ba90f31f10f31da246a4a978975572d4;hb=c068049d840c2f4567c7d07e7fb37247d8e23407;hp=85b92ec5a63b76a1c93c832d83ef1cb51a8b39e2;hpb=37cc06e33515672a43c4cdf776175be4267faf4c;p=flightgear.git diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index 85b92ec5a..9f2291f7b 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -25,295 +25,204 @@ # include #endif -#include // fabs() -#include // sprintf() +#include // sprintf() +#include // atoi() +#include #include -#include +#include -#include STL_STRING -#include +#include #include "runways.hxx" -SG_USING_NAMESPACE(std); -SG_USING_STD(istream); -SG_USING_STD(multimap); +#include +#include +#include +#include +using std::string; -// add an entry to the list -void FGRunwayList::add( 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) { - FGRunway rwy; - - rwy._id = id; - rwy._rwy_no = rwy_no; - // strip trailing "x" if it exists in runway number - string tmp = rwy._rwy_no.substr(2, 1); - if ( tmp == "x" ) { - rwy._rwy_no = rwy._rwy_no.substr(0, 2); - } - - rwy._lon = longitude; - rwy._lat = latitude; - rwy._heading = heading; - rwy._length = length; - rwy._width = width; - rwy._displ_thresh1 = displ_thresh1; - rwy._displ_thresh2 = displ_thresh2; - rwy._stopway1 = stopway1; - rwy._stopway2 = stopway2; - - rwy._lighting_flags = lighting_flags; - rwy._surface_code = surface_code; - rwy._shoulder_code = shoulder_code; - rwy._marking_code = marking_code; - rwy._smoothness = smoothness; - rwy._dist_remaining = dist_remaining; - - if ( rwy_no[0] == 'x' ) { - rwy._type = "taxiway"; - } else { - rwy._type = "runway"; - } - runways.insert(pair(rwy._id, rwy)); } +string FGRunway::reverseIdent(const string& aRunwayIdent) +{ + // Helipads don't have a seperate number per end + if (aRunwayIdent.size() && (aRunwayIdent[0] == 'H' || aRunwayIdent[0] == 'h' || aRunwayIdent[0] == 'x')) { + return aRunwayIdent; + } -// Return reverse rwy number -// eg 01 -> 19 -// 03L -> 21R -static string GetReverseRunwayNo(string& rwyno) { - // cout << "Original rwyno = " << rwyNo << '\n'; + std::string ident(aRunwayIdent); - // Helipads don't have a seperate number per end - if(rwyno.size() && (rwyno[0] == 'H' || rwyno[0] == 'h' || rwyno[0] == 'x')) { - return rwyno; - } - - // standardize input number - string tmp = rwyno.substr(1, 1); - if (( tmp == "L" || tmp == "R" || tmp == "C" ) || (rwyno.size() == 1)) { - tmp = rwyno; - rwyno = "0" + tmp; - SG_LOG( SG_GENERAL, SG_INFO, - "Standardising rwy number from " << tmp << " to " << rwyno ); + char buf[4]; + int rn = atoi(ident.substr(0,2).c_str()); + rn += 18; + while(rn > 36) { + rn -= 36; + } + + sprintf(buf, "%02i", rn); + if(ident.size() == 3) { + char suffix = toupper(ident[2]); + if(suffix == 'L') { + buf[2] = 'R'; + } else if (suffix == 'R') { + buf[2] = 'L'; + } else { + // something else, just copy + buf[2] = suffix; } - char buf[4]; - int rn = atoi(rwyno.substr(0,2).c_str()); - rn += 18; - while(rn > 36) { - rn -= 36; - } - sprintf(buf, "%02i", rn); - if(rwyno.size() == 3) { - if(rwyno.substr(2,1) == "L") { - buf[2] = 'R'; - buf[3] = '\0'; - } else if (rwyno.substr(2,1) == "R") { - buf[2] = 'L'; - buf[3] = '\0'; - } else if (rwyno.substr(2,1) == "C") { - buf[2] = 'C'; - buf[3] = '\0'; - } else if (rwyno.substr(2,1) == "T") { - buf[2] = 'T'; - buf[3] = '\0'; - } else { - SG_LOG(SG_GENERAL, SG_ALERT, "Unknown runway code " - << rwyno << " passed to GetReverseRunwayNo(...)"); - } - } - return(buf); + buf[3] = 0; + } + + return buf; } +double FGRunway::score(double aLengthWt, double aWidthWt, double aSurfaceWt, double aIlsWt) const +{ + int surface = 1; + if (_surface_code == 12 || _surface_code == 5) // dry lakebed & gravel + surface = 2; + else if (_surface_code == 1 || _surface_code == 2) // asphalt & concrete + surface = 3; -// search for the specified apt id (wierd!) -bool FGRunwayList::search( const string& aptid, FGRunway* r ) { - runway_map_iterator pos; - - pos = runways.lower_bound(aptid); - if ( pos != runways.end() ) { - current = pos; - *r = pos->second; - return true; - } else { - return false; - } + int ils = (_ils != 0); + + return _length * aLengthWt + _width * aWidthWt + surface * aSurfaceWt + ils * aIlsWt + 1e-20; } - -// search for the specified apt id and runway no -bool FGRunwayList::search( const string& aptid, const string& rwyno, - FGRunway *r ) +SGGeod FGRunway::begin() const { - string revrwyno = ""; - string runwayno = rwyno; - if ( runwayno.length() ) { - // standardize input number - string tmp = runwayno.substr(1, 1); - if (( tmp == "L" || tmp == "R" || tmp == "C" ) - || (runwayno.size() == 1)) - { - tmp = runwayno; - runwayno = "0" + tmp; - SG_LOG( SG_GENERAL, SG_INFO, "Standardising rwy number from " - << tmp << " to " << runwayno ); - } - revrwyno = GetReverseRunwayNo(runwayno); - } - runway_map_iterator pos; - for ( pos = runways.lower_bound( aptid ); - pos != runways.upper_bound( aptid ); ++pos) - { - if ( pos->second._rwy_no == runwayno ) { - current = pos; - *r = pos->second; - return true; - } else if ( pos->second._rwy_no == revrwyno ) { - // Search again with the other-end runway number. - // Remember we have to munge the heading and rwy_no - // results if this one matches - current = pos; - *r = pos->second; - // NOTE - matching revrwyno implies that runwayno was - // actually correct. - r->_rwy_no = runwayno; - r->_heading += 180.0; - return true; - } - } + return pointOnCenterline(0.0); +} - return false; +SGGeod FGRunway::end() const +{ + return pointOnCenterline(lengthM()); } +SGGeod FGRunway::threshold() const +{ + return pointOnCenterline(_displ_thresh); +} -// (wierd!) -FGRunway FGRunwayList::search( const string& aptid ) { - FGRunway a; - search( aptid, &a ); - return a; +void FGRunway::setReciprocalRunway(PositionedID other) +{ + assert(_reciprocal==0); + _reciprocal = other; } +FGAirport* FGRunway::airport() const +{ + return loadById(_airport); +} -// Return the runway closest to a given heading -bool FGRunwayList::search( const string& aptid, const int tgt_hdg, - FGRunway *runway ) +FGRunway* FGRunway::reciprocalRunway() const { - string rwyNo = search(aptid, tgt_hdg); - return(rwyNo == "NN" ? false : search(aptid, rwyNo, runway)); + return loadById(_reciprocal); } +FGNavRecord* FGRunway::ILS() const +{ + if (_ils == 0) { + return NULL; + } + + return loadById(_ils); +} -// Return the runway number of the runway closest to a given heading -#include
// FIXME remove -string FGRunwayList::search( const string& aptid, const int hdg ) { - //SG_LOG(SG_GENERAL, SG_DEBUG, "searching runway for " << aptid - // << " with target heading " << hdg); +FGNavRecord* FGRunway::glideslope() const +{ + flightgear::NavDataCache* cache = flightgear::NavDataCache::instance(); + PositionedID gsId = cache->findNavaidForRunway(guid(), FGPositioned::GS); + if (gsId == 0) { + return NULL; + } + + return loadById(gsId); +} - FGRunway r; - if (!search(aptid, &r)) { - SG_LOG(SG_GENERAL, SG_ALERT, "Failed to find " - << aptid << " in database."); - return "NN"; +flightgear::SIDList FGRunway::getSIDs() const +{ + FGAirport* apt = airport(); + flightgear::SIDList result; + for (unsigned int i=0; inumSIDs(); ++i) { + flightgear::SID* s = apt->getSIDByIndex(i); + if (s->isForRunway(this)) { + result.push_back(s); } - - double LENWGT = fgGetDouble("/tmp/runway-search/length", 0.01); - double WIDWGT = fgGetDouble("/tmp/runway-search/width", 0.01); - double SURFWGT = fgGetDouble("/tmp/runway-search/surface", 10); - double DEVWGT = fgGetDouble("/tmp/runway-search/deviation", 1); - - FGRunway best; - double max = 0.0; - bool reversed = false; - - do { - if (r._id != aptid) - break; - if (r._type != "runway") - continue; - - int surface = 0; - if (r._surface_code == 1 || r._surface_code == 2) // asphalt & concrete - surface = 2; - else if (r._surface_code == 12 || r._surface_code == 5) // dry lakebed & gravel - surface = 1; - - double quality, bad, diff; - double good = LENWGT * r._length + WIDWGT * r._width + SURFWGT * surface; - - // this side - diff = hdg - r._heading; - while (diff < -180) - diff += 360; - while (diff >= 180) - diff -= 360; - bad = fabs(DEVWGT * diff) + 1e-20; - - quality = good / bad; - //SG_LOG(SG_GENERAL, SG_DEBUG, " runway " << r._rwy_no << " -> " << quality); - if (quality > max) { - max = quality; - best = r; - reversed = false; - } - - // other side - diff = hdg - r._heading - 180; - while (diff < -180) - diff += 360; - while (diff >= 180) - diff -= 360; - bad = fabs(DEVWGT * diff) + 1e-20; - - quality = good / bad; - //SG_LOG(SG_GENERAL, SG_DEBUG, " runway " << GetReverseRunwayNo(r._rwy_no) - // << " -> " << quality); - if (quality > max) { - max = quality; - best = r; - reversed = true; - } - - } while (!next(&r)); - - return reversed ? GetReverseRunwayNo(best._rwy_no) : best._rwy_no; + } // of SIDs at the airport iteration + + return result; } - -bool FGRunwayList::next( FGRunway* runway ) { - ++current; - if ( current != runways.end() ) { - *runway = current->second; - return true; - } else { - return false; +flightgear::STARList FGRunway::getSTARs() const +{ + FGAirport* apt = airport(); + flightgear::STARList result; + for (unsigned int i=0; inumSTARs(); ++i) { + flightgear::STAR* s = apt->getSTARByIndex(i); + if (s->isForRunway(this)) { + result.push_back(s); } + } // of STARs at the airport iteration + + return result; } - -FGRunway FGRunwayList::next() { - FGRunway result; - - ++current; - if ( current != runways.end() ) { - result = current->second; +flightgear::ApproachList +FGRunway::getApproaches(flightgear::ProcedureType type) const +{ + FGAirport* apt = airport(); + flightgear::ApproachList result; + for (unsigned int i=0; inumApproaches(); ++i) + { + flightgear::Approach* s = apt->getApproachByIndex(i); + if( s->runway() == this + && (type == flightgear::PROCEDURE_INVALID || type == s->type()) ) + { + result.push_back(s); } - - return result; + } // of approaches at the airport iteration + + return result; } +void FGRunway::updateThreshold(const SGGeod& newThreshold, double newHeading, + double newDisplacedThreshold, + double newStopway) +{ + modifyPosition(newThreshold); + _heading = newHeading; + _stopway = newStopway; + _displ_thresh = newDisplacedThreshold; +} -// Destructor -FGRunwayList::~FGRunwayList( void ) { +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) +{ }