]> git.mxchange.org Git - flightgear.git/commitdiff
Make FGTaxiNode and FGParking inherit FGPositioned.
authorJames Turner <zakalawe@mac.com>
Mon, 24 Sep 2012 23:31:17 +0000 (00:31 +0100)
committerJames Turner <zakalawe@mac.com>
Mon, 24 Sep 2012 23:31:17 +0000 (00:31 +0100)
In preparation for caching the groundnet in the NavCache, make taxi-nodes and parkings inherit from FGPositioned. As part of this, make them heap (as opposed to value) classes, disable their copy-constructors, remove many mutating operations, and give them real constructors.

17 files changed:
src/AIModel/AIFlightPlanCreate.cxx
src/AIModel/AIFlightPlanCreatePushBack.cxx
src/ATC/trafficcontrol.cxx
src/Airports/dynamicloader.cxx
src/Airports/dynamicloader.hxx
src/Airports/dynamics.cxx
src/Airports/dynamics.hxx
src/Airports/gnnode.cxx
src/Airports/gnnode.hxx
src/Airports/groundnetwork.cxx
src/Airports/groundnetwork.hxx
src/Airports/parking.cxx
src/Airports/parking.hxx
src/Main/positioninit.cxx
src/Navaids/positioned.cxx
src/Navaids/positioned.hxx
src/Scripting/NasalPositioned.cxx

index 30a6989720491ac9c0fba967376ca5e1b0ae7a76..c49b4abe8a6c7504e764ec779c22d4c63c5beb7b 100644 (file)
@@ -313,7 +313,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
         FGTaxiNode *tn =
             apt->getDynamics()->getGroundNetwork()->findNode(node);
         FGAIWaypoint *wpt =
-            createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
+            createOnGround(ac, buffer, tn->geod(), apt->getElevation(),
                            ac->getPerformance()->vTaxi());
         wpt->setRouteIndex(route);
         //cerr << "Nodes left " << taxiRoute->nodesLeft() << " ";
@@ -356,7 +356,7 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac,
 
     FGParking* parkPos = aAirport->getDynamics()->getParking(gateId);
     if (parkPos) {
-        wpt = createOnGround(ac, "ENDtaxi", parkPos->getGeod(), airportElev,
+        wpt = createOnGround(ac, "ENDtaxi", parkPos->geod(), airportElev,
                          ac->getPerformance()->vTaxi());
         pushBackWaypoint(wpt);
     }
@@ -419,7 +419,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
         snprintf(buffer, 10, "%d", node);
         FGTaxiNode *tn = gn->findNode(node);
         FGAIWaypoint *wpt =
-            createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
+            createOnGround(ac, buffer, tn->geod(), apt->getElevation(),
                            ac->getPerformance()->vTaxi());
         wpt->setRouteIndex(route);
         pushBackWaypoint(wpt);
@@ -969,14 +969,14 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
             if (!tn)
                 break;
             
-            double dist = SGGeodesy::distanceM(coord, tn->getGeod());
+            double dist = SGGeodesy::distanceM(coord, tn->geod());
             if (dist < (min + 0.75)) {
                 break;
             }
             min = dist;
         }
         if (tn) {
-            wpt = createOnGround(ac, buffer, tn->getGeod(), currElev, vTaxi);
+            wpt = createOnGround(ac, buffer, tn->geod(), currElev, vTaxi);
             pushBackWaypoint(wpt);
         }
     }
@@ -1024,18 +1024,18 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
     double az; // unused
     SGGeod pos;
   
