From: James Turner Date: Sat, 14 Sep 2013 11:17:33 +0000 (+0100) Subject: Display AI traffic route in map. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=38a373ba845d2bbea920cbcff90be5dc33040fe5;p=flightgear.git Display AI traffic route in map. Add some helpers so MapWidget can show the origin and destination of AIAircraft with a FlightPlan. --- diff --git a/src/AIModel/AIFlightPlan.cxx b/src/AIModel/AIFlightPlan.cxx index 61ba0e56b..eb0e6cc1f 100644 --- a/src/AIModel/AIFlightPlan.cxx +++ b/src/AIModel/AIFlightPlan.cxx @@ -483,3 +483,13 @@ FGParking* FGAIFlightPlan::getParkingGate() { return gate.parking(); } + +FGAirportRef FGAIFlightPlan::departureAirport() const +{ + return departure; +} + +FGAirportRef FGAIFlightPlan::arrivalAirport() const +{ + return arrival; +} diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx index bfd445b27..ff3ff2cef 100644 --- a/src/AIModel/AIFlightPlan.hxx +++ b/src/AIModel/AIFlightPlan.hxx @@ -168,6 +168,8 @@ public: void setGate(const ParkingAssignment& pka); FGParking* getParkingGate(); + FGAirportRef departureAirport() const; + FGAirportRef arrivalAirport() const; private: FGAIFlightPlan *sid; typedef std::vector wpt_vector_type; diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 8dc7c5382..c533de9db 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -287,7 +287,7 @@ FGAIManager::attach(FGAIBase *model) } int -FGAIManager::getNumAiObjects(void) const +FGAIManager::getNumAiObjects() const { return ai_list.size(); } @@ -405,6 +405,17 @@ bool FGAIManager::removeObject(const SGPropertyNode* args) return false; } +FGAIBasePtr FGAIManager::getObjectFromProperty(const SGPropertyNode* aProp) const +{ + BOOST_FOREACH(FGAIBase* ai, get_ai_list()) { + if (ai->_getProps() == aProp) { + return ai; + } + } // of AI objects iteration + + return NULL; +} + bool FGAIManager::loadScenario( const string &filename ) { diff --git a/src/AIModel/AIManager.hxx b/src/AIModel/AIManager.hxx index ed3462b2b..140b34366 100644 --- a/src/AIModel/AIManager.hxx +++ b/src/AIModel/AIManager.hxx @@ -46,16 +46,6 @@ class FGAIManager : public SGSubsystem { public: - - // A list of pointers to AI objects - typedef std::list ai_list_type; - typedef ai_list_type::iterator ai_list_iterator; - typedef ai_list_type::const_iterator ai_list_const_iterator; - - const ai_list_type& get_ai_list() const { - return ai_list; - } - FGAIManager(); virtual ~FGAIManager(); @@ -79,8 +69,6 @@ public: inline double get_user_roll() const { return user_roll; } inline double get_user_agl() const { return user_altitude_agl; } - int getNumAiObjects(void) const; - bool loadScenario( const std::string &filename ); static SGPropertyNode_ptr loadScenarioFile(const std::string& filename); @@ -90,7 +78,26 @@ public: FGAIBasePtr addObject(const SGPropertyNode* definition); + /** + * @brief given a reference to an /ai/models/[n] node, return the + * corresponding AIObject implementation, or NULL. + */ + FGAIBasePtr getObjectFromProperty(const SGPropertyNode* aProp) const; private: + // FGSubmodelMgr is a friend for access to the AI_list + friend class FGSubmodelMgr; + + // A list of pointers to AI objects + typedef std::list ai_list_type; + typedef ai_list_type::iterator ai_list_iterator; + typedef ai_list_type::const_iterator ai_list_const_iterator; + + const ai_list_type& get_ai_list() const { + return ai_list; + } + + int getNumAiObjects() const; + void removeDeadItem(FGAIBase* base); double calcRangeFt(const SGVec3d& aCartPos, FGAIBase* aObject) const; diff --git a/src/GUI/MapWidget.cxx b/src/GUI/MapWidget.cxx index 393a1c4e6..7edb0c93e 100644 --- a/src/GUI/MapWidget.cxx +++ b/src/GUI/MapWidget.cxx @@ -26,6 +26,8 @@ #include
// fgGetKeyModifiers() #include #include +#include +#include const char* RULER_LEGEND_KEY = "ruler-legend"; @@ -1561,22 +1563,38 @@ void MapWidget::drawAIAircraft(const SGPropertyNode* model, const SGGeod& pos, d drawLine(p, project(advance)); } - + + // try to access the flight-plan of the aircraft. There are several layers + // of potential NULL-ness here, so we have to be defensive at each stage. + std::string originICAO, destinationICAO; + FGAIManager* aiManager = static_cast(globals->get_subsystem("ai-model")); + FGAIBasePtr aircraft = aiManager ? aiManager->getObjectFromProperty(model) : NULL; + if (aircraft) { + FGAIAircraft* p = static_cast(aircraft.get()); + if (p->GetFlightPlan()) { + originICAO = p->GetFlightPlan()->departureAirport()->ident(); + destinationICAO = p->GetFlightPlan()->arrivalAirport()->ident(); + } + } // draw callsign / altitude / speed - char buffer[1024]; - ::snprintf(buffer, 1024, "%s\n%d'\n%dkts", - model->getStringValue("callsign", "<>"), - static_cast(pos.getElevationFt() / 50.0) * 50, - speedKts); - - MapData* d = getOrCreateDataForKey((void*) model); - d->setText(buffer); - d->setLabel(model->getStringValue("callsign", "<>")); - d->setPriority(speedKts > 5 ? 60 : 10); // low priority for parked aircraft - d->setOffset(MapData::VALIGN_CENTER | MapData::HALIGN_LEFT, 10); - d->setAnchor(p); - + int altFt50 = static_cast(pos.getElevationFt() / 50.0) * 50; + std::ostringstream ss; + ss << model->getStringValue("callsign", "<>"); + if (speedKts > 1) { + ss << "\n" << altFt50 << "' " << speedKts << "kts"; + } + + if (!originICAO.empty() || ! destinationICAO.empty()) { + ss << "\n" << originICAO << " -> " << destinationICAO; + } + + MapData* d = getOrCreateDataForKey((void*) model); + d->setText(ss.str().c_str()); + d->setLabel(model->getStringValue("callsign", "<>")); + d->setPriority(speedKts > 5 ? 60 : 10); // low priority for parked aircraft + d->setOffset(MapData::VALIGN_CENTER | MapData::HALIGN_LEFT, 10); + d->setAnchor(p); } void MapWidget::drawAIShip(const SGPropertyNode* model, const SGGeod& pos, double hdg)