feat: Add wake turbulence category enum

This commit is contained in:
Lars Toenning
2023-12-18 22:55:08 +01:00
parent fae215ba26
commit 1f4f60d793
13 changed files with 205 additions and 29 deletions

View File

@@ -704,7 +704,7 @@ namespace BlackSample
CDistributorList distributors;
for (int i = 0; i < numberOfMemoParts; ++i)
{
aircraftIcaos.push_back(CAircraftIcaoCode("A" + QString::number(i), "A" + QString::number(i), "L1P", "Lego", "Foo", "M", false, false, false, 0));
aircraftIcaos.push_back(CAircraftIcaoCode("A" + QString::number(i), "A" + QString::number(i), "L1P", "Lego", "Foo", CWakeTurbulenceCategory::MEDIUM, false, false, false, 0));
liveries.push_back(CLivery("A" + QString::number(i), CAirlineIcaoCode("A" + QString::number(i), "Foo", CCountry("DE", "Germany"), "Foo", false, false), "Foo", "red", "blue", false));
distributors.push_back(CDistributor(QString::number(i), "Foo", {}, {}, CSimulatorInfo::FSX));
}

View File

@@ -48,7 +48,7 @@ namespace BlackCore::Context
// if all fails
static const CAircraftModel defaultModel(
"", CAircraftModel::TypeOwnSimulatorModel, "default model",
CAircraftIcaoCode("C172", "L1P", "Cessna", "172", "L", true, false, false, 0));
CAircraftIcaoCode("C172", "L1P", "Cessna", "172", CWakeTurbulenceCategory::LIGHT, true, false, false, 0));
// create one from DB data
if (sApp && sApp->hasWebDataServices())

View File

@@ -225,7 +225,7 @@ namespace BlackGui::Components
if (aircraft.getAircraftIcaoCode().isLoadedFromDb() && aircraft.getAircraftIcaoCode().hasValidWtc())
{
const QString wtc = aircraft.getAircraftIcaoCode().getWtc().toUpper();
const QString wtc = toSingleLetterCode(aircraft.getAircraftIcaoCode().getWtc());
const bool heavyFlag = (wtc.startsWith("H", Qt::CaseInsensitive) || wtc.startsWith("S", Qt::CaseInsensitive));
ui->cb_Heavy->setChecked(heavyFlag);
}
@@ -825,7 +825,7 @@ namespace BlackGui::Components
QPointer<CFlightPlanComponent> myself(this);
QTimer::singleShot(25, this, [=] {
if (!myself || !sGui || sGui->isShuttingDown()) { return; }
const bool heavy = icao.getWtc().startsWith("H");
const bool heavy = icao.getWtc() == BlackMisc::Aviation::WakeTurbulenceCategory::HEAVY;
ui->cb_Heavy->setChecked(heavy);
if (heavy) { ui->cb_Tcas->setChecked(false); }
this->buildPrefixIcaoSuffix();

View File

@@ -266,7 +266,7 @@ namespace BlackGui::Components
CAircraftModel CModelMatcherComponent::defaultModel() const
{
// can somehow dynamilcally determine the models
const CAircraftIcaoCode icaoAircraft("B737", "L2J", "FooBar", "Dummy", "M", false, false, false, 1);
const CAircraftIcaoCode icaoAircraft("B737", "L2J", "FooBar", "Dummy", CWakeTurbulenceCategory::MEDIUM, false, false, false, 1);
const CAirlineIcaoCode icaoAirline("Foo", "FooBar airlines", { "DE", "Germany" }, "FOO", true, true);
const CLivery livery(CLivery::getStandardCode(icaoAirline), icaoAirline, "Standard Foo airlines", "red", "blue", false);
CAircraftModel model("default model", CAircraftModel::TypeOwnSimulatorModel, "dummy model", icaoAircraft, livery);

View File

@@ -73,7 +73,7 @@ namespace BlackGui::Editors
ui->combined_TypeSelector->setCombinedType(icao.getCombinedType());
QString rank(icao.getRankString());
QString wtc(icao.getWtc());
QString wtc(icao.getWtc().toQString());
CGuiUtility::setComboBoxValueByStartingString(ui->cb_Rank, rank, "unspecified");
CGuiUtility::setComboBoxValueByStartingString(ui->cb_Wtc, wtc, "unspecified");
@@ -134,7 +134,7 @@ namespace BlackGui::Editors
bool realWorld = ui->cb_RealWorld->isChecked();
icao.setManufacturer(manufacturer);
icao.setModelDescription(modelDescription);
icao.setWtc(wtc);
icao.setWtc(wtc.isEmpty() ? CWakeTurbulenceCategory() : CWakeTurbulenceCategory(wtc.at(0)));
icao.setCodeFlags(military, legacy, realWorld);
icao.setRank(rank);
icao.setCombinedType(combined);

View File

@@ -99,6 +99,8 @@ add_library(misc SHARED
aviation/track.h
aviation/transponder.cpp
aviation/transponder.h
aviation/waketurbulencecategory.cpp
aviation/waketurbulencecategory.h
# DB
db/artifact.cpp

View File

@@ -28,34 +28,34 @@ namespace BlackMisc::Aviation
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &combinedType) : m_designator(icao.trimmed().toUpper()), m_combinedType(combinedType.trimmed().toUpper())
{}
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &combinedType, const QString &manufacturer, const QString &model, const QString &wtc, bool realworld, bool legacy, bool military, int rank)
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &combinedType, const QString &manufacturer, const QString &model, CWakeTurbulenceCategory wtc, bool realworld, bool legacy, bool military, int rank)
: m_designator(icao.trimmed().toUpper()),
m_combinedType(combinedType.trimmed().toUpper()),
m_manufacturer(manufacturer.trimmed()),
m_modelDescription(model.trimmed()), m_wtc(wtc.trimmed().toUpper()), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
m_modelDescription(model.trimmed()), m_wtc(wtc), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
{
if (m_rank < 0 || m_rank >= 10) { m_rank = 10; }
}
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &iata, const QString &combinedType, const QString &manufacturer, const QString &model, const QString &wtc, bool realworld, bool legacy, bool military, int rank)
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &iata, const QString &combinedType, const QString &manufacturer, const QString &model, CWakeTurbulenceCategory wtc, bool realworld, bool legacy, bool military, int rank)
: m_designator(icao.trimmed().toUpper()),
m_iataCode(iata.trimmed().toUpper()),
m_combinedType(combinedType.trimmed().toUpper()),
m_manufacturer(manufacturer.trimmed()),
m_modelDescription(model.trimmed()), m_wtc(wtc.trimmed().toUpper()), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
m_modelDescription(model.trimmed()), m_wtc(wtc), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
{
if (m_rank < 0 || m_rank >= 10) { m_rank = 10; }
}
CAircraftIcaoCode::CAircraftIcaoCode(const QString &icao, const QString &iata, const QString &family, const QString &combinedType, const QString &manufacturer,
const QString &model, const QString &modelIata, const QString &modelSwift, const QString &wtc, bool realworld, bool legacy, bool military, int rank)
const QString &model, const QString &modelIata, const QString &modelSwift, CWakeTurbulenceCategory wtc, bool realworld, bool legacy, bool military, int rank)
: m_designator(icao.trimmed().toUpper()),
m_iataCode(iata.trimmed().toUpper()),
m_family(family.trimmed().toUpper()),
m_combinedType(combinedType.trimmed().toUpper()),
m_manufacturer(manufacturer.trimmed()),
m_modelDescription(model.trimmed()), m_modelIataDescription(modelIata.trimmed()), m_modelSwiftDescription(modelSwift.trimmed()),
m_wtc(wtc.trimmed().toUpper()), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
m_wtc(wtc), m_realWorld(realworld), m_legacy(legacy), m_military(military), m_rank(rank)
{
if (m_rank < 0 || m_rank >= 10) { m_rank = 10; }
}
@@ -71,8 +71,8 @@ namespace BlackMisc::Aviation
{
Q_UNUSED(i18n);
return (this->hasCategory()) ?
QStringLiteral("%1 %2 %3 cat: %4").arg(this->getDesignatorDbKey(), this->getCombinedType(), this->getWtc(), this->getCategory().getDbKeyAsString()).trimmed() :
QStringLiteral("%1 %2 %3").arg(this->getDesignatorDbKey(), this->getCombinedType(), this->getWtc()).trimmed();
QStringLiteral("%1 %2 %3 cat: %4").arg(this->getDesignatorDbKey(), this->getCombinedType(), this->getWtc().toQString(), this->getCategory().getDbKeyAsString()).trimmed() :
QStringLiteral("%1 %2 %3").arg(this->getDesignatorDbKey(), this->getCombinedType(), this->getWtc().toQString()).trimmed();
}
void CAircraftIcaoCode::updateMissingParts(const CAircraftIcaoCode &otherIcaoCode)
@@ -704,7 +704,7 @@ namespace BlackMisc::Aviation
case IndexModelIataDescription: this->setModelIataDescription(variant.value<QString>()); break;
case IndexModelSwiftDescription: this->setModelSwiftDescription(variant.value<QString>()); break;
case IndexManufacturer: this->setManufacturer(variant.value<QString>()); break;
case IndexWtc: this->setWtc(variant.value<QString>()); break;
case IndexWtc: this->setWtc(variant.value<CWakeTurbulenceCategory>()); break;
case IndexIsLegacy: m_legacy = variant.toBool(); break;
case IndexIsMilitary: m_military = variant.toBool(); break;
case IndexRank: m_rank = variant.toInt(); break;
@@ -742,7 +742,7 @@ namespace BlackMisc::Aviation
return c;
}
case IndexManufacturer: return m_manufacturer.compare(compareValue.getManufacturer(), Qt::CaseInsensitive);
case IndexWtc: return m_wtc.compare(compareValue.getWtc(), Qt::CaseInsensitive);
case IndexWtc: return m_wtc == compareValue.getWtc();
case IndexIsLegacy: return Compare::compare(m_legacy, compareValue.isLegacyAircraft());
case IndexIsMilitary: return Compare::compare(m_military, compareValue.isMilitary());
case IndexIsVtol: return Compare::compare(isVtol(), compareValue.isVtol());
@@ -883,13 +883,14 @@ namespace BlackMisc::Aviation
const QString engine(json.value(prefix % u"engine").toString());
const QString combined(createdCombinedString(type, engineCount, engine));
QString wtc(json.value(prefix % u"wtc").toString());
if (wtc.length() > 1 && wtc.contains("/"))
QString wtcString(json.value(prefix % u"wtc").toString());
if (wtcString.length() > 1 && wtcString.contains("/"))
{
// "L/M" -> "M"
wtc = wtc.right(1);
wtcString = wtcString.right(1);
}
Q_ASSERT_X(wtc.length() < 2, Q_FUNC_INFO, "WTC too long");
Q_ASSERT_X(wtcString.length() < 2, Q_FUNC_INFO, "WTC too long");
const CWakeTurbulenceCategory wtc = wtcString.isEmpty() ? CWakeTurbulenceCategory() : CWakeTurbulenceCategory(wtcString.at(0));
const bool real = CDatastoreUtility::dbBoolStringToBool(json.value(prefix % u"realworld").toString());
const bool legacy = CDatastoreUtility::dbBoolStringToBool(json.value(prefix % u"legacy").toString());

View File

@@ -7,6 +7,7 @@
#define BLACKMISC_AVIATION_AIRCRAFTICAOCODE_H
#include "blackmisc/aviation/aircraftcategory.h"
#include "blackmisc/aviation/waketurbulencecategory.h"
#include "blackmisc/db/datastore.h"
#include "blackmisc/pq/length.h"
#include "blackmisc/blackmiscexport.h"
@@ -60,15 +61,15 @@ namespace BlackMisc::Aviation
//! Constructor
CAircraftIcaoCode(const QString &icao, const QString &combinedType, const QString &manufacturer,
const QString &model, const QString &wtc, bool realworld, bool legacy, bool military, int rank);
const QString &model, CWakeTurbulenceCategory wtc, bool realworld, bool legacy, bool military, int rank);
//! Constructor
CAircraftIcaoCode(const QString &icao, const QString &iata, const QString &combinedType, const QString &manufacturer,
const QString &model, const QString &wtc, bool realworld, bool legacy, bool military, int rank);
const QString &model, CWakeTurbulenceCategory wtc, bool realworld, bool legacy, bool military, int rank);
//! Constructor
CAircraftIcaoCode(const QString &icao, const QString &iata, const QString &family, const QString &combinedType, const QString &manufacturer,
const QString &model, const QString &modelIata, const QString &modelSwift, const QString &wtc, bool realworld, bool legacy, bool military, int rank);
const QString &model, const QString &modelIata, const QString &modelSwift, CWakeTurbulenceCategory wtc, bool realworld, bool legacy, bool military, int rank);
//! Get ICAO designator, e.g. "B737"
const QString &getDesignator() const { return m_designator; }
@@ -198,13 +199,13 @@ namespace BlackMisc::Aviation
bool matchesManufacturer(const QString &manufacturer) const;
//! Get WTC
const QString &getWtc() const { return m_wtc; }
CWakeTurbulenceCategory getWtc() const { return m_wtc; }
//! Set WTC
void setWtc(const QString &wtc) { m_wtc = wtc.trimmed().toUpper(); }
void setWtc(CWakeTurbulenceCategory wtc) { m_wtc = wtc; }
//! Valid WTC code?
bool hasValidWtc() const { return !m_wtc.isEmpty(); }
bool hasValidWtc() const { return !m_wtc.isUnknown(); }
//! Is VTOL aircraft (helicopter, tilt wing)
bool isVtol() const;
@@ -376,7 +377,7 @@ namespace BlackMisc::Aviation
QString m_modelDescription; //!< "A-330-200", the ICAO description
QString m_modelIataDescription; //!< alternative IATA description
QString m_modelSwiftDescription; //!< alternative swift description
QString m_wtc; //!< wake turbulence like "M","H" "L/M", "L", "J", we only use the one letter versions
CWakeTurbulenceCategory m_wtc; //!< ICAO wake turbulence category
bool m_realWorld = true; //!< real world aircraft
bool m_legacy = false; //!< legacy code
bool m_military = false; //!< military aircraft?

View File

@@ -70,6 +70,7 @@ namespace BlackMisc
CCallsign::registerMetadata();
CCallsignSet::registerMetadata();
CComSystem::registerMetadata();
CWakeTurbulenceCategory::registerMetadata();
CFlightPlan::registerMetadata();
CFlightPlanList::registerMetadata();
CSimBriefData::registerMetadata();

View File

@@ -0,0 +1,52 @@
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
#include "waketurbulencecategory.h"
BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CWakeTurbulenceCategory)
namespace BlackMisc::Aviation
{
CWakeTurbulenceCategory::CWakeTurbulenceCategory(WakeTurbulenceCategory wtc) : m_wtc(wtc)
{
}
CWakeTurbulenceCategory::CWakeTurbulenceCategory(QChar letter)
{
letter = letter.toUpper();
if (letter == 'L')
{
m_wtc = LIGHT;
}
else if (letter == 'M')
{
m_wtc = MEDIUM;
}
else if (letter == 'H')
{
m_wtc = HEAVY;
}
else if (letter == 'J')
{
m_wtc = SUPER;
}
else
{
// This includes "-" which is used in the database for aircraft with unknown wake turbulence category
m_wtc = UNKNOWN;
}
}
QString CWakeTurbulenceCategory::convertToQString(bool) const
{
switch (m_wtc)
{
case WakeTurbulenceCategory::LIGHT: return QStringLiteral("L");
case WakeTurbulenceCategory::MEDIUM: return QStringLiteral("M");
case WakeTurbulenceCategory::HEAVY: return QStringLiteral("H");
case WakeTurbulenceCategory::SUPER: return QStringLiteral("J");
default: [[fallthrough]];
case WakeTurbulenceCategory::UNKNOWN: return QStringLiteral("-");
}
}
}

View File

@@ -0,0 +1,61 @@
// 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_WAKETURBULENCECATEGORY_H
#define BLACKMISC_AVIATION_WAKETURBULENCECATEGORY_H
#include "blackmisc/valueobject.h"
#include "blackmisc/blackmiscexport.h"
#include <QString>
#include <QtGlobal>
BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CWakeTurbulenceCategory)
namespace BlackMisc::Aviation
{
class BLACKMISC_EXPORT CWakeTurbulenceCategory : public CValueObject<CWakeTurbulenceCategory>
{
public:
//! ICAO wake turbulence categories
enum WakeTurbulenceCategory
{
UNKNOWN, // required when converting from FAA equipment codes and for some database entries where the correct WTC is not available
LIGHT,
MEDIUM,
HEAVY,
SUPER
};
//! Create default object with unknown wake turbulence category
CWakeTurbulenceCategory() = default;
//! Create object with given wake turbulence category
CWakeTurbulenceCategory(WakeTurbulenceCategory wtc);
//! Create object from single wake turbulence category letter
explicit CWakeTurbulenceCategory(QChar letter);
//! \copydoc BlackMisc::Mixin::String::toQString
QString convertToQString(bool i18n = false) const;
//! Is the wake turbulence category unknown?
bool isUnknown() const { return m_wtc == UNKNOWN; }
//! Is the wake turbulence category of this object the same as \p category?
bool isCategory(WakeTurbulenceCategory category) const { return m_wtc == category; }
private:
WakeTurbulenceCategory m_wtc = UNKNOWN;
BLACK_METACLASS(
CWakeTurbulenceCategory,
BLACK_METAMEMBER(wtc)
);
};
}
Q_DECLARE_METATYPE(BlackMisc::Aviation::CWakeTurbulenceCategory)
#endif // BLACKMISC_AVIATION_WAKETURBULENCECATEGORY_H

View File

@@ -316,7 +316,7 @@ namespace BlackMisc::Simulation
{
const CAircraftModelList ml = this->findByCombinedType(combinedType);
if (ml.isEmpty()) { return ml; }
const QString wtcUc(wtc.toUpper().trimmed());
const CWakeTurbulenceCategory wtcUc = wtc.isEmpty() ? CWakeTurbulenceCategory() : CWakeTurbulenceCategory(wtc.toUpper().trimmed().at(0));
return this->findBy([&](const CAircraftModel &model) {
const CAircraftIcaoCode icao(model.getAircraftIcaoCode());
return icao.getWtc() == wtcUc;

View File

@@ -17,6 +17,7 @@
#include "blackmisc/aviation/informationmessage.h"
#include "blackmisc/aviation/navsystem.h"
#include "blackmisc/aviation/transponder.h"
#include "blackmisc/aviation/waketurbulencecategory.h"
#include "blackmisc/mixin/mixincompare.h"
#include "blackmisc/geo/coordinategeodetic.h"
#include "blackmisc/geo/latitude.h"
@@ -74,6 +75,9 @@ namespace BlackMiscTest
//! Test some of the guessing functions
void testGuessing();
//! Test wake turbulence categories
void testWakeTurbulenceCategories();
};
void CTestAviation::headingBasics()
@@ -380,6 +384,60 @@ namespace BlackMiscTest
QVERIFY(sB737 < sB747);
}
void CTestAviation::testWakeTurbulenceCategories()
{
const CWakeTurbulenceCategory catLight1('L');
const CWakeTurbulenceCategory catLight2('l');
const CWakeTurbulenceCategory catLight3(CWakeTurbulenceCategory::LIGHT);
const CWakeTurbulenceCategory catMedium1('M');
const CWakeTurbulenceCategory catMedium2('m');
const CWakeTurbulenceCategory catMedium3(CWakeTurbulenceCategory::MEDIUM);
const CWakeTurbulenceCategory catHeavy1('H');
const CWakeTurbulenceCategory catHeavy2('h');
const CWakeTurbulenceCategory catHeavy3(CWakeTurbulenceCategory::HEAVY);
const CWakeTurbulenceCategory catSuper1('J');
const CWakeTurbulenceCategory catSuper2('j');
const CWakeTurbulenceCategory catSuper3(CWakeTurbulenceCategory::SUPER);
const CWakeTurbulenceCategory catUnknown1('-');
const CWakeTurbulenceCategory catUnknown2('A');
const CWakeTurbulenceCategory catUnknown3('x');
const CWakeTurbulenceCategory catUnknown4(CWakeTurbulenceCategory::UNKNOWN);
QVERIFY(catLight1.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::LIGHT));
QVERIFY(catLight2.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::LIGHT));
QVERIFY(catLight3.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::LIGHT));
QCOMPARE(catLight1.toQString(), "L");
QVERIFY(catMedium1.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::MEDIUM));
QVERIFY(catMedium2.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::MEDIUM));
QVERIFY(catMedium3.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::MEDIUM));
QCOMPARE(catMedium1.toQString(), "M");
QVERIFY(catHeavy1.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::HEAVY));
QVERIFY(catHeavy2.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::HEAVY));
QVERIFY(catHeavy3.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::HEAVY));
QCOMPARE(catHeavy1.toQString(), "H");
QVERIFY(catSuper1.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::SUPER));
QVERIFY(catSuper2.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::SUPER));
QVERIFY(catSuper3.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::SUPER));
QCOMPARE(catSuper1.toQString(), "J");
QVERIFY(catUnknown1.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::UNKNOWN));
QVERIFY(catUnknown1.isUnknown());
QVERIFY(catUnknown2.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::UNKNOWN));
QVERIFY(catUnknown2.isUnknown());
QVERIFY(catUnknown3.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::UNKNOWN));
QVERIFY(catUnknown3.isUnknown());
QVERIFY(catUnknown4.isCategory(BlackMisc::Aviation::CWakeTurbulenceCategory::UNKNOWN));
QVERIFY(catUnknown4.isUnknown());
QCOMPARE(catUnknown1.toQString(), "-");
}
} // namespace
//! main