-    SGGeodesy::direct(parking->getGeod(), heading, 2.2 * parking->getRadius(),
+    SGGeodesy::direct(parking->geod(), heading, 2.2 * parking->getRadius(),
                       pos, az);
   
     wpt = createOnGround(ac, "taxiStart", pos, aptElev, vTaxiReduced);
     pushBackWaypoint(wpt);
 
-    SGGeodesy::direct(parking->getGeod(), heading, 0.1 * parking->getRadius(),
+    SGGeodesy::direct(parking->geod(), heading, 0.1 * parking->getRadius(),
                     pos, az);
     wpt = createOnGround(ac, "taxiStart2", pos, aptElev, vTaxiReduced);
     pushBackWaypoint(wpt);
 
-    wpt = createOnGround(ac, "END-Parking", parking->getGeod(), aptElev,
+    wpt = createOnGround(ac, "END-Parking", parking->geod(), aptElev,
                        vTaxiReduced);
     pushBackWaypoint(wpt);
     return true;
index 07d7eeca18f37239237811fcd0003d19b1f7f383..7ebdd7af1e1d39c017c6885ca7570de07408ee4d 100644 (file)
@@ -93,8 +93,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
         FGTaxiRoute route;
         //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
         route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
-        parking->setPushBackRoute(new FGTaxiRoute(route));
-
+        parking->setPushBackRoute(std::auto_ptr<FGTaxiRoute>(new FGTaxiRoute(route)));
 
         pushBackRoute = parking->getPushBackRoute();
         int size = pushBackRoute->size();
@@ -111,7 +110,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
             FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
             //ids.pop_back();
             //wpt = new waypoint;
-            FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->getGeod(), dep->getElevation(), vTaxiBackward);
+            FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->geod(), dep->getElevation(), vTaxiBackward);
 
             wpt->setRouteIndex(rte);
             pushBackWaypoint(wpt);
@@ -126,34 +125,29 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
 
         //cerr << "Creating final push forward point for gate " << gateId << endl;
         FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
-        FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
-        FGTaxiSegmentVectorIterator te = tn->getEndRoute();
-        // if the starting node equals the ending node, then there aren't any routes for this parking.
+        // there aren't any routes for this parking.
         // in cases like these we should flag the gate as being inoperative and return false
-        if (ts == te) {
+        if (tn->arcs().empty()) {
             SG_LOG(SG_AI, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
             parking->setAvailable(false);
             return false;
         }
-        tn = (*ts)->getEnd();
-        lastNodeVisited = tn->getIndex();
-        if (tn == NULL) {
-            SG_LOG(SG_AI, SG_ALERT, "No valid taxinode found");
-            exit(1);
-        }
-        double distance = (*ts)->getLength();
+      
+        FGTaxiSegment* pushForwardSegment = tn->arcs().front();
+        lastNodeVisited = pushForwardSegment->getEnd()->getIndex();
+        double distance = pushForwardSegment->getLength();
 
         double parkingHeading = parking->getHeading();
       
         for (int i = 1; i < 10; i++) {
             SGGeod pushForwardPt;
-            SGGeodesy::direct(parking->getGeod(), parkingHeading,
+            SGGeodesy::direct(parking->geod(), parkingHeading,
                               ((i / 10.0) * distance), pushForwardPt, az2);
             char buffer[16];
             snprintf(buffer, 16, "pushback-%02d", i);
             FGAIWaypoint *wpt = createOnGround(ac, string(buffer), pushForwardPt, dep->getElevation(), vTaxiReduced);
 
-            wpt->setRouteIndex((*ts)->getIndex());
+            wpt->setRouteIndex(pushForwardSegment->getIndex());
             pushBackWaypoint(wpt);
         }
         // cerr << "Done " << endl;
index 0c4e2e5d7f4e73660226d094e792418272e714dd..c71dd034dcd6664ffddfb1b01c21941279890461 100644 (file)
@@ -1340,10 +1340,10 @@ void FGStartupController::render(bool visible)
                 if (pos > 0) {
                     FGTaxiSegment *segment  = parent->getGroundNetwork()->findSegment(pos);
                     SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
-                    SGGeod end  (SGGeod::fromDeg(segment->getEnd()->getLongitude(), segment->getEnd()->getLatitude()));
+                    SGGeod end  (segment->getEnd()->geod());
 
                     double length = SGGeodesy::distanceM(start, end);
-                    //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
+                    //heading = SGGeodesy::headingDeg(start->geod(), end->geod());
 
                     double az2, heading; //, distanceM;
                     SGGeodesy::inverse(start, end, heading, az2, length);
@@ -1428,7 +1428,7 @@ void FGStartupController::render(bool visible)
                         double elevationStart = segment->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
                         double elevationEnd   = segment->getEnd  ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
                         if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
-                            SGGeod center2 = segment->getStart()->getGeod();
+                            SGGeod center2 = segment->getStart()->geod();
                             center2.setElevationM(SG_MAX_ELEVATION_M);
                             if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
                                 //elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
@@ -1440,7 +1440,7 @@ void FGStartupController::render(bool visible)
                             segment->getStart()->setElevation(elevationStart);
                         }
                         if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
-                            SGGeod center2 = segment->getEnd()->getGeod();
+                            SGGeod center2 = segment->getEnd()->geod();
                             center2.setElevationM(SG_MAX_ELEVATION_M);
                             if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
                                 //elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
@@ -1459,8 +1459,9 @@ void FGStartupController::render(bool visible)
 
                         //cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
-
-                        WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
+                        SGGeod segCenter(segment->getCenter());
+                        WorldCoordinate( obj_pos, segCenter.getLatitudeDeg(),
+                                        segCenter.getLongitudeDeg(), elevationMean + 0.5 + dx, -(segment->getHeading()), slope );
 
                         //WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) );
 
index 26af2b7112aacae5b55c4ce4869bf25306d8b530..2142a8622f8e2fb9e95a3e79038c94798c6763ac 100644 (file)
 
 #include "dynamicloader.hxx"
 
+/*****************************************************************************
+ * Helper function for parsing position string
+ ****************************************************************************/
+static double processPosition(const string &pos)
+{
+  string prefix;
+  string subs;
+  string degree;
+  string decimal;
+  int sign = 1;
+  double value;
+  subs = pos;
+  prefix= subs.substr(0,1);
+  if (prefix == string("S") || (prefix == string("W")))
+    sign = -1;
+  subs    = subs.substr(1, subs.length());
+  degree  = subs.substr(0, subs.find(" ",0));
+  decimal = subs.substr(subs.find(" ",0), subs.length());
+  
+  value = sign * (atof(degree.c_str()) + atof(decimal.c_str())/60.0);
+  return value;
+}
+
 FGAirportDynamicsXMLLoader::FGAirportDynamicsXMLLoader(FGAirportDynamics* dyn):
-    XMLVisitor(), _dynamics(dyn) {}
+    XMLVisitor(), _dynamics(dyn)
+{}
 
 void  FGAirportDynamicsXMLLoader::startXML () {
   //cout << "FGAirportDynamicsLoader::Start XML" << endl;
@@ -32,150 +56,142 @@ void  FGAirportDynamicsXMLLoader::endXML () {
   //cout << "End XML" << endl;
 }
 
-void  FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttributes &atts) {
-  // const char *attval;
-  FGParking park;
-  FGTaxiNode taxiNode;
-  FGTaxiSegment taxiSegment;
-  int index = 0;
-  string idxStr;
-  taxiSegment.setIndex(index);
-  //cout << "Start element " << name << endl;
-  string attname;
-  string value;
-  string gateName;
-  string gateNumber;
-  string attval;
-  string lat;
-  string lon;
-  int holdPointType;
-  int pushBackPoint;
+void FGAirportDynamicsXMLLoader::startParking(const XMLAttributes &atts)
+{
+  string type;
+  int index;
+  string gateName, gateNumber;
+  string lat, lon;
+  double heading = 0.0;
+  double radius = 1.0;
+  string airlineCodes;
+  int pushBackRoute = 0;
   
-  if (name == string("Parking"))
-    {
-      pushBackPoint = 0;
-      for (int i = 0; i < atts.size(); i++)
+  for (int i = 0; i < atts.size(); i++)
        {
-         //cout << "  " << atts.getName(i) << '=' << atts.getValue(i) << endl; 
-         attname = atts.getName(i);
-         if (attname == string("index")) {
-               park.setIndex(std::atoi(atts.getValue(i)));
-                idxStr = atts.getValue(i);
-          }
-         else if (attname == string("type"))
-           park.setType(atts.getValue(i));
-        else if (attname == string("name"))
-          gateName = atts.getValue(i);
-         else if (attname == string("number"))
+    string attname(atts.getName(i));
+         if (attname == "index") {
+      index = std::atoi(atts.getValue(i));
+    } else if (attname == "type")
+           type = atts.getValue(i);
+    else if (attname == "name")
+      gateName = atts.getValue(i);
+         else if (attname == "number")
            gateNumber = atts.getValue(i);
-         else if (attname == string("lat"))
-          park.setLatitude(atts.getValue(i));
-         else if (attname == string("lon"))
-           park.setLongitude(atts.getValue(i)); 
-         else if (attname == string("heading"))
-           park.setHeading(std::atof(atts.getValue(i)));
-         else if (attname == string("radius")) {
-           string radius = atts.getValue(i);
-           if (radius.find("M") != string::npos)
-             radius = radius.substr(0, radius.find("M",0));
-           //cerr << "Radius " << radius <<endl;
-           park.setRadius(std::atof(radius.c_str()));
+         else if (attname == "lat")
+      lat = atts.getValue(i);
+         else if (attname == "lon")
+           lon = atts.getValue(i);
+         else if (attname == "heading")
+           heading = std::atof(atts.getValue(i));
+         else if (attname == "radius") {
+           string radiusStr = atts.getValue(i);
+           if (radiusStr.find("M") != string::npos)
+             radiusStr = radiusStr.substr(0, radiusStr.find("M",0));
+           radius = std::atof(radiusStr.c_str());
          }
-         else if (attname == string("airlineCodes"))
-            park.setCodes(atts.getValue(i));
-          else if (attname == string("pushBackRoute")) {
-             pushBackPoint = std::atoi(atts.getValue(i));
-            //park.setPushBackPoint(std::atoi(atts.getValue(i)));
-
-           }
-       }
-      park.setPushBackPoint(pushBackPoint);
-      park.setName((gateName+gateNumber));
-      //cerr << "Parking " << idxStr << "( " << gateName << gateNumber << ") has pushBackPoint " << pushBackPoint << endl;
-      _dynamics->addParking(park);
+         else if (attname == "airlineCodes")
+      airlineCodes = atts.getValue(i);
+    else if (attname == "pushBackRoute") {
+      pushBackRoute = std::atoi(atts.getValue(i));      
     }
-  if (name == string("node")) 
-    {
-      for (int i = 0; i < atts.size() ; i++)
-       {
-         attname = atts.getName(i);
-         if (attname == string("index"))
-           taxiNode.setIndex(std::atoi(atts.getValue(i)));
-         if (attname == string("lat"))
-           taxiNode.setLatitude(atts.getValue(i));
-         if (attname == string("lon"))
-           taxiNode.setLongitude(atts.getValue(i));
-         if (attname == string("isOnRunway"))
-            taxiNode.setOnRunway((bool) std::atoi(atts.getValue(i)));
-         if (attname == string("holdPointType")) {
-            attval = atts.getValue(i);
-            if (attval==string("none")) {
-                holdPointType=0;
-            } else if (attval==string("normal")) {
-                 holdPointType=1;
-            } else if (attval==string("CAT II/III")) {
-                 holdPointType=3;
-            } else if (attval==string("PushBack")) {
-                 holdPointType=3;
-            } else {
-                 holdPointType=0;
-            }
-            //cerr << "Setting Holding point to " << holdPointType << endl;
-            taxiNode.setHoldPointType(holdPointType);
-          }
        }
-      _dynamics->getGroundNetwork()->addNode(taxiNode);
+  SGGeod pos(SGGeod::fromDeg(processPosition(lon), processPosition(lat)));
+  
+  FGParking* pk = new FGParking(0, index, pos, heading, radius,
+                                gateName + gateNumber, type, airlineCodes);
+  pk->setPushBackPoint(pushBackRoute);
+  _dynamics->addParking(pk);
+}
+
+void FGAirportDynamicsXMLLoader::startNode(const XMLAttributes &atts)
+{
+  int index;
+  string lat, lon;
+  bool onRunway;
+  int holdPointType;
+  
+  for (int i = 0; i < atts.size() ; i++)
+       {
+         string attname(atts.getName(i));
+         if (attname == "index")
+           index = std::atoi(atts.getValue(i));
+         else if (attname == "lat")
+      lat = atts.getValue(i);
+         else if (attname == "lon")
+           lon = atts.getValue(i);
+    else if (attname == "isOnRunway")
+      onRunway = (bool) std::atoi(atts.getValue(i));
+         else if (attname == "holdPointType") {
+      string attval = atts.getValue(i);
+      if (attval=="none") {
+        holdPointType=0;
+      } else if (attval=="normal") {
+        holdPointType=1;
+      } else if (attval=="CAT II/III") {
+        holdPointType=3;
+      } else if (attval=="PushBack") {
+        holdPointType=3;
+      } else {
+        holdPointType=0;
+      }
     }
-  if (name == string("arc")) 
-    {
-      taxiSegment.setIndex(++index);
-      for (int i = 0; i < atts.size() ; i++)
+       }
+  
+  SGGeod pos(SGGeod::fromDeg(processPosition(lon), processPosition(lat)));
+  FGTaxiNode* taxiNode = new FGTaxiNode(0, index, pos, onRunway, holdPointType);
+  _dynamics->getGroundNetwork()->addNode(taxiNode);
+}
+
+void FGAirportDynamicsXMLLoader::startArc(const XMLAttributes &atts)
+{  
+  int begin, end;
+  bool isPushBackRoute = false;
+  
+  for (int i = 0; i < atts.size() ; i++)
        {
-         attname = atts.getName(i);
-         if (attname == string("begin"))
-           taxiSegment.setStartNodeRef(std::atoi(atts.getValue(i)));
-         if (attname == string("end"))
-           taxiSegment.setEndNodeRef(std::atoi(atts.getValue(i)));
-          if (attname == string("isPushBackRoute"))
-           taxiSegment.setPushBackType((bool) std::atoi(atts.getValue(i)));
+         string attname = atts.getName(i);
+         if (attname == "begin")
+           begin = std::atoi(atts.getValue(i));
+         else if (attname == "end")
+           end = std::atoi(atts.getValue(i));
+    else if (attname == "isPushBackRoute")
+           isPushBackRoute = (bool) std::atoi(atts.getValue(i));
        }
-      _dynamics->getGroundNetwork()->addSegment(taxiSegment);
-    }
-  // sort by radius, in asending order, so that smaller gates are first in the list
+  
+  _dynamics->getGroundNetwork()->addSegment(new FGTaxiSegment(begin, end, isPushBackRoute));
 }
 
-void  FGAirportDynamicsXMLLoader::endElement (const char * name) {
-  //cout << "End element " << name << endl;
-  if (name == string("version")) {
-       _dynamics->getGroundNetwork()->addVersion(atoi(value.c_str()));
-       //std::cerr << "version" << value<< std::endl;
-  }
-  if (name == string("AWOS")) {
-       _dynamics->addAwosFreq(atoi(value.c_str()));
-       //cerr << "Adding AWOS" << value<< endl;
-  }
-  if (name == string("UNICOM")) {
-       _dynamics->addUnicomFreq(atoi(value.c_str()));
-       //cerr << "UNICOM" << value<< endl;
-  }
-if (name == string("CLEARANCE")) {
-       _dynamics->addClearanceFreq(atoi(value.c_str()));
-       //cerr << "Adding CLEARANCE" << value<< endl;
-  }
-if (name == string("GROUND")) {
-       _dynamics->addGroundFreq(atoi(value.c_str()));
-       //cerr << "Adding GROUND" << value<< endl;
+void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttributes &atts)
+{
+  if (!strcmp("Parking", name)) {
+    startParking(atts);
+  } else if (!strcmp("node", name)) {
+    startNode(atts);
+  } else if (!strcmp("arc", name)) {
+    startArc(atts);
   }
+}
 
-if (name == string("TOWER")) {
-       _dynamics->addTowerFreq(atoi(value.c_str()));
-      //cerr << "Adding TOWER" << value<< endl;
-  }
-if (name == string("APPROACH")) {
-       _dynamics->addApproachFreq(atoi(value.c_str()));
-       //cerr << "Adding approach" << value<< endl;
+void  FGAirportDynamicsXMLLoader::endElement (const char * name)
+{
+  int valueAsInt = atoi(value.c_str());
+  if (!strcmp("version", name)) {
+    _dynamics->getGroundNetwork()->addVersion(valueAsInt);
+  } else if (!strcmp("AWOS", name)) {
+    _dynamics->addAwosFreq(valueAsInt);
+  } else if (!strcmp("UNICOM", name)) {
+    _dynamics->addUnicomFreq(valueAsInt);
+  } else if (!strcmp("CLEARANCE", name)) {
+    _dynamics->addClearanceFreq(valueAsInt);
+  } else if (!strcmp("GROUND", name)) {
+    _dynamics->addGroundFreq(valueAsInt);
+  } else if (!strcmp("TOWER", name)) {
+    _dynamics->addTowerFreq(valueAsInt);
+  } else if (!strcmp("APPROACH", name)) {
+    _dynamics->addApproachFreq(valueAsInt);
   }
-
 }
 
 void  FGAirportDynamicsXMLLoader::data (const char * s, int len) {
index 672cda5af7c577be1840f423d3b71de0cd9182af..0584d06ac25b3a67e5e85a79fde1a5bb2d82dcd1 100644 (file)
@@ -35,6 +35,10 @@ protected:
     virtual void error (const char * message, int line, int column);
 
 private:
+    void startParking(const XMLAttributes &atts);    
+    void startNode(const XMLAttributes &atts);
+    void startArc(const XMLAttributes &atts);
+  
     FGAirportDynamics* _dynamics;
     string value;
 };
index 21d45d08be4296056321b0aa59ed221545d052bb..dde1983568d2520e0f8aab84f6d97d24fb22a7b6 100644 (file)
@@ -91,8 +91,7 @@ int FGAirportDynamics::innerGetAvailableParking(double radius, const string & fl
                                            const string & airline,
                                            bool skipEmptyAirlineCode)
 {
-  FGParkingVecIterator i;
-  for (i = parkings.begin(); i != parkings.end(); i++) {
+  BOOST_FOREACH(FGParking* i, parkings) {
     // Taken by another aircraft, or no airline codes
     if (!i->isAvailable()) {
       continue;
@@ -151,49 +150,43 @@ int FGAirportDynamics::getAvailableParking(double radius, const string & flType,
 
 FGParking *FGAirportDynamics::getParking(int id)
 {
-    FGParkingVecIterator i = parkings.begin();
-    for (i = parkings.begin(); i != parkings.end(); i++) {
-        if (id == i->getIndex()) {
-            return &(*i);
-        }
+  BOOST_FOREACH(FGParking* i, parkings) {
+    if (id == i->getIndex()) {
+      return i;
     }
-    return 0;
+  }
+  
+  return NULL;
 }
 
 string FGAirportDynamics::getParkingName(int id)
 {
-    FGParkingVecIterator i = parkings.begin();
-    for (i = parkings.begin(); i != parkings.end(); i++) {
-        if (id == i->getIndex()) {
-            return i->getName();
-        }
-    }
-
-    return string("overflow");
+  FGParking* p = getParking(id);
+  if (p) {
+    return p->getName();
+  }
+  
+  return string();
 }
 
 int FGAirportDynamics::findParkingByName(const std::string& name) const
 {
-  FGParkingVec::const_iterator i = parkings.begin();
-  for (i = parkings.begin(); i != parkings.end(); i++) {
-    if (i->getName() == name) {
+  BOOST_FOREACH(FGParking* i, parkings) {
+    if (name == i->getName()) {
       return i->getIndex();
     }
   }
-  
+
   return -1;
 }
 
 void FGAirportDynamics::releaseParking(int id)
 {
     if (id >= 0) {
-
-        FGParkingVecIterator i = parkings.begin();
-        for (i = parkings.begin(); i != parkings.end(); i++) {
-            if (id == i->getIndex()) {
-                i->setAvailable(true);
-            }
-        }
+      FGParking* parking = getParking(id);
+      if (parking) {
+        parking->setAvailable(true);
+      }
     }
 }
 
@@ -380,7 +373,7 @@ string FGAirportDynamics::chooseRunwayFallback()
     return rwy->ident();
 }
 
-void FGAirportDynamics::addParking(FGParking & park)
+void FGAirportDynamics::addParking(FGParking* park)
 {
     parkings.push_back(park);
 }
index cb489bfa3db458163ef71ac3cb01d0d91eedb8f3..33481b12cbe6db3ded5bbd66fe5a4682b3c6956e 100644 (file)
@@ -99,7 +99,7 @@ public:
   
     void getActiveRunway(const string& trafficType, int action, string& runway, double heading);
 
-    void addParking(FGParking& park);
+    void addParking(FGParking* park);
     
     /**
      * retrieve an available parking by GateID, or -1 if no suitable
index 691a420640a19e6078338d50260d2f7afebd38ad..41e746305cde34e123f89d50559c41a9e670cf52 100644 (file)
@@ -1,99 +1,63 @@
 #include "gnnode.hxx"
-#include "groundnetwork.hxx"
 
-#include <iostream>
-#include <algorithm>
+#include <boost/foreach.hpp>
+
+#include "groundnetwork.hxx"
 
-#include <osg/Geode>
 #include <Main/globals.hxx>
 #include <Scenery/scenery.hxx>
 
-using std::sort;
-using std::string;
-
-/*****************************************************************************
- * Helper function for parsing position string
- ****************************************************************************/
-double processPosition(const string &pos)
-{
-  string prefix;
-  string subs;
-  string degree;
-  string decimal;
-  int sign = 1;
-  double value;
-  subs = pos;
-  prefix= subs.substr(0,1);
-  if (prefix == string("S") || (prefix == string("W")))
-    sign = -1;
-  subs    = subs.substr(1, subs.length());
-  degree  = subs.substr(0, subs.find(" ",0));
-  decimal = subs.substr(subs.find(" ",0), subs.length());
-  
-             
-  //cerr << sign << " "<< degree << " " << decimal << endl;
-  value = sign * (atof(degree.c_str()) + atof(decimal.c_str())/60.0);
-  //cerr << value <<endl;
-  //exit(1);
-  return value;
-}
-
-//bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) {
-//  return a->hasSmallerHeadingDiff(*b);
-//}
-
-bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
-  return a->getLength() > b->getLength();
-}
-
 /**************************************************************************
  * FGTaxiNode
  *************************************************************************/
-void FGTaxiNode::setElevation(double val)
-{
-    geod.setElevationM(val);
-}
 
-void FGTaxiNode::setLatitude (double val)
+FGTaxiNode::FGTaxiNode(PositionedID aGuid, int index, const SGGeod& pos, bool aOnRunway, int aHoldType) :
+  FGPositioned(aGuid, FGPositioned::PARKING, "", pos),
+  index(index),
+  isOnRunway(aOnRunway),
+  holdType(aHoldType)
 {
-  geod.setLatitudeDeg(val);
+  
 }
 
-void FGTaxiNode::setLongitude(double val)
+FGTaxiNode::~FGTaxiNode()
 {
-  geod.setLongitudeDeg(val);
 }
 
-void FGTaxiNode::setLatitude (const string& val)
+void FGTaxiNode::setElevation(double val)
 {
-  geod.setLatitudeDeg(processPosition(val));
+  // ignored for the moment
 }
 
-void FGTaxiNode::setLongitude(const string& val)
-{
-  geod.setLongitudeDeg(processPosition(val));
-}
-  
 double FGTaxiNode::getElevationFt(double refelev)
 {
-    double elevF = geod.getElevationFt();
+    double elevF = elevation();
+#if 0
     double elevationEnd = 0;
     if ((elevF == 0) || (elevF == refelev)) {
-        SGGeod center2 = geod;
+        SGGeod center2 = mPosition;
         FGScenery * local_scenery = globals->get_scenery();
         center2.setElevationM(SG_MAX_ELEVATION_M);
         if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
             geod.setElevationM(elevationEnd);
         }
     }
-    //cerr << "Returning elevation : " << geod.getElevationM() << ". Ref elev (feet) = " << refelev << endl;
-    return geod.getElevationFt();
+#endif
+  return mPosition.getElevationFt();
 }
 
 double FGTaxiNode::getElevationM(double refelev)
 {
-    //double refelevFt = refelev * SG_METER_TO_FEET;
-    //double retval = getElevationFt(refelevFt);
-    //cerr << "Returning elevation : " << geod.getElevationM() << ". Ref elev (meters) = " << refelev << endl;
-    return geod.getElevationM();
+    return geod().getElevationM();
+}
+
+FGTaxiSegment* FGTaxiNode::getArcTo(FGTaxiNode* aEnd) const
+{
+  BOOST_FOREACH(FGTaxiSegment* arc, next) {
+    if (arc->getEnd() == aEnd) {
+      return arc;
+    }
+  }
+  
+  return NULL;
 }
index c64b51fd0fb51248a2d92d97229f3cbaa095b1b5..5902badfbb7cf342df2bab035fa77583983ef6d0 100644 (file)
 #include <string>
 
 #include <simgear/compiler.h>
-#include <simgear/math/sg_geodesy.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
+#include <Navaids/positioned.hxx>
 
 class FGTaxiSegment;
+
 typedef std::vector<FGTaxiSegment*>  FGTaxiSegmentVector;
 typedef FGTaxiSegmentVector::iterator FGTaxiSegmentVectorIterator;
 
 bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b);
 bool sortByLength     (FGTaxiSegment *a, FGTaxiSegment *b);
 
-class FGTaxiNode 
+class FGTaxiNode : public FGPositioned
 {
 protected:
-  SGGeod geod;
   int index;
 
   bool isOnRunway;
   int  holdType;
   FGTaxiSegmentVector next; // a vector of pointers to all the segments leaving from this node
 
-  // used in way finding
+  // used in way finding - should really move to a dynamic struct
   double pathScore;
   FGTaxiNode* previousNode;
   FGTaxiSegment* previousSeg;
 
 
-public:
-  FGTaxiNode() :
-      index(0),
-      isOnRunway(false),
-      holdType(0),
-      pathScore(0),
-      previousNode(0),
-      previousSeg(0)
-{
-};
-
-  FGTaxiNode(const FGTaxiNode &other) :
-      geod(other.geod),
-      index(other.index),
-      isOnRunway(other.isOnRunway),
-      holdType(other.holdType),
-      next(other.next),
-      pathScore(other.pathScore),
-      previousNode(other.previousNode),
-      previousSeg(other.previousSeg)
-{
-};
-
-FGTaxiNode &operator =(const FGTaxiNode &other)
-{
-   geod                               = other.geod;
-   index                              = other.index;
-   isOnRunway                         = other.isOnRunway;
-   holdType                           = other.holdType;
-   next                               = other.next;
-   pathScore                          = other.pathScore;
-   previousNode                       = other.previousNode;
-   previousSeg                        = other.previousSeg;
-   return *this;
-};
-
-  void setIndex(int idx)                  { index = idx;                 };
-  void setLatitude (double val);
-  void setLongitude(double val);
+public:    
+  FGTaxiNode(PositionedID aGuid, int index, const SGGeod& pos, bool aOnRunway, int aHoldType);
+  virtual ~FGTaxiNode();
+  
   void setElevation(double val);
-  void setLatitude (const std::string& val);
-  void setLongitude(const std::string& val);
   void addSegment(FGTaxiSegment *segment) { next.push_back(segment);     };
-  void setHoldPointType(int val)          { holdType = val;              };
-  void setOnRunway(bool val)              { isOnRunway = val;            };
 
   void setPathScore   (double val)         { pathScore    = val; };
   void setPreviousNode(FGTaxiNode *val)    { previousNode = val; };
@@ -99,26 +62,28 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
   FGTaxiSegment *getPreviousSegment() { return previousSeg;  };
 
   double getPathScore() { return pathScore; };
-  double getLatitude() { return geod.getLatitudeDeg();};
-  double getLongitude(){ return geod.getLongitudeDeg();};
-  double getElevationM (double refelev=0);
-  double getElevationFt(double refelev=0);
-
-  const SGGeod& getGeod() const { return geod; }
 
+  double getElevationM (double refelev);
+  double getElevationFt(double refelev);
+  
   int getIndex() const { return index; };
   int getHoldPointType() const { return holdType; };
   bool getIsOnRunway() const { return isOnRunway; };
 
-  FGTaxiNode *getAddress() { return this;};
-  FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
-  FGTaxiSegmentVectorIterator getEndRoute()   { return next.end();   }; 
+  const FGTaxiSegmentVector& arcs() const
+  { return next; }
+  
+  /// find the arg which leads from this node to another.
+  /// returns NULL if no such arc exists.
+  FGTaxiSegment* getArcTo(FGTaxiNode* aEnd) const;
+  
   bool operator<(const FGTaxiNode &other) const { return index < other.index; };
 
 
 };
 
-typedef std::vector<FGTaxiNode*> FGTaxiNodeVector;
+typedef SGSharedPtr<FGTaxiNode> FGTaxiNode_ptr;
+typedef std::vector<FGTaxiNode_ptr> FGTaxiNodeVector;
 typedef FGTaxiNodeVector::iterator FGTaxiNodeVectorIterator;
 
 #endif
index 62449b0cb13fe04cc6c499e0131630ec21609e27..c992f1e7b1e99420340ccdb3fbb0542e650dfab6 100644 (file)
@@ -27,7 +27,7 @@
 #include <math.h>
 #include <algorithm>
 #include <fstream>
-
+#include <boost/foreach.hpp>
 
 #include <osg/Geode>
 #include <osg/Geometry>
@@ -39,6 +39,7 @@
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/scene/util/OsgMath.hxx>
+#include <simgear/structure/exception.hxx>
 
 #include <Airports/simple.hxx>
 #include <Airports/dynamics.hxx>
@@ -59,64 +60,47 @@ using std::string;
  * FGTaxiSegment
  **************************************************************************/
 
-void FGTaxiSegment::setStart(FGTaxiNodeVector * nodes)
+FGTaxiSegment::FGTaxiSegment(int aStart, int aEnd, bool isPushBack) :
+  startNode(aStart),
+  endNode(aEnd),
+  length(0),
+  heading(0),
+  isActive(0),
+  isPushBackRoute(isPushBack),
+  start(0),
+  end(0),
+  index(0),
+  oppositeDirection(0)
 {
-    FGTaxiNodeVectorIterator i = nodes->begin();
-    while (i != nodes->end()) {
-        //cerr << "Scanning start node index" << (*i)->getIndex() << endl;
-        if ((*i)->getIndex() == startNode) {
-            start = (*i)->getAddress();
-            (*i)->addSegment(this);
-            return;
-        }
-        i++;
-    }
-    SG_LOG(SG_GENERAL, SG_ALERT,
-           "Could not find start node " << startNode << endl);
-}
+};
 
-void FGTaxiSegment::setEnd(FGTaxiNodeVector * nodes)
+bool FGTaxiSegment::bindToNodes(const IndexTaxiNodeMap& nodes)
 {
-    FGTaxiNodeVectorIterator i = nodes->begin();
-    while (i != nodes->end()) {
-        //cerr << "Scanning end node index" << (*i)->getIndex() << endl;
-        if ((*i)->getIndex() == endNode) {
-            end = (*i)->getAddress();
-            return;
-        }
-        i++;
-    }
-    SG_LOG(SG_GENERAL, SG_ALERT,
-           "Could not find end node " << endNode << endl);
+  IndexTaxiNodeMap::const_iterator it = nodes.find(startNode);
+  if (it == nodes.end()) {
+    return false;
+  }
+  
+  start = it->second;
+  
+  it = nodes.find(endNode);
+  if (it == nodes.end()) {
+    return false;
+  }
+  
+  end = it->second;
+  
+  start->addSegment(this);
+  double az2;
+  SGGeodesy::inverse(start->geod(), end->geod(), heading, az2, length);
+  return true;
 }
 
-
-
-// There is probably a computationally cheaper way of
-// doing this.
-void FGTaxiSegment::setDimensions(double elevation)
+SGGeod FGTaxiSegment::getCenter() const
 {
-    length = SGGeodesy::distanceM(start->getGeod(), end->getGeod());
-    //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
-
-    double az2; //, distanceM;
-    SGGeodesy::inverse(start->getGeod(), end->getGeod(), heading, az2, length);
-    double coveredDistance = length * 0.5;
-    SGGeodesy::direct(start->getGeod(), heading, coveredDistance, center, az2);
-    //start->setElevation(elevation);
-    //end->setElevation(elevation);
-    //cerr << "Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
+  return SGGeodesy::direct(start->geod(), heading, length * 0.5);
 }
 
-
-//void FGTaxiSegment::setCourseDiff(double crse)
-//{
-//    headingDiff = fabs(course - crse);
-
-//    if (headingDiff > 180)
-//        headingDiff = fabs(headingDiff - 360);
-//}
-
 void FGTaxiSegment::block(int id, time_t blockTime, time_t now)
 {
     BlockListIterator i = blockTimes.begin();
@@ -193,7 +177,7 @@ bool FGTaxiRoute::next(int *nde, int *rte)
         SG_LOG(SG_GENERAL, SG_ALERT,
                "ALERT: Misconfigured TaxiRoute : " << nodes.
                size() << " " << routes.size());
-        exit(1);
+      throw sg_range_exception("misconfigured taxi route");
     }
     if (currNode == nodes.end())
         return false;
@@ -237,15 +221,6 @@ void FGTaxiRoute::rewind(int route)
 /***************************************************************************
  * FGGroundNetwork()
  **************************************************************************/
-bool compare_nodes(FGTaxiNode * a, FGTaxiNode * b)
-{
-    return (*a) < (*b);
-}
-
-bool compare_segments(FGTaxiSegment * a, FGTaxiSegment * b)
-{
-    return (*a) < (*b);
-}
 
 bool compare_trafficrecords(FGTrafficRecord a, FGTrafficRecord b)
 {
@@ -344,11 +319,11 @@ void FGGroundNetwork::saveElevationCache() {
         }
     }
     cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
-    for (FGTaxiNodeVectorIterator node = nodes.begin();
+    for (IndexTaxiNodeMap::iterator node = nodes.begin();
             node != nodes.end(); node++) {
         if (saveData) {
-            cachefile << (*node)->getIndex     () << " "
-            << (*node)->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
+            cachefile << node->second->getIndex     () << " "
+            << node->second->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
             << endl;
         }
     }
@@ -357,33 +332,29 @@ void FGGroundNetwork::saveElevationCache() {
     }
 }
 
-void FGGroundNetwork::addSegment(const FGTaxiSegment & seg)
+void FGGroundNetwork::addSegment(FGTaxiSegment* seg)
 {
-    segments.push_back(new FGTaxiSegment(seg));
+    segments.push_back(seg);
 }
 
-void FGGroundNetwork::addNode(const FGTaxiNode & node)
+void FGGroundNetwork::addNode(FGTaxiNode* node)
 {
-    nodes.push_back(new FGTaxiNode(node));
+  assert(node);
+  IndexTaxiNodeMap::iterator it = nodes.find(node->getIndex());
+  if (it != nodes.end()) {
+    throw sg_range_exception();
+  }
+  
+  nodes.insert(it, std::make_pair(node->getIndex(), node));
 }
 
 void FGGroundNetwork::addNodes(FGParkingVec * parkings)
 {
-    FGTaxiNode n;
-    FGParkingVecIterator i = parkings->begin();
-    while (i != parkings->end()) {
-        n.setIndex(i->getIndex());
-        n.setLatitude(i->getLatitude());
-        n.setLongitude(i->getLongitude());
-        n.setElevation(parent->getElevation()*SG_FEET_TO_METER);
-        nodes.push_back(new FGTaxiNode(n));
-
-        i++;
-    }
+  BOOST_FOREACH(FGParking* parking, *parkings) {
+    addNode(parking);
+  }
 }
 
-
-
 void FGGroundNetwork::init()
 {
     if (networkInitialized) {
@@ -394,96 +365,77 @@ void FGGroundNetwork::init()
     hasNetwork = true;
     nextSave = 0;
     int index = 1;
-    sort(nodes.begin(), nodes.end(), compare_nodes);
-    //sort(segments.begin(), segments.end(), compare_segments());
-    FGTaxiSegmentVectorIterator i = segments.begin();
-    while (i != segments.end()) {
-        (*i)->setStart(&nodes);
-        (*i)->setEnd(&nodes);
-        (*i)->setDimensions(parent->getElevation() * SG_FEET_TO_METER);
-        (*i)->setIndex(index);
-        if ((*i)->isPushBack()) {
-            pushBackNodes.push_back((*i)->getEnd());
-        }
-        //SG_LOG(SG_GENERAL, SG_BULK,  "initializing segment " << (*i)->getIndex() << endl);
-        //SG_LOG(SG_GENERAL, SG_BULK, "Track distance = "     << (*i)->getLength() << endl);
-        //SG_LOG(SG_GENERAL, SG_BULK, "Track runs from "      << (*i)->getStart()->getIndex() << " to "
-        //                                                    << (*i)->getEnd()->getIndex() << endl);
-        i++;
-        index++;
-    }
-
-    i = segments.begin();
-    while (i != segments.end()) {
-        FGTaxiSegmentVectorIterator j = (*i)->getEnd()->getBeginRoute();
-        while (j != (*i)->getEnd()->getEndRoute()) {
-            if ((*j)->getEnd()->getIndex() == (*i)->getStart()->getIndex()) {
-//          int start1 = (*i)->getStart()->getIndex();
-//          int end1   = (*i)->getEnd()  ->getIndex();
-//          int start2 = (*j)->getStart()->getIndex();
-//          int end2   = (*j)->getEnd()->getIndex();
-//          int oppIndex = (*j)->getIndex();
-                //cerr << "Opposite of  " << (*i)->getIndex() << " (" << start1 << "," << end1 << ") "
-                //   << "happens to be " << oppIndex      << " (" << start2 << "," << end2 << ") " << endl;
-                (*i)->setOpposite(*j);
-                break;
-            }
-            j++;
-        }
-        i++;
+  
+  // bind segments to nodes
+    BOOST_FOREACH(FGTaxiSegment* segment, segments) {
+      if (!segment->bindToNodes(nodes)) {
+        SG_LOG(SG_GENERAL, SG_ALERT, "unable to bind taxiway segment");
+      }
+      
+      segment->setIndex(index++);
+      if (segment->isPushBack()) {
+        pushBackNodes.push_back(segment->getEnd());
+      }
+    }
+
+    // establish pairing of segments
+    BOOST_FOREACH(FGTaxiSegment* segment, segments) {
+      FGTaxiSegment* opp = segment->getEnd()->getArcTo(segment->getStart());
+      if (opp) {
+        segment->setOpposite(opp);
+      }
     }
-    //FGTaxiNodeVectorIterator j = nodes.begin();
-    //while (j != nodes.end()) {
-    //    if ((*j)->getHoldPointType() == 3) {
-    //        pushBackNodes.push_back((*j));
-    //    }
-    //    j++;
-    //}
-    //cerr << "Done initializing ground network" << endl;
-    //exit(1);
+
     if (fgGetBool("/sim/ai/groundnet-cache")) {
-        SGPath cacheData(globals->get_fg_home());
-        cacheData.append("ai");
-        string airport = parent->getId();
+        parseCache();
+    }
+  
+    networkInitialized = true;
+}
 
-        if ((airport) != "") {
-            char buffer[128];
-            ::snprintf(buffer, 128, "%c/%c/%c/",
-                       airport[0], airport[1], airport[2]);
-            cacheData.append(buffer);
-            if (!cacheData.exists()) {
-                cacheData.create_dir(0777);
-            }
-            int index;
-            double elev;
-            cacheData.append(airport + "-groundnet-cache.txt");
-            if (cacheData.exists()) {
-                ifstream data(cacheData.c_str());
-                string revisionStr;
-                data >> revisionStr;
-                if (revisionStr != "[GroundNetcachedata:ref:2011:09:04]") {
-                    SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " <<
-                           cacheData.c_str() << " for Airport " << airport);
-                } else {
-                    for (FGTaxiNodeVectorIterator i = nodes.begin();
-                            i != nodes.end();
-                            i++) {
-                        (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
-                        data >> index >> elev;
-                        if (data.eof())
-                            break;
-                        if (index != (*i)->getIndex()) {
-                            SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
-                        } else {
-                            (*i)->setElevation(elev);
-                        }
-                    }
-                }
-            }
+void FGGroundNetwork::parseCache()
+{
+  SGPath cacheData(globals->get_fg_home());
+  cacheData.append("ai");
+  string airport = parent->getId();
+  
+  if (airport.empty()) {
+    return;
+  }
+  
+  char buffer[128];
+  ::snprintf(buffer, 128, "%c/%c/%c/",
+             airport[0], airport[1], airport[2]);
+  cacheData.append(buffer);
+  if (!cacheData.exists()) {
+    cacheData.create_dir(0777);
+  }
+  int index;
+  double elev;
+  cacheData.append(airport + "-groundnet-cache.txt");
+  if (cacheData.exists()) {
+    ifstream data(cacheData.c_str());
+    string revisionStr;
+    data >> revisionStr;
+    if (revisionStr != "[GroundNetcachedata:ref:2011:09:04]") {
+      SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " <<
+             cacheData.c_str() << " for Airport " << airport);
+    } else {
+      for (IndexTaxiNodeMap::iterator i = nodes.begin();
+           i != nodes.end();
+           i++) {
+        i->second->setElevation(parent->elevation() * SG_FEET_TO_METER);
+        data >> index >> elev;
+        if (data.eof())
+          break;
+        if (index != i->second->getIndex()) {
+          SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
+        } else {
+          i->second->setElevation(elev);
         }
+      }
     }
-    //cerr << "Finished initializing " << parent->getId() << " groundnetwork " << endl;
-    networkInitialized = true;
+  }
 }
 
 int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
@@ -491,13 +443,12 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
     double minDist = HUGE_VAL;
     int index = -1;
 
-    for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
-            itr++) {
-        double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
+    IndexTaxiNodeMap::iterator i;
+    for (i = nodes.begin(); i != nodes.end(); i++) {
+        double d = SGGeodesy::distanceM(aGeod, i->second->geod());
         if (d < minDist) {
             minDist = d;
-            index = (*itr)->getIndex();
-            //cerr << "Minimum distance of " << minDist << " for index " << index << endl;
+            index = i->first;
         }
     }
 
@@ -509,42 +460,30 @@ int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
     double minDist = HUGE_VAL;
     int index = -1;
 
-    for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
-            itr++) {
-        if (!((*itr)->getIsOnRunway())) {
+    IndexTaxiNodeMap::iterator i;
+    for (i = nodes.begin(); i != nodes.end(); i++) {
+        if (!i->second->getIsOnRunway()) {
             continue;
         }
-        double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
+      
+        double d = SGGeodesy::distanceM(aGeod, i->second->geod());
         if (d < minDist) {
             minDist = d;
-            index = (*itr)->getIndex();
-            //cerr << "Minimum distance of " << minDist << " for index " << index << endl;
+            index = i->first;
         }
     }
 
     return index;
 }
 
-
-int FGGroundNetwork::findNearestNode(double lat, double lon)
-{
-    return findNearestNode(SGGeod::fromDeg(lon, lat));
-}
-
-FGTaxiNode *FGGroundNetwork::findNode(unsigned idx)
-{                               /*
-                                   for (FGTaxiNodeVectorIterator
-                                   itr = nodes.begin();
-                                   itr != nodes.end(); itr++)
-                                   {
-                                   if (itr->getIndex() == idx)
-                                   return itr->getAddress();
-                                   } */
-
-    if (idx < nodes.size())
-        return nodes[idx]->getAddress();
-    else
-        return 0;
+FGTaxiNode* FGGroundNetwork::findNode(unsigned int idx)
+{                               
+  IndexTaxiNodeMap::iterator i = nodes.find(idx);
+  if (i == nodes.end()) {
+    return NULL;
+  }
+  
+  return i->second;
 }
 
 FGTaxiSegment *FGGroundNetwork::findSegment(unsigned idx)
@@ -558,7 +497,7 @@ FGTaxiSegment *FGGroundNetwork::findSegment(unsigned idx)
                                    }
                                  */
     if ((idx > 0) && (idx <= segments.size()))
-        return segments[idx - 1]->getAddress();
+        return segments[idx - 1];
     else {
         //cerr << "Alert: trying to find invalid segment " << idx << endl;
         return 0;
@@ -575,18 +514,22 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
     //double INFINITE = 100000000000.0;
     // initialize scoring values
     int nParkings = parent->getDynamics()->getNrOfParkings();
-    FGTaxiNodeVector *currNodesSet;
+    FGTaxiNodeVector unvisited;
+  
     if (fullSearch) {
-        currNodesSet = &nodes;
+      // create vector from map values
+      IndexTaxiNodeMap::iterator i;
+      for (i = nodes.begin(); i != nodes.end(); i++) {
+        unvisited.push_back(i->second);
+      }
     } else {
-        currNodesSet = &pushBackNodes;
+        unvisited = pushBackNodes;
     }
-
-    for (FGTaxiNodeVectorIterator
-            itr = currNodesSet->begin(); itr != currNodesSet->end(); itr++) {
-        (*itr)->setPathScore(HUGE_VAL); //infinity by all practical means
-        (*itr)->setPreviousNode(0);     //
-        (*itr)->setPreviousSeg(0);      //
+  
+    BOOST_FOREACH(FGTaxiNode* node, unvisited) {
+        node->setPathScore(HUGE_VAL); //infinity by all practical means
+        node->setPreviousNode(0);     //
+        node->setPreviousSeg(0);      //
     }
 
     FGTaxiNode *firstNode = findNode(start);
@@ -608,49 +551,38 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
         return FGTaxiRoute();
     }
 
-    FGTaxiNodeVector unvisited(*currNodesSet);  // working copy
-
     while (!unvisited.empty()) {
-        FGTaxiNode *best = *(unvisited.begin());
-        for (FGTaxiNodeVectorIterator
-                itr = unvisited.begin(); itr != unvisited.end(); itr++) {
-            if ((*itr)->getPathScore() < best->getPathScore())
-                best = (*itr);
+        FGTaxiNode *best = unvisited.front();
+        BOOST_FOREACH(FGTaxiNode* i, unvisited) {
+            if (i->getPathScore() < best->getPathScore()) {
+                best = i;
+            }
         }
 
+      // remove 'best' from the unvisited set
         FGTaxiNodeVectorIterator newend =
             remove(unvisited.begin(), unvisited.end(), best);
         unvisited.erase(newend, unvisited.end());
 
         if (best == lastNode) { // found route or best not connected
             break;
-        } else {
-            for (FGTaxiSegmentVectorIterator
-                    seg = best->getBeginRoute();
-                    seg != best->getEndRoute(); seg++) {
-                if (fullSearch || (*seg)->isPushBack()) {
-                    FGTaxiNode *tgt = (*seg)->getEnd();
-                    if (!tgt)
-                    {
-                        SG_LOG(SG_GENERAL, SG_ALERT,
-                               "Error in ground network. Found empty segment "
-                               << " at " << ((parent) ? parent->getId() : "<unknown>"));
-                        return FGTaxiRoute();
-                    }
-                    double alt =
-                        best->getPathScore() + (*seg)->getLength() +
-                        (*seg)->getPenalty(nParkings);
-                    if (alt < tgt->getPathScore()) {    // Relax (u,v)
-                        tgt->setPathScore(alt);
-                        tgt->setPreviousNode(best);
-                        tgt->setPreviousSeg(*seg);      //
-                    }
-                } else {
-                    //   // cerr << "Skipping TaxiSegment " << (*seg)->getIndex() << endl;
-                }
-            }
         }
-    }
+      
+        BOOST_FOREACH(FGTaxiSegment* seg, best->arcs()) {
+            if (!fullSearch && !seg->isPushBack()) {
+              continue; // inelligible!
+            }
+          
+            FGTaxiNode *tgt = seg->getEnd();
+            double alt = best->getPathScore() + seg->getLength() +
+                    seg->getPenalty(nParkings);
+            if (alt < tgt->getPathScore()) {    // Relax (u,v)
+                tgt->setPathScore(alt);
+                tgt->setPreviousNode(best);
+                tgt->setPreviousSeg(seg);
+            }
+        } // of outgoing arcs/segments from current best node iteration
+    } // of unvisited nodes remaining
 
     if (lastNode->getPathScore() == HUGE_VAL) {
         // no valid route found
@@ -1080,7 +1012,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
     }
     bool origStatus = current->hasHoldPosition();
     current->setHoldPosition(false);
-    SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
+    //SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
     int currentRoute = i->getCurrentPosition();
     int nextRoute;
     if (i->getIntentions().size()) {
@@ -1100,7 +1032,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
         //   current->setHoldPosition(true);
         //}
         SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
-        SGGeod end  (SGGeod::fromDeg(nx->getStart()->getLongitude(), nx->getStart()->getLatitude()));
+        SGGeod end  (nx->getStart()->geod());
 
         double distance = SGGeodesy::distanceM(start, end);
         if (nx->hasBlock(now) && (distance < i->getRadius() * 4)) {
@@ -1379,10 +1311,10 @@ void FGGroundNetwork::render(bool visible)
             if (pos >= 0) {
 
                 SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
-                SGGeod end  (SGGeod::fromDeg(segments[pos]->getEnd()->getLongitude(), segments[pos]->getEnd()->getLatitude()));
+                SGGeod end  (segments[pos]->getEnd()->geod());
 
                 double length = SGGeodesy::distanceM(start, end);
-                //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
+                //heading = SGGeodesy::headingDeg(start->geod(), end->geod());
 
                 double az2, heading; //, distanceM;
                 SGGeodesy::inverse(start, end, heading, az2, length);
@@ -1466,7 +1398,7 @@ void FGGroundNetwork::render(bool visible)
                     double elevationStart = segments[k]->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
                     double elevationEnd   = segments[k]->getEnd  ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
                     if ((elevationStart == 0)  || (elevationStart == parent->getElevation())) {
-                        SGGeod center2 = segments[k]->getStart()->getGeod();
+                        SGGeod center2 = segments[k]->getStart()->geod();
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
 //                            elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5;
@@ -1478,7 +1410,7 @@ void FGGroundNetwork::render(bool visible)
                         segments[k]->getStart()->setElevation(elevationStart);
                     }
                     if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
-                        SGGeod center2 = segments[k]->getEnd()->getGeod();
+                        SGGeod center2 = segments[k]->getEnd()->geod();
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
 //                            elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5;
@@ -1497,8 +1429,8 @@ void FGGroundNetwork::render(bool visible)
 
                     // cerr << "2. Using mean elevation : " << elevationMean << " and " << slope << endl;
 
-
-                    WorldCoordinate( obj_pos, segments[k]->getLatitude(), segments[k]->getLongitude(), elevationMean+ 0.5, -(segments[k]->getHeading()), slope );
+                    SGGeod segCenter = segments[k]->getCenter();
+                    WorldCoordinate( obj_pos, segCenter.getLatitudeDeg(), segCenter.getLongitudeDeg(), elevationMean+ 0.5, -(segments[k]->getHeading()), slope );
 
                     obj_trans->setMatrix( obj_pos );
                     //osg::Vec3 center(0, 0, 0)
index b79bdfc69a0c1572f793883bf9e7cb73fd86f1de..35fd03c0d3354aeaf19a96005ef8e5a9339ec4bb 100644 (file)
 #ifndef _GROUNDNETWORK_HXX_
 #define _GROUNDNETWORK_HXX_
 
-#include <osg/Geode>
-#include <osg/Geometry>
-#include <osg/MatrixTransform>
-#include <osg/Shape>
-
-
 #include <simgear/compiler.h>
 
 #include <string>
 #include <vector>
 #include <list>
+#include <map>
 
 class Block;
 
@@ -48,10 +43,9 @@ class FGAIFlightPlan; // forward reference
 class FGAirport;      // forward reference
 
 typedef std::vector<FGTaxiSegment*>  FGTaxiSegmentVector;
-typedef std::vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
+typedef FGTaxiSegmentVector::iterator FGTaxiSegmentVectorIterator;
 
-//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
-//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
+typedef std::map<int, FGTaxiNode_ptr> IndexTaxiNodeMap;
 
 class Block
 {
@@ -82,7 +76,6 @@ private:
     int endNode;
     double length;
     double heading;
-    SGGeod center;
     bool isActive;
     bool isPushBackRoute;
     BlockList blockTimes;
@@ -91,75 +84,19 @@ private:
     int index;
     FGTaxiSegment *oppositeDirection;
 
-
-
 public:
-    FGTaxiSegment() :
-            startNode(0),
-            endNode(0),
-            length(0),
-            heading(0),
-            isActive(0),
-            isPushBackRoute(0),
-            start(0),
-            end(0),
-            index(0),
-            oppositeDirection(0)
-    {
-    };
-
-    FGTaxiSegment         (const FGTaxiSegment &other) :
-            startNode         (other.startNode),
-            endNode           (other.endNode),
-            length            (other.length),
-            heading           (other.heading),
-            center            (other.center),
-            isActive          (other.isActive),
-            isPushBackRoute   (other.isPushBackRoute),
-            blockTimes        (other.blockTimes),
-            start             (other.start),
-            end               (other.end),
-            index             (other.index),
-            oppositeDirection (other.oppositeDirection)
-    {
-    };
-
-    FGTaxiSegment& operator=(const FGTaxiSegment &other)
-    {
-        startNode          = other.startNode;
-        endNode            = other.endNode;
-        length             = other.length;
-        heading            = other.heading;
-        center             = other.center;
-        isActive           = other.isActive;
-        isPushBackRoute    = other.isPushBackRoute;
-        blockTimes         = other.blockTimes;
-        start              = other.start;
-        end                = other.end;
-        index              = other.index;
-        oppositeDirection  = other.oppositeDirection;
-        return *this;
-    };
-
+  FGTaxiSegment(int start, int end, bool isPushBack);
+  
     void setIndex        (int val) {
         index     = val;
     };
-    void setStartNodeRef (int val) {
-        startNode = val;
-    };
-    void setEndNodeRef   (int val) {
-        endNode   = val;
-    };
 
     void setOpposite(FGTaxiSegment *opp) {
         oppositeDirection = opp;
     };
 
-    void setStart(FGTaxiNodeVector *nodes);
-    void setEnd  (FGTaxiNodeVector *nodes);
-    void setPushBackType(bool val) {
-        isPushBackRoute = val;
-    };
+    bool bindToNodes(const IndexTaxiNodeMap& nodes);
+  
     void setDimensions(double elevation);
     void block(int id, time_t blockTime, time_t now);
     void unblock(time_t now); 
@@ -177,12 +114,10 @@ public:
     int getIndex() {
         return index;
     };
-    double getLatitude()  {
-        return center.getLatitudeDeg();
-    };
-    double getLongitude() {
-        return center.getLongitudeDeg();
-    };
+  
+    // compute the center of the arc
+    SGGeod getCenter() const;
+  
     double getHeading()   {
         return heading;
     };
@@ -192,10 +127,6 @@ public:
 
     int getPenalty(int nGates);
 
-    FGTaxiSegment *getAddress() {
-        return this;
-    };
-
     bool operator<(const FGTaxiSegment &other) const {
         return index < other.index;
     };
@@ -203,11 +134,6 @@ public:
     FGTaxiSegment *opposite() {
         return oppositeDirection;
     };
-    void setCourseDiff(double crse);
-
-
-
-
 };
 
 
@@ -304,12 +230,12 @@ private:
     //int maxDepth;
     int count;
     int version;
-    FGTaxiNodeVector    nodes;
-    FGTaxiNodeVector    pushBackNodes;
+  
+    IndexTaxiNodeMap nodes;
+    FGTaxiNodeVector pushBackNodes;
+  
     FGTaxiSegmentVector segments;
-    //intVec route;
-    //intVec nodesStack;
-    //intVec routesStack;
+
     TaxiRouteVector routes;
     TrafficVector activeTraffic;
     TrafficVectorIterator currTraffic;
@@ -328,14 +254,14 @@ private:
                            double heading, double speed, double alt);
 
 
-
+    void parseCache();
 public:
     FGGroundNetwork();
     ~FGGroundNetwork();
 
-    void addNode   (const FGTaxiNode& node);
+    void addNode   (FGTaxiNode* node);
     void addNodes  (FGParkingVec *parkings);
-    void addSegment(const FGTaxiSegment& seg);
+    void addSegment(FGTaxiSegment* seg);
     void setVersion (int v) { version = v;};
     
     int getVersion() { return version; };
@@ -348,7 +274,6 @@ public:
         towerController = twrCtrlr;
     };
 
-    int findNearestNode(double lat, double lon);
     int findNearestNode(const SGGeod& aGeod);
     int findNearestNodeOnRunway(const SGGeod& aGeod);
 
index d1fb6512f5978c4d78c09b7a940807f76931beab..58928dfcfa0863492199131c4a7a296679728ddc 100644 (file)
 /*********************************************************************************
  * FGParking
  ********************************************************************************/
-// FGParking::FGParking(double lat,
-//                  double lon,
-//                  double hdg,
-//                  double rad,
-//                  int idx,
-//                  const string &name,
-//                  const string &tpe,
-//                  const string &codes)
-//   : FGTaxiNode(lat,lon,idx)
-// {
-//   heading      = hdg;
-//   parkingName  = name;
-//   type         = tpe;
-//   airlineCodes = codes;
-// }
-FGParking::~FGParking() {
-     delete pushBackRoute; 
+
+FGParking::FGParking(PositionedID aGuid, int index, const SGGeod& pos,
+                     double aHeading, double aRadius,
+                     const std::string& name, const std::string& aType,
+                     const std::string& codes) :
+  FGTaxiNode(aGuid, index, pos, false, 0),
+  heading(aHeading),
+  radius(aRadius),
+  parkingName(name),
+  type(aType),
+  airlineCodes(codes),
+  available(true),
+  pushBackPoint(0)
+{
+}
+
+FGParking::~FGParking()
+{
 }
index 1d009c03cacbad84996188ec4b8af12b2e1685a5..c16038c5163c94fa4e7dd397066a0d01ab7cfc8f 100644 (file)
 #endif
 
 #include <simgear/compiler.h>
+#include <simgear/sg_inlines.h>
 
 #include <string>
 #include <vector>
+#include <memory> // for std::auto_ptr
 
 #include "gnnode.hxx"
 
 class FGTaxiRoute;
 
 
-class FGParking : public FGTaxiNode {
+class FGParking : public FGTaxiNode
+{
 private:
   double heading;
   double radius;
@@ -49,46 +52,15 @@ private:
  
   bool available;
   int pushBackPoint;
-  FGTaxiRoute *pushBackRoute;
+  std::auto_ptr<FGTaxiRoute> pushBackRoute;
 
+  SG_DISABLE_COPY(FGParking);
 public:
-  FGParking() :
-      heading(0),
-      radius(0),
-      available(true),
-      pushBackPoint(0),
-      pushBackRoute(0)
-  {
-  };
-
-  FGParking(const FGParking &other) :
-      FGTaxiNode   (other),
-      heading      (other.heading),
-      radius       (other.radius),
-      parkingName  (other.parkingName),
-      type         (other.type),
-      airlineCodes (other.airlineCodes),
-      available    (other.available),
-      pushBackPoint(other.pushBackPoint),
-      pushBackRoute(other.pushBackRoute)
-  {
-  };
-
-
-  FGParking& operator =(const FGParking &other)
-  {
-      FGTaxiNode::operator=(other);
-      heading      = other.heading;
-      radius       = other.radius;
-      parkingName  = other.parkingName;
-      type         = other.type;
-      airlineCodes = other.airlineCodes;
-      available    = other.available;
-      pushBackPoint= other.pushBackPoint;
-      pushBackRoute= other.pushBackRoute;
-      return *this;
-  };
-  ~FGParking();
+  FGParking(PositionedID aGuid, int index, const SGGeod& pos,
+            double heading, double radius,
+            const std::string& name, const std::string& type,
+            const std::string& codes);
+  virtual ~FGParking();
 
   void setHeading  (double hdg)  { heading     = hdg;  };
   void setRadius   (double rad)  { radius      = rad;  };
@@ -97,7 +69,7 @@ public:
   void setType     (const std::string& tpe)  { type        = tpe;  };
   void setCodes    (const std::string& codes){ airlineCodes= codes;};
 
-  void setPushBackRoute(FGTaxiRoute *val) { pushBackRoute = val; };
+  void setPushBackRoute(std::auto_ptr<FGTaxiRoute> val) { pushBackRoute = val; };
   void setPushBackPoint(int val)          { pushBackPoint = val; };
 
   bool isAvailable ()   const { return available;};
@@ -110,7 +82,7 @@ public:
   std::string getCodes    () const { return airlineCodes;};
   std::string getName     () const { return parkingName; };
 
-  FGTaxiRoute * getPushBackRoute () { return pushBackRoute; };
+  FGTaxiRoute * getPushBackRoute () { return pushBackRoute.get(); };
 
   int getPushBackPoint () { return pushBackPoint; };
 
@@ -118,8 +90,8 @@ public:
     return radius < other.radius; };
 };
 
-typedef std::vector<FGParking> FGParkingVec;
-typedef std::vector<FGParking>::iterator FGParkingVecIterator;
-typedef std::vector<FGParking>::const_iterator FGParkingVecConstIterator;
+typedef std::vector<FGParking*> FGParkingVec;
+typedef FGParkingVec::iterator FGParkingVecIterator;
+typedef FGParkingVec::const_iterator FGParkingVecConstIterator;
 
 #endif
index fd5db70b1069253774454940766f7188f4d41848..d4cdd179935df5134fccc0da95e0602de85c9afa 100644 (file)
@@ -223,7 +223,7 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
   
   FGParking* parking = dcs->getParking(gateID);
   parking->setAvailable(false);
-  fgApplyStartOffset(parking->getGeod(), parking->getHeading());
+  fgApplyStartOffset(parking->geod(), parking->getHeading());
   return true;
 }
 
index 8c47ea46b06a311492bfa17f91c9a83576da8d8b..974f7a980ee0863bc1772bdd54f4afb40598b499 100644 (file)
@@ -143,7 +143,7 @@ const char* FGPositioned::nameForType(Type aTy)
  case RUNWAY: return "runway";
  case TAXIWAY: return "taxiway";
  case PAVEMENT: return "pavement";
- case PARK_STAND: return "parking stand";
+ case PARKING: return "parking stand";
  case FIX: return "fix";
  case VOR: return "VOR";
  case NDB: return "NDB";
@@ -166,6 +166,7 @@ const char* FGPositioned::nameForType(Type aTy)
  case FREQ_CLEARANCE: return "clearance";
  case FREQ_UNICOM: return "unicom";
  case FREQ_APP_DEP: return "approach-departure";
+ case TAXI_NODE: return "taxi-node";
  default:
   return "unknown";
  }
index 7b7771b3f0b53ea444f386730901136566047f1e..e76ab83f674ddafc618a237d13291605a1a588b9 100644 (file)
@@ -25,6 +25,7 @@
 #include <vector>
 #include <stdint.h>
 
+#include <simgear/sg_inlines.h>
 #include <simgear/structure/SGSharedPtr.hxx>
 #include <simgear/math/SGMath.hxx>
 
@@ -48,7 +49,6 @@ public:
     RUNWAY,
     TAXIWAY,
     PAVEMENT,
-    PARK_STAND,
     WAYPOINT,
     FIX,
     NDB,
@@ -77,6 +77,9 @@ public:
     FREQ_ENROUTE,
     FREQ_CLEARANCE,
     FREQ_UNICOM,
+// groundnet items
+    PARKING,  ///< parking position - might be a gate, or stand
+    TAXI_NODE,
     LAST_TYPE
   } Type;
 
@@ -230,6 +233,9 @@ protected:
   const SGVec3d mCart;
   const Type mType;
   const std::string mIdent;
+  
+private:
+  SG_DISABLE_COPY(FGPositioned);
 };
 
 #endif // of FG_POSITIONED_HXX
index 3ec918cbdd92b9e9d3480c6766f4b3ab8e1fdae0..e6b56971ced6828d75bc1897c47db0590ccb9428 100644 (file)
@@ -1350,7 +1350,7 @@ static naRef f_airport_parking(naContext c, naRef me, int argc, naRef* args)
       continue;
     }
     
-    const SGGeod& parkLoc = park->getGeod();
+    const SGGeod& parkLoc = park->geod();
     naRef ph = naNewHash(c);
     hashset(c, ph, "name", stringToNasal(c, park->getName()));
     hashset(c, ph, "lat", naNum(parkLoc.getLatitudeDeg()));