]> git.mxchange.org Git - flightgear.git/commitdiff
Initial framing for reading in-scenery airport data.
authorjmt <jmt>
Sat, 29 Aug 2009 10:21:21 +0000 (10:21 +0000)
committerTim Moore <timoore@redhat.com>
Wed, 2 Sep 2009 22:02:47 +0000 (00:02 +0200)
src/Airports/runways.cxx
src/Airports/runways.hxx
src/Airports/simple.cxx
src/Airports/simple.hxx
src/Airports/xmlloader.cxx
src/Airports/xmlloader.hxx

index e6f62d88bb03274d7e057c1b480bac1601c86612..346dc35bd7872371e8442e11ee5d4be19b1f3e52 100644 (file)
@@ -136,3 +136,7 @@ SGGeod FGRunway::threshold() const
   return pointOnCenterline(_displ_thresh * SG_FEET_TO_METER);
 }
 
+void FGRunway::processThreshold(SGPropertyNode* aThreshold)
+{
+  assert(ident() == aThreshold->getStringValue("rwy"));
+}
index 595c77b8bd53cc23145815ea9c3d2d539d02fd49..15d39c2af9fcd0eec6e6a4f9eafeffc6f1ab4787 100644 (file)
@@ -31,6 +31,7 @@
 // forward decls
 class FGAirport;
 class FGNavRecord;
+class SGPropertyNode;
 
 class FGRunway : public FGRunwayBase
 {
@@ -104,6 +105,11 @@ public:
   
   FGNavRecord* ILS() const { return _ils; }
   void setILS(FGNavRecord* nav) { _ils = nav; }
+  
+  /**
+   * Helper to process property data loaded from an ICAO.threshold.xml file
+   */
+  void processThreshold(SGPropertyNode* aThreshold);
 };
 
 #endif // _FG_RUNWAYS_HXX
index 04dec38b8d4286a29b3ec740298bda969fb28efe..95ce25af424e81e8cb154b5ff0309c7c03e0a48e 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/sg_inlines.h>
 
@@ -56,7 +57,8 @@ FGAirport::FGAirport(const string &id, const SGGeod& location, const SGGeod& tow
     _tower_location(tower_location),
     _name(name),
     _has_metar(has_metar),
-    _dynamics(0)
+    _dynamics(0),
+    mLoadedXML(false)
 {
 }
 
@@ -311,12 +313,73 @@ const FGAirport *fgFindAirportID( const string& id)
 }
 
 
