From 784cf287f0d881d35a2636bb17991ac17798dfd5 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 1 Oct 2017 04:01:28 +0200 Subject: [PATCH] Ref T129, extended flight plan utils * renamed to CFlightPlanUtils::FlightPlanRemarks * now parsing also SELCAL, airline ICAO --- src/blackcore/airspacemonitor.cpp | 4 +- src/blackcore/airspacemonitor.h | 2 +- src/blackmisc/aviation/flightplanutils.cpp | 68 +++++++++++++++------- src/blackmisc/aviation/flightplanutils.h | 31 +++++++--- 4 files changed, 74 insertions(+), 31 deletions(-) diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index e5ec927cd..29a11bec8 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -923,8 +923,8 @@ namespace BlackCore CAirlineIcaoCode airlineIcao(airlineIcaoString); if (!fpRemarks.isEmpty()) { - const CFlightPlanUtils::AirlineRemarks ar = CFlightPlanUtils::parseFlightPlanAirlineRemarks(fpRemarks); - if (ar.hasAnyRemarks()) + const CFlightPlanUtils::FlightPlanRemarks ar = CFlightPlanUtils::parseFlightPlanRemarks(fpRemarks); + if (ar.hasAirlineRemarks()) { const QString airlineName = CAircraftMatcher::reverseLookupAirlineName(ar.flightOperator, callsign, log); if (!airlineName.isEmpty()) diff --git a/src/blackcore/airspacemonitor.h b/src/blackcore/airspacemonitor.h index 6acb442ca..1bc930870 100644 --- a/src/blackcore/airspacemonitor.h +++ b/src/blackcore/airspacemonitor.h @@ -248,7 +248,7 @@ namespace BlackCore CPartsPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign, thread safe access required BlackMisc::Aviation::CCallsignSet m_aircraftSupportingParts; //!< aircraft supporting parts, thread safe access required - QMap m_flightPlanCache; //!< flight plan information retrieved any cached + QMap m_flightPlanCache; //!< flight plan information retrieved from network and cached INetwork *m_network = nullptr; //!< corresponding network interface CAirspaceAnalyzer *m_analyzer = nullptr; //!< owned analyzer diff --git a/src/blackmisc/aviation/flightplanutils.cpp b/src/blackmisc/aviation/flightplanutils.cpp index c3112efc0..d1bb8e0b4 100644 --- a/src/blackmisc/aviation/flightplanutils.cpp +++ b/src/blackmisc/aviation/flightplanutils.cpp @@ -8,32 +8,39 @@ */ #include "flightplanutils.h" +#include "airlineicaocode.h" #include +#include + +using namespace BlackMisc::Network; namespace BlackMisc { namespace Aviation { - CFlightPlanUtils::AirlineRemarks CFlightPlanUtils::parseFlightPlanAirlineRemarks(const QString &remarks) + CFlightPlanUtils::FlightPlanRemarks CFlightPlanUtils::parseFlightPlanRemarks(const QString &remarks, const CVoiceCapabilities voiceCapabilities) { - AirlineRemarks ar; + // examples: VFPS = VATSIM Flightplan Prefile System + // 1) RT/KESTREL OPR/MYTRAVEL REG/G-DAJC SEL/FP-ES PER/C NAV/RNP10 + // 2) OPR/UAL CALLSIGN/UNITED + // 3) /v/FPL-VIR9-IS-A346/DEP/S-EGLL/ARR/KJFK/REG/G-VGAS/TCAS RVR/200 OPR/VIRGI + + FlightPlanRemarks ar; // marked as NULL so far if (remarks.isEmpty()) { return ar; } const QString r = remarks.toUpper(); - if (r.contains("/CALLSIGN")) + const QString cs = cut(r, "/REG"); // registration is what we call callsign + if (!cs.isEmpty()) { ar.callsign = CCallsign(cs, CCallsign::Aircraft); } + ar.voiceCapabilities = voiceCapabilities.isUnknown() ? CVoiceCapabilities(remarks) : voiceCapabilities; + ar.flightOperator = cut(r, "/OPR"); // operator, e.g. British airways, sometimes people use ICAO code here + ar.selcal = cut(r, "/SEL"); // SELCAL + ar.radioTelephony = cut(r, "/CALLSIGN"); // used similar to radio telephony + if (ar.radioTelephony.isEmpty()) { ar.radioTelephony = cut(r, "/RT"); } + if (!ar.flightOperator.isEmpty() && CAirlineIcaoCode::isValidAirlineDesignator(ar.flightOperator)) { - // used similar to radio telephony - ar.radioTelephony = cut(r, "/CALLSIGN"); - } - else if (r.contains("/RT")) - { - // radio telephony designator - ar.radioTelephony = cut(r, "/RT"); - } - if (r.contains("/OPR")) - { - // operator, e.g. British airways - ar.flightOperator = cut(r, "/OPR"); + // move to airline ICAO + qSwap(ar.flightOperator, ar.airlineIcao); } + ar.isNull = false; return ar; } @@ -47,12 +54,33 @@ namespace BlackMisc int to = remarks.indexOf(' ', f + 1); if (to < 0) { to = maxIndex; } // no more spaces const QString cut = remarks.mid(f, to - f).replace('/', ' '); // variations like /OPR/EASYJET/ - // problem is that this cuts something like "Uzbekistan airways" + // problem is that this cuts something like "Uzbekistan Airways" return cut; } + + QString CFlightPlanUtils::aircraftIcaoCodeFromEquipmentCode(const QString &equipmentCodeAndAircraft) + { + // http://uk.flightaware.com/about/faq_aircraft_flight_plan_suffix.rvt + // we expect something like H/B772/F B773 B773/F + thread_local const QRegularExpression reg("/."); + QString aircraftIcaoCode(equipmentCodeAndAircraft); + aircraftIcaoCode = aircraftIcaoCode.replace(reg, "").trimmed().toUpper(); + return aircraftIcaoCode; + } + + bool CFlightPlanUtils::FlightPlanRemarks::hasAnyRemarks() const + { + return this->hasAirlineRemarks() || !selcal.isEmpty() || !voiceCapabilities.isUnknown(); + } + + bool CFlightPlanUtils::FlightPlanRemarks::hasAirlineRemarks() const + { + return !radioTelephony.isEmpty() || !flightOperator.isEmpty() || !airlineIcao.isEmpty(); + } + + bool CFlightPlanUtils::FlightPlanRemarks::hasValidAirlineIcao() const + { + return !airlineIcao.isEmpty(); // member only set if valid + } } // namespace } // namespace - -// RT/KESTREL OPR/MYTRAVEL REG/G-DAJC SEL/FP-ES PER/C NAV/RNP10 -// VFPS = VATSIM Flightplan Prefile System -// OPR/UAL CALLSIGN/UNITED diff --git a/src/blackmisc/aviation/flightplanutils.h b/src/blackmisc/aviation/flightplanutils.h index 0a2b6eff2..dfb2413b2 100644 --- a/src/blackmisc/aviation/flightplanutils.h +++ b/src/blackmisc/aviation/flightplanutils.h @@ -13,6 +13,8 @@ #define BLACKMISC_AVIATION_FLIGHTPLANUTILS_H #include "blackmisc/blackmiscexport.h" +#include "blackmisc/network/voicecapabilities.h" +#include "callsign.h" #include namespace BlackMisc @@ -23,24 +25,37 @@ namespace BlackMisc class BLACKMISC_EXPORT CFlightPlanUtils { public: - //! Useful value in flight plan remarks - struct AirlineRemarks + //! Useful values in flight plan remarks + struct BLACKMISC_EXPORT FlightPlanRemarks { QString radioTelephony; //!< radio telephony designator QString flightOperator; //!< operator, i.e. normally the airline name + QString airlineIcao; //!< airline ICAO as provided in flightplan + QString selcal; //!< SELCAL + CCallsign callsign; //!< callsign of other pilot + bool isNull = true; //!< marked as NULL + Network::CVoiceCapabilities voiceCapabilities; //!< voice capabilities - //! Any remarks available - bool hasAnyRemarks() const - { - return !radioTelephony.isEmpty() || !flightOperator.isEmpty(); - } + //! Any remarks available? + bool hasAnyRemarks() const; + + //! Airline remarks + bool hasAirlineRemarks() const; + + //! Valid airline ICAO? + //! \remark valid here means valid syntax, no guarantee it really exists + bool hasValidAirlineIcao() const; }; //! Constructor CFlightPlanUtils() = delete; //! Parse remarks from a flight plan - static AirlineRemarks parseFlightPlanAirlineRemarks(const QString &remarks); + static FlightPlanRemarks parseFlightPlanRemarks(const QString &remarks, const Network::CVoiceCapabilities voiceCapabilities = {}); + + //! Get aircraft ICAO code from equipment code like + //! \remark we expect something like H/B772/F B773 B773/F + static QString aircraftIcaoCodeFromEquipmentCode(const QString &equipmentCodeAndAircraft); private: //! Cut the remarks part