+ // assert(e->isFixedPosition());
+ double ed = SGGeodesy::distanceM(aDest, e->position());
+ if (ed < d) { // new best match
+ enroute = e;
+ d = ed;
+ sid = mSIDs[i];
+ }
+ } // of SID iteration
+
+ if (!mSIDs.empty() && !sid) {
+ SG_LOG(SG_GENERAL, SG_INFO, ident() << "selectSID, no SID found (runway="
+ << (aRwy ? aRwy->ident() : "no runway preference"));
+ }
+
+ return make_pair(sid, enroute);
+}
+
+pair<STAR*, WayptRef>
+FGAirport::selectSTAR(const SGGeod& aOrigin, FGRunway* aRwy)
+{
+ loadProcedures();
+
+ WayptRef enroute;
+ STAR* star = NULL;
+ double d = 1e9;
+
+ for (unsigned int i=0; i<mSTARs.size(); ++i) {
+ if (!mSTARs[i]->isForRunway(aRwy)) {
+ continue;
+ }
+
+ SG_LOG(SG_GENERAL, SG_INFO, "STAR " << mSTARs[i]->ident() << " is valid for runway");
+ WayptRef e = mSTARs[i]->findBestTransition(aOrigin);
+ if (!e) {
+ continue; // strange, but let's not worry about it
+ }
+
+ // assert(e->isFixedPosition());
+ double ed = SGGeodesy::distanceM(aOrigin, e->position());
+ if (ed < d) { // new best match
+ enroute = e;
+ d = ed;
+ star = mSTARs[i];
+ }
+ } // of STAR iteration
+
+ return make_pair(star, enroute);
+}
+
+
+void FGAirport::addSID(flightgear::SID* aSid)
+{
+ mSIDs.push_back(aSid);
+}
+
+void FGAirport::addSTAR(STAR* aStar)
+{
+ mSTARs.push_back(aStar);
+}
+
+void FGAirport::addApproach(Approach* aApp)
+{
+ mApproaches.push_back(aApp);
+}
+
+unsigned int FGAirport::numSIDs() const
+{
+ loadProcedures();
+ return mSIDs.size();
+}
+
+flightgear::SID* FGAirport::getSIDByIndex(unsigned int aIndex) const
+{
+ loadProcedures();
+ return mSIDs[aIndex];
+}
+
+flightgear::SID* FGAirport::findSIDWithIdent(const std::string& aIdent) const
+{
+ loadProcedures();
+ for (unsigned int i=0; i<mSIDs.size(); ++i) {
+ if (mSIDs[i]->ident() == aIdent) {
+ return mSIDs[i];
+ }
+ }
+
+ return NULL;
+}
+
+unsigned int FGAirport::numSTARs() const
+{
+ loadProcedures();
+ return mSTARs.size();
+}
+
+STAR* FGAirport::getSTARByIndex(unsigned int aIndex) const
+{
+ loadProcedures();
+ return mSTARs[aIndex];
+}
+
+STAR* FGAirport::findSTARWithIdent(const std::string& aIdent) const
+{
+ loadProcedures();
+ for (unsigned int i=0; i<mSTARs.size(); ++i) {
+ if (mSTARs[i]->ident() == aIdent) {
+ return mSTARs[i];
+ }
+ }
+
+ return NULL;
+}
+
+unsigned int FGAirport::numApproaches() const
+{
+ loadProcedures();
+ return mApproaches.size();
+}
+
+Approach* FGAirport::getApproachByIndex(unsigned int aIndex) const
+{
+ loadProcedures();
+ 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;