mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-21 04:45:31 +08:00
feat: Add ICAO equipment code classes
This commit is contained in:
@@ -71,10 +71,14 @@ add_library(misc SHARED
|
|||||||
aviation/callsignobjectlist.h
|
aviation/callsignobjectlist.h
|
||||||
aviation/callsignset.cpp
|
aviation/callsignset.cpp
|
||||||
aviation/callsignset.h
|
aviation/callsignset.h
|
||||||
|
aviation/comnavequipment.cpp
|
||||||
|
aviation/comnavequipment.h
|
||||||
aviation/comsystem.cpp
|
aviation/comsystem.cpp
|
||||||
aviation/comsystem.h
|
aviation/comsystem.h
|
||||||
aviation/flightplan.cpp
|
aviation/flightplan.cpp
|
||||||
aviation/flightplan.h
|
aviation/flightplan.h
|
||||||
|
aviation/flightplanaircraftinfo.cpp
|
||||||
|
aviation/flightplanaircraftinfo.h
|
||||||
aviation/flightplanlist.cpp
|
aviation/flightplanlist.cpp
|
||||||
aviation/flightplanlist.h
|
aviation/flightplanlist.h
|
||||||
aviation/heading.cpp
|
aviation/heading.cpp
|
||||||
@@ -95,6 +99,8 @@ add_library(misc SHARED
|
|||||||
aviation/selcal.h
|
aviation/selcal.h
|
||||||
aviation/simbriefdata.cpp
|
aviation/simbriefdata.cpp
|
||||||
aviation/simbriefdata.h
|
aviation/simbriefdata.h
|
||||||
|
aviation/ssrequipment.cpp
|
||||||
|
aviation/ssrequipment.h
|
||||||
aviation/track.cpp
|
aviation/track.cpp
|
||||||
aviation/track.h
|
aviation/track.h
|
||||||
aviation/transponder.cpp
|
aviation/transponder.cpp
|
||||||
|
|||||||
212
src/blackmisc/aviation/comnavequipment.cpp
Normal file
212
src/blackmisc/aviation/comnavequipment.cpp
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
#include "comnavequipment.h"
|
||||||
|
|
||||||
|
BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CComNavEquipment)
|
||||||
|
|
||||||
|
namespace BlackMisc::Aviation
|
||||||
|
{
|
||||||
|
CComNavEquipment::CComNavEquipment(ComNavEquipment comNavEquipment, CpdlcSatcomEquipment cpdlcSatcomEquipment) : m_equipment(comNavEquipment), m_cpdlcSatcomEquipment(cpdlcSatcomEquipment)
|
||||||
|
{
|
||||||
|
if (m_equipment == ComNavEquipment())
|
||||||
|
{
|
||||||
|
m_equipment = NoEquip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CComNavEquipment::CComNavEquipment(QString equipment)
|
||||||
|
{
|
||||||
|
if (equipment.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_equipment = {}; // Clear default flag
|
||||||
|
|
||||||
|
auto append_equipment_flag_if_exist = [&equipment, this](ComNavEquipmentOption flag) {
|
||||||
|
QString str = flagToString(flag);
|
||||||
|
if (equipment.contains(str))
|
||||||
|
{
|
||||||
|
equipment = equipment.remove(str);
|
||||||
|
m_equipment |= flag;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto append_satcom_flag_if_exist = [&equipment, this](CpdlcSatcomEquipmentOption flag) {
|
||||||
|
QString str = flagToString(flag);
|
||||||
|
if (equipment.contains(str))
|
||||||
|
{
|
||||||
|
equipment = equipment.remove(str);
|
||||||
|
m_cpdlcSatcomEquipment |= flag;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
append_equipment_flag_if_exist(Standard);
|
||||||
|
append_equipment_flag_if_exist(Gbas);
|
||||||
|
append_equipment_flag_if_exist(Lpv);
|
||||||
|
append_equipment_flag_if_exist(LoranC);
|
||||||
|
append_equipment_flag_if_exist(Dme);
|
||||||
|
append_equipment_flag_if_exist(FmcAcars);
|
||||||
|
append_equipment_flag_if_exist(DFisAcars);
|
||||||
|
append_equipment_flag_if_exist(PdcAcars);
|
||||||
|
append_equipment_flag_if_exist(Adf);
|
||||||
|
append_equipment_flag_if_exist(Gnss);
|
||||||
|
append_equipment_flag_if_exist(HfRtf);
|
||||||
|
append_equipment_flag_if_exist(InertiaNavigation);
|
||||||
|
append_equipment_flag_if_exist(Mls);
|
||||||
|
append_equipment_flag_if_exist(Ils);
|
||||||
|
append_equipment_flag_if_exist(NoEquip);
|
||||||
|
append_equipment_flag_if_exist(Vor);
|
||||||
|
append_equipment_flag_if_exist(Pbn);
|
||||||
|
append_equipment_flag_if_exist(Tacan);
|
||||||
|
append_equipment_flag_if_exist(UhfRtf);
|
||||||
|
append_equipment_flag_if_exist(VhfRtf);
|
||||||
|
append_equipment_flag_if_exist(Rvsm);
|
||||||
|
append_equipment_flag_if_exist(Mnps);
|
||||||
|
append_equipment_flag_if_exist(Vhf833);
|
||||||
|
append_equipment_flag_if_exist(Other);
|
||||||
|
append_satcom_flag_if_exist(CpdlcAtn);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansHfdl);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansVdlA);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansVdl2);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansSatcomInmarsat);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansSatcomMtsat);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansSatcomIridium);
|
||||||
|
append_satcom_flag_if_exist(AtcSatvoiceInmarsat);
|
||||||
|
append_satcom_flag_if_exist(AtcSatvoiceMtsat);
|
||||||
|
append_satcom_flag_if_exist(AtcSatvoiceIridium);
|
||||||
|
append_satcom_flag_if_exist(CpdlcRcp400);
|
||||||
|
append_satcom_flag_if_exist(CpdlcRcp240);
|
||||||
|
append_satcom_flag_if_exist(SatvoiceRcp400);
|
||||||
|
|
||||||
|
if (!equipment.isEmpty() && m_equipment == ComNavEquipment())
|
||||||
|
{
|
||||||
|
// Default if nothing correct is provided
|
||||||
|
m_equipment = NoEquip;
|
||||||
|
m_cpdlcSatcomEquipment = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CComNavEquipment::enabledOptions() const
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
auto append_equipment_flag_if_exist = [&list, this](ComNavEquipmentOption flag) {
|
||||||
|
if (m_equipment.testFlag(flag)) list << flagToString(flag);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto append_satcom_flag_if_exist = [&list, this](CpdlcSatcomEquipmentOption flag) {
|
||||||
|
if (m_cpdlcSatcomEquipment.testFlag(flag)) list << flagToString(flag);
|
||||||
|
};
|
||||||
|
|
||||||
|
append_equipment_flag_if_exist(Standard);
|
||||||
|
append_equipment_flag_if_exist(Gbas);
|
||||||
|
append_equipment_flag_if_exist(Lpv);
|
||||||
|
append_equipment_flag_if_exist(LoranC);
|
||||||
|
append_equipment_flag_if_exist(Dme);
|
||||||
|
append_equipment_flag_if_exist(FmcAcars);
|
||||||
|
append_equipment_flag_if_exist(DFisAcars);
|
||||||
|
append_equipment_flag_if_exist(PdcAcars);
|
||||||
|
append_equipment_flag_if_exist(Adf);
|
||||||
|
append_equipment_flag_if_exist(Gnss);
|
||||||
|
append_equipment_flag_if_exist(HfRtf);
|
||||||
|
append_equipment_flag_if_exist(InertiaNavigation);
|
||||||
|
append_satcom_flag_if_exist(CpdlcAtn);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansHfdl);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansVdlA);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansVdl2);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansSatcomInmarsat);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansSatcomMtsat);
|
||||||
|
append_satcom_flag_if_exist(CpdlcFansSatcomIridium);
|
||||||
|
append_equipment_flag_if_exist(Mls);
|
||||||
|
append_equipment_flag_if_exist(Ils);
|
||||||
|
append_satcom_flag_if_exist(AtcSatvoiceInmarsat);
|
||||||
|
append_satcom_flag_if_exist(AtcSatvoiceMtsat);
|
||||||
|
append_satcom_flag_if_exist(AtcSatvoiceIridium);
|
||||||
|
append_equipment_flag_if_exist(NoEquip);
|
||||||
|
append_equipment_flag_if_exist(Vor);
|
||||||
|
append_satcom_flag_if_exist(CpdlcRcp400);
|
||||||
|
append_satcom_flag_if_exist(CpdlcRcp240);
|
||||||
|
append_satcom_flag_if_exist(SatvoiceRcp400);
|
||||||
|
append_equipment_flag_if_exist(Pbn);
|
||||||
|
append_equipment_flag_if_exist(Tacan);
|
||||||
|
append_equipment_flag_if_exist(UhfRtf);
|
||||||
|
append_equipment_flag_if_exist(VhfRtf);
|
||||||
|
append_equipment_flag_if_exist(Rvsm);
|
||||||
|
append_equipment_flag_if_exist(Mnps);
|
||||||
|
append_equipment_flag_if_exist(Vhf833);
|
||||||
|
append_equipment_flag_if_exist(Other);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CComNavEquipment::convertToQString(bool) const
|
||||||
|
{
|
||||||
|
const QString equipmentString = enabledOptions().join("");
|
||||||
|
Q_ASSERT_X(!equipmentString.isEmpty(), Q_FUNC_INFO, "Equipment string should not be empty");
|
||||||
|
return equipmentString;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CComNavEquipment::flagToString(CpdlcSatcomEquipmentOption flag)
|
||||||
|
{
|
||||||
|
switch (flag)
|
||||||
|
{
|
||||||
|
case CpdlcAtn: return QStringLiteral("J1");
|
||||||
|
case CpdlcFansHfdl: return QStringLiteral("J2");
|
||||||
|
case CpdlcFansVdlA: return QStringLiteral("J3");
|
||||||
|
case CpdlcFansVdl2: return QStringLiteral("J4");
|
||||||
|
case CpdlcFansSatcomInmarsat: return QStringLiteral("J5");
|
||||||
|
case CpdlcFansSatcomMtsat: return QStringLiteral("J6");
|
||||||
|
case CpdlcFansSatcomIridium: return QStringLiteral("J7");
|
||||||
|
case AtcSatvoiceInmarsat: return QStringLiteral("M1");
|
||||||
|
case AtcSatvoiceMtsat: return QStringLiteral("M2");
|
||||||
|
case AtcSatvoiceIridium: return QStringLiteral("M3");
|
||||||
|
case CpdlcRcp400: return QStringLiteral("P1");
|
||||||
|
case CpdlcRcp240: return QStringLiteral("P2");
|
||||||
|
case SatvoiceRcp400: return QStringLiteral("P3");
|
||||||
|
default: return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CComNavEquipment::flagToString(ComNavEquipmentOption flag)
|
||||||
|
{
|
||||||
|
switch (flag)
|
||||||
|
{
|
||||||
|
case Standard: return QStringLiteral("S");
|
||||||
|
case Gbas: return QStringLiteral("A");
|
||||||
|
case Lpv: return QStringLiteral("B");
|
||||||
|
case LoranC: return QStringLiteral("C");
|
||||||
|
case Dme: return QStringLiteral("D");
|
||||||
|
case FmcAcars: return QStringLiteral("E1");
|
||||||
|
case DFisAcars: return QStringLiteral("E2");
|
||||||
|
case PdcAcars: return QStringLiteral("E3");
|
||||||
|
case Adf: return QStringLiteral("F");
|
||||||
|
case Gnss: return QStringLiteral("G");
|
||||||
|
case HfRtf: return QStringLiteral("H");
|
||||||
|
case InertiaNavigation: return QStringLiteral("I");
|
||||||
|
case Mls: return QStringLiteral("K");
|
||||||
|
case Ils: return QStringLiteral("L");
|
||||||
|
case NoEquip: return QStringLiteral("N");
|
||||||
|
case Vor: return QStringLiteral("O");
|
||||||
|
case Pbn: return QStringLiteral("R");
|
||||||
|
case Tacan: return QStringLiteral("T");
|
||||||
|
case UhfRtf: return QStringLiteral("U");
|
||||||
|
case VhfRtf: return QStringLiteral("V");
|
||||||
|
case Rvsm: return QStringLiteral("W");
|
||||||
|
case Mnps: return QStringLiteral("X");
|
||||||
|
case Vhf833: return QStringLiteral("Y");
|
||||||
|
case Other: return QStringLiteral("Z");
|
||||||
|
default: return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CComNavEquipment::allEquipmentLetters()
|
||||||
|
{
|
||||||
|
// In order as they appear in the final string
|
||||||
|
static const QStringList r({ "S", "A", "B", "C", "D", "E1", "E2", "E3", "F", "G", "H", "I", "J1", "J2", "J3", "J4", "J5", "J6", "J7", "K", "L", "M1", "M2", "M3",
|
||||||
|
"N", "O", "P1", "P2", "P3", "R", "T", "U", "V", "W", "X", "Y", "Z" });
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
116
src/blackmisc/aviation/comnavequipment.h
Normal file
116
src/blackmisc/aviation/comnavequipment.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_AVIATION_COMNAVEQUIPMENT_H
|
||||||
|
#define BLACKMISC_AVIATION_COMNAVEQUIPMENT_H
|
||||||
|
|
||||||
|
#include "blackmisc/blackmiscexport.h"
|
||||||
|
#include "blackmisc/valueobject.h"
|
||||||
|
|
||||||
|
BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CComNavEquipment)
|
||||||
|
|
||||||
|
namespace BlackMisc::Aviation
|
||||||
|
{
|
||||||
|
//! ICAO flightplan field 10a
|
||||||
|
class BLACKMISC_EXPORT CComNavEquipment : public BlackMisc::CValueObject<CComNavEquipment>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// QFlag uses int as an underlying type. Hence, the equipment is split up into two enums.
|
||||||
|
// Once Qt adds a QFlag64, these can be united.
|
||||||
|
// See https://bugreports.qt.io/browse/QTBUG-53178
|
||||||
|
|
||||||
|
//! CPLDC and SATCOM equipment options
|
||||||
|
enum CpdlcSatcomEquipmentOption : int
|
||||||
|
{
|
||||||
|
CpdlcAtn = (1 << 0),
|
||||||
|
CpdlcFansHfdl = (1 << 1),
|
||||||
|
CpdlcFansVdlA = (1 << 2),
|
||||||
|
CpdlcFansVdl2 = (1 << 3),
|
||||||
|
CpdlcFansSatcomInmarsat = (1 << 4),
|
||||||
|
CpdlcFansSatcomMtsat = (1 << 5),
|
||||||
|
CpdlcFansSatcomIridium = (1 << 6),
|
||||||
|
AtcSatvoiceInmarsat = (1 << 7),
|
||||||
|
AtcSatvoiceMtsat = (1 << 8),
|
||||||
|
AtcSatvoiceIridium = (1 << 9),
|
||||||
|
CpdlcRcp400 = (1 << 10),
|
||||||
|
CpdlcRcp240 = (1 << 11),
|
||||||
|
SatvoiceRcp400 = (1 << 12),
|
||||||
|
};
|
||||||
|
|
||||||
|
//! COM/NAV equipment options
|
||||||
|
enum ComNavEquipmentOption : int
|
||||||
|
{
|
||||||
|
Standard = (1 << 0),
|
||||||
|
Gbas = (1 << 1),
|
||||||
|
Lpv = (1 << 2),
|
||||||
|
LoranC = (1 << 3),
|
||||||
|
Dme = (1 << 4),
|
||||||
|
FmcAcars = (1 << 5),
|
||||||
|
DFisAcars = (1 << 6),
|
||||||
|
PdcAcars = (1 << 7),
|
||||||
|
Adf = (1 << 8),
|
||||||
|
Gnss = (1 << 9),
|
||||||
|
HfRtf = (1 << 10),
|
||||||
|
InertiaNavigation = (1 << 11),
|
||||||
|
Mls = (1 << 12),
|
||||||
|
Ils = (1 << 13),
|
||||||
|
NoEquip = (1 << 14),
|
||||||
|
Vor = (1 << 15),
|
||||||
|
Pbn = (1 << 16),
|
||||||
|
Tacan = (1 << 17),
|
||||||
|
UhfRtf = (1 << 18),
|
||||||
|
VhfRtf = (1 << 19),
|
||||||
|
Rvsm = (1 << 20),
|
||||||
|
Mnps = (1 << 21),
|
||||||
|
Vhf833 = (1 << 22),
|
||||||
|
Other = (1 << 23)
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_FLAGS(ComNavEquipment, ComNavEquipmentOption);
|
||||||
|
Q_DECLARE_FLAGS(CpdlcSatcomEquipment, CpdlcSatcomEquipmentOption);
|
||||||
|
|
||||||
|
//! Create default equipment with Standard COM/NAV
|
||||||
|
CComNavEquipment() = default;
|
||||||
|
|
||||||
|
//! Create object with given COM/NAV, CPDLC and SATCOM equipment
|
||||||
|
CComNavEquipment(ComNavEquipment comNavEquipment, CpdlcSatcomEquipment cpdlcSatcomEquipment);
|
||||||
|
|
||||||
|
//! Create object from an ICAO equipment string (for example "SDE2E3FGHIJ1RWXY")
|
||||||
|
explicit CComNavEquipment(QString equipment);
|
||||||
|
|
||||||
|
//! Get all possible equipment code letters
|
||||||
|
static QStringList allEquipmentLetters();
|
||||||
|
|
||||||
|
//! @{
|
||||||
|
//! Does this object contains \p equip?
|
||||||
|
bool hasEquipment(ComNavEquipmentOption equip) const { return m_equipment.testFlag(equip); }
|
||||||
|
bool hasEquipment(CpdlcSatcomEquipmentOption equip) const { return m_cpdlcSatcomEquipment.testFlag(equip); }
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
//! Get all enabled equipment codes of this object as a list
|
||||||
|
QStringList enabledOptions() const;
|
||||||
|
|
||||||
|
//! Get the equipment string of this object (for example "SDE2E3FGHIJ1RWXY")
|
||||||
|
QString convertToQString(bool i18n = false) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! @{
|
||||||
|
//! Get the string for the specific equipment
|
||||||
|
static QString flagToString(CpdlcSatcomEquipmentOption flag);
|
||||||
|
static QString flagToString(ComNavEquipmentOption flag);
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
ComNavEquipment m_equipment = Standard;
|
||||||
|
CpdlcSatcomEquipment m_cpdlcSatcomEquipment;
|
||||||
|
|
||||||
|
BLACK_METACLASS(
|
||||||
|
CComNavEquipment,
|
||||||
|
BLACK_METAMEMBER(equipment),
|
||||||
|
BLACK_METAMEMBER(cpdlcSatcomEquipment)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::Aviation::CComNavEquipment)
|
||||||
|
|
||||||
|
#endif // BLACKMISC_AVIATION_COMNAVEQUIPMENT_H
|
||||||
388
src/blackmisc/aviation/flightplanaircraftinfo.cpp
Normal file
388
src/blackmisc/aviation/flightplanaircraftinfo.cpp
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
#include "flightplanaircraftinfo.h"
|
||||||
|
|
||||||
|
BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CFlightPlanAircraftInfo)
|
||||||
|
|
||||||
|
namespace BlackMisc::Aviation
|
||||||
|
{
|
||||||
|
CFlightPlanAircraftInfo::CFlightPlanAircraftInfo(const CAircraftIcaoCode &aircraftIcao, const CComNavEquipment &comNavEquipment,
|
||||||
|
const CSsrEquipment &ssrEquipment, const CWakeTurbulenceCategory &wtc) : m_aircraftIcao(aircraftIcao),
|
||||||
|
m_comNavEquipment(comNavEquipment),
|
||||||
|
m_ssrEquipment(ssrEquipment),
|
||||||
|
m_wtc(wtc) {}
|
||||||
|
|
||||||
|
CFlightPlanAircraftInfo::CFlightPlanAircraftInfo(QString equipmentCodeAndAircraft)
|
||||||
|
{
|
||||||
|
equipmentCodeAndAircraft = equipmentCodeAndAircraft.trimmed().toUpper().replace(" ", "");
|
||||||
|
const int numberSlash = equipmentCodeAndAircraft.count("/");
|
||||||
|
const int numberHypen = equipmentCodeAndAircraft.count("-");
|
||||||
|
if (numberHypen == 1 && numberSlash == 2)
|
||||||
|
{
|
||||||
|
parseIcaoEquipmentCode(equipmentCodeAndAircraft);
|
||||||
|
}
|
||||||
|
else if (numberSlash >= 1 && numberSlash <= 2 && numberHypen == 0)
|
||||||
|
{
|
||||||
|
parseFaaEquipmentCode(equipmentCodeAndAircraft);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parseUnknownEquipmentCode(equipmentCodeAndAircraft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CFlightPlanAircraftInfo::asIcaoString() const
|
||||||
|
{
|
||||||
|
// Avoid returning empty wake turbulence categories and send it to the server.
|
||||||
|
// This can in particular happen when translating from FAA codes to ICAO codes.
|
||||||
|
// This sets a default wake turbulence category of MEDIUM if the category is unknown otherwise.
|
||||||
|
QChar wtc;
|
||||||
|
if (!m_wtc.isUnknown())
|
||||||
|
{
|
||||||
|
wtc = m_wtc.toQString().at(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wtc = CWakeTurbulenceCategory(CWakeTurbulenceCategory::MEDIUM).toQString().at(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_aircraftIcao.getDesignator() % "/" % wtc % "-" % m_comNavEquipment.toQString() % "/" % m_ssrEquipment.toQString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CFlightPlanAircraftInfo::asFaaString() const
|
||||||
|
{
|
||||||
|
// TCAS prefix (T/) is not used
|
||||||
|
QString s;
|
||||||
|
if (m_wtc.isCategory(CWakeTurbulenceCategory::HEAVY))
|
||||||
|
{
|
||||||
|
s = "H/";
|
||||||
|
}
|
||||||
|
else if (m_wtc.isCategory(CWakeTurbulenceCategory::SUPER))
|
||||||
|
{
|
||||||
|
s = "J/";
|
||||||
|
}
|
||||||
|
s += m_aircraftIcao.getDesignator() % "/" % equipmentToFaaCode(m_comNavEquipment, m_ssrEquipment);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAircraftIcaoCode CFlightPlanAircraftInfo::getAircraftIcao() const
|
||||||
|
{
|
||||||
|
return m_aircraftIcao;
|
||||||
|
}
|
||||||
|
|
||||||
|
CComNavEquipment CFlightPlanAircraftInfo::getComNavEquipment() const
|
||||||
|
{
|
||||||
|
return m_comNavEquipment;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSsrEquipment CFlightPlanAircraftInfo::getSsrEquipment() const
|
||||||
|
{
|
||||||
|
return m_ssrEquipment;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWakeTurbulenceCategory CFlightPlanAircraftInfo::getWtc() const
|
||||||
|
{
|
||||||
|
return m_wtc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CFlightPlanAircraftInfo::convertToQString(bool) const
|
||||||
|
{
|
||||||
|
return asIcaoString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlightPlanAircraftInfo::parseIcaoEquipmentCode(const QString &equipment)
|
||||||
|
{
|
||||||
|
// Example: B789/H-SDE1E2E3FGHIJ2J3J4J5M1RWXY/LB1D1
|
||||||
|
QStringList firstSplit = equipment.split("/");
|
||||||
|
Q_ASSERT_X(firstSplit.size() == 3, Q_FUNC_INFO, "Cannot split string as required for the ICAO format");
|
||||||
|
if (!CAircraftIcaoCode::isValidDesignator(firstSplit[0]) || firstSplit[1].isEmpty() || firstSplit[2].isEmpty())
|
||||||
|
{
|
||||||
|
return; // Invalid equipment code, leave everything default initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
m_aircraftIcao = CAircraftIcaoCode(firstSplit[0]);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_ssrEquipment = CSsrEquipment(firstSplit[2]);
|
||||||
|
}
|
||||||
|
catch (const std::invalid_argument &)
|
||||||
|
{
|
||||||
|
m_ssrEquipment = CSsrEquipment();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList secondSplit = firstSplit[1].split("-");
|
||||||
|
if (secondSplit.size() != 2)
|
||||||
|
{
|
||||||
|
return; // Invalid code, leave everything else default initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!secondSplit[0].isEmpty())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// if the wake turbulence category incorrectly contains more than one letter
|
||||||
|
// just take the first letter
|
||||||
|
m_wtc = CWakeTurbulenceCategory(secondSplit[0].at(0));
|
||||||
|
}
|
||||||
|
catch (std::invalid_argument &)
|
||||||
|
{
|
||||||
|
m_wtc = CWakeTurbulenceCategory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_wtc = CWakeTurbulenceCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_comNavEquipment = CComNavEquipment(secondSplit[1]);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error &)
|
||||||
|
{
|
||||||
|
m_comNavEquipment = CComNavEquipment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlightPlanAircraftInfo::parseFaaEquipmentCode(const QString &equipment)
|
||||||
|
{
|
||||||
|
// Example: H/A346/L
|
||||||
|
QStringList split = equipment.split('/');
|
||||||
|
Q_ASSERT_X(split.size() == 2 || split.size() == 3, Q_FUNC_INFO, "Cannot split string as required for the FAA format");
|
||||||
|
bool missingEquipmentCode = false;
|
||||||
|
|
||||||
|
if (CAircraftIcaoCode::isValidDesignator(split.at(split.size() - 2)))
|
||||||
|
{
|
||||||
|
m_aircraftIcao = CAircraftIcaoCode(split.at(split.size() - 2));
|
||||||
|
}
|
||||||
|
else if (CAircraftIcaoCode::isValidDesignator(split.at(split.size() - 1)))
|
||||||
|
{
|
||||||
|
// the equipment code is missing (like J/A388)
|
||||||
|
m_aircraftIcao = CAircraftIcaoCode(split.at(split.size() - 1));
|
||||||
|
missingEquipmentCode = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_aircraftIcao = CAircraftIcaoCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check prefix (wake turbulence category)
|
||||||
|
if (split.length() == 3)
|
||||||
|
{
|
||||||
|
const QString &prefix = split.at(0);
|
||||||
|
if (prefix == "H" || prefix == "J")
|
||||||
|
{
|
||||||
|
m_wtc = CWakeTurbulenceCategory(prefix.at(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (split.length() == 2 && split.at(0).size() == 1)
|
||||||
|
{
|
||||||
|
// the equipment code is missing (like J/A388)
|
||||||
|
m_wtc = CWakeTurbulenceCategory(split.at(0).at(0));
|
||||||
|
missingEquipmentCode = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_wtc = CWakeTurbulenceCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equipment Code
|
||||||
|
if (missingEquipmentCode || split.at(split.size() - 1).isEmpty())
|
||||||
|
{
|
||||||
|
return; // No (empty) equipment code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always taking the first character. If the code contains more than one character, this is likely an error, but we will try it anyway
|
||||||
|
QChar equipmentCode = split.at(split.size() - 1).at(0);
|
||||||
|
auto [comNavEquipment, ssrEquipment] = faaCodeToEquipment(equipmentCode);
|
||||||
|
m_comNavEquipment = comNavEquipment;
|
||||||
|
m_ssrEquipment = ssrEquipment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlightPlanAircraftInfo::parseUnknownEquipmentCode(const QString &equipment)
|
||||||
|
{
|
||||||
|
// likely one part only
|
||||||
|
QStringList split = equipment.split("/");
|
||||||
|
if (split[0].length() > 1 && CAircraftIcaoCode::isValidDesignator(split[0]))
|
||||||
|
{
|
||||||
|
// only ICAO
|
||||||
|
m_aircraftIcao = split[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// something invalid. Keep default initialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<CComNavEquipment, CSsrEquipment> CFlightPlanAircraftInfo::faaCodeToEquipment(QChar equipmentCode)
|
||||||
|
{
|
||||||
|
CComNavEquipment equip;
|
||||||
|
CSsrEquipment ssr;
|
||||||
|
|
||||||
|
// COM/NAV equipment
|
||||||
|
if (equipmentCode == 'H' || equipmentCode == 'O' || equipmentCode == 'W')
|
||||||
|
{
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Rvsm }, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'Z')
|
||||||
|
{
|
||||||
|
// PBN might not be the correct translation for "RNAV" but we use it to differentiate the codes
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Rvsm | CComNavEquipment::Pbn }, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'L')
|
||||||
|
{
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Rvsm | CComNavEquipment::Gnss }, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'X' || equipmentCode == 'T' || equipmentCode == 'U')
|
||||||
|
{
|
||||||
|
equip = CComNavEquipment({}, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'D' || equipmentCode == 'B' || equipmentCode == 'A')
|
||||||
|
{
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Dme }, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'M' || equipmentCode == 'N' || equipmentCode == 'P')
|
||||||
|
{
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Tacan }, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'Y' || equipmentCode == 'C' || equipmentCode == 'I')
|
||||||
|
{
|
||||||
|
// PBN might not be the correct translation for "RNAV" but we use it to differentiate the codes
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Pbn }, {});
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'V' || equipmentCode == 'S' || equipmentCode == 'G')
|
||||||
|
{
|
||||||
|
equip = CComNavEquipment({ CComNavEquipment::Gnss }, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSR equipment
|
||||||
|
if (equipmentCode == 'W' || equipmentCode == 'Z' || equipmentCode == 'L' || equipmentCode == 'U' ||
|
||||||
|
equipmentCode == 'A' || equipmentCode == 'P' || equipmentCode == 'I' || equipmentCode == 'G')
|
||||||
|
{
|
||||||
|
ssr = CSsrEquipment::SSrEquipment { CSsrEquipment::ModeAC };
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'H' || equipmentCode == 'O' || equipmentCode == 'X' || equipmentCode == 'D' ||
|
||||||
|
equipmentCode == 'M' || equipmentCode == 'Y' || equipmentCode == 'V')
|
||||||
|
{
|
||||||
|
// "O" corresponds to a failed Mode C transponder.
|
||||||
|
// The ICAO format does not contain a separate code for a failed Mode C transponder
|
||||||
|
ssr = CSsrEquipment::SSrEquipment { CSsrEquipment::None };
|
||||||
|
}
|
||||||
|
else if (equipmentCode == 'T' || equipmentCode == 'B' || equipmentCode == 'N' || equipmentCode == 'C' ||
|
||||||
|
equipmentCode == 'S')
|
||||||
|
{
|
||||||
|
// The ICAO format does not contain a separate code for a general NONE Mode C transponder. We use Mode A instead.
|
||||||
|
ssr = CSsrEquipment::SSrEquipment { CSsrEquipment::ModeA };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { equip, ssr };
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar CFlightPlanAircraftInfo::equipmentToFaaCode(const CComNavEquipment &equip, const CSsrEquipment &ssr)
|
||||||
|
{
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Rvsm))
|
||||||
|
{
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::None))
|
||||||
|
{
|
||||||
|
// This could also be 'O' as we cannot differentiate between a failed transponder and a failed Mode C transponder
|
||||||
|
return 'H';
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the following, do not check the transponder capability, as the FAA codes only work with Mode C and not Mode S transponders
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Gnss))
|
||||||
|
{
|
||||||
|
return 'L';
|
||||||
|
}
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Pbn))
|
||||||
|
{
|
||||||
|
// PBN is used for RNAV when converting from FAA string to CFlightPlanAircraftInfo
|
||||||
|
return 'Z';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'W';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Gnss))
|
||||||
|
{
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::None))
|
||||||
|
{
|
||||||
|
return 'V';
|
||||||
|
}
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::ModeAC))
|
||||||
|
{
|
||||||
|
return 'G';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'S';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Tacan))
|
||||||
|
{
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::None))
|
||||||
|
{
|
||||||
|
return 'M';
|
||||||
|
}
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::ModeAC))
|
||||||
|
{
|
||||||
|
return 'P';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'N';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Pbn))
|
||||||
|
{
|
||||||
|
// PBN is used for RNAV when converting from FAA string to CFlightPlanAircraftInfo
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::None))
|
||||||
|
{
|
||||||
|
return 'Y';
|
||||||
|
}
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::ModeAC))
|
||||||
|
{
|
||||||
|
return 'I';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'C';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (equip.hasEquipment(CComNavEquipment::Dme))
|
||||||
|
{
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::None))
|
||||||
|
{
|
||||||
|
return 'D';
|
||||||
|
}
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::ModeAC))
|
||||||
|
{
|
||||||
|
return 'A';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'B';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No DME
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::None))
|
||||||
|
{
|
||||||
|
return 'X';
|
||||||
|
}
|
||||||
|
if (ssr.hasEquipment(CSsrEquipment::ModeAC))
|
||||||
|
{
|
||||||
|
return 'U';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'T';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
84
src/blackmisc/aviation/flightplanaircraftinfo.h
Normal file
84
src/blackmisc/aviation/flightplanaircraftinfo.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_AVIATION_FLIGHTPLAN_AIRCRAFT_INFO_H
|
||||||
|
#define BLACKMISC_AVIATION_FLIGHTPLAN_AIRCRAFT_INFO_H
|
||||||
|
|
||||||
|
#include "blackmisc/blackmiscexport.h"
|
||||||
|
#include "blackmisc/valueobject.h"
|
||||||
|
#include "blackmisc/aviation/aircrafticaocode.h"
|
||||||
|
#include "blackmisc/aviation/comnavequipment.h"
|
||||||
|
#include "blackmisc/aviation/ssrequipment.h"
|
||||||
|
#include "blackmisc/aviation/waketurbulencecategory.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CFlightPlanAircraftInfo)
|
||||||
|
|
||||||
|
namespace BlackMisc::Aviation
|
||||||
|
{
|
||||||
|
//! Flightplan-related information about an aircraft (aircraft ICAO, equipment and WTC)
|
||||||
|
class BLACKMISC_EXPORT CFlightPlanAircraftInfo : public CValueObject<CFlightPlanAircraftInfo>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFlightPlanAircraftInfo() = default;
|
||||||
|
|
||||||
|
//! Create info from given aircraft ICAO, equipment and wake turbulence category
|
||||||
|
CFlightPlanAircraftInfo(const CAircraftIcaoCode &aircraftIcao, const CComNavEquipment &comNavEquipment,
|
||||||
|
const CSsrEquipment &ssrEquipment, const CWakeTurbulenceCategory &wtc);
|
||||||
|
|
||||||
|
//! Create aircraft info from a string that contains the 4 parts of an ICAO equipment code (AIRCRAFT_ICAO/WTC-EQUIPMENT/SSR).
|
||||||
|
//! Passing FAA equipment codes like "H/B772/F" is supported as well
|
||||||
|
explicit CFlightPlanAircraftInfo(QString equipmentCodeAndAircraft);
|
||||||
|
|
||||||
|
//! Full string in ICAO format: "AIRCRAFT_ICAO/WTC-EQUIPMENT/SSR"
|
||||||
|
QString asIcaoString() const;
|
||||||
|
|
||||||
|
//! Full string in FAA format: "H/J (if heavy/super)/AIRCRAFT_ICAO/EQUIPMENT-CODE"
|
||||||
|
QString asFaaString() const;
|
||||||
|
|
||||||
|
//! Get Aircraft ICAO
|
||||||
|
CAircraftIcaoCode getAircraftIcao() const;
|
||||||
|
|
||||||
|
//! Get COM/NAV equipment
|
||||||
|
CComNavEquipment getComNavEquipment() const;
|
||||||
|
|
||||||
|
//! Get SSR equipment
|
||||||
|
CSsrEquipment getSsrEquipment() const;
|
||||||
|
|
||||||
|
//! Get Wake Turbulence Category
|
||||||
|
CWakeTurbulenceCategory getWtc() const;
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Mixin::String::toQString
|
||||||
|
QString convertToQString(bool i18n = false) const;
|
||||||
|
|
||||||
|
//! Transform single character FAA equipment code to ICAO-based COM/NAV and SSR equipment
|
||||||
|
static std::tuple<CComNavEquipment, CSsrEquipment> faaCodeToEquipment(QChar equipmentCode);
|
||||||
|
|
||||||
|
//! Transform ICAO-based COM/NAV and SSR equipment to a single character FAA equipment code
|
||||||
|
static QChar equipmentToFaaCode(const CComNavEquipment &equip, const CSsrEquipment &ssr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CAircraftIcaoCode m_aircraftIcao; //!< Aircraft ICAO code
|
||||||
|
CComNavEquipment m_comNavEquipment; //!< COM & NAV equipment (flight plan field 10a)
|
||||||
|
CSsrEquipment m_ssrEquipment; //!< secondary surveillance radar equipment (flight plan field 10b)
|
||||||
|
CWakeTurbulenceCategory m_wtc; //!< wake turbulence category. This information is also part of m_aircraftIcao, but is not always filled.
|
||||||
|
|
||||||
|
void parseIcaoEquipmentCode(const QString &equipment); //!< Initialize members from ICAO format equipment codes
|
||||||
|
void parseFaaEquipmentCode(const QString &equipment); //!< Initialize members from FAA format equipment codes
|
||||||
|
void parseUnknownEquipmentCode(const QString &equipment); //!< Initialize members from unknown format equipment strings (best guesses)
|
||||||
|
|
||||||
|
BLACK_METACLASS(
|
||||||
|
CFlightPlanAircraftInfo,
|
||||||
|
BLACK_METAMEMBER(aircraftIcao),
|
||||||
|
BLACK_METAMEMBER(comNavEquipment),
|
||||||
|
BLACK_METAMEMBER(ssrEquipment),
|
||||||
|
BLACK_METAMEMBER(wtc)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::Aviation::CFlightPlanAircraftInfo)
|
||||||
|
|
||||||
|
#endif // BLACKMISC_AVIATION_FLIGHTPLAN_AIRCRAFT_INFO_H
|
||||||
@@ -70,8 +70,11 @@ namespace BlackMisc
|
|||||||
CCallsign::registerMetadata();
|
CCallsign::registerMetadata();
|
||||||
CCallsignSet::registerMetadata();
|
CCallsignSet::registerMetadata();
|
||||||
CComSystem::registerMetadata();
|
CComSystem::registerMetadata();
|
||||||
|
CSsrEquipment::registerMetadata();
|
||||||
|
CComNavEquipment::registerMetadata();
|
||||||
CWakeTurbulenceCategory::registerMetadata();
|
CWakeTurbulenceCategory::registerMetadata();
|
||||||
CFlightPlan::registerMetadata();
|
CFlightPlan::registerMetadata();
|
||||||
|
CFlightPlanAircraftInfo::registerMetadata();
|
||||||
CFlightPlanList::registerMetadata();
|
CFlightPlanList::registerMetadata();
|
||||||
CSimBriefData::registerMetadata();
|
CSimBriefData::registerMetadata();
|
||||||
CFlightPlanRemarks::registerMetadata();
|
CFlightPlanRemarks::registerMetadata();
|
||||||
|
|||||||
203
src/blackmisc/aviation/ssrequipment.cpp
Normal file
203
src/blackmisc/aviation/ssrequipment.cpp
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
#include "ssrequipment.h"
|
||||||
|
|
||||||
|
BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CSsrEquipment)
|
||||||
|
|
||||||
|
namespace BlackMisc::Aviation
|
||||||
|
{
|
||||||
|
CSsrEquipment::CSsrEquipment(SSrEquipment equipment) : m_equipment(equipment)
|
||||||
|
{
|
||||||
|
if (m_equipment == SSrEquipment())
|
||||||
|
{
|
||||||
|
m_equipment = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSsrEquipment::CSsrEquipment(QString equipment)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (equipment.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_equipment = {}; // Clear default flag
|
||||||
|
|
||||||
|
auto append_equipment_flag_if_exist = [&equipment, this](SsrEquipmentOption flag) {
|
||||||
|
QString str = flagToString(flag);
|
||||||
|
if (equipment.contains(str))
|
||||||
|
{
|
||||||
|
equipment = equipment.remove(str);
|
||||||
|
m_equipment |= flag;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
append_equipment_flag_if_exist(None);
|
||||||
|
append_equipment_flag_if_exist(ModeA);
|
||||||
|
append_equipment_flag_if_exist(ModeAC);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeE);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeH);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeI);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeL);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeX);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeP);
|
||||||
|
append_equipment_flag_if_exist(ModeSTypeS);
|
||||||
|
append_equipment_flag_if_exist(AdsBB1);
|
||||||
|
append_equipment_flag_if_exist(AdsBB2);
|
||||||
|
append_equipment_flag_if_exist(AdsBU1);
|
||||||
|
append_equipment_flag_if_exist(AdsBU2);
|
||||||
|
append_equipment_flag_if_exist(AdsBV1);
|
||||||
|
append_equipment_flag_if_exist(AdsBV2);
|
||||||
|
append_equipment_flag_if_exist(AdsCD1);
|
||||||
|
append_equipment_flag_if_exist(AdsCG1);
|
||||||
|
|
||||||
|
if (!equipment.isEmpty() && m_equipment == SSrEquipment())
|
||||||
|
{
|
||||||
|
// Default if nothing correct is provided
|
||||||
|
m_equipment = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CSsrEquipment::enabledOptions() const
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
// Append flag (as string) to list if flag exists in current equipment
|
||||||
|
auto append_flag_if_exist = [&list, this](SsrEquipmentOption flag) {
|
||||||
|
if (m_equipment.testFlag(flag)) list << flagToString(flag);
|
||||||
|
};
|
||||||
|
|
||||||
|
append_flag_if_exist(None);
|
||||||
|
append_flag_if_exist(ModeA);
|
||||||
|
append_flag_if_exist(ModeAC);
|
||||||
|
append_flag_if_exist(ModeSTypeE);
|
||||||
|
append_flag_if_exist(ModeSTypeH);
|
||||||
|
append_flag_if_exist(ModeSTypeI);
|
||||||
|
append_flag_if_exist(ModeSTypeL);
|
||||||
|
append_flag_if_exist(ModeSTypeX);
|
||||||
|
append_flag_if_exist(ModeSTypeP);
|
||||||
|
append_flag_if_exist(ModeSTypeS);
|
||||||
|
append_flag_if_exist(AdsBB1);
|
||||||
|
append_flag_if_exist(AdsBB2);
|
||||||
|
append_flag_if_exist(AdsBU1);
|
||||||
|
append_flag_if_exist(AdsBU2);
|
||||||
|
append_flag_if_exist(AdsBV1);
|
||||||
|
append_flag_if_exist(AdsBV2);
|
||||||
|
append_flag_if_exist(AdsCD1);
|
||||||
|
append_flag_if_exist(AdsCG1);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSsrEquipment::convertToQString(bool) const
|
||||||
|
{
|
||||||
|
const QString equipmentString = enabledOptions().join("");
|
||||||
|
Q_ASSERT_X(!equipmentString.isEmpty(), Q_FUNC_INFO, "Equipment string should not be empty");
|
||||||
|
return equipmentString;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSsrEquipment::flagToString(CSsrEquipment::SSrEquipment flag)
|
||||||
|
{
|
||||||
|
if (flag == None)
|
||||||
|
{
|
||||||
|
static const QString q("N");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeA)
|
||||||
|
{
|
||||||
|
static const QString q("A");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeAC)
|
||||||
|
{
|
||||||
|
static const QString q("C");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeE)
|
||||||
|
{
|
||||||
|
static const QString q("E");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeH)
|
||||||
|
{
|
||||||
|
static const QString q("H");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeI)
|
||||||
|
{
|
||||||
|
static const QString q("I");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeL)
|
||||||
|
{
|
||||||
|
static const QString q("L");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeX)
|
||||||
|
{
|
||||||
|
static const QString q("X");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeP)
|
||||||
|
{
|
||||||
|
static const QString q("P");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == ModeSTypeS)
|
||||||
|
{
|
||||||
|
static const QString q("S");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsBB1)
|
||||||
|
{
|
||||||
|
static const QString q("B1");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsBB2)
|
||||||
|
{
|
||||||
|
static const QString q("B2");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsBU1)
|
||||||
|
{
|
||||||
|
static const QString q("U1");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsBU2)
|
||||||
|
{
|
||||||
|
static const QString q("U2");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsBV1)
|
||||||
|
{
|
||||||
|
static const QString q("V1");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsBV2)
|
||||||
|
{
|
||||||
|
static const QString q("V2");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsCD1)
|
||||||
|
{
|
||||||
|
static const QString q("D1");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (flag == AdsCG1)
|
||||||
|
{
|
||||||
|
static const QString q("G1");
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CSsrEquipment::allEquipmentLetters()
|
||||||
|
{
|
||||||
|
// In order as they appear in the final string
|
||||||
|
static const QStringList r({ "N", "A", "C", "E", "H", "I", "L", "X", "P", "S", "B1", "B2", "U1", "U2", "V1", "V2", "D1", "G1" });
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
79
src/blackmisc/aviation/ssrequipment.h
Normal file
79
src/blackmisc/aviation/ssrequipment.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_AVIATION_SSREQUIPMENT_H
|
||||||
|
#define BLACKMISC_AVIATION_SSREQUIPMENT_H
|
||||||
|
|
||||||
|
#include "blackmisc/blackmiscexport.h"
|
||||||
|
#include "blackmisc/valueobject.h"
|
||||||
|
|
||||||
|
BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CSsrEquipment)
|
||||||
|
|
||||||
|
namespace BlackMisc::Aviation
|
||||||
|
{
|
||||||
|
//! ICAO flightplan field 10b
|
||||||
|
class BLACKMISC_EXPORT CSsrEquipment : public BlackMisc::CValueObject<CSsrEquipment>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum SsrEquipmentOption : int
|
||||||
|
{
|
||||||
|
None = (1 << 0),
|
||||||
|
ModeA = (1 << 1),
|
||||||
|
ModeAC = (1 << 2),
|
||||||
|
ModeSTypeE = (1 << 3),
|
||||||
|
ModeSTypeH = (1 << 4),
|
||||||
|
ModeSTypeI = (1 << 5),
|
||||||
|
ModeSTypeL = (1 << 6),
|
||||||
|
ModeSTypeX = (1 << 7),
|
||||||
|
ModeSTypeP = (1 << 8),
|
||||||
|
ModeSTypeS = (1 << 9),
|
||||||
|
AdsBB1 = (1 << 10),
|
||||||
|
AdsBB2 = (1 << 11),
|
||||||
|
AdsBU1 = (1 << 12),
|
||||||
|
AdsBU2 = (1 << 13),
|
||||||
|
AdsBV1 = (1 << 14),
|
||||||
|
AdsBV2 = (1 << 15),
|
||||||
|
AdsCD1 = (1 << 16),
|
||||||
|
AdsCG1 = (1 << 17)
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_FLAGS(SSrEquipment, SsrEquipmentOption);
|
||||||
|
|
||||||
|
//! Create default SSR equipment with "None" equipment enabled
|
||||||
|
CSsrEquipment() = default;
|
||||||
|
|
||||||
|
//! Create object with given equipment
|
||||||
|
CSsrEquipment(SSrEquipment equipment);
|
||||||
|
|
||||||
|
//! Create object from an ICAO SSR equipment string (for example "LB1")
|
||||||
|
explicit CSsrEquipment(QString equipment);
|
||||||
|
|
||||||
|
//! Get all possible SSR equipment code letters
|
||||||
|
static QStringList allEquipmentLetters();
|
||||||
|
|
||||||
|
//! Get all enabled SSR equipment codes of this object as a list
|
||||||
|
QStringList enabledOptions() const;
|
||||||
|
|
||||||
|
//! Get the SSR equipment string of this object (for example "LB1")
|
||||||
|
QString convertToQString(bool i18n = false) const;
|
||||||
|
|
||||||
|
//! Does this object contains \p equip?
|
||||||
|
bool hasEquipment(SsrEquipmentOption equip) const { return m_equipment.testFlag(equip); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Get the string for the specific SSR equipment
|
||||||
|
static QString flagToString(SSrEquipment flag);
|
||||||
|
|
||||||
|
SSrEquipment m_equipment = None;
|
||||||
|
|
||||||
|
BLACK_METACLASS(
|
||||||
|
CSsrEquipment,
|
||||||
|
BLACK_METAMEMBER(equipment)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::Aviation::CSsrEquipment)
|
||||||
|
|
||||||
|
#endif // BLACKMISC_AVIATION_SSREQUIPMENT_H
|
||||||
@@ -30,6 +30,12 @@ add_swift_test(
|
|||||||
LINK_LIBRARIES misc tests_test Qt::Core
|
LINK_LIBRARIES misc tests_test Qt::Core
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_swift_test(
|
||||||
|
NAME misc_aviation_flightplanaircraftinfo
|
||||||
|
SOURCES aviation/testflightplan/testflightplanaircraftinfo.cpp
|
||||||
|
LINK_LIBRARIES misc tests_test Qt::Core
|
||||||
|
)
|
||||||
|
|
||||||
##############
|
##############
|
||||||
## Geo ##
|
## Geo ##
|
||||||
##############
|
##############
|
||||||
|
|||||||
@@ -0,0 +1,229 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||||
|
|
||||||
|
//! \cond PRIVATE_TESTS
|
||||||
|
//! \file
|
||||||
|
//! \ingroup testblackmisc
|
||||||
|
|
||||||
|
#include "blackmisc/aviation/flightplanaircraftinfo.h"
|
||||||
|
#include "test.h"
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
using namespace BlackMisc::Aviation;
|
||||||
|
|
||||||
|
namespace BlackMiscTest
|
||||||
|
{
|
||||||
|
//! Flightplan unit tests
|
||||||
|
class CTestFlightPlanAircraftInfo : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
//! Convert ICAO equipment code to CFlightPlanAircraftInfo and vice versa
|
||||||
|
void icaoConvert();
|
||||||
|
|
||||||
|
//! Convert FAA equipment code to CFlightPlanAircraftInfo and vice versa
|
||||||
|
void faaConvert();
|
||||||
|
|
||||||
|
//! Convert non FAA/ICAO equipment code to CFlightPlanAircraftInfo and vice versa
|
||||||
|
void nonValidConvert();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct TestEntry
|
||||||
|
{
|
||||||
|
QString m_icaoEquipment;
|
||||||
|
QString m_faaEquipment;
|
||||||
|
QString m_aircraftIcao;
|
||||||
|
CWakeTurbulenceCategory m_wtc;
|
||||||
|
CComNavEquipment m_equipment;
|
||||||
|
CSsrEquipment m_ssrEquipment;
|
||||||
|
};
|
||||||
|
|
||||||
|
QList<TestEntry> m_testEntries {
|
||||||
|
{ "B737/M-SDE2E3FGHIRWXY/LB1",
|
||||||
|
"B737/L",
|
||||||
|
"B737",
|
||||||
|
CWakeTurbulenceCategory::MEDIUM,
|
||||||
|
CComNavEquipment(CComNavEquipment::ComNavEquipment(CComNavEquipment::Standard | CComNavEquipment::Dme | CComNavEquipment::DFisAcars | CComNavEquipment::PdcAcars | CComNavEquipment::Adf | CComNavEquipment::Gnss | CComNavEquipment::HfRtf | CComNavEquipment::InertiaNavigation | CComNavEquipment::Pbn | CComNavEquipment::Rvsm | CComNavEquipment::Mnps | CComNavEquipment::Vhf833),
|
||||||
|
CComNavEquipment::CpdlcSatcomEquipment()),
|
||||||
|
CSsrEquipment::SSrEquipment(CSsrEquipment::ModeSTypeL | CSsrEquipment::AdsBB1) },
|
||||||
|
{ "B748/H-SDE3FGHIM1M2RWXY/LB1",
|
||||||
|
"H/B748/L",
|
||||||
|
"B748",
|
||||||
|
CWakeTurbulenceCategory::HEAVY,
|
||||||
|
CComNavEquipment(CComNavEquipment::ComNavEquipment(CComNavEquipment::Standard | CComNavEquipment::Dme | CComNavEquipment::PdcAcars | CComNavEquipment::Adf | CComNavEquipment::Gnss | CComNavEquipment::HfRtf | CComNavEquipment::InertiaNavigation | CComNavEquipment::Pbn | CComNavEquipment::Rvsm | CComNavEquipment::Mnps | CComNavEquipment::Vhf833),
|
||||||
|
CComNavEquipment::CpdlcSatcomEquipment(CComNavEquipment::AtcSatvoiceInmarsat | CComNavEquipment::AtcSatvoiceMtsat)),
|
||||||
|
CSsrEquipment::SSrEquipment(CSsrEquipment::ModeSTypeL | CSsrEquipment::AdsBB1) },
|
||||||
|
{ "C172/L-DGV/C",
|
||||||
|
"C172/G",
|
||||||
|
"C172",
|
||||||
|
CWakeTurbulenceCategory::LIGHT,
|
||||||
|
CComNavEquipment(CComNavEquipment::ComNavEquipment(CComNavEquipment::VhfRtf | CComNavEquipment::Gnss | CComNavEquipment::Dme),
|
||||||
|
CComNavEquipment::CpdlcSatcomEquipment()),
|
||||||
|
CSsrEquipment::SSrEquipment(CSsrEquipment::ModeAC) },
|
||||||
|
{ "A388/J-SADE2E3FGHIJ3J4J5M1RWXY/LB1D1",
|
||||||
|
"J/A388/L",
|
||||||
|
"A388",
|
||||||
|
CWakeTurbulenceCategory::SUPER,
|
||||||
|
CComNavEquipment(CComNavEquipment::ComNavEquipment(CComNavEquipment::Standard | CComNavEquipment::Gbas | CComNavEquipment::Dme | CComNavEquipment::DFisAcars | CComNavEquipment::PdcAcars | CComNavEquipment::Adf | CComNavEquipment::Gnss | CComNavEquipment::HfRtf | CComNavEquipment::InertiaNavigation | CComNavEquipment::Pbn | CComNavEquipment::Rvsm | CComNavEquipment::Mnps | CComNavEquipment::Vhf833),
|
||||||
|
CComNavEquipment::CpdlcSatcomEquipment(CComNavEquipment::CpdlcFansVdlA | CComNavEquipment::CpdlcFansVdl2 | CComNavEquipment::CpdlcFansSatcomInmarsat | CComNavEquipment::AtcSatvoiceInmarsat)),
|
||||||
|
CSsrEquipment::SSrEquipment(CSsrEquipment::ModeSTypeL | CSsrEquipment::AdsBB1 | CSsrEquipment::AdsCD1) }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void CTestFlightPlanAircraftInfo::icaoConvert()
|
||||||
|
{
|
||||||
|
for (const TestEntry &entry : m_testEntries)
|
||||||
|
{
|
||||||
|
CFlightPlanAircraftInfo info(entry.m_icaoEquipment);
|
||||||
|
|
||||||
|
QVERIFY2(info.getAircraftIcao().hasDesignator(), "Should have designator");
|
||||||
|
QVERIFY2(info.getAircraftIcao().getDesignator() == entry.m_aircraftIcao, "Should have same aircraft ICAO code");
|
||||||
|
QCOMPARE(info.getWtc(), entry.m_wtc);
|
||||||
|
QCOMPARE(info.getComNavEquipment(), entry.m_equipment);
|
||||||
|
QCOMPARE(info.getSsrEquipment(), entry.m_ssrEquipment);
|
||||||
|
QCOMPARE(info.asIcaoString(), entry.m_icaoEquipment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTestFlightPlanAircraftInfo::faaConvert()
|
||||||
|
{
|
||||||
|
for (const TestEntry &entry : m_testEntries)
|
||||||
|
{
|
||||||
|
CFlightPlanAircraftInfo info(entry.m_faaEquipment);
|
||||||
|
|
||||||
|
QVERIFY2(info.getAircraftIcao().hasDesignator(), "Should have designator");
|
||||||
|
QCOMPARE(info.getAircraftIcao().getDesignator(), entry.m_aircraftIcao);
|
||||||
|
|
||||||
|
// FAA code only contains information about heavy and super wake turbulence category
|
||||||
|
if (entry.m_wtc.isCategory(CWakeTurbulenceCategory::HEAVY) || entry.m_wtc.isCategory(CWakeTurbulenceCategory::SUPER))
|
||||||
|
{
|
||||||
|
QCOMPARE(info.getWtc(), entry.m_wtc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QVERIFY2(info.getWtc().isUnknown(), "Should have UNKNOWN wake turbulence category");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cannot compare COM/NAV equipment and SSR equipment as the FAA code does not contain that much detail
|
||||||
|
|
||||||
|
QCOMPARE(info.asFaaString(), entry.m_faaEquipment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTestFlightPlanAircraftInfo::nonValidConvert()
|
||||||
|
{
|
||||||
|
// Missing WTC and equipment code
|
||||||
|
CFlightPlanAircraftInfo info("A388");
|
||||||
|
QCOMPARE(info.asFaaString(), "A388/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "A388/M-S/N");
|
||||||
|
|
||||||
|
// FAA format: Missing equipment code
|
||||||
|
info = CFlightPlanAircraftInfo("J/A388");
|
||||||
|
QCOMPARE(info.asFaaString(), "J/A388/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "A388/J-S/N");
|
||||||
|
|
||||||
|
// FAA format: Wrong aircraft ICAO (but correct length according to CAircraftIcaoCode::isValidDesignator)
|
||||||
|
info = CFlightPlanAircraftInfo("H/A1/W");
|
||||||
|
QCOMPARE(info.asFaaString(), "H/A1/W");
|
||||||
|
QCOMPARE(info.asIcaoString(), "A1/H-W/C");
|
||||||
|
|
||||||
|
// FAA format: Missing aircraft ICAO with WTC
|
||||||
|
info = CFlightPlanAircraftInfo("H//W");
|
||||||
|
QCOMPARE(info.asFaaString(), "H//W");
|
||||||
|
QCOMPARE(info.asIcaoString(), "/H-W/C");
|
||||||
|
|
||||||
|
// FAA format: Equipment code only
|
||||||
|
info = CFlightPlanAircraftInfo("/W");
|
||||||
|
QCOMPARE(info.asFaaString(), "/W");
|
||||||
|
QCOMPARE(info.asIcaoString(), "/M-W/C");
|
||||||
|
|
||||||
|
// Wrong aircraft ICAO (too short) without WTC and equipment
|
||||||
|
info = CFlightPlanAircraftInfo("X");
|
||||||
|
QCOMPARE(info.asFaaString(), "/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "/M-S/N");
|
||||||
|
|
||||||
|
// Wrong aircraft ICAO (too long) without WTC and equipment
|
||||||
|
info = CFlightPlanAircraftInfo("ABCDEFGHIJKL");
|
||||||
|
QCOMPARE(info.asFaaString(), "/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "/M-S/N");
|
||||||
|
|
||||||
|
// Empty
|
||||||
|
info = CFlightPlanAircraftInfo("");
|
||||||
|
QCOMPARE(info.asFaaString(), "/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "/M-S/N");
|
||||||
|
|
||||||
|
// FAA format: Lower case (all)
|
||||||
|
info = CFlightPlanAircraftInfo("h/b744/L");
|
||||||
|
QCOMPARE(info.asFaaString(), "H/B744/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B744/H-GW/C");
|
||||||
|
|
||||||
|
// FAA format: Lower case without WTC
|
||||||
|
info = CFlightPlanAircraftInfo("b738/w");
|
||||||
|
QCOMPARE(info.asFaaString(), "B738/W");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B738/M-W/C");
|
||||||
|
|
||||||
|
// Lower case without WTC and equipment
|
||||||
|
info = CFlightPlanAircraftInfo("dh8d");
|
||||||
|
QCOMPARE(info.asFaaString(), "DH8D/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "DH8D/M-S/N");
|
||||||
|
|
||||||
|
// FAA format: Invalid WTC
|
||||||
|
info = CFlightPlanAircraftInfo("Q/A346");
|
||||||
|
QCOMPARE(info.asFaaString(), "A346/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "A346/M-S/N");
|
||||||
|
|
||||||
|
// FAA format: Leading whitespace
|
||||||
|
info = CFlightPlanAircraftInfo(" H/B748/L");
|
||||||
|
QCOMPARE(info.asFaaString(), "H/B748/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B748/H-GW/C");
|
||||||
|
|
||||||
|
// FAA format: Trailing whitespace
|
||||||
|
info = CFlightPlanAircraftInfo("H/B748/L ");
|
||||||
|
QCOMPARE(info.asFaaString(), "H/B748/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B748/H-GW/C");
|
||||||
|
|
||||||
|
// FAA format: Whitespaces in between
|
||||||
|
info = CFlightPlanAircraftInfo("H / B7 48 /L");
|
||||||
|
QCOMPARE(info.asFaaString(), "H/B748/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B748/H-GW/C");
|
||||||
|
|
||||||
|
// ICAO format: Invalid WTC
|
||||||
|
info = CFlightPlanAircraftInfo("A339/?-S/N");
|
||||||
|
QCOMPARE(info.asFaaString(), "A339/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "A339/M-S/N");
|
||||||
|
|
||||||
|
// ICAO format: Missing SSR equipment code
|
||||||
|
info = CFlightPlanAircraftInfo("A339/H-S");
|
||||||
|
QCOMPARE(info.asFaaString(), "A339/X");
|
||||||
|
QCOMPARE(info.asIcaoString(), "A339/M-S/N");
|
||||||
|
|
||||||
|
// ICAO format: Lowercase
|
||||||
|
info = CFlightPlanAircraftInfo("b737/m-sde2e3fghirwxy/lb1");
|
||||||
|
QCOMPARE(info.asFaaString(), "B737/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B737/M-SDE2E3FGHIRWXY/LB1");
|
||||||
|
|
||||||
|
// ICAO format: Leading whitespace
|
||||||
|
info = CFlightPlanAircraftInfo(" B737/M-SDE2E3FGHIRWXY/LB1");
|
||||||
|
QCOMPARE(info.asFaaString(), "B737/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B737/M-SDE2E3FGHIRWXY/LB1");
|
||||||
|
|
||||||
|
// ICAO format: Trailing whitespace
|
||||||
|
info = CFlightPlanAircraftInfo("B737/M-SDE2E3FGHIRWXY/LB1 ");
|
||||||
|
QCOMPARE(info.asFaaString(), "B737/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B737/M-SDE2E3FGHIRWXY/LB1");
|
||||||
|
|
||||||
|
// ICAO format: Whitespaces in between
|
||||||
|
info = CFlightPlanAircraftInfo("B737/ M - SDE2E3FGH IRWXY / LB1");
|
||||||
|
QCOMPARE(info.asFaaString(), "B737/L");
|
||||||
|
QCOMPARE(info.asIcaoString(), "B737/M-SDE2E3FGHIRWXY/LB1");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // ns
|
||||||
|
|
||||||
|
//! main
|
||||||
|
BLACKTEST_APPLESS_MAIN(BlackMiscTest::CTestFlightPlanAircraftInfo);
|
||||||
|
|
||||||
|
#include "testflightplanaircraftinfo.moc"
|
||||||
|
|
||||||
|
//! \endcond
|
||||||
Reference in New Issue
Block a user