mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-04 16:56:53 +08:00
Ref T70, utility functions
* remove duplicates * 3 model descriptions
This commit is contained in:
@@ -55,6 +55,19 @@ namespace BlackMisc
|
||||
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)
|
||||
: 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)
|
||||
{
|
||||
if (m_rank < 0 || m_rank >= 10) { m_rank = 10; }
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getDesignatorDbKey() const
|
||||
{
|
||||
if (this->isLoadedFromDb())
|
||||
@@ -83,6 +96,9 @@ namespace BlackMisc
|
||||
if (!this->hasValidCombinedType() && otherIcaoCode.hasValidCombinedType()) { this->setCombinedType(otherIcaoCode.getCombinedType()); }
|
||||
if (this->m_manufacturer.isEmpty()) { this->setManufacturer(otherIcaoCode.getManufacturer());}
|
||||
if (this->m_modelDescription.isEmpty()) { this->setModelDescription(otherIcaoCode.getModelDescription()); }
|
||||
if (this->m_modelIataDescription.isEmpty()) { this->setModelIataDescription(otherIcaoCode.getModelIataDescription()); }
|
||||
if (this->m_modelSwiftDescription.isEmpty()) { this->setModelSwiftDescription(otherIcaoCode.getModelSwiftDescription()); }
|
||||
if (this->m_family.isEmpty()) { this->setFamily(otherIcaoCode.getFamily()); }
|
||||
if (!this->hasValidDbKey())
|
||||
{
|
||||
// need to observe if it makes sense to copy the key but not copying the whole object
|
||||
@@ -224,6 +240,18 @@ namespace BlackMisc
|
||||
return c;
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::getCombinedModelDescription() const
|
||||
{
|
||||
// Shortcut for most cases
|
||||
if (!this->hasModelIataDescription() && !this->hasModelSwiftDescription()) { return this->getModelDescription(); }
|
||||
|
||||
QStringList combined({ this->getModelDescription() });
|
||||
if (this->hasModelIataDescription()) { combined.append(this->getModelIataDescription()); }
|
||||
if (this->hasModelSwiftDescription()) { combined.append(this->getModelSwiftDescription()); }
|
||||
combined.removeDuplicates();
|
||||
return combined.join(", ");
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::matchesCombinedType(const QString &combinedType) const
|
||||
{
|
||||
const QString cc(combinedType.toUpper().trimmed().replace(' ', '*').replace('-', '*'));
|
||||
@@ -291,6 +319,12 @@ namespace BlackMisc
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAircraftIcaoCode::isDbDuplicate() const
|
||||
{
|
||||
return m_modelIataDescription.startsWith("duplicate", Qt::CaseInsensitive) ||
|
||||
m_modelSwiftDescription.startsWith("duplicate", Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
void CAircraftIcaoCode::setCodeFlags(bool military, bool legacy, bool realWorld)
|
||||
{
|
||||
m_military = military;
|
||||
@@ -402,7 +436,7 @@ namespace BlackMisc
|
||||
{
|
||||
if (index.isMyself()) { return CVariant::from(*this); }
|
||||
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); }
|
||||
ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexAircraftDesignator:
|
||||
@@ -415,6 +449,12 @@ namespace BlackMisc
|
||||
return CVariant::fromValue(this->m_combinedType);
|
||||
case IndexModelDescription:
|
||||
return CVariant::fromValue(this->m_modelDescription);
|
||||
case IndexModelIataDescription:
|
||||
return CVariant::fromValue(this->m_modelIataDescription);
|
||||
case IndexModelSwiftDescription:
|
||||
return CVariant::fromValue(this->m_modelSwiftDescription);
|
||||
case IndexCombinedDescription:
|
||||
return CVariant::fromValue(this->getCombinedModelDescription());
|
||||
case IndexManufacturer:
|
||||
return CVariant::fromValue(this->m_manufacturer);
|
||||
case IndexWtc:
|
||||
@@ -440,7 +480,7 @@ namespace BlackMisc
|
||||
{
|
||||
if (index.isMyself()) { (*this) = variant.to<CAircraftIcaoCode>(); return; }
|
||||
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(index, variant); return; }
|
||||
ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexAircraftDesignator:
|
||||
@@ -458,6 +498,12 @@ namespace BlackMisc
|
||||
case IndexModelDescription:
|
||||
this->setModelDescription(variant.value<QString>());
|
||||
break;
|
||||
case IndexModelIataDescription:
|
||||
this->setModelIataDescription(variant.value<QString>());
|
||||
break;
|
||||
case IndexModelSwiftDescription:
|
||||
this->setModelSwiftDescription(variant.value<QString>());
|
||||
break;
|
||||
case IndexManufacturer:
|
||||
this->setManufacturer(variant.value<QString>());
|
||||
break;
|
||||
@@ -496,6 +542,24 @@ namespace BlackMisc
|
||||
return m_combinedType.compare(compareValue.getCombinedType(), Qt::CaseInsensitive);
|
||||
case IndexModelDescription:
|
||||
return m_modelDescription.compare(compareValue.getModelDescription(), Qt::CaseInsensitive);
|
||||
case IndexModelIataDescription:
|
||||
return m_modelIataDescription.compare(compareValue.getModelIataDescription(), Qt::CaseInsensitive);
|
||||
case IndexModelSwiftDescription:
|
||||
return m_modelSwiftDescription.compare(compareValue.getModelSwiftDescription(), Qt::CaseInsensitive);
|
||||
case IndexCombinedDescription:
|
||||
{
|
||||
// compare without generating new strings
|
||||
int c = m_modelDescription.compare(compareValue.getModelDescription(), Qt::CaseInsensitive);
|
||||
if (c == 0)
|
||||
{
|
||||
c = m_modelIataDescription.compare(compareValue.getModelIataDescription(), Qt::CaseInsensitive);
|
||||
if (c == 0)
|
||||
{
|
||||
c = m_modelSwiftDescription.compare(compareValue.getModelSwiftDescription(), Qt::CaseInsensitive);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
case IndexManufacturer:
|
||||
return m_manufacturer.compare(compareValue.getManufacturer(), Qt::CaseInsensitive);
|
||||
case IndexWtc:
|
||||
@@ -615,15 +679,17 @@ namespace BlackMisc
|
||||
return CAircraftIcaoCode();
|
||||
}
|
||||
|
||||
QString designator(json.value(prefix + "designator").toString());
|
||||
QString iata(json.value(prefix + "iata").toString());
|
||||
QString family(json.value(prefix + "family").toString());
|
||||
QString manufacturer(json.value(prefix + "manufacturer").toString());
|
||||
QString model(json.value(prefix + "model").toString());
|
||||
QString type(json.value(prefix + "type").toString());
|
||||
QString engine(json.value(prefix + "engine").toString());
|
||||
int engineCount(json.value(prefix + "enginecount").toInt(-1));
|
||||
QString combined(createdCombinedString(type, engineCount, engine));
|
||||
const QString designator(json.value(prefix + "designator").toString());
|
||||
const QString iata(json.value(prefix + "iata").toString());
|
||||
const QString family(json.value(prefix + "family").toString());
|
||||
const QString manufacturer(json.value(prefix + "manufacturer").toString());
|
||||
const QString model(json.value(prefix + "model").toString());
|
||||
const QString modelIata(json.value(prefix + "modeliata").toString());
|
||||
const QString modelSwift(json.value(prefix + "modelswift").toString());
|
||||
const QString type(json.value(prefix + "type").toString());
|
||||
const QString engine(json.value(prefix + "engine").toString());
|
||||
const int engineCount(json.value(prefix + "enginecount").toInt(-1));
|
||||
const QString combined(createdCombinedString(type, engineCount, engine));
|
||||
QString wtc(json.value(prefix + "wtc").toString());
|
||||
if (wtc.length() > 1 && wtc.contains("/"))
|
||||
{
|
||||
@@ -632,17 +698,16 @@ namespace BlackMisc
|
||||
}
|
||||
Q_ASSERT_X(wtc.length() < 2, Q_FUNC_INFO, "WTC too long");
|
||||
|
||||
bool real = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "realworld").toString());
|
||||
bool legacy = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "legacy").toString());
|
||||
bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString());
|
||||
int rank(json.value(prefix + "rank").toInt(10));
|
||||
const bool real = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "realworld").toString());
|
||||
const bool legacy = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "legacy").toString());
|
||||
const bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString());
|
||||
const int rank(json.value(prefix + "rank").toInt(10));
|
||||
|
||||
CAircraftIcaoCode code(
|
||||
designator, iata, combined,
|
||||
manufacturer, model, wtc,
|
||||
designator, iata, family, combined, manufacturer,
|
||||
model, modelIata, modelSwift, wtc,
|
||||
real, legacy, military, rank
|
||||
);
|
||||
code.setFamily(family);
|
||||
code.setKeyAndTimestampFromDatabaseJson(json, prefix);
|
||||
return code;
|
||||
}
|
||||
@@ -650,39 +715,17 @@ namespace BlackMisc
|
||||
QString CAircraftIcaoCode::createdCombinedString(const QString &type, const QString &engineCount, const QString &engine)
|
||||
{
|
||||
Q_ASSERT_X(engineCount.length() < 2, Q_FUNC_INFO, "Wrong engine count");
|
||||
|
||||
QString c(type.trimmed().toUpper().left(1));
|
||||
if (c.isEmpty()) { c.append("-"); }
|
||||
if (engineCount.isEmpty())
|
||||
{
|
||||
c.append("-");
|
||||
}
|
||||
else
|
||||
{
|
||||
c.append(engineCount);
|
||||
}
|
||||
if (engine.isEmpty())
|
||||
{
|
||||
c.append("-");
|
||||
}
|
||||
else
|
||||
{
|
||||
c.append(engine.at(0));
|
||||
}
|
||||
QString c(type.isEmpty() ? "-" : type.trimmed().left(1).toUpper());
|
||||
c += engineCount.isEmpty() ? "-" : engineCount.trimmed();
|
||||
c += engine.isEmpty() ? "-" : engine.trimmed().left(1).toUpper();
|
||||
Q_ASSERT_X(c.length() == 3, Q_FUNC_INFO, "Wrong combined length");
|
||||
return c;
|
||||
}
|
||||
|
||||
QString CAircraftIcaoCode::createdCombinedString(const QString &type, int engineCount, const QString &engine)
|
||||
{
|
||||
if (engineCount >= 0 && engineCount < 10)
|
||||
{
|
||||
return createdCombinedString(type, QString::number(engineCount), engine);
|
||||
}
|
||||
else
|
||||
{
|
||||
return createdCombinedString(type, "", engine);
|
||||
}
|
||||
const bool valid = engineCount >= 0 && engineCount < 10;
|
||||
return createdCombinedString(type, valid ? QString::number(engineCount) : "", engine);
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -44,13 +44,16 @@ namespace BlackMisc
|
||||
IndexCombinedAircraftType,
|
||||
IndexManufacturer,
|
||||
IndexModelDescription,
|
||||
IndexModelIataDescription,
|
||||
IndexModelSwiftDescription,
|
||||
IndexCombinedDescription,
|
||||
IndexWtc,
|
||||
IndexIsRealworld,
|
||||
IndexIsMilitary,
|
||||
IndexIsLegacy,
|
||||
IndexIsVtol,
|
||||
IndexRank,
|
||||
IndexDesignatorManufacturer //!< designator and manufacturer
|
||||
IndexDesignatorManufacturer //!< designator and manufacturer
|
||||
};
|
||||
|
||||
//! Default constructor.
|
||||
@@ -67,6 +70,10 @@ namespace BlackMisc
|
||||
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);
|
||||
|
||||
//! 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);
|
||||
|
||||
//! Get ICAO designator, e.g. "B737"
|
||||
const QString &getDesignator() const { return m_designator; }
|
||||
|
||||
@@ -133,9 +140,18 @@ namespace BlackMisc
|
||||
//! Set type
|
||||
void setCombinedType(const QString &type) { this->m_combinedType = type.trimmed().toUpper(); }
|
||||
|
||||
//! Get model description, e.g. "A-330-200"
|
||||
//! Get IACO model description, e.g. "A-330-200"
|
||||
const QString &getModelDescription() const { return m_modelDescription; }
|
||||
|
||||
//! Get IATA model description
|
||||
const QString &getModelIataDescription() const { return m_modelIataDescription; }
|
||||
|
||||
//! Get swift model description
|
||||
const QString &getModelSwiftDescription() const { return m_modelSwiftDescription; }
|
||||
|
||||
//! Combined description
|
||||
QString getCombinedModelDescription() const;
|
||||
|
||||
//! Matches given combined code
|
||||
//! \remark * can be used as wildcard, e.g. L*J, L**
|
||||
bool matchesCombinedType(const QString &combinedType) const;
|
||||
@@ -143,12 +159,24 @@ namespace BlackMisc
|
||||
//! Designator + Manufacturer
|
||||
QString getDesignatorManufacturer() const;
|
||||
|
||||
//! Set the model description
|
||||
//! Set the model description (ICAO description)
|
||||
void setModelDescription(const QString &modelDescription) { m_modelDescription = modelDescription.trimmed(); }
|
||||
|
||||
//! Has model description
|
||||
//! Set the alternative IATA model description
|
||||
void setModelIataDescription(const QString &modelDescription) { m_modelIataDescription = modelDescription.trimmed(); }
|
||||
|
||||
//! Set the alternative swift model description
|
||||
void setModelSwiftDescription(const QString &modelDescription) { m_modelSwiftDescription = modelDescription.trimmed(); }
|
||||
|
||||
//! Has model description?
|
||||
bool hasModelDescription() const { return !this->m_modelDescription.isEmpty(); }
|
||||
|
||||
//! Has IATA model description?
|
||||
bool hasModelIataDescription() const { return !this->m_modelIataDescription.isEmpty(); }
|
||||
|
||||
//! Has swift model description?
|
||||
bool hasModelSwiftDescription() const { return !this->m_modelSwiftDescription.isEmpty(); }
|
||||
|
||||
//! Get manufacturer, e.g. "Airbus"
|
||||
const QString &getManufacturer() const { return m_manufacturer; }
|
||||
|
||||
@@ -182,6 +210,10 @@ namespace BlackMisc
|
||||
//! Legacy aircraft (no current ICAO code)
|
||||
bool isLegacyAircraft() const { return m_legacy; }
|
||||
|
||||
//! Is DB duplicate, means redundant ICAO DB entry.
|
||||
//! \see https://aviation.stackexchange.com/q/37848/4024
|
||||
bool isDbDuplicate() const;
|
||||
|
||||
//! Flags
|
||||
void setCodeFlags(bool military, bool legacy, bool realWorld);
|
||||
|
||||
@@ -280,17 +312,19 @@ namespace BlackMisc
|
||||
static CAircraftIcaoCode fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString());
|
||||
|
||||
private:
|
||||
QString m_designator; //!< "B737"
|
||||
QString m_iataCode; //!< "320"
|
||||
QString m_family; //!< "A350" (not a real ICAO code, but a family)
|
||||
QString m_combinedType; //!< "L2J"
|
||||
QString m_manufacturer; //!< "Airbus"
|
||||
QString m_modelDescription; //!< "A-330-200"
|
||||
QString m_wtc; //!< wake turbulence "M","H" "L/M", "L", we only use the one letter versions
|
||||
bool m_realWorld = true; //!< real world aircraft
|
||||
bool m_legacy = false; //!< legacy code
|
||||
bool m_military = false; //!< military aircraft?
|
||||
int m_rank = 10; //!< rank among same codes
|
||||
QString m_designator; //!< "B737"
|
||||
QString m_iataCode; //!< "320"
|
||||
QString m_family; //!< "A350" (not a real ICAO code, but a family)
|
||||
QString m_combinedType; //!< "L2J"
|
||||
QString m_manufacturer; //!< "Airbus"
|
||||
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 "M","H" "L/M", "L", we only use the one letter versions
|
||||
bool m_realWorld = true; //!< real world aircraft
|
||||
bool m_legacy = false; //!< legacy code
|
||||
bool m_military = false; //!< military aircraft?
|
||||
int m_rank = 10; //!< rank among same codes
|
||||
|
||||
//! Create a combined string like L2J
|
||||
static QString createdCombinedString(const QString &type, const QString &engineCount, const QString &engine);
|
||||
@@ -308,6 +342,8 @@ namespace BlackMisc
|
||||
BLACK_METAMEMBER(combinedType),
|
||||
BLACK_METAMEMBER(manufacturer),
|
||||
BLACK_METAMEMBER(modelDescription),
|
||||
BLACK_METAMEMBER(modelIataDescription),
|
||||
BLACK_METAMEMBER(modelSwiftDescription),
|
||||
BLACK_METAMEMBER(wtc),
|
||||
BLACK_METAMEMBER(military),
|
||||
BLACK_METAMEMBER(realWorld),
|
||||
|
||||
@@ -172,6 +172,11 @@ namespace BlackMisc
|
||||
this->removeIf([](const CAircraftIcaoCode & icao) { return !icao.hasValidCombinedType(); });
|
||||
}
|
||||
|
||||
void CAircraftIcaoCodeList::removeDuplicates()
|
||||
{
|
||||
this->removeIf(&CAircraftIcaoCode::isDbDuplicate, true);
|
||||
}
|
||||
|
||||
QStringList CAircraftIcaoCodeList::toCompleterStrings(bool withIataCodes, bool withFamily, bool sort) const
|
||||
{
|
||||
QStringList c;
|
||||
@@ -218,6 +223,18 @@ namespace BlackMisc
|
||||
return c;
|
||||
}
|
||||
|
||||
QSet<QString> CAircraftIcaoCodeList::allFamilies() const
|
||||
{
|
||||
QSet<QString> c;
|
||||
for (const CAircraftIcaoCode &icao : *this)
|
||||
{
|
||||
if (!icao.hasFamily()) { continue; }
|
||||
const QString d(icao.getFamily());
|
||||
c.insert(d);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
QSet<QString> CAircraftIcaoCodeList::allManufacturers(bool onlyKnownDesignators) const
|
||||
{
|
||||
QSet<QString> c;
|
||||
@@ -231,15 +248,16 @@ namespace BlackMisc
|
||||
return c;
|
||||
}
|
||||
|
||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete)
|
||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::fromDatabaseJson(const QJsonArray &array, bool ignoreIncompleteAndDuplicates)
|
||||
{
|
||||
CAircraftIcaoCodeList codes;
|
||||
for (const QJsonValue &value : array)
|
||||
{
|
||||
CAircraftIcaoCode icao(CAircraftIcaoCode::fromDatabaseJson(value.toObject()));
|
||||
if (ignoreIncomplete && !icao.hasSpecialDesignator() && !icao.hasCompleteData())
|
||||
const CAircraftIcaoCode icao(CAircraftIcaoCode::fromDatabaseJson(value.toObject()));
|
||||
if (ignoreIncompleteAndDuplicates)
|
||||
{
|
||||
continue;
|
||||
if (!icao.hasSpecialDesignator() && !icao.hasCompleteData()) { continue; }
|
||||
if (icao.isDbDuplicate()) { continue; }
|
||||
}
|
||||
codes.push_back(icao);
|
||||
}
|
||||
@@ -250,7 +268,7 @@ namespace BlackMisc
|
||||
{
|
||||
if (icaoPattern.hasValidDbKey())
|
||||
{
|
||||
int k = icaoPattern.getDbKey();
|
||||
const int k = icaoPattern.getDbKey();
|
||||
CAircraftIcaoCode c(this->findByKey(k));
|
||||
if (c.hasCompleteData()) { return c; }
|
||||
}
|
||||
|
||||
@@ -103,17 +103,23 @@ namespace BlackMisc
|
||||
//! Remove invalid combined codes
|
||||
void removeInvalidCombinedCodes();
|
||||
|
||||
//! Remove duplicates as marked by CAircraftIcaoCode::isDbDuplicate
|
||||
void removeDuplicates();
|
||||
|
||||
//! For selection completion
|
||||
QStringList toCompleterStrings(bool withIataCodes = false, bool withFamily = false, bool sort = true) const;
|
||||
|
||||
//! All ICAO codes, no duplicates
|
||||
QSet<QString> allIcaoCodes(bool noUnspecified = true) const;
|
||||
|
||||
//! All families, no duplicates
|
||||
QSet<QString> allFamilies() const;
|
||||
|
||||
//! All manufacturers
|
||||
QSet<QString> allManufacturers(bool onlyKnownDesignators = true) const;
|
||||
|
||||
//! From our database JSON format
|
||||
static CAircraftIcaoCodeList fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete = true);
|
||||
static CAircraftIcaoCodeList fromDatabaseJson(const QJsonArray &array, bool ignoreIncompleteAndDuplicates = true);
|
||||
};
|
||||
} //namespace
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user