+void FGAirport::loadSceneryDefintions() const
+{
+  mLoadedXML = true;
+  
+  // allow users to disable the scenery data in the short-term
+  // longer term, this option can probably disappear
+  if (fgGetBool("/sim/use-scenery-airport-data") == false) {
+    return; 
+  }
+  
+  SGPath path;
+  SGPropertyNode_ptr rootNode = new SGPropertyNode;
+  if (XMLLoader::findAirportData(ident(), "threshold", path)) {
+    readProperties(path.str(), rootNode);
+    const_cast<FGAirport*>(this)->readThresholdData(rootNode);
+  }
+  
+  // repeat for the tower data
+  rootNode = new SGPropertyNode;
+  if (XMLLoader::findAirportData(ident(), "twr", path)) {
+    readProperties(path.str(), rootNode);
+    const_cast<FGAirport*>(this)->readTowerData(rootNode);
+  }
+}
+
+void FGAirport::readThresholdData(SGPropertyNode* aRoot)
+{
+  SGPropertyNode* runway;
+  int runwayIndex = 0;
+  for (; (runway = aRoot->getChild("runway", runwayIndex)) != NULL; ++runwayIndex) {
+    SGPropertyNode* t0 = runway->getChild("threshold", 0),
+      *t1 = runway->getChild("threshold", 1);
+    assert(t0);
+    assert(t1); // too strict? mayeb we should finally allow single-ended runways
+    
+    processThreshold(t0);
+    processThreshold(t1);
+  } // of runways iteration
+}
+
+void FGAirport::processThreshold(SGPropertyNode* aThreshold)
+{
+  // first, let's identify the current runway
+  string id(aThreshold->getStringValue("rwy"));
+  if (!hasRunwayWithIdent(id)) {
+    SG_LOG(SG_GENERAL, SG_WARN, "FGAirport::processThreshold: "
+      "found runway not defined in the global data:" << ident() << "/" << id);
+    return;
+  }
+  
+  FGRunway* rwy = getRunwayByIdent(id);
+  rwy->processThreshold(aThreshold);
+}
+
+void FGAirport::readTowerData(SGPropertyNode* aRoot)
+{
+  SGPropertyNode* twrNode = aRoot->getChild("twr");
+  double lat = twrNode->getDoubleValue("lat"), 
+    lon = twrNode->getDoubleValue("lon"), 
+    elevM = twrNode->getDoubleValue("elev-m");
+    
+  _tower_location = SGGeod::fromDegM(lon, lat, elevM);
+}
+
 // get airport elevation
 double fgGetAirportElev( const string& id )
 {
-    SG_LOG( SG_GENERAL, SG_BULK,
-            "Finding elevation for airport: " << id );
-
     const FGAirport *a=fgFindAirportID( id);
     if (a) {
         return a->getElevation();
@@ -329,9 +392,6 @@ double fgGetAirportElev( const string& id )
 // get airport position
 SGGeod fgGetAirportPos( const string& id )
 {
-    SG_LOG( SG_ATC, SG_BULK,
-            "Finding position for airport: " << id );
-
     const FGAirport *a = fgFindAirportID( id);
 
     if (a) {
index 71fb97fb8b8cf4b4797607c1ff0e2ce2c7054dc4..60b54d0ff558d2889b1758200d681c9d65e2cc81 100644 (file)
@@ -39,6 +39,7 @@ class FGAirportDynamics;
 class FGRunway;
 class FGTaxiway;
 class FGPavement;
+class SGPropertyNode;
 
 typedef SGSharedPtr<FGRunway> FGRunwayPtr;
 typedef SGSharedPtr<FGTaxiway> FGTaxiwayPtr;
@@ -49,12 +50,6 @@ typedef SGSharedPtr<FGPavement> FGPavementPtr;
  **************************************************************************************/
 class FGAirport : public FGPositioned
 {
-private:
-    SGGeod _tower_location;
-    std::string _name;
-    bool _has_metar;
-    FGAirportDynamics *_dynamics;
-
 public:
     FGAirport(const std::string& id, const SGGeod& location, const SGGeod& tower, 
             const std::string& name, bool has_metar, Type aType);
@@ -173,8 +168,36 @@ private:
      */
     Runway_iterator getIteratorForRunwayIdent(const std::string& aIdent) const;
 
+    // disable these
     FGAirport operator=(FGAirport &other);
     FGAirport(const FGAirport&);
+  
+    /**
+     * helper to read airport data from the scenery XML files.
+     */
+    void loadSceneryDefintions() const;
+    
+    /**
+     * Helpers to process property data loaded from an ICAO.threshold.xml file
+     */
+    void readThresholdData(SGPropertyNode* aRoot);
+    void processThreshold(SGPropertyNode* aThreshold);
+    
+    /**
+     * Helper to parse property data loaded from an ICAO.twr.xml filke
+     */
+    void readTowerData(SGPropertyNode* aRoot);
+    
+    SGGeod _tower_location;
+    std::string _name;
+    bool _has_metar;
+    FGAirportDynamics *_dynamics;
+
+    /**
+     * This flag indicates if we have attempted to load data from the scenery
+     * storage to supplement the Apt.Dat information.
+     */
+    mutable bool mLoadedXML;
     
     std::vector<FGRunwayPtr> mRunways;
     std::vector<FGTaxiwayPtr> mTaxiways;
index de35f4d1338215d11db273257f828e633f0d641b..f2f81daf975178e4ae1fa589b872dbbaefd2ad52 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <simgear/misc/sg_path.hxx>
 
+#include <simgear/xml/easyxml.hxx>
+
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 
 #include "dynamics.hxx"
 #include "runwayprefs.hxx"
 
+using std::string;
+
 XMLLoader::XMLLoader() {}
 XMLLoader::~XMLLoader() {}
 
-string XMLLoader::expandICAODirs(const string in){
+string XMLLoader::expandICAODirs(const string& in){
      //cerr << "Expanding " << in << endl;
      if (in.size() == 4) {
           char buffer[11];
@@ -143,3 +147,39 @@ void XMLLoader::load(FGSidStar* p) {
         }
     }
 }
+
+bool XMLLoader::findAirportData(const std::string& aICAO, 
+    const std::string& aFileName, SGPath& aPath)
+{
+  string_list sc = globals->get_fg_scenery();
+  char buffer[128];
+  ::snprintf(buffer, 128, "%c/%c/%c/%s.%s.xml", 
+    aICAO[0], aICAO[1], aICAO[2], 
+    aICAO.c_str(), aFileName.c_str());
+
+  for (string_list_iterator it = sc.begin(); it != sc.end(); ++it) {
+    SGPath path(*it);
+    path.append("Airports");
+    path.append(string(buffer));
+    if (path.exists()) {
+      aPath = path;
+      return true;
+    } // of path exists
+  } // of scenery path iteration
+
+
+  return false;
+}
+
+bool XMLLoader::loadAirportXMLDataIntoVisitor(const string& aICAO, 
+    const string& aFileName, XMLVisitor& aVisitor)
+{
+  SGPath path;
+  if (!findAirportData(aICAO, aFileName, path)) {
+    return false;
+  }
+
+  readXML(path.str(), aVisitor);
+  return true;
+}
+
index eb066495f09a2c6fc52d6c664248cd49c4e64345..88ab5af8168e6239c6c198523e00e7448403f18b 100644 (file)
 #ifndef _XML_LOADER_HXX_
 #define _XML_LOADER_HXX_
 
-#include <simgear/xml/easyxml.hxx>
-
 class FGAirportDynamics;
 class FGRunwayPreference;
 class FGSidStar;
 
-
+class XMLVisitor; // ffrom easyxml.hxx
 
 class XMLLoader {
 public:
   XMLLoader();
   ~XMLLoader();
-  static string expandICAODirs(const string in);
+  static string expandICAODirs(const std::string& in);
+  
   static void load(FGRunwayPreference* p);
   static void load(FGAirportDynamics*  d);
   static void load(FGSidStar*          s);
   
+  /**
+   * Search the scenery for a file name of the form:
+   *   I/C/A/ICAO.filename.xml
+   * and parse it as an XML property list, passing the data to the supplied
+   * visitor. If no such file could be found, returns false, otherwise returns
+   * true. Other failures (malformed XML, etc) with throw an exception.
+   */
+  static bool loadAirportXMLDataIntoVisitor(const std::string& aICAO, 
+    const std::string& aFileName, XMLVisitor& aVisitor);
+  
+  /**
+   * Search the scenery for a file name of the form:
+   *   I/C/A/ICAO.filename.xml
+   * and return the corresponding SGPath if found (and true),
+   * or false and invalid path if no matching data could be found
+   */
+  static bool findAirportData(const std::string& aICAO, 
+    const std::string& aFileName, SGPath& aPath);
 };
 
 #endif