1
0
Fork 0

Launcher finds parking positions from scenery

- change launcher to examine the scenery paths and hence load
  ground-net files for airports to populate parking data.

- refactor ground-net XML parsing to use FGGroundNetwork only, not
  AirportDynamics. 

- change parenting  of GroundNetwork to Airport, since it contains
  immutable data now.
This commit is contained in:
James Turner 2016-01-10 16:38:01 -06:00
parent 4befe0e6ea
commit d10d279064
14 changed files with 188 additions and 127 deletions

View file

@ -54,6 +54,8 @@
#include <ATC/CommStation.hxx>
#include <Navaids/NavDataCache.hxx>
#include <Navaids/navrecord.hxx>
#include <Airports/groundnetwork.hxx>
#include <Airports/xmlloader.hxx>
using std::vector;
using std::pair;
@ -969,6 +971,19 @@ FGAirportDynamicsRef FGAirport::getDynamics() const
return flightgear::AirportDynamicsManager::find(const_cast<FGAirport*>(this));
}
FGGroundNetwork *FGAirport::groundNetwork() const
{
if (!_groundNetwork.get()) {
_groundNetwork.reset(new FGGroundNetwork(const_cast<FGAirport*>(this)));
XMLLoader::load(_groundNetwork.get());
_groundNetwork->init();
}
return _groundNetwork.get();
}
// get airport elevation
double fgGetAirportElev( const std::string& id )
{

View file

@ -39,6 +39,8 @@
#include "airports_fwd.hxx"
#include "runways.hxx"
class FGGroundNetwork;
/***************************************************************************************
*
**************************************************************************************/
@ -91,6 +93,8 @@ class FGAirport : public FGPositioned
FGAirportDynamicsRef getDynamics() const;
FGGroundNetwork* groundNetwork() const;
unsigned int numRunways() const;
unsigned int numHelipads() const;
FGRunwayRef getRunwayByIndex(unsigned int aIndex) const;
@ -354,6 +358,8 @@ private:
std::vector<SIDRef> mSIDs;
std::vector<STARRef> mSTARs;
std::vector<ApproachRef> mApproaches;
mutable std::auto_ptr<FGGroundNetwork> _groundNetwork;
};
// find basic airport location info from airport database

View file

@ -79,8 +79,6 @@ FGAirportDynamicsRef AirportDynamicsManager::dynamicsForICAO(const std::string &
return FGAirportDynamicsRef();
FGAirportDynamicsRef d(new FGAirportDynamics(apt));
XMLLoader::load(d.ptr());
d->init();
FGRunwayPreference rwyPrefs(apt);
@ -96,7 +94,7 @@ FGAirportDynamicsRef AirportDynamicsManager::find(const std::string &icao)
if (icao.empty())
return FGAirportDynamicsRef();
AirportDynamicsManager* instance = static_cast<AirportDynamicsManager*>(globals->get_subsystem("airport-dynamics"));
AirportDynamicsManager* instance = globals->get_subsystem<AirportDynamicsManager>();
if (!instance)
return FGAirportDynamicsRef();

View file

@ -24,8 +24,8 @@
#include "dynamicloader.hxx"
#include <Navaids/NavDataCache.hxx>
#include <Airports/dynamics.hxx>
#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <Airports/groundnetwork.hxx>
using std::string;
@ -53,15 +53,16 @@ static double processPosition(const string &pos)
return value;
}
FGAirportDynamicsXMLLoader::FGAirportDynamicsXMLLoader(FGAirportDynamics* dyn):
XMLVisitor(), _dynamics(dyn)
FGGroundNetXMLLoader::FGGroundNetXMLLoader(FGGroundNetwork* net):
XMLVisitor(),
_groundNetwork(net)
{}
void FGAirportDynamicsXMLLoader::startXML () {
void FGGroundNetXMLLoader::startXML () {
//cout << "FGAirportDynamicsLoader::Start XML" << endl;
}
void FGAirportDynamicsXMLLoader::endXML ()
void FGGroundNetXMLLoader::endXML ()
{
ParkingPushbackIndex::const_iterator it;
@ -82,7 +83,7 @@ void FGAirportDynamicsXMLLoader::endXML ()
}
void FGAirportDynamicsXMLLoader::startParking(const XMLAttributes &atts)
void FGGroundNetXMLLoader::startParking(const XMLAttributes &atts)
{
string type;
int index = 0;
@ -134,10 +135,10 @@ void FGAirportDynamicsXMLLoader::startParking(const XMLAttributes &atts)
}
_indexMap[index] = parking;
_dynamics->getGroundNetwork()->addParking(parking);
_groundNetwork->addParking(parking);
}
void FGAirportDynamicsXMLLoader::startNode(const XMLAttributes &atts)
void FGGroundNetXMLLoader::startNode(const XMLAttributes &atts)
{
int index = 0;
string lat, lon;
@ -181,7 +182,7 @@ void FGAirportDynamicsXMLLoader::startNode(const XMLAttributes &atts)
_unreferencedNodes.insert(node);
}
void FGAirportDynamicsXMLLoader::startArc(const XMLAttributes &atts)
void FGGroundNetXMLLoader::startArc(const XMLAttributes &atts)
{
int begin = 0, end = 0;
bool isPushBackRoute = false;
@ -199,7 +200,7 @@ void FGAirportDynamicsXMLLoader::startArc(const XMLAttributes &atts)
IntPair e(begin, end);
if (_arcSet.find(e) != _arcSet.end()) {
SG_LOG(SG_NAVAID, SG_WARN, _dynamics->parent()->ident() << " ground-net: skipping duplicate edge:" << begin << "->" << end);
SG_LOG(SG_NAVAID, SG_WARN, _groundNetwork->airport()->ident() << " ground-net: skipping duplicate edge:" << begin << "->" << end);
return;
}
@ -224,13 +225,13 @@ void FGAirportDynamicsXMLLoader::startArc(const XMLAttributes &atts)
}
_arcSet.insert(e);
_dynamics->getGroundNetwork()->addSegment(fromNode, toNode);
_groundNetwork->addSegment(fromNode, toNode);
if (isPushBackRoute) {
// toNode->setIsPushback();
}
}
void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttributes &atts)
void FGGroundNetXMLLoader::startElement (const char * name, const XMLAttributes &atts)
{
if (!strcmp("Parking", name)) {
startParking(atts);
@ -241,27 +242,27 @@ void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttri
}
}
void FGAirportDynamicsXMLLoader::endElement (const char * name)
void FGGroundNetXMLLoader::endElement (const char * name)
{
int valueAsInt = atoi(value.c_str());
if (!strcmp("version", name)) {
_dynamics->getGroundNetwork()->addVersion(valueAsInt);
_groundNetwork->addVersion(valueAsInt);
} else if (!strcmp("AWOS", name)) {
_dynamics->addAwosFreq(valueAsInt);
_groundNetwork->addAwosFreq(valueAsInt);
} else if (!strcmp("UNICOM", name)) {
_dynamics->addUnicomFreq(valueAsInt);
_groundNetwork->addUnicomFreq(valueAsInt);
} else if (!strcmp("CLEARANCE", name)) {
_dynamics->addClearanceFreq(valueAsInt);
_groundNetwork->addClearanceFreq(valueAsInt);
} else if (!strcmp("GROUND", name)) {
_dynamics->addGroundFreq(valueAsInt);
_groundNetwork->addGroundFreq(valueAsInt);
} else if (!strcmp("TOWER", name)) {
_dynamics->addTowerFreq(valueAsInt);
_groundNetwork->addTowerFreq(valueAsInt);
} else if (!strcmp("APPROACH", name)) {
_dynamics->addApproachFreq(valueAsInt);
_groundNetwork->addApproachFreq(valueAsInt);
}
}
void FGAirportDynamicsXMLLoader::data (const char * s, int len) {
void FGGroundNetXMLLoader::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))
@ -270,14 +271,14 @@ void FGAirportDynamicsXMLLoader::data (const char * s, int len) {
value = string("");
}
void FGAirportDynamicsXMLLoader::pi (const char * target, const char * data) {
void FGGroundNetXMLLoader::pi (const char * target, const char * data) {
//cout << "Processing instruction " << target << ' ' << data << endl;
}
void FGAirportDynamicsXMLLoader::warning (const char * message, int line, int column) {
void FGGroundNetXMLLoader::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) {
void FGGroundNetXMLLoader::error (const char * message, int line, int column) {
SG_LOG(SG_IO, SG_ALERT, "Error: " << message << " (" << line << ',' << column << ')');
}

View file

@ -16,14 +16,16 @@
#ifndef _DYNAMIC_LOADER_HXX_
#define _DYNAMIC_LOADER_HXX_
#include <set>
#include <simgear/xml/easyxml.hxx>
#include "dynamics.hxx"
#include "groundnetwork.hxx"
#include <Airports/parking.hxx>
class FGAirportDynamicsXMLLoader : public XMLVisitor {
class FGGroundNetXMLLoader : public XMLVisitor {
public:
FGAirportDynamicsXMLLoader(FGAirportDynamics* dyn);
FGGroundNetXMLLoader(FGGroundNetwork* gn);
protected:
virtual void startXML ();
@ -40,7 +42,8 @@ private:
void startNode(const XMLAttributes &atts);
void startArc(const XMLAttributes &atts);
FGAirportDynamics* _dynamics;
FGGroundNetwork* _groundNetwork;
std::string value;
// map from local (groundnet.xml) ids to parking instances

View file

@ -160,7 +160,6 @@ FGAirportDynamics::FGAirportDynamics(FGAirport * ap):
{
lastUpdate = 0;
groundNetwork.reset(new FGGroundNetwork);
}
// Destructor
@ -173,8 +172,6 @@ FGAirportDynamics::~FGAirportDynamics()
// Initialization required after XMLRead
void FGAirportDynamics::init()
{
groundNetwork->init(this);
groundController.setTowerController(&towerController);
groundController.init(this);
}
@ -183,7 +180,7 @@ FGParking* FGAirportDynamics::innerGetAvailableParking(double radius, const stri
const string & airline,
bool skipEmptyAirlineCode)
{
const FGParkingList& parkings(groundNetwork->allParkings());
const FGParkingList& parkings(getGroundNetwork()->allParkings());
FGParkingList::const_iterator it;
for (it = parkings.begin(); it != parkings.end(); ++it) {
FGParkingRef parking = *it;
@ -210,7 +207,7 @@ FGParking* FGAirportDynamics::innerGetAvailableParking(double radius, const stri
bool FGAirportDynamics::hasParkings() const
{
return !groundNetwork->allParkings().empty();
return !getGroundNetwork()->allParkings().empty();
}
ParkingAssignment FGAirportDynamics::getAvailableParking(double radius, const string & flType,
@ -238,7 +235,7 @@ ParkingAssignment FGAirportDynamics::getAvailableParking(double radius, const st
ParkingAssignment FGAirportDynamics::getParkingByName(const std::string& name) const
{
const FGParkingList& parkings(groundNetwork->allParkings());
const FGParkingList& parkings(getGroundNetwork()->allParkings());
FGParkingList::const_iterator it;
for (it = parkings.begin(); it != parkings.end(); ++it) {
if ((*it)->name() == name) {
@ -246,7 +243,12 @@ ParkingAssignment FGAirportDynamics::getParkingByName(const std::string& name) c
}
}
return ParkingAssignment();
return ParkingAssignment();
}
FGGroundNetwork *FGAirportDynamics::getGroundNetwork() const
{
return _ap->groundNetwork();
}
void FGAirportDynamics::setParkingAvailable(FGParking* park, bool available)
@ -300,7 +302,7 @@ public:
FGParkingList FGAirportDynamics::getParkings(bool onlyAvailable, const std::string &type) const
{
FGParkingList result(groundNetwork->allParkings());
FGParkingList result(getGroundNetwork()->allParkings());
GetParkingsPredicate pred(onlyAvailable, type, this);
FGParkingList::iterator it = std::remove_if(result.begin(), result.end(), pred);
@ -767,6 +769,9 @@ int FGAirportDynamics::getGroundFrequency(unsigned leg)
SG_LOG(SG_ATC, SG_ALERT,
"Leg value is smaller than one at " << SG_ORIGIN);
}
const intVec& freqGround(getGroundNetwork()->getGroundFrequencies());
if (freqGround.size() == 0) {
return 0;
}
@ -790,6 +795,9 @@ int FGAirportDynamics::getTowerFrequency(unsigned nr)
SG_LOG(SG_ATC, SG_ALERT,
"Leg value is smaller than two at " << SG_ORIGIN);
}
const intVec& freqTower(getGroundNetwork()->getTowerFrequencies());
if (freqTower.size() == 0) {
return 0;
}

View file

@ -67,9 +67,6 @@ private:
// if a parking item is in this set, it is occupied
ParkingSet occupiedParkings;
std::auto_ptr<FGGroundNetwork> groundNetwork;
FGRunwayPreference rwyPrefs;
FGStartupController startupController;
FGTowerController towerController;
@ -82,12 +79,6 @@ private:
stringVec takeoff;
stringVec milActive, comActive, genActive, ulActive;
stringVec *currentlyActive;
intVec freqAwos; // </AWOS>
intVec freqUnicom; // </UNICOM>
intVec freqClearance;// </CLEARANCE>
intVec freqGround; // </GROUND>
intVec freqTower; // </TOWER>
intVec freqApproach; // </APPROACH>
int atisSequenceIndex;
double atisSequenceTimeStamp;
@ -112,25 +103,6 @@ public:
FGAirportDynamics(FGAirport* ap);
virtual ~FGAirportDynamics();
void addAwosFreq (int val) {
freqAwos.push_back(val);
};
void addUnicomFreq (int val) {
freqUnicom.push_back(val);
};
void addClearanceFreq(int val) {
freqClearance.push_back(val);
};
void addGroundFreq (int val) {
freqGround.push_back(val);
};
void addTowerFreq (int val) {
freqTower.push_back(val);
};
void addApproachFreq (int val) {
freqApproach.push_back(val);
};
void init();
double getElevation() const;
@ -182,10 +154,7 @@ public:
return &approachController;
};
FGGroundNetwork* getGroundNetwork() const
{
return groundNetwork.get();
}
FGGroundNetwork* getGroundNetwork() const;
int getGroundFrequency(unsigned leg);
int getTowerFrequency (unsigned nr);

View file

@ -38,13 +38,11 @@
#include <simgear/timing/timestamp.hxx>
#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx>
#include <Airports/runways.hxx>
#include <Scenery/scenery.hxx>
using std::string;
using flightgear::NavDataCache;
/***************************************************************************
* FGTaxiSegment
@ -157,9 +155,8 @@ bool FGTaxiRoute::next(FGTaxiNodeRef& node, int *rte)
* FGGroundNetwork()
**************************************************************************/
FGGroundNetwork::FGGroundNetwork() :
dynamics(NULL),
parent(NULL)
FGGroundNetwork::FGGroundNetwork(FGAirport* airport) :
parent(airport)
{
hasNetwork = false;
version = 0;
@ -174,18 +171,17 @@ FGGroundNetwork::~FGGroundNetwork()
}
// owning references to ground-net nodes will also drop
SG_LOG(SG_NAVAID, SG_INFO, "destroying ground net for " << parent->ident());
}
void FGGroundNetwork::init(FGAirportDynamics* dyn)
void FGGroundNetwork::init()
{
if (networkInitialized) {
SG_LOG(SG_GENERAL, SG_WARN, "duplicate ground-network init");
return;
}
dynamics = dyn;
parent = dyn->parent();
assert(parent);
hasNetwork = true;
int index = 1;
@ -454,3 +450,13 @@ FGTaxiNodeVector FGGroundNetwork::segmentsFrom(const FGTaxiNodeRef &from) const
return result;
}
const intVec& FGGroundNetwork::getTowerFrequencies() const
{
return freqTower;
}
const intVec& FGGroundNetwork::getGroundFrequencies() const
{
return freqGround;
}

View file

@ -177,9 +177,8 @@ public:
class FGGroundNetwork
{
private:
friend class FGAirportDynamicsXMLLoader;
friend class FGGroundNetXMLLoader;
FGAirportDynamics* dynamics; // weak back-pointer to our owner
bool hasNetwork;
bool networkInitialized;
@ -207,18 +206,46 @@ private:
FGTaxiNodeVector segmentsFrom(const FGTaxiNodeRef& from) const;
void addAwosFreq (int val) {
freqAwos.push_back(val);
};
void addUnicomFreq (int val) {
freqUnicom.push_back(val);
};
void addClearanceFreq(int val) {
freqClearance.push_back(val);
};
void addGroundFreq (int val) {
freqGround.push_back(val);
};
void addTowerFreq (int val) {
freqTower.push_back(val);
};
void addApproachFreq (int val) {
freqApproach.push_back(val);
};
intVec freqAwos; // </AWOS>
intVec freqUnicom; // </UNICOM>
intVec freqClearance;// </CLEARANCE>
intVec freqGround; // </GROUND>
intVec freqTower; // </TOWER>
intVec freqApproach; // </APPROACH>
public:
FGGroundNetwork();
FGGroundNetwork(FGAirport* pr);
~FGGroundNetwork();
void setVersion (int v) { version = v;};
int getVersion() { return version; };
void init(FGAirportDynamics* pr);
void init();
bool exists() {
return hasNetwork;
};
FGAirport* airport() const
{ return parent; }
FGTaxiNodeRef findNearestNode(const SGGeod& aGeod) const;
FGTaxiNodeRef findNearestNodeOnRunway(const SGGeod& aGeod, FGRunway* aRunway = NULL) const;
@ -244,6 +271,10 @@ public:
void addVersion(int v) {version = v; };
void unblockAllSegments(time_t now);
const intVec& getTowerFrequencies() const;
const intVec& getGroundFrequencies() const;
};

View file

@ -42,10 +42,10 @@ using std::string;
XMLLoader::XMLLoader() {}
XMLLoader::~XMLLoader() {}
void XMLLoader::load(FGAirportDynamics* d)
void XMLLoader::load(FGGroundNetwork* net)
{
SGPath path;
if (!findAirportData(d->parent()->ident(), "groundnet", path)) {
if (!findAirportData(net->airport()->ident(), "groundnet", path)) {
return;
}
@ -53,7 +53,7 @@ void XMLLoader::load(FGAirportDynamics* d)
SGTimeStamp t;
t.stamp();
try {
FGAirportDynamicsXMLLoader visitor(d);
FGGroundNetXMLLoader visitor(net);
readXML(path.str(), visitor);
} catch (sg_exception& e) {
SG_LOG(SG_NAVAID, SG_INFO, "parsing groundnet XML failed:" << e.getFormattedMessage());

View file

@ -26,7 +26,7 @@ public:
~XMLLoader();
static void load(FGRunwayPreference* p);
static void load(FGAirportDynamics* d);
static void load(FGGroundNetwork* net);
static void load(FGSidStar* s);
/**

View file

@ -33,7 +33,8 @@
#include "NavaidDiagram.hxx"
#include <Airports/airport.hxx>
#include <Airports/dynamics.hxx> // for parking
#include <Airports/groundnetwork.hxx>
#include <Main/globals.hxx>
#include <Navaids/NavDataCache.hxx>
#include <Navaids/navrecord.hxx>
@ -699,26 +700,26 @@ void LocationWidget::onLocationChanged()
}
}
#if 0
m_ui->parkingCombo->clear();
FGAirportDynamics* dynamics = apt->getDynamics();
PositionedIDVec parkings = NavDataCache::instance()->airportItemsOfType(m_location->guid(),
FGPositioned::PARKING);
if (parkings.empty()) {
m_ui->parkingCombo->setEnabled(false);
m_ui->parkingRadio->setEnabled(false);
} else {
m_ui->parkingCombo->setEnabled(true);
m_ui->parkingRadio->setEnabled(true);
Q_FOREACH(PositionedID parking, parkings) {
FGParking* park = dynamics->getParking(parking);
m_ui->parkingCombo->addItem(QString::fromStdString(park->getName()),
static_cast<qlonglong>(parking));
FGGroundNetwork* ground = apt->groundNetwork();
if (ground && ground->exists()) {
FGParkingList parkings = ground->allParkings();
if (parkings.empty()) {
m_ui->parkingCombo->setEnabled(false);
m_ui->parkingRadio->setEnabled(false);
} else {
m_ui->parkingCombo->setEnabled(true);
m_ui->parkingRadio->setEnabled(true);
m_ui->airportDiagram->addParking(park);
}
}
#endif
FGParkingList::const_iterator it;
for (it = parkings.begin(); it != parkings.end(); ++it) {
m_ui->parkingCombo->addItem(QString::fromStdString((*it)->getName()),
(*it)->getIndex());
m_ui->airportDiagram->addParking(*it);
}
} // of have parkings
} // of was able to create dynamics
} else if (m_locationIsLatLon) {
m_ui->stack->setCurrentIndex(1);
@ -752,7 +753,7 @@ void LocationWidget::onAirportParkingClicked(FGParkingRef park)
{
if (park) {
m_ui->parkingRadio->setChecked(true);
int parkingIndex = m_ui->parkingCombo->findText(QString::fromStdString(park->name()));
int parkingIndex = m_ui->parkingCombo->findData(park->getIndex());
m_ui->parkingCombo->setCurrentIndex(parkingIndex);
m_ui->airportDiagram->setSelectedRunway(FGRunwayRef());
}
@ -873,23 +874,10 @@ void LocationWidget::updateDescription()
} else {
m_ui->airportDiagram->setApproachExtensionDistance(0.0);
}
} else {
}
#if 0
QString locationOnAirport;
if (m_ui->runwayRadio->isChecked()) {
} else if (m_ui->parkingRadio->isChecked()) {
locationOnAirport = QString("at parking position %1").arg(m_ui->parkingCombo->currentText());
}
m_ui->airportDescription->setText();
#endif
emit descriptionChanged(locationDescription());
}

View file

@ -417,15 +417,16 @@ bool runLauncherDialog()
loadNaturalEarthData();
// setup scenery paths now, especially TerraSync path for airport
// parking locations (after they're downloaded)
QtLauncher dlg;
dlg.exec();
if (dlg.result() != QDialog::Accepted) {
return false;
}
// don't set scenery paths twice
globals->clear_fg_scenery();
return true;
}
@ -576,6 +577,32 @@ QtLauncher::~QtLauncher()
}
void QtLauncher::setSceneryPaths()
{
globals->clear_fg_scenery();
// mimic what optionss.cxx does, so we can find airport data for parking
// positions
QSettings settings;
// append explicit scenery paths
Q_FOREACH(QString path, settings.value("scenery-paths").toStringList()) {
globals->append_fg_scenery(path.toStdString());
}
// append the TerraSync path
QString downloadDir = settings.value("download-dir").toString();
if (downloadDir.isEmpty()) {
downloadDir = QString::fromStdString(flightgear::defaultDownloadDir());
}
SGPath terraSyncDir(downloadDir.toStdString());
terraSyncDir.append("TerraSync");
if (terraSyncDir.exists()) {
globals->append_fg_scenery(terraSyncDir.str());
}
}
void QtLauncher::setInAppMode()
{
m_inAppMode = true;
@ -608,7 +635,10 @@ void QtLauncher::restoreSettings()
// select the default C172p
}
updateSelectedAircraft();
if (!m_inAppMode) {
setSceneryPaths();
}
m_ui->location->restoreSettings();
// rating filters
@ -1090,6 +1120,9 @@ void QtLauncher::onEditPaths()
QSettings settings;
m_aircraftModel->setPaths(settings.value("aircraft-paths").toStringList());
m_aircraftModel->scanDirs();
// re-set scenery dirs
setSceneryPaths();
}
}

View file

@ -50,6 +50,9 @@ public:
virtual ~QtLauncher();
void setInAppMode();
void setSceneryPaths();
private slots:
// run is used when the launcher is invoked before the main app is
// started