diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index da549404e..465684b2d 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -25,6 +25,7 @@ using namespace BlackMisc::Simulation; using namespace BlackMisc::Network; using namespace BlackMisc::Geo; using namespace BlackMisc::PhysicalQuantities; +using namespace BlackMisc::Weather; namespace BlackCore { @@ -60,6 +61,7 @@ namespace BlackCore // AutoConnection: this should also avoid race conditions by updating the bookings this->connect(this->m_webDataReader->getBookingReader(), &CVatsimBookingReader::dataRead, this, &CAirspaceMonitor::ps_receivedBookings); this->connect(this->m_webDataReader->getDataFileReader(), &CVatsimDataFileReader::dataRead, this, &CAirspaceMonitor::ps_receivedDataFile); + this->connect(this->m_webDataReader->getMetarReader(), &CVatsimMetarReader::metarUpdated, this, &CAirspaceMonitor::ps_updateMetars); // Force snapshot in the main event loop this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, this, &CAirspaceMonitor::airspaceAircraftSnapshot, Qt::QueuedConnection); @@ -322,31 +324,9 @@ namespace BlackCore return m_otherClients; } - BlackMisc::Aviation::CInformationMessage CAirspaceMonitor::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) + CMetar CAirspaceMonitor::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) { - CInformationMessage metar; - if (airportIcaoCode.isEmpty()) return metar; - if (this->m_metarCache.contains(airportIcaoCode)) metar = this->m_metarCache[airportIcaoCode]; - if (metar.isEmpty() || metar.timeDiffReceivedMs() > 10 * 1000) - { - // outdated, or not in cache at all - this->m_network->sendMetarQuery(airportIcaoCode); - - // with this little trick we try to make an asynchronous signal / slot - // based approach a synchronous return value - QTime waitForMetar = QTime::currentTime().addMSecs(1000); - while (QTime::currentTime() < waitForMetar) - { - // process some other events and hope network answer is received already - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); - if (m_metarCache.contains(airportIcaoCode)) - { - metar = this->m_metarCache[airportIcaoCode]; - break; - } - } - } - return metar; + return m_metars.findFirstByOrDefault(&CMetar::getAirportIcaoCode, airportIcaoCode); } CAtcStation CAirspaceMonitor::getAtcStationForComUnit(const CComSystem &comSystem) @@ -400,7 +380,7 @@ namespace BlackCore void CAirspaceMonitor::clear() { - m_metarCache.clear(); + m_metars.clear(); m_flightPlanCache.clear(); m_icaoCodeCache.clear(); @@ -548,21 +528,9 @@ namespace BlackCore this->m_otherClients.applyIf(&CClient::getCallsign, callsign, vm); } - void CAirspaceMonitor::ps_metarReceived(const QString &metarMessage) + void CAirspaceMonitor::ps_metarReceived(const QString & /** metarMessage **/) { - if (!this->m_connected || metarMessage.length() < 10) return; // invalid - const QString icaoCode = metarMessage.left(4).toUpper(); - const QString icaoCodeTower = icaoCode + "_TWR"; - CCallsign callsignTower(icaoCodeTower); - CInformationMessage metar(CInformationMessage::METAR, metarMessage); - - // add METAR to existing stations - CPropertyIndexVariantMap vm(CAtcStation::IndexMetar, CVariant::from(metar)); - this->m_atcStationsOnline.applyIf(&CAtcStation::getCallsign, callsignTower, vm); - this->m_atcStationsBooked.applyIf(&CAtcStation::getCallsign, callsignTower, vm); - this->m_metarCache.insert(icaoCode, metar); - if (this->m_atcStationsOnline.containsCallsign(callsignTower)) { emit this->changedAtcStationsOnline(); } - if (this->m_atcStationsBooked.containsCallsign(callsignTower)) { emit this->changedAtcStationsBooked(); } + // deprecated } void CAirspaceMonitor::ps_flightPlanReceived(const CCallsign &callsign, const CFlightPlan &flightPlan) @@ -647,6 +615,12 @@ namespace BlackCore } } + void CAirspaceMonitor::ps_updateMetars(const CMetarSet &metars) + { + Q_ASSERT(BlackCore::isCurrentThreadObjectThread(this)); + m_metars = metars; + } + void CAirspaceMonitor::ps_sendReadyForModelMatching(const CCallsign &callsign, int trial) { // some checks for special conditions, e.g. logout -> empty list, but still signals pending diff --git a/src/blackcore/airspace_monitor.h b/src/blackcore/airspace_monitor.h index dc522d4e9..f0afe792b 100644 --- a/src/blackcore/airspace_monitor.h +++ b/src/blackcore/airspace_monitor.h @@ -14,12 +14,14 @@ #include "blackcore/blackcoreexport.h" #include "blackcore/network.h" +#include "blackcore/vatsim_metar_reader.h" #include "airspace_analyzer.h" #include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/simulation/ownaircraftprovider.h" #include "blackmisc/simulation/remoteaircraftprovider.h" #include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/aircraftsituationlist.h" +#include "blackmisc/weather/metarset.h" #include "blackmisc/network/clientlist.h" #include "blackmisc/aviation/flightplan.h" #include "blackmisc/network/userlist.h" @@ -116,7 +118,7 @@ namespace BlackCore BlackMisc::Network::CClientList getOtherClientsForCallsigns(const BlackMisc::Aviation::CCallsignSet &callsigns) const; //! Returns a METAR for the given airport, if available - BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode); + BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode); //! Returns the current online ATC stations BlackMisc::Aviation::CAtcStationList getAtcStationsOnline() const { return m_atcStationsOnline; } @@ -205,13 +207,13 @@ namespace BlackCore BlackMisc::Aviation::CAtcStationList m_atcStationsBooked; BlackMisc::Network::CClientList m_otherClients; BlackMisc::Simulation::CSimulatedAircraftList m_aircraftInRange; + BlackMisc::Weather::CMetarSet m_metars; // hashs, because not sorted by key but keeping order CSituationsPerCallsign m_situationsByCallsign; //!< situations, for performance reasons per callsign CPartsPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts - QMap m_metarCache; QMap m_flightPlanCache; QMap m_icaoCodeCache; @@ -277,6 +279,7 @@ namespace BlackCore void ps_frequencyReceived(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::PhysicalQuantities::CFrequency &frequency); void ps_receivedBookings(const BlackMisc::Aviation::CAtcStationList &bookedStations); void ps_receivedDataFile(); + void ps_updateMetars(const BlackMisc::Weather::CMetarSet &metars); void ps_aircraftConfigReceived(const BlackMisc::Aviation::CCallsign &callsign, const QJsonObject &jsonObject, bool isFull); void ps_aircraftInterimUpdateReceived(const BlackMisc::Aviation::CAircraftSituation &situation); void ps_sendInterimPositions(); diff --git a/src/blackcore/context_network.h b/src/blackcore/context_network.h index 225b5fbfb..2634f55a1 100644 --- a/src/blackcore/context_network.h +++ b/src/blackcore/context_network.h @@ -16,6 +16,7 @@ #include "blackcore/context.h" #include "blackmisc/identifier.h" #include "blackmisc/aviation/atcstationlist.h" +#include "blackmisc/weather/metar.h" #include "blackmisc/simulation/simulatedaircraftlist.h" #include "blackmisc/statusmessage.h" #include "blackmisc/statusmessagelist.h" @@ -140,6 +141,9 @@ namespace BlackCore //! Bookings read void vatsimBookingsRead(int number); + //! Metar read + void vatsimMetarsRead(int number); + //! ICAO codes read void aircraftIcaoCodeRead(int number); @@ -238,7 +242,7 @@ namespace BlackCore virtual bool parseCommandLine(const QString &commandLine, const BlackMisc::CIdentifier &originator) = 0; //! Get METAR, if not available request it (code such as EDDF, KLAX) - virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) = 0; + virtual BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) = 0; //! Use the selected COM1/2 frequencies, and get the corresponding voice room for it virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const = 0; diff --git a/src/blackcore/context_network_empty.h b/src/blackcore/context_network_empty.h index 95db313a0..b064de72b 100644 --- a/src/blackcore/context_network_empty.h +++ b/src/blackcore/context_network_empty.h @@ -134,11 +134,11 @@ namespace BlackCore } //! \copydoc IContextNetwork::getMetar - virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override + BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override { Q_UNUSED(airportIcaoCode); logEmptyContextWarning(Q_FUNC_INFO); - return BlackMisc::Aviation::CInformationMessage(); + return {}; } //! \copydoc IContextNetwork::getSelectedVoiceRooms() diff --git a/src/blackcore/context_network_impl.cpp b/src/blackcore/context_network_impl.cpp index fe7f3df79..4b9aa8889 100644 --- a/src/blackcore/context_network_impl.cpp +++ b/src/blackcore/context_network_impl.cpp @@ -14,6 +14,7 @@ #include "context_simulator.h" #include "context_ownaircraft_impl.h" #include "network_vatlib.h" +#include "vatsim_metar_reader.h" #include "airspace_monitor.h" #include "web_datareader.h" #include "blackmisc/networkutils.h" @@ -32,6 +33,7 @@ using namespace BlackMisc::Network; using namespace BlackMisc::Geo; using namespace BlackMisc::Audio; using namespace BlackMisc::Simulation; +using namespace BlackMisc::Weather; namespace BlackCore { @@ -59,7 +61,8 @@ namespace BlackCore this->m_webDataReader = new CWebDataReader(CWebDataReader::AllReaders, this); this->m_webReaderSignalConnections = this->m_webDataReader->connectVatsimDataSignals( std::bind(&CContextNetwork::vatsimBookingsRead, this, std::placeholders::_1), - std::bind(&CContextNetwork::vatsimDataFileRead, this, std::placeholders::_1)); + std::bind(&CContextNetwork::vatsimDataFileRead, this, std::placeholders::_1), + std::bind(&CContextNetwork::vatsimMetarsRead, this, std::placeholders::_1)); this->m_webReaderSignalConnections.append( this->m_webDataReader->connectSwiftDatabaseSignals( this, // the object here must be the same as in the bind @@ -441,6 +444,12 @@ namespace BlackCore m_airspace->analyzer()->setSimulatorRenderRestrictionsChanged(restricted, enabled, maxAircraft, maxRenderedDistance, maxRenderedBoundary); } + void CContextNetwork::ps_updateMetars(const BlackMisc::Weather::CMetarSet &metars) + { + if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO; } + CLogMessage(this).info("%1 METARs updated") << metars.size(); + } + void CContextNetwork::ps_checkForSupervisiorTextMessage(const CTextMessageList &messages) { if (messages.containsPrivateMessages()) @@ -617,7 +626,7 @@ namespace BlackCore this->m_airspace->testAddAircraftParts(parts, incremental); } - BlackMisc::Aviation::CInformationMessage CContextNetwork::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) + CMetar CContextNetwork::getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) { if (this->isDebugEnabled()) { CLogMessage(this, CLogCategory::contextSlot()).debug() << Q_FUNC_INFO << airportIcaoCode; } return m_airspace->getMetar(airportIcaoCode); diff --git a/src/blackcore/context_network_impl.h b/src/blackcore/context_network_impl.h index 10fa04294..fe8af1cb1 100644 --- a/src/blackcore/context_network_impl.h +++ b/src/blackcore/context_network_impl.h @@ -21,6 +21,7 @@ #include "blackmisc/simulation/remoteaircraftprovider.h" #include "blackmisc/aviation/atcstationlist.h" #include "blackmisc/aviation/aircraftsituationlist.h" +#include "blackmisc/weather/metarset.h" #include "blackmisc/setnetwork.h" #include "blackmisc/network/clientlist.h" #include "blackmisc/digestsignal.h" @@ -33,6 +34,7 @@ namespace BlackCore { class CAirspaceMonitor; class CWebDataReader; + class CVatsimMetarReader; //! Network context implementation class BLACKCORE_EXPORT CContextNetwork : @@ -168,7 +170,7 @@ namespace BlackCore virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override; //! \copydoc IContextNetwork::getMetar - virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override; + BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override; //! \copydoc IContextNetwork::getSelectedVoiceRooms() virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override; @@ -244,10 +246,14 @@ namespace BlackCore BlackMisc::CDigestSignal m_dsAtcStationsOnlineChanged { this, &IContextNetwork::changedAtcStationsOnline, &IContextNetwork::changedAtcStationsOnlineDigest, 750, 4 }; BlackMisc::CDigestSignal m_dsAircraftsInRangeChanged { this, &IContextNetwork::changedAircraftInRange, &IContextNetwork::changedAircraftInRangeDigest, 750, 4 }; + //! Own aircraft from \sa CContextOwnAircraft const BlackMisc::Simulation::CSimulatedAircraft ownAircraft() const; private slots: + //! Update METAR collection + void ps_updateMetars(const BlackMisc::Weather::CMetarSet &metars); + //! Check if a supervisor message was received void ps_checkForSupervisiorTextMessage(const BlackMisc::Network::CTextMessageList &messages); diff --git a/src/blackcore/context_network_proxy.cpp b/src/blackcore/context_network_proxy.cpp index 25d651166..130c89fe5 100644 --- a/src/blackcore/context_network_proxy.cpp +++ b/src/blackcore/context_network_proxy.cpp @@ -16,6 +16,7 @@ using namespace BlackMisc; using namespace BlackMisc::Network; using namespace BlackMisc::Aviation; +using namespace BlackMisc::Weather; namespace BlackCore { @@ -75,6 +76,9 @@ namespace BlackCore s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), "vatsimBookingsRead", this, SIGNAL(vatsimBookingsRead(int))); Q_ASSERT(s); + s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), + "vatsimMetarsRead", this, SIGNAL(vatsimMetarsRead(int))); + Q_ASSERT(s); s = connection.connect(serviceName, IContextNetwork::ObjectPath(), IContextNetwork::InterfaceName(), "changedRemoteAircraftModel", this, SIGNAL(changedRemoteAircraftModel(BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::CIdentifier))); Q_ASSERT(s); @@ -268,9 +272,9 @@ namespace BlackCore return this->m_dBusInterface->callDBusRet(QLatin1Literal("loadFlightPlanFromNetwork"), callsign); } - CInformationMessage CContextNetworkProxy::getMetar(const CAirportIcaoCode &airportIcaoCode) + CMetar CContextNetworkProxy::getMetar(const CAirportIcaoCode &airportIcaoCode) { - return this->m_dBusInterface->callDBusRet(QLatin1Literal("getMetar"), airportIcaoCode); + return this->m_dBusInterface->callDBusRet(QLatin1Literal("getMetar"), airportIcaoCode); } } // namespace diff --git a/src/blackcore/context_network_proxy.h b/src/blackcore/context_network_proxy.h index 020dd7176..70879a40a 100644 --- a/src/blackcore/context_network_proxy.h +++ b/src/blackcore/context_network_proxy.h @@ -100,7 +100,7 @@ namespace BlackCore virtual BlackMisc::Aviation::CFlightPlan loadFlightPlanFromNetwork(const BlackMisc::Aviation::CCallsign &callsign) const override; //! \copydoc IContextNetwork::getMetar - virtual BlackMisc::Aviation::CInformationMessage getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override; + BlackMisc::Weather::CMetar getMetar(const BlackMisc::Aviation::CAirportIcaoCode &airportIcaoCode) override; //! \copydoc IContextNetwork::getSelectedVoiceRooms() virtual BlackMisc::Audio::CVoiceRoomList getSelectedVoiceRooms() const override; diff --git a/src/blackcore/global_reader_settings.cpp b/src/blackcore/global_reader_settings.cpp index 98f508910..5733d7a5b 100644 --- a/src/blackcore/global_reader_settings.cpp +++ b/src/blackcore/global_reader_settings.cpp @@ -15,7 +15,8 @@ namespace BlackCore m_protocolIcaoReader("http"), m_serverIcaoReader("ubuntu12"), m_baseUrlIcaoReader("vatrep/public"), m_protocolModelReader("http"), m_serverModelReader("ubuntu12"), m_baseUrlModelReader("vatrep/public"), m_bookingsUrl("http://vatbook.euroutepro.com/xml2.php"), - m_vatsimDataFileUrls({ "http://info.vroute.net/vatsim-data.txt" }) + m_vatsimDataFileUrls({ "http://info.vroute.net/vatsim-data.txt" }), + m_metarUrl("http://metar.vatsim.net/metar.php?id=all") { } const CGlobalReaderSettings &CGlobalReaderSettings::instance() diff --git a/src/blackcore/global_reader_settings.h b/src/blackcore/global_reader_settings.h index 346832b50..2049a087a 100644 --- a/src/blackcore/global_reader_settings.h +++ b/src/blackcore/global_reader_settings.h @@ -46,6 +46,9 @@ namespace BlackCore //! VATSIM data file URLs const QStringList &vatsimDataFileUrls() const { return m_vatsimDataFileUrls; } + //! VATSIM metar url + const QString &vatsimMetarUrl() const { return m_metarUrl; } + //! Singleton static const CGlobalReaderSettings &instance(); @@ -64,6 +67,7 @@ namespace BlackCore QString m_baseUrlModelReader; QString m_bookingsUrl; QStringList m_vatsimDataFileUrls; + QString m_metarUrl; }; } #endif // guard diff --git a/src/blackcore/web_datareader.cpp b/src/blackcore/web_datareader.cpp index d6789d214..9a7c1da54 100644 --- a/src/blackcore/web_datareader.cpp +++ b/src/blackcore/web_datareader.cpp @@ -10,6 +10,7 @@ #include "blackcore/web_datareader.h" #include "vatsimbookingreader.h" #include "vatsimdatafilereader.h" +#include "vatsim_metar_reader.h" #include "icaodatareader.h" #include "modeldatareader.h" #include "global_reader_settings.h" @@ -32,7 +33,9 @@ namespace BlackCore this->initReaders(readerFlags); } - QList CWebDataReader::connectVatsimDataSignals(std::function bookingsRead, std::function dataFileRead) + QList CWebDataReader::connectVatsimDataSignals(std::function bookingsRead, + std::function dataFileRead, + std::function metarRead) { // bind does not allow to define connection type // so anything in its own thread will be sent with this thread affinity @@ -51,6 +54,13 @@ namespace BlackCore Q_ASSERT_X(c2, Q_FUNC_INFO, "connect failed"); cl.append(c2); } + + if (m_readerFlags.testFlag(VatsimMetarReader)) + { + QMetaObject::Connection c3 = connect(this, &CWebDataReader::vatsimMetarRead, metarRead); + Q_ASSERT_X(c3, Q_FUNC_INFO, "connect failed"); + cl.append(c3); + } return cl; } @@ -138,6 +148,7 @@ namespace BlackCore this->disconnect(); // all signals if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); } if (this->m_vatsimDataFileReader) { this->m_vatsimDataFileReader->requestStop(); this->m_vatsimDataFileReader->quit(); } + if (this->m_vatsimMetarReader) { this->m_vatsimMetarReader->requestStop(); this->m_vatsimMetarReader->quit(); } } const CLogCategoryList &CWebDataReader::getLogCategories() @@ -166,7 +177,16 @@ namespace BlackCore this->m_vatsimDataFileReader->setInterval(90 * 1000); } - // 3. ICAO data reader + // 3. VATSIM metar + if (flags.testFlag(VatsimMetarReader)) + { + this->m_vatsimMetarReader = new CVatsimMetarReader(this, CGlobalReaderSettings::instance().vatsimMetarUrl()); + connect(this->m_vatsimMetarReader, &CVatsimMetarReader::metarUpdated, this, &CWebDataReader::ps_metarRead); + this->m_vatsimMetarReader->start(); + this->m_vatsimMetarReader->setInterval(5 * 60 * 1000); + } + + // 4. ICAO data reader if (flags.testFlag(IcaoDataReader)) { this->m_icaoDataReader = new CIcaoDataReader(this, CGlobalReaderSettings::instance().protocolIcaoReader(), CGlobalReaderSettings::instance().serverIcaoReader(), CGlobalReaderSettings::instance().baseUrlIcaoReader()); @@ -175,7 +195,7 @@ namespace BlackCore this->m_icaoDataReader->start(); } - // 4. Model reader + // 5. Model reader if (flags.testFlag(ModelReader)) { this->m_modelDataReader = new CModelDataReader(this, CGlobalReaderSettings::instance().protocolModelReader(), CGlobalReaderSettings::instance().serverModelReader(), CGlobalReaderSettings::instance().baseUrlModelReader()); @@ -198,6 +218,12 @@ namespace BlackCore emit vatsimDataFileRead(lines); } + void CWebDataReader::ps_metarRead(const BlackMisc::Weather::CMetarSet &metars) + { + CLogMessage(this).info("Read %1 VATSIM metar stations") << metars.size(); + emit vatsimMetarRead(metars.size()); + } + void CWebDataReader::ps_readAircraftIcaoCodes(int number) { CLogMessage(this).info("Read %1 aircraft ICAO codes") << number; @@ -241,6 +267,7 @@ namespace BlackCore if (this->m_vatsimBookingReader) {this->m_vatsimBookingReader->readInBackgroundThread(); } if (this->m_vatsimDataFileReader) this->m_vatsimDataFileReader->readInBackgroundThread(); + if (this->m_vatsimMetarReader) this->m_vatsimMetarReader->readInBackgroundThread(); if (this->m_icaoDataReader) { this->m_icaoDataReader->readInBackgroundThread(); } if (this->m_modelDataReader) { this->m_modelDataReader->readInBackgroundThread(); } } diff --git a/src/blackcore/web_datareader.h b/src/blackcore/web_datareader.h index 81ee3a017..d2760cbe5 100644 --- a/src/blackcore/web_datareader.h +++ b/src/blackcore/web_datareader.h @@ -20,6 +20,7 @@ #include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/network/serverlist.h" #include "blackmisc/simulation/distributorlist.h" +#include "blackmisc/weather/metarset.h" #include namespace BlackCore @@ -28,6 +29,7 @@ namespace BlackCore class CVatsimDataFileReader; class CIcaoDataReader; class CModelDataReader; + class CVatsimMetarReader; /** * Encapsulates reading data from web sources @@ -43,9 +45,10 @@ namespace BlackCore None = 0, VatsimBookingReader = 1 << 0, VatsimDataReader = 1 << 1, - IcaoDataReader = 1 << 2, - ModelReader = 1 << 3, - AllVatsimReaders = VatsimBookingReader | VatsimDataReader, + VatsimMetarReader = 1 << 2, + IcaoDataReader = 1 << 3, + ModelReader = 1 << 4, + AllVatsimReaders = VatsimBookingReader | VatsimDataReader | VatsimMetarReader, AllSwiftDbReaders = IcaoDataReader | ModelReader, AllReaders = 0xFFFF }; @@ -58,7 +61,9 @@ namespace BlackCore void gracefulShutdown(); //! Relay signals for VATSIM data - QList connectVatsimDataSignals(std::function bookingsRead, std::function dataFileRead); + QList connectVatsimDataSignals(std::function bookingsRead, + std::function dataFileRead, + std::function metarRead); //! Relay signals for swift data QList connectSwiftDatabaseSignals( @@ -100,6 +105,9 @@ namespace BlackCore //! Data file reader CVatsimDataFileReader *getDataFileReader() const { return m_vatsimDataFileReader; } + //! Metar reader + CVatsimMetarReader *getMetarReader() const { return m_vatsimMetarReader; } + //! Reader flags WebReader getReaderFlags() const { return m_readerFlags; } @@ -117,6 +125,9 @@ namespace BlackCore //! Bookings read void vatsimBookingsRead(int number); + //! Metars read + void vatsimMetarRead(int number); + //! ICAO codes read void aircraftIcaoCodeRead(int number); @@ -139,6 +150,9 @@ namespace BlackCore //! Data file has been read void ps_dataFileRead(int lines); + //! Metars have been read + void ps_metarRead(const BlackMisc::Weather::CMetarSet &metars); + //! Read ICAO codes void ps_readAircraftIcaoCodes(int number); @@ -163,6 +177,7 @@ namespace BlackCore // for reading XML and VATSIM data files CVatsimBookingReader *m_vatsimBookingReader = nullptr; CVatsimDataFileReader *m_vatsimDataFileReader = nullptr; + CVatsimMetarReader *m_vatsimMetarReader = nullptr; CIcaoDataReader *m_icaoDataReader = nullptr; CModelDataReader *m_modelDataReader = nullptr; }; diff --git a/src/blackgui/components/atcstationcomponent.cpp b/src/blackgui/components/atcstationcomponent.cpp index 78c031cd1..4784fa4f1 100644 --- a/src/blackgui/components/atcstationcomponent.cpp +++ b/src/blackgui/components/atcstationcomponent.cpp @@ -12,6 +12,7 @@ #include "ui_atcstationcomponent.h" #include "blackmisc/aviation/informationmessage.h" #include "blackmisc/logmessage.h" +#include "blackmisc/weather/metar.h" #include "blackcore/context_network.h" #include "blackcore/context_ownaircraft.h" @@ -21,6 +22,7 @@ using namespace BlackGui::Views; using namespace BlackMisc; using namespace BlackMisc::Aviation; using namespace BlackMisc::PhysicalQuantities; +using namespace BlackMisc::Weather; using namespace BlackCore; namespace BlackGui @@ -135,7 +137,6 @@ namespace BlackGui { this->ui->tvp_AtcStationsOnline->clear(); this->updateTreeView(); - this->ui->le_AtcStationsOnlineMetar->clear(); } } @@ -146,24 +147,22 @@ namespace BlackGui void CAtcStationComponent::getMetar(const QString &airportIcaoCode) { - if (!this->getIContextNetwork()->isConnected()) - { - this->ui->te_AtcStationsOnlineInfo->clear(); - return; - } QString icao = airportIcaoCode.isEmpty() ? this->ui->le_AtcStationsOnlineMetar->text().trimmed().toUpper() : airportIcaoCode.trimmed().toUpper(); this->ui->le_AtcStationsOnlineMetar->setText(icao); if (icao.length() != 4) { return; } - CInformationMessage metar = this->getIContextNetwork()->getMetar(icao); - if (metar.getType() != CInformationMessage::METAR) { return; } - if (metar.isEmpty()) + CMetar metar = this->getIContextNetwork()->getMetar(icao); + if (metar == CMetar()) { this->ui->te_AtcStationsOnlineInfo->clear(); } else { - this->ui->te_AtcStationsOnlineInfo->setText(metar.getMessage()); + QString metarText = metar.getMessage(); + metarText += "\n\n"; + metarText += metar.getMetarText(); + this->ui->te_AtcStationsOnlineInfo->setText(metarText); } + this->ui->le_AtcStationsOnlineMetar->clear(); } void CAtcStationComponent::ps_reloadAtcStationsBooked() @@ -210,7 +209,6 @@ namespace BlackGui { this->ui->tvp_AtcStationsOnline->clear(); this->updateTreeView(); - this->ui->le_AtcStationsOnlineMetar->clear(); } }