]> git.mxchange.org Git - flightgear.git/commitdiff
James Turner:
authorehofman <ehofman>
Thu, 11 Sep 2008 08:38:09 +0000 (08:38 +0000)
committerehofman <ehofman>
Thu, 11 Sep 2008 08:38:09 +0000 (08:38 +0000)
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.

30 files changed:
src/AIModel/AIFlightPlan.hxx
src/AIModel/AIFlightPlanCreate.cxx
src/AIModel/AIFlightPlanCreateCruise.cxx
src/ATCDCL/AILocalTraffic.cxx
src/ATCDCL/ATCutils.cxx
src/ATCDCL/ATCutils.hxx
src/ATCDCL/approach.cxx
src/ATCDCL/atis.cxx
src/ATCDCL/ground.cxx
src/ATCDCL/tower.cxx
src/Airports/apt_loader.cxx
src/Airports/dynamics.cxx
src/Airports/runwayprefs.cxx
src/Airports/runways.cxx
src/Airports/runways.hxx
src/Airports/simple.cxx
src/Airports/simple.hxx
src/Cockpit/hud.cxx
src/Cockpit/hud.hxx
src/Cockpit/hud_rwy.cxx
src/Instrumentation/HUD/HUD.hxx
src/Instrumentation/HUD/HUD_runway.cxx
src/Instrumentation/KLN89/kln89_page_apt.cxx
src/Instrumentation/KLN89/kln89_page_apt.hxx
src/Instrumentation/groundradar.cxx
src/Instrumentation/groundradar.hxx
src/Instrumentation/mk_viii.cxx
src/Main/fg_init.cxx
src/Navaids/navdb.cxx
src/Scripting/NasalSys.cxx

index 2229715659cef547127b27d551df07552d44bca8..593a83a5c7022352d0443bbbe92310d2c993b2ba 100644 (file)
@@ -24,7 +24,6 @@
 #include <string>
 
 #include <Airports/simple.hxx>
-#include <Airports/runways.hxx>
 #include <Navaids/awynet.hxx>
 
 #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 <waypoint*> wpt_vector_type;
   typedef wpt_vector_type::const_iterator wpt_vector_iterator;
 
index 89797696f3b7ac0d931fe287b7d0394b58328dc8..482d16aeef0e6b08708bfb5b313e151f64e6da0b 100644 (file)
@@ -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");
index d6d790978c940faf7b53183a8bb54da2b305537d..a12241268b19a77085cac789e23bf814859dc142 100755 (executable)
@@ -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;
index bcaab722e3ae18386c0da2f43ea79a3b3d90fdb1..63c1848c4042869ae0dc0f49016d9d9d6ad9ad78 100644 (file)
@@ -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, 
index c5a229fee1cf04b97c631a4d111b86e723eb4993..03ed9f43d14e654244c0f64a74a74583312385df 100644 (file)
@@ -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);
        }
        
index b5248b84a3342e48d6abebd0066ed1c86c80d377..7a53564a417b455d41229cef55903a0022b053ff 100644 (file)
@@ -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);
 
index c935cbc2903045ee537c534b1a835c7a340f45b5..6e75de47cd28c0b70beac0c901ccd8f974f5a00f 100644 (file)
@@ -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();
 }
 
 // ========================================================================
index 4f9d93de4047be78d906c1a5f86b64645ac598bd..d3be4ea23bfbe8fb9b42aa937fa2eec05ffe4b3a 100644 (file)
@@ -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()));
index 2a6643e00565a415427b3429249555dfeb380390..8f309e370264fa1c15c6595c3c4dc0f51b7ced70 100644 (file)
@@ -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
index e2b2ce605cdc72a0b5e657882ad2d8db7b8cb8f7..52d50f9a83c6ddc30656c0955e11cd260ae8b0f6 100644 (file)
@@ -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
index d3d6217f99c7814124f76d029fbac9d616e12425..1f92be4d5ed3b11be5058ccfdc8f4db5f758efe6 100644 (file)
@@ -100,7 +100,7 @@ bool fgAirportDBLoad( FGAirportList *airports,
     string line;
     char tmp[2049];
     tmp[2048] = 0;
-    vector<FGRunway> runways;
+    vector<FGRunwayPtr> 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 ) {
index 41b77bae1663f773d3b7a0bcb8ec7afecbf3a6e4..5f41b8d9ecfeb09571763c397e0f88ca06513b40 100644 (file)
@@ -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) {
index ae204474e46dc2a68b5cfce948006da5c51e4445..3572275c0d8534d9683e274c5b692c1832fed748 100644 (file)
@@ -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: " <<rwy._heading << endl;
                  //cerr << "Wind Speed  : " << windSpeed << endl;
                  if (hdgDiff > 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
index 589be2e999d9709ae088ebc36773f29c40c0dcad..cc2c350150c232212b220a9d0f431b5dea109776 100644 (file)
@@ -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;
 }
index 996f38045372a5dc3d7c4ae9cd59c9c8486c836c..a2cc2ae621e9b48c7922edf2fda91348b144645a 100644 (file)
 
 #include <simgear/compiler.h>
 
+#include <simgear/math/sg_geodesy.hxx>
+
+#include "Navaids/positioned.hxx"
+
 #include <string>
-#include <vector>
 
-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<FGRunway> FGRunwayVector;
-
 #endif // _FG_RUNWAYS_HXX
index 2ebfb8434579cd7f00f0838d4786ea4f7c958119..9a0a4dab40ca849962a2e6ff729dde35ef0dd4b8 100644 (file)
@@ -47,6 +47,7 @@
 #include <Main/fg_props.hxx>
 #include <Airports/runways.hxx>
 #include <Airports/dynamics.hxx>
+#include <Airports/runways.hxx>
 
 #include <string>
 
@@ -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) {
index bedbd7d9144f38799630dd71653766f582c128e4..2236b76607a3677262a2eae5cb90b8a0fa5f5fd3 100644 (file)
@@ -27,8 +27,6 @@
 #ifndef _FG_SIMPLE_HXX
 #define _FG_SIMPLE_HXX
 
-#include <simgear/math/point3d.hxx>
-
 #include <simgear/compiler.h>
 
 #include <string>
 #include <set>
 #include <vector>
 
-#include "Airports/runways.hxx"
+#include <simgear/math/point3d.hxx>
+
+#include "Navaids/positioned.hxx"
 
 // forward decls
 class FGAirportDynamics;
+class FGRunway;
+
+typedef SGSharedPtr<FGRunway> 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<FGRunwayPtr>::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<FGRunway> mRunways;
-    std::vector<FGRunway> mTaxiways;
+    std::vector<FGRunwayPtr> mRunways;
+    std::vector<FGRunwayPtr> mTaxiways;
 };
 
 
