From: ehofman Date: Thu, 11 Sep 2008 08:38:09 +0000 (+0000) Subject: James Turner: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=aa78341698c0ede62bd45d864c1e866d309b420d;p=flightgear.git James Turner: Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace. An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal. --- diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx index 222971565..593a83a5c 100644 --- a/src/AIModel/AIFlightPlan.hxx +++ b/src/AIModel/AIFlightPlan.hxx @@ -24,7 +24,6 @@ #include #include -#include #include #include "AIBase.hxx" @@ -33,6 +32,7 @@ using std::vector; using std::string; class FGTaxiRoute; +class FGRunway; class FGAIFlightPlan { @@ -93,7 +93,8 @@ public: void setTime(time_t st) { start_time = st; } int getGate() const { return gateId; } double getLeadInAngle() const { return leadInAngle; } - const string& getRunway() const { return rwy._rwy_no; } + const string& getRunway() const; + void setRepeat(bool r) { repeat = r; } bool getRepeat(void) const { return repeat; } void restart(void); @@ -105,7 +106,7 @@ public: bool isActive(time_t time) {return time >= this->getStartTime();} private: - FGRunway rwy; + FGRunway* rwy; typedef vector wpt_vector_type; typedef wpt_vector_type::const_iterator wpt_vector_iterator; diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index 89797696f..482d16aee 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -141,11 +141,11 @@ void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, rwy = apt->getRunwayByIdent(activeRunway); // Determine the beginning of he runway - heading = rwy._heading; + heading = rwy->headingDeg(); double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, - rwy._length * SG_FEET_TO_METER * 0.5 - 5.0, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, + rwy->lengthM() * 0.5 - 5.0, &lat2, &lon2, &az2 ); if (apt->getDynamics()->getGroundNetwork()->exists()) @@ -499,11 +499,11 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee rwy = apt->getRunwayByIdent(activeRunway); } // Acceleration point, 105 meters into the runway, - heading = rwy._heading; + heading = rwy->headingDeg(); double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, - rwy._length * SG_FEET_TO_METER * 0.5 - 105.0, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, + rwy->lengthM() * 0.5 - 105.0, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "accel"; @@ -532,8 +532,8 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee wpt = new waypoint; wpt->name = "SOC"; - wpt->latitude = rwy._lat; - wpt->longitude = rwy._lon; + wpt->latitude = rwy->latitude(); + wpt->longitude = rwy->longitude(); wpt->altitude = apt->getElevation()+1000; wpt->speed = speed; wpt->crossat = -10000; @@ -545,8 +545,8 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee waypoints.push_back(wpt); - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, - rwy._length * SG_FEET_TO_METER, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading, + rwy->lengthM(), &lat2, &lon2, &az2 ); wpt = new waypoint; @@ -567,7 +567,7 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee // Tower control until they have reached the 3000 ft climb point - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading, 5000, &lat2, &lon2, &az2 ); @@ -586,7 +586,7 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee wpt->routeIndex = 0; waypoints.push_back(wpt); - // geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, + // geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading, // 100000, // &lat2, &lon2, &az2 ); // wpt = new waypoint; @@ -626,11 +626,11 @@ void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, } - heading = rwy._heading; + heading = rwy->headingDeg(); double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } //cerr << "Creating climb at : " << rwy._id << " " << rwy._rwy_no << endl; - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading, 10*SG_NM_TO_METER, &lat2, &lon2, &az2 ); wpt = new waypoint; @@ -648,7 +648,7 @@ void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, waypoints.push_back(wpt); - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading, 20*SG_NM_TO_METER, &lat2, &lon2, &az2 ); wpt = new waypoint; @@ -709,12 +709,12 @@ void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, // " at airport " << arr->getId()); // exit(1); // } -// heading = rwy._heading; +// heading = rwy->headingDeg(); // azimuth = heading + 180.0; // while ( azimuth >= 360.0 ) { azimuth -= 360.0; } -// geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, +// geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, // 110000, // &lat2, &lon2, &az2 ); // wpt = new waypoint; @@ -753,10 +753,10 @@ void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType) apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway); rwy = apt->getRunwayByIdent(activeRunway); - heading = rwy._heading; + heading = rwy->headingDeg(); azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, 100000, &lat2, &lon2, &az2 ); @@ -775,7 +775,7 @@ void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType) waypoints.push_back(wpt); // Three thousand ft. Slowing down to 160 kts - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, 8*SG_NM_TO_METER, &lat2, &lon2, &az2 ); wpt = new waypoint; @@ -807,13 +807,13 @@ void FGAIFlightPlan::createLanding(FGAirport *apt) waypoint *wpt; - heading = rwy._heading; + heading = rwy->headingDeg(); azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } //Runway Threshold - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, - rwy._length*0.45 * SG_FEET_TO_METER, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, + rwy->lengthM() *0.45, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END"); @@ -830,13 +830,13 @@ void FGAIFlightPlan::createLanding(FGAirport *apt) waypoints.push_back(wpt); //Full stop at the runway centerpoint - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, - rwy._length*0.45, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, + rwy->lengthFt() *0.45, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "Center"; //wpt_node->getStringValue("name", "END"); - wpt->latitude = rwy._lat; - wpt->longitude = rwy._lon; + wpt->latitude = rwy->latitude(); + wpt->longitude = rwy->longitude(); wpt->altitude = apt->getElevation(); wpt->speed = 30; wpt->crossat = -10000; @@ -847,8 +847,8 @@ void FGAIFlightPlan::createLanding(FGAirport *apt) wpt->routeIndex = 0; waypoints.push_back(wpt); - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, - rwy._length*0.45 * SG_FEET_TO_METER, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading, + rwy->lengthM() *0.45, &lat2, &lon2, &az2 ); wpt = new waypoint; wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END"); diff --git a/src/AIModel/AIFlightPlanCreateCruise.cxx b/src/AIModel/AIFlightPlanCreateCruise.cxx index d6d790978..a12241268 100755 --- a/src/AIModel/AIFlightPlanCreateCruise.cxx +++ b/src/AIModel/AIFlightPlanCreateCruise.cxx @@ -271,7 +271,7 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, // { // cerr << "Creating cruise to EHAM " << latitude << " " << longitude << endl; // } - heading = rwy._heading; + heading = rwy->headingDeg(); azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } @@ -337,12 +337,12 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, arr->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway); rwy = arr->getRunwayByIdent(activeRunway); - heading = rwy._heading; + heading = rwy->headingDeg(); azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, + geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth, 110000, &lat2, &lon2, &az2 ); wpt = new waypoint; diff --git a/src/ATCDCL/AILocalTraffic.cxx b/src/ATCDCL/AILocalTraffic.cxx index bcaab722e..63c1848c4 100644 --- a/src/ATCDCL/AILocalTraffic.cxx +++ b/src/ATCDCL/AILocalTraffic.cxx @@ -167,9 +167,9 @@ void FGAILocalTraffic::GetRwyDetails(const string& id) { const FGAirport* apt = fgFindAirportID(id); assert(apt); - FGRunway runway(apt->getActiveRunwayForUsage()); + FGRunway* runway(apt->getActiveRunwayForUsage()); - double hdg = runway._heading; + double hdg = runway->headingDeg(); double other_way = hdg - 180.0; while(other_way <= 0.0) { other_way += 360.0; @@ -177,12 +177,12 @@ void FGAILocalTraffic::GetRwyDetails(const string& id) { // move to the +l end/center of the runway //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; - Point3D origin = Point3D(runway._lon, runway._lat, aptElev); + Point3D origin = Point3D(runway->longitude(), runway->latitude(), aptElev); Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway._length * SG_FEET_TO_METER; - rwy.width = runway._width * SG_FEET_TO_METER; + rwy.length = runway->lengthM(); + rwy.width = runway->widthM(); geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), hdg, diff --git a/src/ATCDCL/ATCutils.cxx b/src/ATCDCL/ATCutils.cxx index c5a229fee..03ed9f43d 100644 --- a/src/ATCDCL/ATCutils.cxx +++ b/src/ATCDCL/ATCutils.cxx @@ -293,10 +293,10 @@ double GetAngleDiff_deg( const double &a1, const double &a2) { // Runway stuff // Given a Point3D (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway -bool OnRunway(const Point3D& pt, const FGRunway& rwy) { +bool OnRunway(const Point3D& pt, const FGRunway* rwy) { FGATCAlignedProjection ortho; - Point3D centre(rwy._lon, rwy._lat, 0.0); // We don't need the elev - ortho.Init(centre, rwy._heading); + Point3D centre(rwy->longitude(), rwy->latitude(), 0.0); // We don't need the elev + ortho.Init(centre, rwy->headingDeg()); Point3D xyc = ortho.ConvertToLocal(centre); Point3D xyp = ortho.ConvertToLocal(pt); @@ -304,8 +304,8 @@ bool OnRunway(const Point3D& pt, const FGRunway& rwy) { //cout << "Length offset = " << fabs(xyp.y() - xyc.y()) << '\n'; //cout << "Width offset = " << fabs(xyp.x() - xyc.x()) << '\n'; - if((fabs(xyp.y() - xyc.y()) < ((rwy._length/2.0) + 5.0)) - && (fabs(xyp.x() - xyc.x()) < (rwy._width/2.0))) { + if((fabs(xyp.y() - xyc.y()) < ((rwy->lengthFt()/2.0) + 5.0)) + && (fabs(xyp.x() - xyc.x()) < (rwy->widthFt()/2.0))) { return(true); } diff --git a/src/ATCDCL/ATCutils.hxx b/src/ATCDCL/ATCutils.hxx index b5248b84a..7a53564a4 100644 --- a/src/ATCDCL/ATCutils.hxx +++ b/src/ATCDCL/ATCutils.hxx @@ -99,5 +99,5 @@ double GetAngleDiff_deg( const double &a1, const double &a2); ****************/ // Given a Point3D (lon/lat/elev) and an FGRunway struct, determine if the point lies on the runway -bool OnRunway(const Point3D& pt, const FGRunway& rwy); +bool OnRunway(const Point3D& pt, const FGRunway* rwy); diff --git a/src/ATCDCL/approach.cxx b/src/ATCDCL/approach.cxx index c935cbc29..6e75de47c 100644 --- a/src/ATCDCL/approach.cxx +++ b/src/ATCDCL/approach.cxx @@ -563,13 +563,13 @@ void FGApproach::get_active_runway() { const FGAirport* apt = fgFindAirportID(ident); assert(apt); - FGRunway runway = apt->getActiveRunwayForUsage(); + FGRunway* runway = apt->getActiveRunwayForUsage(); - active_runway = runway._rwy_no; - active_rw_hdg = runway._heading; - active_rw_lon = runway._lon; - active_rw_lat = runway._lat; - active_rw_len = runway._length; + active_runway = runway->ident(); + active_rw_hdg = runway->headingDeg(); + active_rw_lon = runway->longitude(); + active_rw_lat = runway->latitude(); + active_rw_len = runway->lengthFt(); } // ======================================================================== diff --git a/src/ATCDCL/atis.cxx b/src/ATCDCL/atis.cxx index 4f9d93de4..d3be4ea23 100644 --- a/src/ATCDCL/atis.cxx +++ b/src/ATCDCL/atis.cxx @@ -212,7 +212,7 @@ void FGATIS::UpdateTransmission() { const FGAirport* apt = fgFindAirportID(ident); assert(apt); - string rwy_no = apt->getActiveRunwayForUsage()._rwy_no; + string rwy_no = apt->getActiveRunwayForUsage()->ident(); if(rwy_no != "NN") { transmission += " / Landing_and_departing_runway "; transmission += ConvertRwyNumToSpokenString(atoi(rwy_no.c_str())); diff --git a/src/ATCDCL/ground.cxx b/src/ATCDCL/ground.cxx index 2a6643e00..8f309e370 100644 --- a/src/ATCDCL/ground.cxx +++ b/src/ATCDCL/ground.cxx @@ -363,27 +363,27 @@ void FGGround::DoRwyDetails() { const FGAirport* apt = fgFindAirportID(ident); assert(apt); - FGRunway runway = apt->getActiveRunwayForUsage(); + FGRunway* runway = apt->getActiveRunwayForUsage(); - activeRwy = runway._rwy_no; - rwy.rwyID = runway._rwy_no; + activeRwy = runway->ident(); + rwy.rwyID = runway->ident(); SG_LOG(SG_ATC, SG_INFO, "In FGGround, active runway for airport " << ident << " is " << activeRwy); // Get the threshold position - double other_way = runway._heading - 180.0; + double other_way = runway->headingDeg() - 180.0; while(other_way <= 0.0) { other_way += 360.0; } // move to the +l end/center of the runway //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; - Point3D origin = Point3D(runway._lon, runway._lat, aptElev); + Point3D origin = Point3D(runway->longitude(), runway->latitude(), aptElev); Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway._length * SG_FEET_TO_METER; + rwy.length = runway->lengthM(); geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); - geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway._heading, + geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway->headingDeg(), rwy.length / 2.0 - 25.0, &tolat, &tolon, &tor ); // Note - 25 meters in from the runway end is a bit of a hack to put the plane ahead of the user. // now copy what we need out of runway into rwy @@ -391,7 +391,7 @@ void FGGround::DoRwyDetails() { Point3D takeoff_end = Point3D(tolon, tolat, aptElev); //cout << "Threshold position = " << tshlon << ", " << tshlat << ", " << aptElev << '\n'; //cout << "Takeoff position = " << tolon << ", " << tolat << ", " << aptElev << '\n'; - rwy.hdg = runway._heading; + rwy.hdg = runway->headingDeg(); // Set the projection for the local area based on this active runway ortho.Init(rwy.threshold_pos, rwy.hdg); rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos); // should come out as zero diff --git a/src/ATCDCL/tower.cxx b/src/ATCDCL/tower.cxx index e2b2ce605..52d50f9a8 100644 --- a/src/ATCDCL/tower.cxx +++ b/src/ATCDCL/tower.cxx @@ -1513,38 +1513,36 @@ void FGTower::DoRwyDetails() { const FGAirport* apt = fgFindAirportID(ident); assert(apt); - FGRunway runway = apt->getActiveRunwayForUsage(); - - //cout << "RUNWAY GOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOD\n"; + FGRunway* runway = apt->getActiveRunwayForUsage(); - activeRwy = runway._rwy_no; - rwy.rwyID = runway._rwy_no; - SG_LOG(SG_ATC, SG_INFO, "Active runway for airport " << ident << " is " << activeRwy); + activeRwy = runway->ident(); + rwy.rwyID = runway->ident(); + SG_LOG(SG_ATC, SG_INFO, "In FGGround, active runway for airport " << ident << " is " << activeRwy); // Get the threshold position - double other_way = runway._heading - 180.0; + double other_way = runway->headingDeg() - 180.0; while(other_way <= 0.0) { other_way += 360.0; } // move to the +l end/center of the runway //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; - Point3D origin = Point3D(runway._lon, runway._lat, aptElev); + Point3D origin = Point3D(runway->longitude(), runway->latitude(), aptElev); Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway._length * SG_FEET_TO_METER; - rwy.width = runway._width * SG_FEET_TO_METER; + rwy.length = runway->lengthM(); geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); - geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway._heading, + geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), runway->headingDeg(), rwy.length / 2.0 - 25.0, &tolat, &tolon, &tor ); + // Note - 25 meters in from the runway end is a bit of a hack to put the plane ahead of the user. // now copy what we need out of runway into rwy rwy.threshold_pos = Point3D(tshlon, tshlat, aptElev); Point3D takeoff_end = Point3D(tolon, tolat, aptElev); //cout << "Threshold position = " << tshlon << ", " << tshlat << ", " << aptElev << '\n'; //cout << "Takeoff position = " << tolon << ", " << tolat << ", " << aptElev << '\n'; - rwy.hdg = runway._heading; + rwy.hdg = runway->headingDeg(); // Set the projection for the local area based on this active runway ortho.Init(rwy.threshold_pos, rwy.hdg); rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos); // should come out as zero diff --git a/src/Airports/apt_loader.cxx b/src/Airports/apt_loader.cxx index d3d6217f9..1f92be4d5 100644 --- a/src/Airports/apt_loader.cxx +++ b/src/Airports/apt_loader.cxx @@ -100,7 +100,7 @@ bool fgAirportDBLoad( FGAirportList *airports, string line; char tmp[2049]; tmp[2048] = 0; - vector runways; + vector runways; unsigned int line_id = 0; unsigned int line_num = 0; @@ -212,10 +212,15 @@ bool fgAirportDBLoad( FGAirportList *airports, int surface_code = atoi( token[10].c_str() ); - FGRunway rwy(rwy_no, lon, lat, heading, length, - width, displ_thresh1, displ_thresh2, - stopway1, stopway2, surface_code); + FGRunway* rwy = new FGRunway(NULL, rwy_no, lon, lat, heading, length, + width, displ_thresh1, stopway1, surface_code, false); + + FGRunway* reciprocal = new FGRunway(NULL, FGRunway::reverseIdent(rwy_no), + lon, lat, heading + 180.0, length, width, + displ_thresh2, stopway2, surface_code, true); + runways.push_back(rwy); + runways.push_back(reciprocal); } else if ( line_id == 18 ) { // beacon entry (ignore) } else if ( line_id == 14 ) { diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index 41b77bae1..5f41b8d9e 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -485,8 +485,8 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s string FGAirportDynamics::chooseRunwayFallback() { - FGRunway rwy = _ap->getActiveRunwayForUsage(); - return rwy._rwy_no; + FGRunway* rwy = _ap->getActiveRunwayForUsage(); + return rwy->ident(); } void FGAirportDynamics::addParking(FGParking& park) { diff --git a/src/Airports/runwayprefs.cxx b/src/Airports/runwayprefs.cxx index ae204474e..3572275c0 100644 --- a/src/Airports/runwayprefs.cxx +++ b/src/Airports/runwayprefs.cxx @@ -202,7 +202,7 @@ void RunwayGroup::setActive(const FGAirport* airport, stringVec *currentlyActive) { - FGRunway rwy; + FGRunway* rwy; int activeRwys = rwyList.size(); // get the number of runways active int nrOfPreferences; // bool found = true; @@ -238,7 +238,7 @@ void RunwayGroup::setActive(const FGAirport* airport, rwy = airport->getRunwayByIdent(rwyList[j].getRwyList(i)); //cerr << "Succes" << endl; - hdgDiff = fabs(windHeading - rwy._heading); + hdgDiff = fabs(windHeading - rwy->headingDeg()); //cerr << "Wind Heading: " << windHeading << "Runway Heading: " < 180) @@ -307,7 +307,7 @@ void RunwayGroup::setActive(const FGAirport* airport, rwy = airport->getRunwayByIdent(name); //cerr << "Succes" << endl; - hdgDiff = fabs(windHeading - rwy._heading); + hdgDiff = fabs(windHeading - rwy->headingDeg()); if (hdgDiff > 180) hdgDiff = 360 - hdgDiff; hdgDiff *= ((2*M_PI)/360.0); // convert to radians diff --git a/src/Airports/runways.cxx b/src/Airports/runways.cxx index 589be2e99..cc2c35015 100644 --- a/src/Airports/runways.cxx +++ b/src/Airports/runways.cxx @@ -42,43 +42,55 @@ using std::istream; using std::multimap; using std::string; -FGRunway::FGRunway() +static FGPositioned::Type runwayTypeFromNumber(const std::string& aRwyNo) { + return (aRwyNo[0] == 'x') ? FGPositioned::TAXIWAY : FGPositioned::RUNWAY; } -FGRunway::FGRunway(const string& rwy_no, - const double longitude, const double latitude, - const double heading, const double length, - const double width, - const double displ_thresh1, const double displ_thresh2, - const double stopway1, const double stopway2, - const int surface_code) +static std::string cleanRunwayNo(const std::string& aRwyNo) { - _rwy_no = rwy_no; - if (rwy_no[0] == 'x') { - _type = "taxiway"; - } else { - _type = "runway"; - + if (aRwyNo[0] == 'x') { + return std::string(); // no ident for taxiways + } + + string result(aRwyNo); // canonicalise runway ident - if ((rwy_no.size() == 1) || !isdigit(rwy_no[1])) { - _rwy_no = "0" + rwy_no; - } + if ((aRwyNo.size() == 1) || !isdigit(aRwyNo[1])) { + result = "0" + aRwyNo; + } - if ((_rwy_no.size() > 2) && (_rwy_no[2] == 'x')) { - _rwy_no = _rwy_no.substr(0, 2); + // trim off trailing garbage + if (result.size() > 2) { + char suffix = toupper(result[2]); + if (suffix == 'X') { + result = result.substr(0, 2); } } + + return result; +} +FGRunway::FGRunway(FGAirport* aAirport, const string& rwy_no, + const double longitude, const double latitude, + const double heading, const double length, + const double width, + const double displ_thresh, + const double stopway, + const int surface_code, + bool reciprocal) : + FGPositioned(runwayTypeFromNumber(rwy_no), cleanRunwayNo(rwy_no), latitude, longitude, 0.0), + _airport(aAirport), + _reciprocal(reciprocal) +{ + _rwy_no = ident(); + _lon = longitude; _lat = latitude; _heading = heading; _length = length; _width = width; - _displ_thresh1 = displ_thresh1; - _displ_thresh2 = displ_thresh2; - _stopway1 = stopway1; - _stopway2 = stopway2; + _displ_thresh = displ_thresh; + _stopway = stopway; _surface_code = surface_code; } @@ -101,22 +113,17 @@ 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; @@ -135,5 +142,32 @@ double FGRunway::score(double aLengthWt, double aWidthWt, double aSurfaceWt) con bool FGRunway::isTaxiway() const { - return (_rwy_no[0] == 'x'); + return (type() == TAXIWAY); +} + +SGGeod FGRunway::threshold() const +{ + return pointOnCenterline(0.0); +} + +SGGeod FGRunway::reverseThreshold() const +{ + return pointOnCenterline(lengthM()); +} + +SGGeod FGRunway::displacedThreshold() const +{ + return pointOnCenterline(_displ_thresh * SG_FEET_TO_METER); +} + +SGGeod FGRunway::pointOnCenterline(double aOffset) const +{ + SGGeod result; + double dummyAz2; + double halfLengthMetres = lengthM() * 0.5; + + SGGeodesy::direct(mPosition, _heading, + aOffset - halfLengthMetres, + result, dummyAz2); + return result; } diff --git a/src/Airports/runways.hxx b/src/Airports/runways.hxx index 996f38045..a2cc2ae62 100644 --- a/src/Airports/runways.hxx +++ b/src/Airports/runways.hxx @@ -26,52 +26,121 @@ #include +#include + +#include "Navaids/positioned.hxx" + #include -#include -class FGRunway -{ +// forward decls +class FGAirport; + +class FGRunway : public FGPositioned +{ + FGAirport* _airport; ///< owning airport + bool _reciprocal; public: - FGRunway(); - FGRunway(const std::string& rwy_no, + FGRunway(FGAirport* aAirport, const std::string& rwy_no, const double longitude, const double latitude, const double heading, const double length, const double width, - const double displ_thresh1, const double displ_thresh2, - const double stopway1, const double stopway2, - const int surface_code); + const double displ_thresh, + const double stopway, + const int surface_code, + const bool reciprocal); /** * given a runway identifier (06, 18L, 31R) compute the identifier for the - * opposite heading runway (24, 36R, 13L) string. + * reciprocal heading runway (24, 36R, 13L) string. */ static std::string reverseIdent(const std::string& aRunayIdent); - + /** * score this runway according to the specified weights. Used by * FGAirport::findBestRunwayForHeading */ 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 _reciprocal; } + + /** + * Test if this is a taxiway or not + */ bool isTaxiway() const; + /** + * Get the runway threshold point - this is syntatic sugar, equivalent to + * calling pointOnCenterline(0.0); + */ + SGGeod threshold() const; + + /** + * Get the (possibly displaced) threshold point. + */ + SGGeod displacedThreshold() const; + + /** + * Get the opposite threshold - this is equivalent to calling + * pointOnCenterline(lengthFt()); + */ + SGGeod reverseThreshold() const; + + /** + * Retrieve a position on the extended runway centerline. Positive values + * are in the direction of the runway heading, negative values are in the + * opposited direction. 0.0 corresponds to the (non-displaced) threshold + */ + SGGeod pointOnCenterline(double aOffset) const; + + /** + * Runway length in ft + */ + double lengthFt() const + { return _length; } + + double lengthM() const + { return _length * SG_FEET_TO_METER; } + + double widthFt() const + { return _width; } + + double widthM() const + { return _width * SG_FEET_TO_METER; } + + /** + * Runway heading in degrees. + */ + double headingDeg() const + { return _heading; } + + /** + * Airport this runway is located at + */ + FGAirport* airport() const + { return _airport; } + + // FIXME - should die once airport / runway creation is cleaned up + void setAirport(FGAirport* aAirport) + { _airport = aAirport; } + std::string _rwy_no; - std::string _type; // runway / taxiway double _lon; double _lat; + double _displ_thresh; + double _stopway; + double _heading; double _length; double _width; - double _displ_thresh1; - double _displ_thresh2; - double _stopway1; - double _stopway2; - + int _surface_code; }; -typedef std::vector FGRunwayVector; - #endif // _FG_RUNWAYS_HXX diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 2ebfb8434..9a0a4dab4 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -47,6 +47,7 @@ #include
#include #include +#include #include @@ -109,7 +110,7 @@ unsigned int FGAirport::numRunways() const return mRunways.size(); } -FGRunway FGAirport::getRunwayByIndex(unsigned int aIndex) const +FGRunway* FGAirport::getRunwayByIndex(unsigned int aIndex) const { assert(aIndex >= 0 && aIndex < mRunways.size()); return mRunways[aIndex]; @@ -117,48 +118,31 @@ FGRunway FGAirport::getRunwayByIndex(unsigned int aIndex) const bool FGAirport::hasRunwayWithIdent(const string& aIdent) const { - bool dummy; - return (getIteratorForRunwayIdent(aIdent, dummy) != mRunways.end()); + return (getIteratorForRunwayIdent(aIdent) != mRunways.end()); } -FGRunway FGAirport::getRunwayByIdent(const string& aIdent) const +FGRunway* FGAirport::getRunwayByIdent(const string& aIdent) const { - bool reversed; - FGRunwayVector::const_iterator it = getIteratorForRunwayIdent(aIdent, reversed); + Runway_iterator it = getIteratorForRunwayIdent(aIdent); if (it == mRunways.end()) { SG_LOG(SG_GENERAL, SG_ALERT, "no such runway '" << aIdent << "' at airport " << _id); throw sg_range_exception("unknown runway " + aIdent + " at airport:" + _id, "FGAirport::getRunwayByIdent"); } - if (!reversed) { - return *it; - } - - FGRunway result(*it); - result._heading += 180.0; - result._rwy_no = FGRunway::reverseIdent(it->_rwy_no); - return result; + return *it; } -FGRunwayVector::const_iterator -FGAirport::getIteratorForRunwayIdent(const string& aIdent, bool& aReversed) const +FGAirport::Runway_iterator +FGAirport::getIteratorForRunwayIdent(const string& aIdent) const { string ident(aIdent); if ((aIdent.size() == 1) || !isdigit(aIdent[1])) { ident = "0" + aIdent; } - string reversedRunway = FGRunway::reverseIdent(ident); - FGRunwayVector::const_iterator it = mRunways.begin(); - + Runway_iterator it = mRunways.begin(); for (; it != mRunways.end(); ++it) { - if (it->_rwy_no == ident) { - aReversed = false; - return it; - } - - if (it->_rwy_no == reversedRunway) { - aReversed = true; + if ((*it)->ident() == ident) { return it; } } @@ -179,10 +163,10 @@ static double normaliseBearing(double aBearing) return aBearing; } -FGRunway FGAirport::findBestRunwayForHeading(double aHeading) const +FGRunway* FGAirport::findBestRunwayForHeading(double aHeading) const { - FGRunwayVector::const_iterator it = mRunways.begin(); - FGRunway result; + Runway_iterator it = mRunways.begin(); + FGRunway* result = NULL; double currentBestQuality = 0.0; SGPropertyNode *param = fgGetNode("/sim/airport/runways/search", true); @@ -192,10 +176,9 @@ FGRunway FGAirport::findBestRunwayForHeading(double aHeading) const double deviationWeight = param->getDoubleValue("deviation-weight", 1); for (; it != mRunways.end(); ++it) { - double good = it->score(lengthWeight, widthWeight, surfaceWeight); + double good = (*it)->score(lengthWeight, widthWeight, surfaceWeight); - // first side - double dev = normaliseBearing(aHeading - it->_heading); + double dev = normaliseBearing(aHeading - (*it)->headingDeg()); double bad = fabs(deviationWeight * dev) + 1e-20; double quality = good / bad; @@ -203,17 +186,6 @@ FGRunway FGAirport::findBestRunwayForHeading(double aHeading) const currentBestQuality = quality; result = *it; } - - dev = normaliseBearing(aHeading - it->_heading - 180.0); - bad = fabs(deviationWeight * dev) + 1e-20; - quality = good / bad; - - if (quality > currentBestQuality) { - currentBestQuality = quality; - result = *it; - result._heading += 180.0; - result._rwy_no = FGRunway::reverseIdent(it->_rwy_no); - } } return result; @@ -224,22 +196,24 @@ unsigned int FGAirport::numTaxiways() const return mTaxiways.size(); } -FGRunway FGAirport::getTaxiwayByIndex(unsigned int aIndex) const +FGRunway* FGAirport::getTaxiwayByIndex(unsigned int aIndex) const { assert(aIndex >= 0 && aIndex < mTaxiways.size()); return mTaxiways[aIndex]; } -void FGAirport::addRunway(const FGRunway& aRunway) +void FGAirport::addRunway(FGRunway* aRunway) { - if (aRunway.isTaxiway()) { + aRunway->setAirport(this); + + if (aRunway->isTaxiway()) { mTaxiways.push_back(aRunway); } else { mRunways.push_back(aRunway); } } -FGRunway FGAirport::getActiveRunwayForUsage() const +FGRunway* FGAirport::getActiveRunwayForUsage() const { static FGEnvironmentMgr* envMgr = NULL; if (!envMgr) { diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index bedbd7d91..2236b7660 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -27,8 +27,6 @@ #ifndef _FG_SIMPLE_HXX #define _FG_SIMPLE_HXX -#include - #include #include @@ -36,10 +34,15 @@ #include #include -#include "Airports/runways.hxx" +#include + +#include "Navaids/positioned.hxx" // forward decls class FGAirportDynamics; +class FGRunway; + +typedef SGSharedPtr FGRunwayPtr; /*************************************************************************************** * @@ -81,32 +84,34 @@ public: void setId(const std::string& id) { _id = id; } void setMetar(bool value) { _has_metar = value; } - FGRunway getActiveRunwayForUsage() const; + FGRunway* getActiveRunwayForUsage() const; FGAirportDynamics *getDynamics(); unsigned int numRunways() const; - FGRunway getRunwayByIndex(unsigned int aIndex) const; + FGRunway* getRunwayByIndex(unsigned int aIndex) const; bool hasRunwayWithIdent(const std::string& aIdent) const; - FGRunway getRunwayByIdent(const std::string& aIdent) const; - FGRunway findBestRunwayForHeading(double aHeading) const; + FGRunway* getRunwayByIdent(const std::string& aIdent) const; + FGRunway* findBestRunwayForHeading(double aHeading) const; unsigned int numTaxiways() const; - FGRunway getTaxiwayByIndex(unsigned int aIndex) const; + FGRunway* getTaxiwayByIndex(unsigned int aIndex) const; - void addRunway(const FGRunway& aRunway); + void addRunway(FGRunway* aRunway); private: + typedef std::vector::const_iterator Runway_iterator; + /** * Helper to locate a runway by ident */ - FGRunwayVector::const_iterator getIteratorForRunwayIdent(const std::string& aIdent, bool& aReversed) const; + Runway_iterator getIteratorForRunwayIdent(const std::string& aIdent) const; FGAirport operator=(FGAirport &other); FGAirport(const FGAirport&); - std::vector mRunways; - std::vector mTaxiways; + std::vector mRunways; + std::vector mTaxiways; }; diff --git a/src/Cockpit/hud.cxx b/src/Cockpit/hud.cxx index bee7a6011..e6903caab 100644 --- a/src/Cockpit/hud.cxx +++ b/src/Cockpit/hud.cxx @@ -47,6 +47,7 @@ #include // FGFontCache #include
#include +#include #include "hud.hxx" diff --git a/src/Cockpit/hud.hxx b/src/Cockpit/hud.hxx index 8c7d16328..831aa00f5 100644 --- a/src/Cockpit/hud.hxx +++ b/src/Cockpit/hud.hxx @@ -61,10 +61,11 @@ namespace osg { #include
#include
#include
-#include #include +class FGRunway; + using std::deque; using std::vector; @@ -509,7 +510,7 @@ private: bool drawLine(const sgdVec3& a1, const sgdVec3& a2, const sgdVec3& p1, const sgdVec3& p2); void drawArrow(); - bool get_active_runway(FGRunway& rwy); + FGRunway* get_active_runway(); void get_rwy_points(sgdVec3 *points); void setLineWidth(void); @@ -517,7 +518,7 @@ private: double mm[16],pm[16], arrowScale, arrowRad, lnScale; double scaleDist, default_pitch, default_heading; GLint view[4]; - FGRunway runway; + FGRunway* runway; FGViewer* cockpit_view; unsigned short stippleOut, stippleCen; bool drawIA, drawIAAlways; diff --git a/src/Cockpit/hud_rwy.cxx b/src/Cockpit/hud_rwy.cxx index 91fe234f8..fd216479b 100644 --- a/src/Cockpit/hud_rwy.cxx +++ b/src/Cockpit/hud_rwy.cxx @@ -82,7 +82,7 @@ runway_instr::runway_instr(const SGPropertyNode *node) : void runway_instr::draw() { - if (!is_broken() && get_active_runway(runway)) { + if (!is_broken() && (runway = get_active_runway())) { glPushAttrib(GL_LINE_STIPPLE | GL_LINE_STIPPLE_PATTERN | GL_LINE_WIDTH); float modelView[4][4], projMat[4][4]; bool anyLines; @@ -175,39 +175,38 @@ void runway_instr::draw() } -bool runway_instr::get_active_runway(FGRunway& runway) +FGRunway* runway_instr::get_active_runway() { const FGAirport* apt = fgFindAirportID(fgGetString("/sim/presets/airport-id")); - if (!apt) return false; + if (!apt) return NULL; - runway = apt->getActiveRunwayForUsage(); - return (!runway._rwy_no.empty()); + return apt->getActiveRunwayForUsage(); } void runway_instr::get_rwy_points(sgdVec3 *points3d) { double alt = current_aircraft.fdm_state->get_Runway_altitude() * SG_FEET_TO_METER; - double length = (runway._length / 2.0) * SG_FEET_TO_METER; - double width = (runway._width / 2.0) * SG_FEET_TO_METER; + double length = runway->lengthM() * 0.5; + double width = runway->widthM() * 0.5; double frontLat, frontLon, backLat, backLon,az, tempLat, tempLon; - geo_direct_wgs_84(alt, runway._lat, runway._lon, runway._heading, length, &backLat, &backLon, &az); + geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading, length, &backLat, &backLon, &az); sgGeodToCart(backLat * SG_DEGREES_TO_RADIANS, backLon * SG_DEGREES_TO_RADIANS, alt, points3d[4]); - geo_direct_wgs_84(alt, runway._lat, runway._lon, runway._heading + 180, length, &frontLat, &frontLon, &az); + geo_direct_wgs_84(alt, runway->_lat, runway->_lon, runway->_heading + 180, length, &frontLat, &frontLon, &az); sgGeodToCart(frontLat * SG_DEGREES_TO_RADIANS, frontLon * SG_DEGREES_TO_RADIANS, alt, points3d[5]); - geo_direct_wgs_84(alt, backLat, backLon, runway._heading + 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, backLat, backLon, runway->_heading + 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[0]); - geo_direct_wgs_84(alt, backLat, backLon, runway._heading - 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, backLat, backLon, runway->_heading - 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[1]); - geo_direct_wgs_84(alt, frontLat, frontLon, runway._heading - 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, frontLat, frontLon, runway->_heading - 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[2]); - geo_direct_wgs_84(alt, frontLat, frontLon, runway._heading + 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, frontLat, frontLon, runway->_heading + 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, points3d[3]); } @@ -387,8 +386,8 @@ void runway_instr::drawArrow() Point3D ac(0.0), rwy(0.0); ac.setlat(current_aircraft.fdm_state->get_Latitude_deg()); ac.setlon(current_aircraft.fdm_state->get_Longitude_deg()); - rwy.setlat(runway._lat); - rwy.setlon(runway._lon); + rwy.setlat(runway->_lat); + rwy.setlon(runway->_lon); float theta = GetHeadingFromTo(ac, rwy); theta -= fgGetDouble("/orientation/heading-deg"); theta = -theta; @@ -418,8 +417,8 @@ void runway_instr::setLineWidth() { //Calculate the distance from the runway, A double course, distance; - calc_gc_course_dist(Point3D(runway._lon * SGD_DEGREES_TO_RADIANS, - runway._lat * SGD_DEGREES_TO_RADIANS, 0.0), + calc_gc_course_dist(Point3D(runway->longitude() * SGD_DEGREES_TO_RADIANS, + runway->latitude() * SGD_DEGREES_TO_RADIANS, 0.0), Point3D(current_aircraft.fdm_state->get_Longitude(), current_aircraft.fdm_state->get_Latitude(), 0.0 ), &course, &distance); diff --git a/src/Instrumentation/HUD/HUD.hxx b/src/Instrumentation/HUD/HUD.hxx index ba0b4d4b1..c1a0e21a0 100644 --- a/src/Instrumentation/HUD/HUD.hxx +++ b/src/Instrumentation/HUD/HUD.hxx @@ -577,7 +577,7 @@ private: bool boundOutsidePoints(sgdVec3& v, sgdVec3& m); bool drawLine(const sgdVec3& a1, const sgdVec3& a2, const sgdVec3& p1, const sgdVec3& p2); void drawArrow(); - bool get_active_runway(FGRunway& rwy); + FGRunway* get_active_runway(); void get_rwy_points(sgdVec3 *points); void setLineWidth(); @@ -592,7 +592,7 @@ private: double _default_pitch; double _default_heading; GLint _view[4]; - FGRunway _runway; + FGRunway* _runway; FGViewer* _cockpit_view; unsigned short _stipple_out; // stipple pattern of the outline of the runway unsigned short _stipple_center; // stipple pattern of the center line of the runway diff --git a/src/Instrumentation/HUD/HUD_runway.cxx b/src/Instrumentation/HUD/HUD_runway.cxx index 286360cd2..d9b77665a 100644 --- a/src/Instrumentation/HUD/HUD_runway.cxx +++ b/src/Instrumentation/HUD/HUD_runway.cxx @@ -74,7 +74,8 @@ HUD::Runway::Runway(HUD *hud, const SGPropertyNode *node, float x, float y) : void HUD::Runway::draw() { - if (!get_active_runway(_runway)) + _runway = get_active_runway(); + if (!_runway) return; glPushAttrib(GL_LINE_STIPPLE | GL_LINE_STIPPLE_PATTERN | GL_LINE_WIDTH); @@ -168,13 +169,12 @@ void HUD::Runway::draw() } -bool HUD::Runway::get_active_runway(FGRunway& runway) +FGRunway* HUD::Runway::get_active_runway() { const FGAirport* apt = fgFindAirportID(fgGetString("/sim/presets/airport-id")); - if (!apt) return false; + if (!apt) return NULL; - runway = apt->getActiveRunwayForUsage(); - return (!runway._rwy_no.empty()); + return apt->getActiveRunwayForUsage(); } @@ -182,26 +182,26 @@ bool HUD::Runway::get_active_runway(FGRunway& runway) void HUD::Runway::get_rwy_points(sgdVec3 *_points3d) { double alt = current_aircraft.fdm_state->get_Runway_altitude() * SG_FEET_TO_METER; - double length = (_runway._length / 2.0) * SG_FEET_TO_METER; - double width = (_runway._width / 2.0) * SG_FEET_TO_METER; + double length = _runway->lengthM() * 0.5; + double width = _runway->widthM() * 0.5; double frontLat, frontLon, backLat, backLon,az, tempLat, tempLon; - geo_direct_wgs_84(alt, _runway._lat, _runway._lon, _runway._heading, length, &backLat, &backLon, &az); + geo_direct_wgs_84(alt, _runway->latitude(), _runway->longitude(), _runway->headingDeg(), length, &backLat, &backLon, &az); sgGeodToCart(backLat * SG_DEGREES_TO_RADIANS, backLon * SG_DEGREES_TO_RADIANS, alt, _points3d[4]); - geo_direct_wgs_84(alt, _runway._lat, _runway._lon, _runway._heading + 180, length, &frontLat, &frontLon, &az); + geo_direct_wgs_84(alt, _runway->latitude(), _runway->longitude(), _runway->headingDeg() + 180, length, &frontLat, &frontLon, &az); sgGeodToCart(frontLat * SG_DEGREES_TO_RADIANS, frontLon * SG_DEGREES_TO_RADIANS, alt, _points3d[5]); - geo_direct_wgs_84(alt, backLat, backLon, _runway._heading + 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, backLat, backLon, _runway->headingDeg() + 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, _points3d[0]); - geo_direct_wgs_84(alt, backLat, backLon, _runway._heading - 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, backLat, backLon, _runway->headingDeg() - 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, _points3d[1]); - geo_direct_wgs_84(alt, frontLat, frontLon, _runway._heading - 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, frontLat, frontLon, _runway->headingDeg() - 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, _points3d[2]); - geo_direct_wgs_84(alt, frontLat, frontLon, _runway._heading + 90, width, &tempLat, &tempLon, &az); + geo_direct_wgs_84(alt, frontLat, frontLon, _runway->headingDeg() + 90, width, &tempLat, &tempLon, &az); sgGeodToCart(tempLat * SG_DEGREES_TO_RADIANS, tempLon * SG_DEGREES_TO_RADIANS, alt, _points3d[3]); } @@ -380,8 +380,8 @@ void HUD::Runway::drawArrow() Point3D ac(0.0), rwy(0.0); ac.setlat(current_aircraft.fdm_state->get_Latitude_deg()); ac.setlon(current_aircraft.fdm_state->get_Longitude_deg()); - rwy.setlat(_runway._lat); - rwy.setlon(_runway._lon); + rwy.setlat(_runway->latitude()); + rwy.setlon(_runway->longitude()); float theta = GetHeadingFromTo(ac, rwy); theta -= fgGetDouble("/orientation/heading-deg"); theta = -theta; @@ -412,8 +412,8 @@ void HUD::Runway::setLineWidth() { //Calculate the distance from the runway, A double course, distance; - calc_gc_course_dist(Point3D(_runway._lon * SGD_DEGREES_TO_RADIANS, - _runway._lat * SGD_DEGREES_TO_RADIANS, 0.0), + calc_gc_course_dist(Point3D(_runway->longitude() * SGD_DEGREES_TO_RADIANS, + _runway->latitude() * SGD_DEGREES_TO_RADIANS, 0.0), Point3D(current_aircraft.fdm_state->get_Longitude(), current_aircraft.fdm_state->get_Latitude(), 0.0 ), &course, &distance); diff --git a/src/Instrumentation/KLN89/kln89_page_apt.cxx b/src/Instrumentation/KLN89/kln89_page_apt.cxx index 0be5c4acd..b370d54ad 100644 --- a/src/Instrumentation/KLN89/kln89_page_apt.cxx +++ b/src/Instrumentation/KLN89/kln89_page_apt.cxx @@ -28,6 +28,8 @@ #include "kln89_page_apt.hxx" #include #include
+#include + // This function is copied from Airports/runways.cxx // TODO - Make the original properly available and remove this instance!!!! @@ -202,8 +204,8 @@ void KLN89AptPage::Update(double dt) { // I guess we can make a heuristic guess as to fuel availability from the runway sizes // For now assume that airports with asphalt or concrete runways will have at least 100L, // and that runways over 4000ft will have JET. - if(_aptRwys[0]._surface_code <= 2) { - if(_aptRwys[0]._length >= 4000) { + if(_aptRwys[0]->_surface_code <= 2) { + if(_aptRwys[0]->lengthFt() >= 4000) { _kln89->DrawText("JET 100L", 2, 0, 1); } else { _kln89->DrawText("100L", 2, 0, 1); @@ -223,17 +225,17 @@ void KLN89AptPage::Update(double dt) { string s; if(i < _aptRwys.size()) { // Rwy No. - string s = _aptRwys[i]._rwy_no; + string s = _aptRwys[i]->ident(); _kln89->DrawText(s, 2, 9, 3); _kln89->DrawText("/", 2, 12, 3); _kln89->DrawText(GetReverseRunwayNo(s), 2, 13, 3); // Length - s = GPSitoa(int(float(_aptRwys[i]._length) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); + s = GPSitoa(int(float(_aptRwys[i]->lengthFt()) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); _kln89->DrawText(s, 2, 5 - s.size(), 2); _kln89->DrawText((_kln89->_altUnits == GPS_ALT_UNITS_FT ? "ft" : "m"), 2, 5, 2); // Surface // TODO - why not store these strings as an array? - switch(_aptRwys[i]._surface_code) { + switch(_aptRwys[i]->_surface_code) { case 1: // Asphalt - fall through case 2: @@ -271,17 +273,17 @@ void KLN89AptPage::Update(double dt) { i++; if(i < _aptRwys.size()) { // Rwy No. - string s = _aptRwys[i]._rwy_no; + string s = _aptRwys[i]->ident(); _kln89->DrawText(s, 2, 9, 1); _kln89->DrawText("/", 2, 12, 1); _kln89->DrawText(GetReverseRunwayNo(s), 2, 13, 1); // Length - s = GPSitoa(int(float(_aptRwys[i]._length) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); + s = GPSitoa(int(float(_aptRwys[i]->lengthFt()) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); _kln89->DrawText(s, 2, 5 - s.size(), 0); _kln89->DrawText((_kln89->_altUnits == GPS_ALT_UNITS_FT ? "ft" : "m"), 2, 5, 0); // Surface // TODO - why not store these strings as an array? - switch(_aptRwys[i]._surface_code) { + switch(_aptRwys[i]->_surface_code) { case 1: // Asphalt - fall through case 2: @@ -519,8 +521,8 @@ void KLN89AptPage::UpdateAirport(const string& id) { // build local array, longest runway first for (unsigned int r=0; rnumRunways(); ++r) { - FGRunway rwy(apt->getRunwayByIndex(r)); - if ((r > 0) && (rwy._length > _aptRwys.front()._length)) { + FGRunway* rwy(apt->getRunwayByIndex(r)); + if ((r > 0) && (rwy->lengthFt() > _aptRwys.front()->lengthFt())) { _aptRwys.insert(_aptRwys.begin(), rwy); } else { _aptRwys.push_back(rwy); diff --git a/src/Instrumentation/KLN89/kln89_page_apt.hxx b/src/Instrumentation/KLN89/kln89_page_apt.hxx index 2aef1bee7..33dd5603c 100644 --- a/src/Instrumentation/KLN89/kln89_page_apt.hxx +++ b/src/Instrumentation/KLN89/kln89_page_apt.hxx @@ -26,7 +26,7 @@ #include "kln89.hxx" -#include +class FGRunway; struct AptFreq { string service; @@ -60,7 +60,7 @@ private: string _save_apt_id; const FGAirport* ap; - vector _aptRwys; + vector _aptRwys; vector _aptFreqs; iap_list_type _iaps; diff --git a/src/Instrumentation/groundradar.cxx b/src/Instrumentation/groundradar.cxx index ee000f234..219c1c32b 100644 --- a/src/Instrumentation/groundradar.cxx +++ b/src/Instrumentation/groundradar.cxx @@ -112,14 +112,14 @@ void GroundRadar::createTexture(const char* texture_name) FGTextureManager::addTexture(texture_name, getTexture()); } -void GroundRadar::addRunwayVertices(const FGRunway& aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices) +void GroundRadar::addRunwayVertices(const FGRunway* aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices) { double az1, az2, dist_m; - geo_inverse_wgs_84(aTowerLat, aTowerLon, aRunway._lat, aRunway._lon, &az1, &az2, &dist_m); + geo_inverse_wgs_84(aTowerLat, aTowerLon, aRunway->latitude(), aRunway->longitude(), &az1, &az2, &dist_m); osg::Vec3 center = fromPolar(az1, dist_m * aScale) + osg::Vec3(256, 256, 0); - osg::Vec3 leftcenter = fromPolar(aRunway._heading, aRunway._length * SG_FEET_TO_METER * aScale / 2) + center; - osg::Vec3 lefttop = fromPolar(aRunway._heading - 90, aRunway._width * SG_FEET_TO_METER * aScale / 2) + leftcenter; + osg::Vec3 leftcenter = fromPolar(aRunway->headingDeg(), aRunway->lengthM() * aScale / 2) + center; + osg::Vec3 lefttop = fromPolar(aRunway->headingDeg() - 90, aRunway->widthM() * aScale / 2) + leftcenter; osg::Vec3 leftbottom = leftcenter * 2 - lefttop; osg::Vec3 rightbottom = center * 2 - lefttop; osg::Vec3 righttop = center * 2 - leftbottom; @@ -151,13 +151,15 @@ void GroundRadar::updateTexture() for (unsigned int i=0; inumRunways(); ++i) { - FGRunway runway(apt->getRunwayByIndex(i)); + FGRunway* runway(apt->getRunwayByIndex(i)); + if (runway->isReciprocal()) continue; + addRunwayVertices(runway, tower_lat, tower_lon, scale, rwy_vertices.get()); } for (unsigned int i=0; inumTaxiways(); ++i) { - FGRunway runway(apt->getTaxiwayByIndex(i)); + FGRunway* runway(apt->getTaxiwayByIndex(i)); addRunwayVertices(runway, tower_lat, tower_lon, scale, taxi_vertices.get()); } diff --git a/src/Instrumentation/groundradar.hxx b/src/Instrumentation/groundradar.hxx index 0836a526b..2a78cab59 100644 --- a/src/Instrumentation/groundradar.hxx +++ b/src/Instrumentation/groundradar.hxx @@ -43,7 +43,7 @@ public: protected: void createTexture(const char* texture_name); - void addRunwayVertices(const FGRunway& aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices); + void addRunwayVertices(const FGRunway* aRunway, double aTowerLat, double aTowerLon, double aScale, osg::Vec3Array* aVertices); osg::ref_ptr _geom; SGPropertyNode_ptr _airport_node; diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index 401af8a5b..1deabde7c 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -4260,13 +4260,9 @@ bool MK_VIII::Mode6Handler::test_airport (const FGAirport *airport) { for (unsigned int r=0; rnumRunways(); ++r) { - FGRunway rwy(airport->getRunwayByIndex(r)); + FGRunway* rwy(airport->getRunwayByIndex(r)); - if (test_runway(&rwy)) return true; - - // reciprocal runway - rwy._heading = get_reciprocal_heading(rwy._heading); - if (test_runway(&rwy)) return true; + if (test_runway(rwy)) return true; } return false; @@ -4497,33 +4493,15 @@ void MK_VIII::TCFHandler::select_runway (const FGAirport *airport, FGRunway *_runway) { -/* - FGRunway r; - bool status = globals->get_runways()->search(airport->getId(), &r); - assert(status); - - } - while (globals->get_runways()->next(&r) && r._id == airport->getId()); - */ - double min_diff = 360; for (unsigned int r=0; rnumRunways(); ++r) { - FGRunway rwy(airport->getRunwayByIndex(r)); - double diff = get_azimuth_difference(&rwy); + FGRunway* rwy(airport->getRunwayByIndex(r)); + double diff = get_azimuth_difference(rwy); if (diff < min_diff) { min_diff = diff; - *_runway = rwy; - } - - // reciprocal runway - rwy._heading = get_reciprocal_heading(rwy._heading); - diff = get_azimuth_difference(&rwy); - if (diff < min_diff) - { - min_diff = diff; - *_runway = rwy; + _runway = rwy; } } // of airport runways iteration } @@ -4531,7 +4509,7 @@ MK_VIII::TCFHandler::select_runway (const FGAirport *airport, bool MK_VIII::TCFHandler::AirportFilter::pass(FGAirport *a) { for (unsigned int r=0; rnumRunways(); ++r) { - if (a->getRunwayByIndex(r)._length >= mk->conf.runway_database) { + if (a->getRunwayByIndex(r)->lengthFt() >= mk->conf.runway_database) { return true; } } @@ -4561,15 +4539,15 @@ MK_VIII::TCFHandler::update_runway () has_runway = true; - FGRunway _runway; - select_runway(airport, &_runway); + FGRunway* _runway; + select_runway(airport, _runway); - runway.center.latitude = _runway._lat; - runway.center.longitude = _runway._lon; + runway.center.latitude = _runway->latitude(); + runway.center.longitude = _runway->longitude(); runway.elevation = airport->getElevation(); - double half_length_m = _runway._length / 2 * SG_FEET_TO_METER; + double half_length_m = _runway->lengthM() * 0.5; runway.half_length = half_length_m * SG_METER_TO_NM; // b3 ________________ b0 @@ -4579,8 +4557,8 @@ MK_VIII::TCFHandler::update_runway () // b2 b1 // get heading to runway threshold (h0) and end (h1) - runway.edges[0].heading = _runway._heading; - runway.edges[1].heading = get_reciprocal_heading(_runway._heading); + runway.edges[0].heading = _runway->headingDeg(); + runway.edges[1].heading = get_reciprocal_heading(_runway->headingDeg()); double az; @@ -4604,7 +4582,7 @@ MK_VIII::TCFHandler::update_runway () &runway.edges[1].position.longitude, &az); - double half_width_m = _runway._width / 2 * SG_FEET_TO_METER; + double half_width_m = _runway->widthM() * 0.5; // get position of threshold bias area edges (b0 and b1) get_bias_area_edges(&runway.edges[0].position, diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 1ec3e2960..98a459d10 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -764,20 +764,15 @@ static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { const FGAirport* apt = fgFindAirportID(id); if (!apt) return false; - FGRunway r = apt->findBestRunwayForHeading(tgt_hdg); - fgSetString("/sim/atc/runway", r._rwy_no.c_str()); + FGRunway* r = apt->findBestRunwayForHeading(tgt_hdg); + fgSetString("/sim/atc/runway", r->ident().c_str()); double lat2, lon2, az2; - double heading = r._heading; + double heading = r->headingDeg(); double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - SG_LOG( SG_GENERAL, SG_INFO, - "runway = " << r._lon << ", " << r._lat - << " length = " << r._length * SG_FEET_TO_METER - << " heading = " << azimuth ); - - geo_direct_wgs_84 ( 0, r._lat, r._lon, azimuth, r._length * SG_FEET_TO_METER * 0.5 + geo_direct_wgs_84 ( 0, r->latitude(), r->longitude(), azimuth, r->lengthM() * 0.5 - fgGetDouble("/sim/airport/runways/start-offset-m", 5.0), &lat2, &lon2, &az2 ); @@ -892,20 +887,15 @@ static bool fgSetPosFromAirportIDandRwy( const string& id, const string& rwy, bo return false; } - FGRunway r(apt->getRunwayByIdent(rwy)); - fgSetString("/sim/atc/runway", r._rwy_no.c_str()); + FGRunway* r(apt->getRunwayByIdent(rwy)); + fgSetString("/sim/atc/runway", r->ident().c_str()); double lat2, lon2, az2; - double heading = r._heading; + double heading = r->headingDeg(); double azimuth = heading + 180.0; while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - SG_LOG( SG_GENERAL, SG_INFO, - "runway = " << r._lon << ", " << r._lat - << " length = " << r._length * SG_FEET_TO_METER - << " heading = " << azimuth ); - - geo_direct_wgs_84 ( 0, r._lat, r._lon, azimuth, r._length * SG_FEET_TO_METER * 0.5 + geo_direct_wgs_84 ( 0, r->latitude(), r->longitude(), azimuth, r->lengthM() * 0.5 - fgGetDouble("/sim/airport/runways/start-offset-m", 5.0), &lat2, &lon2, &az2 ); diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 54ab04b17..2efab7388 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -214,7 +214,7 @@ bool fgNavDBInit( FGAirportList *airports, static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, double threshold ) { - double hdg = rwy->_heading; + double hdg = rwy->headingDeg(); hdg += 180.0; if ( hdg > 360.0 ) { hdg -= 360.0; @@ -222,8 +222,8 @@ static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, // calculate runway threshold point double thresh_lat, thresh_lon, return_az; - geo_direct_wgs_84 ( 0.0, rwy->_lat, rwy->_lon, hdg, - rwy->_length/2.0 * SG_FEET_TO_METER, + geo_direct_wgs_84 ( 0.0, rwy->latitude(), rwy->longitude(), hdg, + rwy->lengthM() * 0.5, &thresh_lat, &thresh_lon, &return_az ); // cout << "Threshold = " << thresh_lat << "," << thresh_lon << endl; @@ -249,7 +249,7 @@ static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, // cout << "orig heading = " << loc->get_multiuse() << endl; // cout << "new heading = " << rwy->_heading << endl; - double hdg_diff = loc->get_multiuse() - rwy->_heading; + double hdg_diff = loc->get_multiuse() - rwy->headingDeg(); // clamp to [-180.0 ... 180.0] if ( hdg_diff < -180.0 ) { @@ -261,7 +261,7 @@ static void update_loc_position( FGNavRecord *loc, FGRunway *rwy, if ( fabs(hdg_diff) <= threshold ) { loc->set_lat( nloc_lat ); loc->set_lon( nloc_lon ); - loc->set_multiuse( rwy->_heading ); + loc->set_multiuse( rwy->headingDeg() ); } } @@ -290,8 +290,8 @@ void fgNavDBAlignLOCwithRunway( FGAirportList *airports, FGNavList *loclist, FGAirport* airport = airports->search(parts[0]); if (!airport) continue; // not found - FGRunway r = airport->getRunwayByIdent(parts[1]); - update_loc_position( (*loc), &r, threshold ); + FGRunway* r = airport->getRunwayByIdent(parts[1]); + update_loc_position( (*loc), r, threshold ); ++loc; } ++freq; diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index a47bf5c1a..e449cdb89 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -555,24 +555,22 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args) // set runway hash naRef rwys = naNewHash(c); for (unsigned int r=0; rnumRunways(); ++r) { - FGRunway rwy(apt->getRunwayByIndex(r)); + FGRunway* rwy(apt->getRunwayByIndex(r)); naRef rwyid = naStr_fromdata(naNewString(c), - const_cast(rwy._rwy_no.c_str()), - rwy._rwy_no.length()); + const_cast(rwy->ident().c_str()), + rwy->ident().length()); naRef rwydata = naNewHash(c); #define HASHSET(s,l,n) naHash_set(rwydata, naStr_fromdata(naNewString(c),s,l),n) HASHSET("id", 2, rwyid); - HASHSET("lat", 3, naNum(rwy._lat)); - HASHSET("lon", 3, naNum(rwy._lon)); - HASHSET("heading", 7, naNum(rwy._heading)); - HASHSET("length", 6, naNum(rwy._length * SG_FEET_TO_METER)); - HASHSET("width", 5, naNum(rwy._width * SG_FEET_TO_METER)); - HASHSET("threshold1", 10, naNum(rwy._displ_thresh1 * SG_FEET_TO_METER)); - HASHSET("threshold2", 10, naNum(rwy._displ_thresh2 * SG_FEET_TO_METER)); - HASHSET("stopway1", 8, naNum(rwy._stopway1 * SG_FEET_TO_METER)); - HASHSET("stopway2", 8, naNum(rwy._stopway2 * SG_FEET_TO_METER)); + HASHSET("lat", 3, naNum(rwy->latitude())); + HASHSET("lon", 3, naNum(rwy->longitude())); + HASHSET("heading", 7, naNum(rwy->headingDeg())); + HASHSET("length", 6, naNum(rwy->lengthM())); + HASHSET("width", 5, naNum(rwy->widthM())); + HASHSET("threshold1", 10, naNum(rwy->_displ_thresh * SG_FEET_TO_METER)); + HASHSET("stopway1", 8, naNum(rwy->_stopway * SG_FEET_TO_METER)); #undef HASHSET naHash_set(rwys, rwyid, rwydata); }