1
0
Fork 0

Thomas Foerster:

I refactored the XML loading code out of FGAirportDynamics and
FGRunwayPreference. I also added a new class XMLLoader, which serves as a
facade to the loader functions. Further I changed FGRunwayPreference to just
keep a FGAirport ref, which is more concise and closer to the right(tm)
solution than storing the airport data a second time ;-)
This commit is contained in:
durk 2007-07-04 17:39:03 +00:00
parent bb634fcd2e
commit 7dfae1562b
10 changed files with 423 additions and 366 deletions

View file

@ -10,7 +10,11 @@ libAirports_a_SOURCES = \
parking.cxx parking.hxx \ parking.cxx parking.hxx \
groundnetwork.cxx groundnetwork.hxx \ groundnetwork.cxx groundnetwork.hxx \
dynamics.cxx dynamics.hxx \ dynamics.cxx dynamics.hxx \
trafficcontrol.hxx trafficcontrol.cxx trafficcontrol.hxx trafficcontrol.cxx \
dynamicloader.hxx dynamicloader.cxx \
runwayprefloader.hxx runwayprefloader.cxx \
xmlloader.hxx xmlloader.cxx
calc_loc_SOURCES = calc_loc.cxx calc_loc_SOURCES = calc_loc.cxx
calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz $(base_LIBS) calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz $(base_LIBS)

View file

@ -0,0 +1,115 @@
#include "dynamicloader.hxx"
FGAirportDynamicsXMLLoader::FGAirportDynamicsXMLLoader(FGAirportDynamics* dyn):
XMLVisitor(), _dynamics(dyn) {}
void FGAirportDynamicsXMLLoader::startXML () {
//cout << "Start XML" << endl;
}
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;
taxiSegment.setIndex(index);
//cout << "Start element " << name << endl;
string attname;
string value;
string gateName;
string gateNumber;
string lat;
string lon;
if (name == string("Parking"))
{
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(atoi(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"))
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(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(atof(radius.c_str()));
}
else if (attname == string("airlineCodes"))
park.setCodes(atts.getValue(i));
}
park.setName((gateName+gateNumber));
_dynamics->addParking(park);
}
if (name == string("node"))
{
for (int i = 0; i < atts.size() ; i++)
{
attname = atts.getName(i);
if (attname == string("index"))
taxiNode.setIndex(atoi(atts.getValue(i)));
if (attname == string("lat"))
taxiNode.setLatitude(atts.getValue(i));
if (attname == string("lon"))
taxiNode.setLongitude(atts.getValue(i));
}
_dynamics->getGroundNetwork()->addNode(taxiNode);
}
if (name == string("arc"))
{
taxiSegment.setIndex(++index);
for (int i = 0; i < atts.size() ; i++)
{
attname = atts.getName(i);
if (attname == string("begin"))
taxiSegment.setStartNodeRef(atoi(atts.getValue(i)));
if (attname == string("end"))
taxiSegment.setEndNodeRef(atoi(atts.getValue(i)));
}
_dynamics->getGroundNetwork()->addSegment(taxiSegment);
}
// sort by radius, in asending order, so that smaller gates are first in the list
}
void FGAirportDynamicsXMLLoader::endElement (const char * name) {
//cout << "End element " << name << endl;
}
void FGAirportDynamicsXMLLoader::data (const char * s, int len) {
string token = string(s,len);
//cout << "Character data " << string(s,len) << endl;
//if ((token.find(" ") == string::npos && (token.find('\n')) == string::npos))
//value += token;
//else
//value = string("");
}
void FGAirportDynamicsXMLLoader::pi (const char * target, const char * data) {
//cout << "Processing instruction " << target << ' ' << data << endl;
}
void FGAirportDynamicsXMLLoader::warning (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_WARN, "Warning: " << message << " (" << line << ',' << column << ')');
}
void FGAirportDynamicsXMLLoader::error (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_ALERT, "Error: " << message << " (" << line << ',' << column << ')');
}

View file