index bee7a6011d64cd63ad01acda58b090cc66af6f99..e6903caabbdb287910d472112eaefee5586bfb58 100644 (file)
@@ -47,6 +47,7 @@
 #include <GUI/new_gui.hxx>           // FGFontCache
 #include <Main/globals.hxx>
 #include <Scenery/scenery.hxx>
+#include <Airports/runways.hxx>
 
 #include "hud.hxx"
 
index 8c7d1632813282697f8639bbfa8f49e939ce7b25..831aa00f59c77817ce5a8e1c4c9850dc5a0769f8 100644 (file)
@@ -61,10 +61,11 @@ namespace osg {
 #include <Main/fg_props.hxx>
 #include <Main/globals.hxx>
 #include <Main/viewmgr.hxx>
-#include <Airports/runways.hxx>
 
 #include <plib/sg.h>
 
+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;
index 91fe234f8194159512ebadffea82381cadb10cc1..fd216479b6f7b21a72dece7533cd6fd52209b5af 100644 (file)
@@ -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);
index ba0b4d4b1f04f72c665167b7c03912fda96a1842..c1a0e21a0a3b422d9acf69fb531969ef5edeaadf 100644 (file)
@@ -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
index 286360cd25938b5125d8bb5e2ebdfb1ba95aa487..d9b77665a1ce93a8e236ac33906d44e8a38968d1 100644 (file)
@@ -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);
index 0be5c4acd185075a1fd1a2d91e00c990096a0eae..b370d54ad2b5a2afb910a178a4f879010af8039b 100644 (file)
@@ -28,6 +28,8 @@
 #include "kln89_page_apt.hxx"
 #include <ATCDCL/commlist.hxx>
 #include <Main/globals.hxx>
+#include <Airports/runways.hxx>
+
 
 // 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; r<apt->numRunways(); ++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);
index 2aef1bee79630fc3ed8d4acbc677be4ef163d6a1..33dd5603cd37d0cdebe651098c6c5f0c317907d9 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "kln89.hxx"
 
-#include <Airports/runways.hxx>
+class FGRunway;
 
 struct AptFreq {
        string service;
@@ -60,7 +60,7 @@ private:
        string _save_apt_id;
        const FGAirport* ap;
        
-       vector<FGRunway> _aptRwys;
+       vector<FGRunway*> _aptRwys;
        vector<AptFreq> _aptFreqs;
        
        iap_list_type _iaps;
index ee000f234207b18548513f0930f1b8905561fc0a..219c1c32b4a6fbf277be395d63a2bf2a8f87bcd8 100644 (file)
@@ -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; i<apt->numRunways(); ++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; i<apt->numTaxiways(); ++i)
     {
-      FGRunway runway(apt->getTaxiwayByIndex(i));
+      FGRunway* runway(apt->getTaxiwayByIndex(i));
       addRunwayVertices(runway, tower_lat, tower_lon, scale, taxi_vertices.get());
     }
     
index 0836a526b893c9ad79d7335f16fbbc19d9816105..2a78cab5903552b342b2209f163410344cc72131 100644 (file)
@@ -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<osg::Geometry> _geom;
     SGPropertyNode_ptr _airport_node;
index 401af8a5bd968a907d52cd74f103f2547acda17c..1deabde7c5ccd1f385a014c742c6a946bfa6f534 100755 (executable)
@@ -4260,13 +4260,9 @@ bool
 MK_VIII::Mode6Handler::test_airport (const FGAirport *airport)
 {
   for (unsigned int r=0; r<airport->numRunways(); ++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; r<airport->numRunways(); ++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; r<a->numRunways(); ++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,
index 1ec3e2960119f604be379e15e47471d6b5bafc48..98a459d10483c6c71abdd83319f42a219cc8b77e 100644 (file)
@@ -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 );
     
index 54ab04b17d19594b4684b2f2f63204a4f916edc6..2efab738876378aef4a2d8f7bbf05b71872c3594 100644 (file)
@@ -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;
index a47bf5c1a21a0b8d8cc23fa14ad217da37cf073a..e449cdb89523fb00f6b8624f4c02a63319712308 100644 (file)
@@ -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; r<apt->numRunways(); ++r) {
-      FGRunway rwy(apt->getRunwayByIndex(r));
+      FGRunway* rwy(apt->getRunwayByIndex(r));
       
       naRef rwyid = naStr_fromdata(naNewString(c),
-                    const_cast<char *>(rwy._rwy_no.c_str()),
-                    rwy._rwy_no.length());
+                    const_cast<char *>(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);
     }