1
0
Fork 0

Initial framing for reading in-scenery airport data.

This commit is contained in:
jmt 2009-08-29 10:21:21 +00:00 committed by Tim Moore
parent a1a610f7d5
commit 1c015387ba
6 changed files with 168 additions and 18 deletions

View 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"));
}

View 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

View 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) {

View 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,9 +168,37 @@ 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;
std::vector<FGPavementPtr> mPavements;

View 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>
@ -25,10 +27,12 @@
#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;
}

View file

@ -16,23 +16,40 @@
#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