@ -48,16 +48,11 @@ SG_USING_STD(vector);
SG_USING_STD(sort); SG_USING_STD(sort);
SG_USING_STD(random_shuffle); SG_USING_STD(random_shuffle);
#include "simple.hxx"
#include "dynamics.hxx" #include "dynamics.hxx"
/********** FGAirport Dynamics *********************************************/ FGAirportDynamics::FGAirportDynamics(FGAirport* ap) :
_ap(ap), rwyPrefs(ap) {
FGAirportDynamics::FGAirportDynamics(double lat, double lon, double elev, string id) :
_longitude(lon),
_latitude(lat),
_elevation(elev),
_id(id)
{
lastUpdate = 0; lastUpdate = 0;
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
@ -66,13 +61,13 @@ FGAirportDynamics::FGAirportDynamics(double lat, double lon, double elev, string
} }
} }
// Note that the ground network should also be copied // Note that the ground network should also be copied
FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other) :
rwyPrefs(other.rwyPrefs)
{ {
for (FGParkingVecConstIterator ip= other.parkings.begin(); ip != other.parkings.end(); ip++) for (FGParkingVecConstIterator ip= other.parkings.begin(); ip != other.parkings.end(); ip++)
parkings.push_back(*(ip)); parkings.push_back(*(ip));
rwyPrefs = other.rwyPrefs; // rwyPrefs = other.rwyPrefs;
lastUpdate = other.lastUpdate; lastUpdate = other.lastUpdate;
stringVecConstIterator il; stringVecConstIterator il;
@ -109,6 +104,7 @@ void FGAirportDynamics::init()
groundNetwork.addNodes(&parkings); groundNetwork.addNodes(&parkings);
groundNetwork.init(); groundNetwork.init();
groundNetwork.setTowerController(&towerController); groundNetwork.setTowerController(&towerController);
groundNetwork.setParent(_ap);
} }
bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, const string &flType, const string &acType, const string &airline) bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, const string &flType, const string &acType, const string &airline)
@ -130,9 +126,9 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
if (parkings.begin() == parkings.end()) if (parkings.begin() == parkings.end())
{ {
//cerr << "Could not find parking spot at " << _id << endl; //cerr << "Could not find parking spot at " << _ap->getId() << endl;
*lat = _latitude; *lat = _ap->getLatitude();
*lon = _longitude; *lon = _ap->getLongitude();
*heading = 0; *heading = 0;
found = true; found = true;
} }
@ -270,13 +266,13 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
} }
if (!found) if (!found)
{ {
//cerr << "Traffic overflow at" << _id //cerr << "Traffic overflow at" << _ap->getId()
// << ". flType = " << flType // << ". flType = " << flType
// << ". airline = " << airline // << ". airline = " << airline
// << " Radius = " <<rad // << " Radius = " <<rad
// << endl; // << endl;
*lat = _latitude; *lat = _ap->getLatitude();
*lon = _longitude; *lon = _ap->getLongitude();
*heading = 0; *heading = 0;
*gateId = -1; *gateId = -1;
//exit(1); //exit(1);
@ -288,8 +284,8 @@ void FGAirportDynamics::getParking (int id, double *lat, double* lon, double *he
{ {
if (id < 0) if (id < 0)
{ {
*lat = _latitude; *lat = _ap->getLatitude();
*lon = _longitude; *lon = _ap->getLongitude();
*heading = 0; *heading = 0;
} }
else else
@ -337,117 +333,6 @@ void FGAirportDynamics::releaseParking(int id)
} }
} }
void FGAirportDynamics::startXML () {
//cout << "Start XML" << endl;
}
void FGAirportDynamics::endXML () {
//cout << "End XML" << endl;
}
void FGAirportDynamics::startElement (const char * name, const XMLAttributes &atts) {
// const char *attval;
FGParking park;
FGTaxiNode taxiNode;
FGTaxiSegment taxiSegment;
int index = 0;
taxiSegment.setIndex(index);
//cout << "Start element " << name << endl;
string attname;
string value;
string gateName;
string gateNumber;
string lat;
string lon;
if (name == string("Parking"))
{
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(atoi(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"))
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(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(atof(radius.c_str()));
}
else if (attname == string("airlineCodes"))
park.setCodes(atts.getValue(i));
}
park.setName((gateName+gateNumber));
parkings.push_back(park);
}
if (name == string("node"))
{
for (int i = 0; i < atts.size() ; i++)
{
attname = atts.getName(i);
if (attname == string("index"))
taxiNode.setIndex(atoi(atts.getValue(i)));
if (attname == string("lat"))
taxiNode.setLatitude(atts.getValue(i));
if (attname == string("lon"))
taxiNode.setLongitude(atts.getValue(i));
}
groundNetwork.addNode(taxiNode);
}
if (name == string("arc"))
{
taxiSegment.setIndex(++index);
for (int i = 0; i < atts.size() ; i++)
{
attname = atts.getName(i);
if (attname == string("begin"))
taxiSegment.setStartNodeRef(atoi(atts.getValue(i)));
if (attname == string("end"))
taxiSegment.setEndNodeRef(atoi(atts.getValue(i)));
}
groundNetwork.addSegment(taxiSegment);
}
// sort by radius, in asending order, so that smaller gates are first in the list
}
void FGAirportDynamics::endElement (const char * name) {
//cout << "End element " << name << endl;
}
void FGAirportDynamics::data (const char * s, int len) {
string token = string(s,len);
//cout << "Character data " << string(s,len) << endl;
//if ((token.find(" ") == string::npos && (token.find('\n')) == string::npos))
//value += token;
//else
//value = string("");
}
void FGAirportDynamics::pi (const char * target, const char * data) {
//cout << "Processing instruction " << target << ' ' << data << endl;
}
void FGAirportDynamics::warning (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_WARN, "Warning: " << message << " (" << line << ',' << column << ')');
}
void FGAirportDynamics::error (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_ALERT, "Error: " << message << " (" << line << ',' << column << ')');
}
void FGAirportDynamics::setRwyUse(const FGRunwayPreference& ref) void FGAirportDynamics::setRwyUse(const FGRunwayPreference& ref)
{ {
rwyPrefs = ref; rwyPrefs = ref;
@ -540,7 +425,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
//string rwy_no = globals->get_runways()->search(apt->getId(), int(wind_heading)); //string rwy_no = globals->get_runways()->search(apt->getId(), int(wind_heading));
string scheduleName; string scheduleName;
//cerr << "finding active Runway for" << _id << endl; //cerr << "finding active Runway for" << _ap->getId() << endl;
//cerr << "Nr of seconds since day start << " << dayStart << endl; //cerr << "Nr of seconds since day start << " << dayStart << endl;
ScheduleTime *currSched; ScheduleTime *currSched;
@ -564,7 +449,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
//cerr << "Nr of Active Runways = " << nrActiveRunways << endl; //cerr << "Nr of Active Runways = " << nrActiveRunways << endl;
// //
currRunwayGroup->setActive(_id, currRunwayGroup->setActive(_ap->getId(),
windSpeed, windSpeed,
windHeading, windHeading,
maxTail, maxTail,
@ -622,7 +507,7 @@ void FGAirportDynamics::getActiveRunway(const string &trafficType, int action, s
} }
} }
//runway = globals->get_runways()->search(_id, int(windHeading)); //runway = globals->get_runways()->search(_ap->getId(), int(windHeading));
//cerr << "Seleceted runway: " << runway << endl; //cerr << "Seleceted runway: " << runway << endl;
} }
} }
@ -642,5 +527,25 @@ string FGAirportDynamics::chooseRunwayFallback()
//which is consistent with Flightgear's initial setup. //which is consistent with Flightgear's initial setup.
} }
return globals->get_runways()->search(_id, int(windHeading)); return globals->get_runways()->search(_ap->getId(), int(windHeading));
}
void FGAirportDynamics::addParking(FGParking& park) {
parkings.push_back(park);
}
double FGAirportDynamics::getLatitude() const {
return _ap->getLatitude();
}
double FGAirportDynamics::getLongitude() const {
return _ap->getLongitude();
}
double FGAirportDynamics::getElevation() const {
return _ap->getElevation();
}
const string& FGAirportDynamics::getId() const {
return _ap->getId();
} }

View file

@ -34,14 +34,12 @@
#include "runwayprefs.hxx" #include "runwayprefs.hxx"
#include "trafficcontrol.hxx" #include "trafficcontrol.hxx"
class FGAirport;
class FGAirportDynamics : public XMLVisitor { class FGAirportDynamics {
private: private:
double _longitude; // degrees FGAirport* _ap;
double _latitude; // degrees
double _elevation; // ft
string _id;
FGParkingVec parkings; FGParkingVec parkings;
FGRunwayPreference rwyPrefs; FGRunwayPreference rwyPrefs;
@ -64,19 +62,22 @@ private:
string chooseRunwayFallback(); string chooseRunwayFallback();
public: public:
FGAirportDynamics(double, double, double, string); FGAirportDynamics(FGAirport* ap);
FGAirportDynamics(const FGAirportDynamics &other); FGAirportDynamics(const FGAirportDynamics &other);
~FGAirportDynamics(); ~FGAirportDynamics();
void init(); void init();
double getLongitude() const { return _longitude;}; double getLongitude() const;
// Returns degrees // Returns degrees
double getLatitude() const { return _latitude; }; double getLatitude() const;
// Returns ft // Returns ft
double getElevation() const { return _elevation;}; double getElevation() const;
const string& getId() const;
void getActiveRunway(const string& trafficType, int action, string& runway); void getActiveRunway(const string& trafficType, int action, string& runway);
void addParking(FGParking& park);
bool getAvailableParking(double *lat, double *lon, bool getAvailableParking(double *lat, double *lon,
double *heading, int *gate, double rad, const string& fltype, double *heading, int *gate, double rad, const string& fltype,
const string& acType, const string& airline); const string& acType, const string& airline);
@ -93,16 +94,6 @@ public:
void setRwyUse(const FGRunwayPreference& ref); void setRwyUse(const FGRunwayPreference& ref);
// Some overloaded virtual XMLVisitor members
virtual void startXML ();
virtual void endXML ();
virtual void startElement (const char * name, const XMLAttributes &atts);
virtual void endElement (const char * name);
virtual void data (const char * s, int len);
virtual void pi (const char * target, const char * data);
virtual void warning (const char * message, int line, int column);
virtual void error (const char * message, int line, int column);
}; };

View file

@ -0,0 +1,143 @@
#include <simgear/debug/logstream.hxx>
#include "runwayprefloader.hxx"
FGRunwayPreferenceXMLLoader::FGRunwayPreferenceXMLLoader(FGRunwayPreference* p):XMLVisitor(), _pref(p) {}
void FGRunwayPreferenceXMLLoader::startXML () {
// cout << "Start XML" << endl;
}
void FGRunwayPreferenceXMLLoader::endXML () {
//cout << "End XML" << endl;
}
void FGRunwayPreferenceXMLLoader::startElement (const char * name, const XMLAttributes &atts) {
//cout << "StartElement " << name << endl;
value = string("");
if (!(strcmp(name, "wind"))) {
//cerr << "Will be processing Wind" << endl;
for (int i = 0; i < atts.size(); i++)
{
//cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
//attname = atts.getName(i);
if (atts.getName(i) == string("tail")) {
//cerr << "Tail Wind = " << atts.getValue(i) << endl;
currTimes.setTailWind(atof(atts.getValue(i)));
}
if (atts.getName(i) == string("cross")) {
//cerr << "Cross Wind = " << atts.getValue(i) << endl;
currTimes.setCrossWind(atof(atts.getValue(i)));
}
}
}
if (!(strcmp(name, "time"))) {
//cerr << "Will be processing time" << endl;
for (int i = 0; i < atts.size(); i++)
{
if (atts.getName(i) == string("start")) {
//cerr << "Start Time = " << atts.getValue(i) << endl;
currTimes.addStartTime(processTime(atts.getValue(i)));
}
if (atts.getName(i) == string("end")) {
//cerr << "End time = " << atts.getValue(i) << endl;
currTimes.addEndTime(processTime(atts.getValue(i)));
}
if (atts.getName(i) == string("schedule")) {
//cerr << "Schedule Name = " << atts.getValue(i) << endl;
currTimes.addScheduleName(atts.getValue(i));
}
}
}
if (!(strcmp(name, "takeoff"))) {
rwyList.clear();
}
if (!(strcmp(name, "landing")))
{
rwyList.clear();
}
if (!(strcmp(name, "schedule"))) {
for (int i = 0; i < atts.size(); i++)
{
//cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
//attname = atts.getName(i);
if (atts.getName(i) == string("name")) {
//cerr << "Schedule name = " << atts.getValue(i) << endl;
scheduleName = atts.getValue(i);
}
}
}
}
//based on a string containing hour and minute, return nr seconds since day start.
time_t FGRunwayPreferenceXMLLoader::processTime(const string &tme)
{
string hour = tme.substr(0, tme.find(":",0));
string minute = tme.substr(tme.find(":",0)+1, tme.length());
//cerr << "hour = " << hour << " Minute = " << minute << endl;
return (atoi(hour.c_str()) * 3600 + atoi(minute.c_str()) * 60);
}
void FGRunwayPreferenceXMLLoader::endElement (const char * name) {
//cout << "End element " << name << endl;
if (!(strcmp(name, "rwyuse"))) {
_pref->setInitialized(true);
}
if (!(strcmp(name, "com"))) { // Commercial Traffic
//cerr << "Setting time table for commerical traffic" << endl;
_pref->setComTimes(currTimes);
currTimes.clear();
}
if (!(strcmp(name, "gen"))) { // General Aviation
//cerr << "Setting time table for general aviation" << endl;
_pref->setGenTimes(currTimes);
currTimes.clear();
}
if (!(strcmp(name, "mil"))) { // Military Traffic
//cerr << "Setting time table for military traffic" << endl;
_pref->setMilTimes(currTimes);
currTimes.clear();
}
if (!(strcmp(name, "takeoff"))) {
//cerr << "Adding takeoff: " << value << endl;
rwyList.set(name, value);
rwyGroup.add(rwyList);
}
if (!(strcmp(name, "landing"))) {
//cerr << "Adding landing: " << value << endl;
rwyList.set(name, value);
rwyGroup.add(rwyList);
}
if (!(strcmp(name, "schedule"))) {
//cerr << "Adding schedule" << scheduleName << endl;
rwyGroup.setName(scheduleName);
//rwyGroup.addRunways(rwyList);
_pref->addRunwayGroup(rwyGroup);
rwyGroup.clear();
//exit(1);
}
}
void FGRunwayPreferenceXMLLoader::data (const char * s, int len) {
string token = string(s,len);
//cout << "Character data " << string(s,len) << endl;
//if ((token.find(" ") == string::npos && (token.find('\n')) == string::npos))
// value += token;
//else
// value = string("");
value += token;
}
void FGRunwayPreferenceXMLLoader::pi (const char * target, const char * data) {
//cout << "Processing instruction " << target << ' ' << data << endl;
}
void FGRunwayPreferenceXMLLoader::warning (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_WARN, "Warning: " << message << " (" << line << ',' << column << ')');
}
void FGRunwayPreferenceXMLLoader::error (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_ALERT, "Error: " << message << " (" << line << ',' << column << ')');
}

View file

@ -44,6 +44,7 @@
#include <Airports/runways.hxx> #include <Airports/runways.hxx>
#include "runwayprefs.hxx" #include "runwayprefs.hxx"
#include "simple.hxx"
/****************************************************************************** /******************************************************************************
* ScheduleTime * ScheduleTime
@ -364,7 +365,8 @@ void RunwayGroup::getActive(int i, string &name, string &type)
/***************************************************************************** /*****************************************************************************
* FGRunway preference * FGRunway preference
****************************************************************************/ ****************************************************************************/
FGRunwayPreference::FGRunwayPreference() FGRunwayPreference::FGRunwayPreference(FGAirport* ap) :
_ap(ap)
{ {
//cerr << "Running default Constructor" << endl; //cerr << "Running default Constructor" << endl;
initialized = false; initialized = false;
@ -373,16 +375,11 @@ FGRunwayPreference::FGRunwayPreference()
FGRunwayPreference::FGRunwayPreference(const FGRunwayPreference &other) FGRunwayPreference::FGRunwayPreference(const FGRunwayPreference &other)
{ {
initialized = other.initialized; initialized = other.initialized;
value = other.value;
scheduleName = other.scheduleName;
comTimes = other.comTimes; // Commercial Traffic; comTimes = other.comTimes; // Commercial Traffic;
genTimes = other.genTimes; // General Aviation; genTimes = other.genTimes; // General Aviation;
milTimes = other.milTimes; // Military Traffic; milTimes = other.milTimes; // Military Traffic;
currTimes= other.currTimes; // Needed for parsing;
rwyList = other.rwyList;
rwyGroup = other.rwyGroup;
PreferenceListConstIterator i; PreferenceListConstIterator i;
for (i = other.preferences.begin(); i != other.preferences.end(); i++) for (i = other.preferences.begin(); i != other.preferences.end(); i++)
preferences.push_back(*i); preferences.push_back(*i);
@ -391,16 +388,11 @@ FGRunwayPreference::FGRunwayPreference(const FGRunwayPreference &other)
FGRunwayPreference & FGRunwayPreference::operator= (const FGRunwayPreference &other) FGRunwayPreference & FGRunwayPreference::operator= (const FGRunwayPreference &other)
{ {
initialized = other.initialized; initialized = other.initialized;
value = other.value;
scheduleName = other.scheduleName;
comTimes = other.comTimes; // Commercial Traffic; comTimes = other.comTimes; // Commercial Traffic;
genTimes = other.genTimes; // General Aviation; genTimes = other.genTimes; // General Aviation;
milTimes = other.milTimes; // Military Traffic; milTimes = other.milTimes; // Military Traffic;
currTimes= other.currTimes; // Needed for parsing;
rwyList = other.rwyList;
rwyGroup = other.rwyGroup;
PreferenceListConstIterator i; PreferenceListConstIterator i;
preferences.clear(); preferences.clear();
for (i = other.preferences.begin(); i != other.preferences.end(); i++) for (i = other.preferences.begin(); i != other.preferences.end(); i++)
@ -435,140 +427,6 @@ RunwayGroup *FGRunwayPreference::getGroup(const string &groupName)
return 0; return 0;
} }
void FGRunwayPreference::startXML () { string FGRunwayPreference::getId() {
// cout << "Start XML" << endl; return _ap->getId();
} };
void FGRunwayPreference::endXML () {
// cout << "End XML" << endl;
}
void FGRunwayPreference::startElement (const char * name, const XMLAttributes &atts) {
//cout << "StartElement " << name << endl;
value = string("");
if (!(strcmp(name, "wind"))) {
//cerr << "Will be processing Wind" << endl;
for (int i = 0; i < atts.size(); i++)
{
//cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
//attname = atts.getName(i);
if (atts.getName(i) == string("tail")) {
//cerr << "Tail Wind = " << atts.getValue(i) << endl;
currTimes.setTailWind(atof(atts.getValue(i)));
}
if (atts.getName(i) == string("cross")) {
//cerr << "Cross Wind = " << atts.getValue(i) << endl;
currTimes.setCrossWind(atof(atts.getValue(i)));
}
}
}
if (!(strcmp(name, "time"))) {
//cerr << "Will be processing time" << endl;
for (int i = 0; i < atts.size(); i++)
{
if (atts.getName(i) == string("start")) {
//cerr << "Start Time = " << atts.getValue(i) << endl;
currTimes.addStartTime(processTime(atts.getValue(i)));
}
if (atts.getName(i) == string("end")) {
//cerr << "End time = " << atts.getValue(i) << endl;
currTimes.addEndTime(processTime(atts.getValue(i)));
}
if (atts.getName(i) == string("schedule")) {
//cerr << "Schedule Name = " << atts.getValue(i) << endl;
currTimes.addScheduleName(atts.getValue(i));
}
}
}
if (!(strcmp(name, "takeoff"))) {
rwyList.clear();
}
if (!(strcmp(name, "landing")))
{
rwyList.clear();
}
if (!(strcmp(name, "schedule"))) {
for (int i = 0; i < atts.size(); i++)
{
//cout << " " << atts.getName(i) << '=' << atts.getValue(i) << endl;
//attname = atts.getName(i);
if (atts.getName(i) == string("name")) {
//cerr << "Schedule name = " << atts.getValue(i) << endl;
scheduleName = atts.getValue(i);
}
}
}
}
//based on a string containing hour and minute, return nr seconds since day start.
time_t FGRunwayPreference::processTime(const string &tme)
{
string hour = tme.substr(0, tme.find(":",0));
string minute = tme.substr(tme.find(":",0)+1, tme.length());
//cerr << "hour = " << hour << " Minute = " << minute << endl;
return (atoi(hour.c_str()) * 3600 + atoi(minute.c_str()) * 60);
}
void FGRunwayPreference::endElement (const char * name) {
//cout << "End element " << name << endl;
if (!(strcmp(name, "rwyuse"))) {
initialized = true;
}
if (!(strcmp(name, "com"))) { // Commercial Traffic
//cerr << "Setting time table for commerical traffic" << endl;
comTimes = currTimes;
currTimes.clear();
}
if (!(strcmp(name, "gen"))) { // General Aviation
//cerr << "Setting time table for general aviation" << endl;
genTimes = currTimes;
currTimes.clear();
}
if (!(strcmp(name, "mil"))) { // Military Traffic
//cerr << "Setting time table for military traffic" << endl;
genTimes = currTimes;
currTimes.clear();
}
if (!(strcmp(name, "takeoff"))) {
//cerr << "Adding takeoff: " << value << endl;
rwyList.set(name, value);
rwyGroup.add(rwyList);
}
if (!(strcmp(name, "landing"))) {
//cerr << "Adding landing: " << value << endl;
rwyList.set(name, value);
rwyGroup.add(rwyList);
}
if (!(strcmp(name, "schedule"))) {
//cerr << "Adding schedule" << scheduleName << endl;
rwyGroup.setName(scheduleName);
//rwyGroup.addRunways(rwyList);
preferences.push_back(rwyGroup);
rwyGroup.clear();
//exit(1);
}
}
void FGRunwayPreference::data (const char * s, int len) {
string token = string(s,len);
//cout << "Character data " << string(s,len) << endl;
//if ((token.find(" ") == string::npos && (token.find('\n')) == string::npos))
// value += token;
//else
// value = string("");
value += token;
}
void FGRunwayPreference::pi (const char * target, const char * data) {
//cout << "Processing instruction " << target << ' ' << data << endl;
}
void FGRunwayPreference::warning (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_WARN, "Warning: " << message << " (" << line << ',' << column << ')');
}
void FGRunwayPreference::error (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_ALERT, "Error: " << message << " (" << line << ',' << column << ')');
}

View file

@ -24,7 +24,14 @@
#ifndef _RUNWAYPREFS_HXX_ #ifndef _RUNWAYPREFS_HXX_
#define _RUNWAYPREFS_HXX_ #define _RUNWAYPREFS_HXX_
#include <simgear/xml/easyxml.hxx> #include <time.h>
#include <vector>
#include <string>
#include <simgear/compiler.h>
SG_USING_STD(vector);
SG_USING_STD(string);
typedef vector<time_t> timeVec; typedef vector<time_t> timeVec;
typedef vector<time_t>::const_iterator timeVecConstIterator; typedef vector<time_t>::const_iterator timeVecConstIterator;
@ -33,6 +40,7 @@ typedef vector<string> stringVec;
typedef vector<string>::iterator stringVecIterator; typedef vector<string>::iterator stringVecIterator;
typedef vector<string>::const_iterator stringVecConstIterator; typedef vector<string>::const_iterator stringVecConstIterator;
class FGAirport;
/***************************************************************************/ /***************************************************************************/
class ScheduleTime { class ScheduleTime {
@ -120,42 +128,37 @@ typedef vector<RunwayGroup>::const_iterator PreferenceListConstIterator;
/******************************************************************************/ /******************************************************************************/
class FGRunwayPreference : public XMLVisitor { class FGRunwayPreference {
private: private:
string value; FGAirport* _ap;
string scheduleName;
ScheduleTime comTimes; // Commercial Traffic; ScheduleTime comTimes; // Commercial Traffic;
ScheduleTime genTimes; // General Aviation; ScheduleTime genTimes; // General Aviation;
ScheduleTime milTimes; // Military Traffic; ScheduleTime milTimes; // Military Traffic;
ScheduleTime currTimes; // Needed for parsing;
RunwayList rwyList;
RunwayGroup rwyGroup;
PreferenceList preferences; PreferenceList preferences;
time_t processTime(const string&);
bool initialized; bool initialized;
public: public:
FGRunwayPreference(); FGRunwayPreference(FGAirport* ap);
FGRunwayPreference(const FGRunwayPreference &other); FGRunwayPreference(const FGRunwayPreference &other);
FGRunwayPreference & operator= (const FGRunwayPreference &other); FGRunwayPreference & operator= (const FGRunwayPreference &other);
ScheduleTime *getSchedule(const char *trafficType); ScheduleTime *getSchedule(const char *trafficType);
RunwayGroup *getGroup(const string& groupName); RunwayGroup *getGroup(const string& groupName);
bool available() { return initialized; };
// Some overloaded virtual XMLVisitor members string getId();
virtual void startXML ();
virtual void endXML (); bool available() { return initialized; };
virtual void startElement (const char * name, const XMLAttributes &atts); void setInitialized(bool state) { initialized = state; };
virtual void endElement (const char * name);
virtual void data (const char * s, int len); void setMilTimes(ScheduleTime& t) { milTimes = t; };
virtual void pi (const char * target, const char * data); void setGenTimes(ScheduleTime& t) { genTimes = t; };
virtual void warning (const char * message, int line, int column); void setComTimes(ScheduleTime& t) { comTimes = t; };
virtual void error (const char * message, int line, int column);
void addRunwayGroup(RunwayGroup& g) { preferences.push_back(g); };
}; };
#endif #endif

View file

@ -50,6 +50,7 @@
#include STL_STRING #include STL_STRING
#include "simple.hxx" #include "simple.hxx"
#include "xmlloader.hxx"
SG_USING_STD(sort); SG_USING_STD(sort);
SG_USING_STD(random_shuffle); SG_USING_STD(random_shuffle);
@ -89,45 +90,13 @@ FGAirportDynamics * FGAirport::getDynamics()
if (dynamics != 0) { if (dynamics != 0) {
return dynamics; return dynamics;
} else { } else {
FGRunwayPreference rwyPrefs;
//cerr << "Trying to load dynamics for " << _id << endl; //cerr << "Trying to load dynamics for " << _id << endl;
dynamics = new FGAirportDynamics(_latitude, _longitude, _elevation, _id); dynamics = new FGAirportDynamics(this);
XMLLoader::load(dynamics);
SGPath parkpath( globals->get_fg_root() ); FGRunwayPreference rwyPrefs(this);
parkpath.append( "/AI/Airports/" ); XMLLoader::load(&rwyPrefs);
parkpath.append(_id);
parkpath.append("parking.xml");
SGPath rwyPrefPath( globals->get_fg_root() );
rwyPrefPath.append( "AI/Airports/" );
rwyPrefPath.append(_id);
rwyPrefPath.append("rwyuse.xml");
//if (ai_dirs.find(id.c_str()) != ai_dirs.end()
// && parkpath.exists())
if (parkpath.exists()) {
try {
readXML(parkpath.str(),*dynamics);
//cerr << "Initializing " << getId() << endl;
dynamics->init();
dynamics->getGroundNetwork()->setParent(this);
} catch (const sg_exception &e) {
//cerr << "unable to read " << parkpath.str() << endl;
}
}
//if (ai_dirs.find(id.c_str()) != ai_dirs.end()
// && rwyPrefPath.exists())
if (rwyPrefPath.exists()) {
try {
readXML(rwyPrefPath.str(), rwyPrefs);
dynamics->setRwyUse(rwyPrefs); dynamics->setRwyUse(rwyPrefs);
} catch (const sg_exception &e) {
//cerr << "unable to read " << rwyPrefPath.str() << endl;
//exit(1);
}
}
//exit(1);
} }
return dynamics; return dynamics;
} }
@ -178,7 +147,6 @@ void FGAirportList::add( const string &id, const double longitude,
const double latitude, const double elevation, const double latitude, const double elevation,
const string &name, const bool has_metar ) const string &name, const bool has_metar )
{ {
FGRunwayPreference rwyPrefs;
FGAirport* a = new FGAirport(id, longitude, latitude, elevation, name, has_metar); FGAirport* a = new FGAirport(id, longitude, latitude, elevation, name, has_metar);
airports_by_id[a->getId()] = a; airports_by_id[a->getId()] = a;

View file

@ -0,0 +1,50 @@
#include <simgear/misc/sg_path.hxx>
#include <Main/globals.hxx>
#include "xmlloader.hxx"
#include "dynamicloader.hxx"
#include "runwayprefloader.hxx"
#include "dynamics.hxx"
#include "runwayprefs.hxx"
XMLLoader::XMLLoader() {}
XMLLoader::~XMLLoader() {}
void XMLLoader::load(FGAirportDynamics* d) {
FGAirportDynamicsXMLLoader visitor(d);
SGPath parkpath( globals->get_fg_root() );
parkpath.append( "/AI/Airports/" );
parkpath.append( d->getId() );
parkpath.append( "parking.xml" );
if (parkpath.exists()) {
try {
readXML(parkpath.str(), visitor);
d->init();
} catch (const sg_exception &e) {
//cerr << "unable to read " << parkpath.str() << endl;
}
}
}
void XMLLoader::load(FGRunwayPreference* p) {
FGRunwayPreferenceXMLLoader visitor(p);
SGPath rwyPrefPath( globals->get_fg_root() );
rwyPrefPath.append( "AI/Airports/" );
rwyPrefPath.append( p->getId() );
rwyPrefPath.append( "rwyuse.xml" );
//if (ai_dirs.find(id.c_str()) != ai_dirs.end()
// && rwyPrefPath.exists())
if (rwyPrefPath.exists()) {
try {
readXML(rwyPrefPath.str(), visitor);
} catch (const sg_exception &e) {
//cerr << "unable to read " << rwyPrefPath.str() << endl;
}
}
}

View file

@ -0,0 +1,20 @@
#ifndef _XML_LOADER_HXX_
#define _XML_LOADER_HXX_
#include <simgear/xml/easyxml.hxx>
class FGAirportDynamics;
class FGRunwayPreference;
class XMLLoader {
public:
XMLLoader();
~XMLLoader();
static void load(FGRunwayPreference* p);
static void load(FGAirportDynamics* d);
};
#endif