Initial framing for reading in-scenery airport data.
This commit is contained in:
parent
a1a610f7d5
commit
1c015387ba
6 changed files with 168 additions and 18 deletions
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue