#include <Airports/xmlloader.hxx>
#include <Navaids/procedure.hxx>
#include <Navaids/waypoint.hxx>
+#include <Navaids/PositionedBinding.hxx>
+#include <ATC/CommStation.hxx>
using std::vector;
+using std::pair;
+
using namespace flightgear;
// magic import of a helper which uses FGPositioned internals
FGAirportDynamics * FGAirport::getDynamics()
{
- if (_dynamics != 0) {
+ if (_dynamics) {
return _dynamics;
- } else {
- //cerr << "Trying to load dynamics for " << _id << endl;
- _dynamics = new FGAirportDynamics(this);
- XMLLoader::load(_dynamics);
-
- FGRunwayPreference rwyPrefs(this);
- XMLLoader::load(&rwyPrefs);
- _dynamics->setRwyUse(rwyPrefs);
+ }
+
+ _dynamics = new FGAirportDynamics(this);
+ XMLLoader::load(_dynamics);
- //FGSidStar SIDs(this);
- XMLLoader::load(_dynamics->getSIDs());
- }
+ FGRunwayPreference rwyPrefs(this);
+ XMLLoader::load(&rwyPrefs);
+ _dynamics->setRwyUse(rwyPrefs);
+ XMLLoader::load(_dynamics->getSIDs());
+
return _dynamics;
}
}
mRunwaysLoaded = true;
- loadSceneryDefintions();
+ loadSceneryDefinitions();
}
void FGAirport::loadTaxiways() const
Route::loadAirportProcedures(path, const_cast<FGAirport*>(this));
}
-void FGAirport::loadSceneryDefintions() const
+void FGAirport::loadSceneryDefinitions() const
{
// allow users to disable the scenery data in the short-term
// longer term, this option can probably disappear
// first, let's identify the current runway
string id(aThreshold->getStringValue("rwy"));
if (!hasRunwayWithIdent(id)) {
- SG_LOG(SG_GENERAL, SG_WARN, "FGAirport::processThreshold: "
+ SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: "
"found runway not defined in the global data:" << ident() << "/" << id);
return;
}
SGPropertyNode* twrNode = aRoot->getChild("tower")->getChild("twr");
double lat = twrNode->getDoubleValue("lat"),
lon = twrNode->getDoubleValue("lon"),
- elevM = twrNode->getDoubleValue("elev-m");
-
- _tower_location = SGGeod::fromDegM(lon, lat, elevM);
+ elevM = twrNode->getDoubleValue("elev-m");
+// tower elevation is AGL, not AMSL. Since we don't want to depend on the
+// scenery for a precise terrain elevation, we use the field elevation
+// (this is also what the apt.dat code does)
+ double fieldElevationM = geod().getElevationM();
+
+ _tower_location = SGGeod::fromDegM(lon, lat, fieldElevationM + elevM);
}
bool FGAirport::buildApproach(Waypt* aEnroute, STAR* aSTAR, FGRunway* aRwy, WayptVec& aRoute)
<< (aRwy ? aRwy->ident() : "no runway preference"));
}
- return make_pair(sid, enroute);
+ return std::make_pair(sid, enroute);
}
pair<STAR*, WayptRef>
}
} // of STAR iteration
- return make_pair(star, enroute);
+ return std::make_pair(star, enroute);
}
return mApproaches[aIndex];
}
+class AirportNodeListener : public SGPropertyChangeListener
+{
+public:
+ AirportNodeListener()
+ {
+ SGPropertyNode* airports = fgGetNode("/sim/airport");
+ airports->addChangeListener(this, false);
+ }
+
+ virtual void valueChanged(SGPropertyNode*)
+ {
+ }
+
+ virtual void childAdded(SGPropertyNode* pr, SGPropertyNode* child)
+ {
+ FGAirport* apt = FGAirport::findByIdent(child->getName());
+ if (!apt) {
+ return;
+ }
+
+ flightgear::PositionedBinding::bind(apt, child);
+ }
+};
+
+void FGAirport::installPropertyListener()
+{
+ new AirportNodeListener;
+}
+
+flightgear::PositionedBinding*
+FGAirport::createBinding(SGPropertyNode* nd) const
+{
+ return new flightgear::AirportBinding(this, nd);
+}
+
+void FGAirport::setCommStations(CommStationList& comms)
+{
+ mCommStations.swap(comms);
+ for (unsigned int c=0; c<mCommStations.size(); ++c) {
+ mCommStations[c]->setAirport(this);
+ }
+}
+
+CommStationList
+FGAirport::commStationsOfType(FGPositioned::Type aTy) const
+{
+ CommStationList result;
+ for (unsigned int c=0; c<mCommStations.size(); ++c) {
+ if (mCommStations[c]->type() == aTy) {
+ result.push_back(mCommStations[c]);
+ }
+ }
+ return result;
+}
+
// get airport elevation
double fgGetAirportElev( const string& id )
{