Ref T70, utility functions

* remove duplicates
* 3 model descriptions
This commit is contained in:
Klaus Basan
2017-06-15 00:33:38 +02:00
parent 96c27c1c5b
commit 63598a6a4e
4 changed files with 169 additions and 66 deletions

View File

@@ -55,6 +55,19 @@ namespace BlackMisc
if (m_rank < 0 || m_rank >= 10) { m_rank = 10; } 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 QString CAircraftIcaoCode::getDesignatorDbKey() const
{ {
if (this->isLoadedFromDb()) if (this->isLoadedFromDb())
@@ -83,6 +96,9 @@ namespace BlackMisc
if (!this->hasValidCombinedType() && otherIcaoCode.hasValidCombinedType()) { this->setCombinedType(otherIcaoCode.getCombinedType()); } if (!this->hasValidCombinedType() && otherIcaoCode.hasValidCombinedType()) { this->setCombinedType(otherIcaoCode.getCombinedType()); }
if (this->m_manufacturer.isEmpty()) { this->setManufacturer(otherIcaoCode.getManufacturer());} if (this->m_manufacturer.isEmpty()) { this->setManufacturer(otherIcaoCode.getManufacturer());}
if (this->m_modelDescription.isEmpty()) { this->setModelDescription(otherIcaoCode.getModelDescription()); } 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()) if (!this->hasValidDbKey())
{ {
// need to observe if it makes sense to copy the key but not copying the whole object // 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; 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 bool CAircraftIcaoCode::matchesCombinedType(const QString &combinedType) const
{ {
const QString cc(combinedType.toUpper().trimmed().replace(' ', '*').replace('-', '*')); const QString cc(combinedType.toUpper().trimmed().replace(' ', '*').replace('-', '*'));
@@ -291,6 +319,12 @@ namespace BlackMisc
return false; 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) void CAircraftIcaoCode::setCodeFlags(bool military, bool legacy, bool realWorld)
{ {
m_military = military; m_military = military;
@@ -402,7 +436,7 @@ namespace BlackMisc
{ {
if (index.isMyself()) { return CVariant::from(*this); } if (index.isMyself()) { return CVariant::from(*this); }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); } if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { return IDatastoreObjectWithIntegerKey::propertyByIndex(index); }
ColumnIndex i = index.frontCasted<ColumnIndex>(); const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i) switch (i)
{ {
case IndexAircraftDesignator: case IndexAircraftDesignator:
@@ -415,6 +449,12 @@ namespace BlackMisc
return CVariant::fromValue(this->m_combinedType); return CVariant::fromValue(this->m_combinedType);
case IndexModelDescription: case IndexModelDescription:
return CVariant::fromValue(this->m_modelDescription); 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: case IndexManufacturer:
return CVariant::fromValue(this->m_manufacturer); return CVariant::fromValue(this->m_manufacturer);
case IndexWtc: case IndexWtc:
@@ -440,7 +480,7 @@ namespace BlackMisc
{ {
if (index.isMyself()) { (*this) = variant.to<CAircraftIcaoCode>(); return; } if (index.isMyself()) { (*this) = variant.to<CAircraftIcaoCode>(); return; }
if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(index, variant); return; } if (IDatastoreObjectWithIntegerKey::canHandleIndex(index)) { IDatastoreObjectWithIntegerKey::setPropertyByIndex(index, variant); return; }
ColumnIndex i = index.frontCasted<ColumnIndex>(); const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i) switch (i)
{ {
case IndexAircraftDesignator: case IndexAircraftDesignator:
@@ -458,6 +498,12 @@ namespace BlackMisc
case IndexModelDescription: case IndexModelDescription:
this->setModelDescription(variant.value<QString>()); this->setModelDescription(variant.value<QString>());
break; break;
case IndexModelIataDescription:
this->setModelIataDescription(variant.value<QString>());
break;
case IndexModelSwiftDescription:
this->setModelSwiftDescription(variant.value<QString>());
break;
case IndexManufacturer: case IndexManufacturer:
this->setManufacturer(variant.value<QString>()); this->setManufacturer(variant.value<QString>());
break; break;
@@ -496,6 +542,24 @@ namespace BlackMisc
return m_combinedType.compare(compareValue.getCombinedType(), Qt::CaseInsensitive); return m_combinedType.compare(compareValue.getCombinedType(), Qt::CaseInsensitive);
case IndexModelDescription: case IndexModelDescription:
return m_modelDescription.compare(compareValue.getModelDescription(), Qt::CaseInsensitive); 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: case IndexManufacturer:
return m_manufacturer.compare(compareValue.getManufacturer(), Qt::CaseInsensitive); return m_manufacturer.compare(compareValue.getManufacturer(), Qt::CaseInsensitive);
case IndexWtc: case IndexWtc:
@@ -615,15 +679,17 @@ namespace BlackMisc
return CAircraftIcaoCode(); return CAircraftIcaoCode();
} }
QString designator(json.value(prefix + "designator").toString()); const QString designator(json.value(prefix + "designator").toString());
QString iata(json.value(prefix + "iata").toString()); const QString iata(json.value(prefix + "iata").toString());
QString family(json.value(prefix + "family").toString()); const QString family(json.value(prefix + "family").toString());
QString manufacturer(json.value(prefix + "manufacturer").toString()); const QString manufacturer(json.value(prefix + "manufacturer").toString());
QString model(json.value(prefix + "model").toString()); const QString model(json.value(prefix + "model").toString());
QString type(json.value(prefix + "type").toString()); const QString modelIata(json.value(prefix + "modeliata").toString());
QString engine(json.value(prefix + "engine").toString()); const QString modelSwift(json.value(prefix + "modelswift").toString());
int engineCount(json.value(prefix + "enginecount").toInt(-1)); const QString type(json.value(prefix + "type").toString());
QString combined(createdCombinedString(type, engineCount, engine)); 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()); QString wtc(json.value(prefix + "wtc").toString());
if (wtc.length() > 1 && wtc.contains("/")) if (wtc.length() > 1 && wtc.contains("/"))
{ {
@@ -632,17 +698,16 @@ namespace BlackMisc
} }
Q_ASSERT_X(wtc.length() < 2, Q_FUNC_INFO, "WTC too long"); Q_ASSERT_X(wtc.length() < 2, Q_FUNC_INFO, "WTC too long");
bool real = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "realworld").toString()); const bool real = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "realworld").toString());
bool legacy = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "legacy").toString()); const bool legacy = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "legacy").toString());
bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString()); const bool military = CDatastoreUtility::dbBoolStringToBool(json.value(prefix + "military").toString());
int rank(json.value(prefix + "rank").toInt(10)); const int rank(json.value(prefix + "rank").toInt(10));
CAircraftIcaoCode code( CAircraftIcaoCode code(
designator, iata, combined, designator, iata, family, combined, manufacturer,
manufacturer, model, wtc, model, modelIata, modelSwift, wtc,
real, legacy, military, rank real, legacy, military, rank
); );
code.setFamily(family);
code.setKeyAndTimestampFromDatabaseJson(json, prefix); code.setKeyAndTimestampFromDatabaseJson(json, prefix);
return code; return code;
} }
@@ -650,39 +715,17 @@ namespace BlackMisc
QString CAircraftIcaoCode::createdCombinedString(const QString &type, const QString &engineCount, const QString &engine) QString CAircraftIcaoCode::createdCombinedString(const QString &type, const QString &engineCount, const QString &engine)
{ {
Q_ASSERT_X(engineCount.length() < 2, Q_FUNC_INFO, "Wrong engine count"); Q_ASSERT_X(engineCount.length() < 2, Q_FUNC_INFO, "Wrong engine count");
QString c(type.isEmpty() ? "-" : type.trimmed().left(1).toUpper());
QString c(type.trimmed().toUpper().left(1)); c += engineCount.isEmpty() ? "-" : engineCount.trimmed();
if (c.isEmpty()) { c.append("-"); } c += engine.isEmpty() ? "-" : engine.trimmed().left(1).toUpper();
if (engineCount.isEmpty())
{
c.append("-");
}
else
{
c.append(engineCount);
}
if (engine.isEmpty())
{
c.append("-");
}
else
{
c.append(engine.at(0));
}
Q_ASSERT_X(c.length() == 3, Q_FUNC_INFO, "Wrong combined length"); Q_ASSERT_X(c.length() == 3, Q_FUNC_INFO, "Wrong combined length");
return c; return c;
} }
QString CAircraftIcaoCode::createdCombinedString(const QString &type, int engineCount, const QString &engine) QString CAircraftIcaoCode::createdCombinedString(const QString &type, int engineCount, const QString &engine)
{ {
if (engineCount >= 0 && engineCount < 10) const bool valid = engineCount >= 0 && engineCount < 10;
{ return createdCombinedString(type, valid ? QString::number(engineCount) : "", engine);
return createdCombinedString(type, QString::number(engineCount), engine);
}
else
{
return createdCombinedString(type, "", engine);
}
} }
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -44,13 +44,16 @@ namespace BlackMisc
IndexCombinedAircraftType, IndexCombinedAircraftType,
IndexManufacturer, IndexManufacturer,
IndexModelDescription, IndexModelDescription,
IndexModelIataDescription,
IndexModelSwiftDescription,
IndexCombinedDescription,
IndexWtc, IndexWtc,
IndexIsRealworld, IndexIsRealworld,
IndexIsMilitary, IndexIsMilitary,
IndexIsLegacy, IndexIsLegacy,
IndexIsVtol, IndexIsVtol,
IndexRank, IndexRank,
IndexDesignatorManufacturer //!< designator and manufacturer IndexDesignatorManufacturer //!< designator and manufacturer
}; };
//! Default constructor. //! Default constructor.
@@ -67,6 +70,10 @@ namespace BlackMisc
CAircraftIcaoCode(const QString &icao, const QString &iata, const QString &combinedType, const QString &manufacturer, 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, 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" //! Get ICAO designator, e.g. "B737"
const QString &getDesignator() const { return m_designator; } const QString &getDesignator() const { return m_designator; }
@@ -133,9 +140,18 @@ namespace BlackMisc
//! Set type //! Set type
void setCombinedType(const QString &type) { this->m_combinedType = type.trimmed().toUpper(); } 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; } 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 //! Matches given combined code
//! \remark * can be used as wildcard, e.g. L*J, L** //! \remark * can be used as wildcard, e.g. L*J, L**
bool matchesCombinedType(const QString &combinedType) const; bool matchesCombinedType(const QString &combinedType) const;
@@ -143,12 +159,24 @@ namespace BlackMisc
//! Designator + Manufacturer //! Designator + Manufacturer
QString getDesignatorManufacturer() const; QString getDesignatorManufacturer() const;
//! Set the model description //! Set the model description (ICAO description)
void setModelDescription(const QString &modelDescription) { m_modelDescription = modelDescription.trimmed(); } 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(); } 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" //! Get manufacturer, e.g. "Airbus"
const QString &getManufacturer() const { return m_manufacturer; } const QString &getManufacturer() const { return m_manufacturer; }
@@ -182,6 +210,10 @@ namespace BlackMisc
//! Legacy aircraft (no current ICAO code) //! Legacy aircraft (no current ICAO code)
bool isLegacyAircraft() const { return m_legacy; } 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 //! Flags
void setCodeFlags(bool military, bool legacy, bool realWorld); void setCodeFlags(bool military, bool legacy, bool realWorld);
@@ -280,17 +312,19 @@ namespace BlackMisc
static CAircraftIcaoCode fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString()); static CAircraftIcaoCode fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString());
private: private:
QString m_designator; //!< "B737" QString m_designator; //!< "B737"
QString m_iataCode; //!< "320" QString m_iataCode; //!< "320"
QString m_family; //!< "A350" (not a real ICAO code, but a family) QString m_family; //!< "A350" (not a real ICAO code, but a family)
QString m_combinedType; //!< "L2J" QString m_combinedType; //!< "L2J"
QString m_manufacturer; //!< "Airbus" QString m_manufacturer; //!< "Airbus"
QString m_modelDescription; //!< "A-330-200" QString m_modelDescription; //!< "A-330-200", the ICAO description
QString m_wtc; //!< wake turbulence "M","H" "L/M", "L", we only use the one letter versions QString m_modelIataDescription; //!< alternative IATA description
bool m_realWorld = true; //!< real world aircraft QString m_modelSwiftDescription; //!< alternative swift description
bool m_legacy = false; //!< legacy code QString m_wtc; //!< wake turbulence "M","H" "L/M", "L", we only use the one letter versions
bool m_military = false; //!< military aircraft? bool m_realWorld = true; //!< real world aircraft
int m_rank = 10; //!< rank among same codes 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 //! Create a combined string like L2J
static QString createdCombinedString(const QString &type, const QString &engineCount, const QString &engine); static QString createdCombinedString(const QString &type, const QString &engineCount, const QString &engine);
@@ -308,6 +342,8 @@ namespace BlackMisc
BLACK_METAMEMBER(combinedType), BLACK_METAMEMBER(combinedType),
BLACK_METAMEMBER(manufacturer), BLACK_METAMEMBER(manufacturer),
BLACK_METAMEMBER(modelDescription), BLACK_METAMEMBER(modelDescription),
BLACK_METAMEMBER(modelIataDescription),
BLACK_METAMEMBER(modelSwiftDescription),
BLACK_METAMEMBER(wtc), BLACK_METAMEMBER(wtc),
BLACK_METAMEMBER(military), BLACK_METAMEMBER(military),
BLACK_METAMEMBER(realWorld), BLACK_METAMEMBER(realWorld),

View File

@@ -172,6 +172,11 @@ namespace BlackMisc
this->removeIf([](const CAircraftIcaoCode & icao) { return !icao.hasValidCombinedType(); }); 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 CAircraftIcaoCodeList::toCompleterStrings(bool withIataCodes, bool withFamily, bool sort) const
{ {
QStringList c; QStringList c;
@@ -218,6 +223,18 @@ namespace BlackMisc
return c; 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> CAircraftIcaoCodeList::allManufacturers(bool onlyKnownDesignators) const
{ {
QSet<QString> c; QSet<QString> c;
@@ -231,15 +248,16 @@ namespace BlackMisc
return c; return c;
} }
CAircraftIcaoCodeList CAircraftIcaoCodeList::fromDatabaseJson(const QJsonArray &array, bool ignoreIncomplete) CAircraftIcaoCodeList CAircraftIcaoCodeList::fromDatabaseJson(const QJsonArray &array, bool ignoreIncompleteAndDuplicates)
{ {
CAircraftIcaoCodeList codes; CAircraftIcaoCodeList codes;
for (const QJsonValue &value : array) for (const QJsonValue &value : array)
{ {
CAircraftIcaoCode icao(CAircraftIcaoCode::fromDatabaseJson(value.toObject())); const CAircraftIcaoCode icao(CAircraftIcaoCode::fromDatabaseJson(value.toObject()));
if (ignoreIncomplete && !icao.hasSpecialDesignator() && !icao.hasCompleteData()) if (ignoreIncompleteAndDuplicates)
{ {
continue; if (!icao.hasSpecialDesignator() && !icao.hasCompleteData()) { continue; }
if (icao.isDbDuplicate()) { continue; }
} }
codes.push_back(icao); codes.push_back(icao);
} }
@@ -250,7 +268,7 @@ namespace BlackMisc
{ {
if (icaoPattern.hasValidDbKey()) if (icaoPattern.hasValidDbKey())
{ {
int k = icaoPattern.getDbKey(); const int k = icaoPattern.getDbKey();
CAircraftIcaoCode c(this->findByKey(k)); CAircraftIcaoCode c(this->findByKey(k));
if (c.hasCompleteData()) { return c; } if (c.hasCompleteData()) { return c; }
} }

View File

@@ -103,17 +103,23 @@ namespace BlackMisc
//! Remove invalid combined codes //! Remove invalid combined codes
void removeInvalidCombinedCodes(); void removeInvalidCombinedCodes();
//! Remove duplicates as marked by CAircraftIcaoCode::isDbDuplicate
void removeDuplicates();
//! For selection completion //! For selection completion
QStringList toCompleterStrings(bool withIataCodes = false, bool withFamily = false, bool sort = true) const; QStringList toCompleterStrings(bool withIataCodes = false, bool withFamily = false, bool sort = true) const;
//! All ICAO codes, no duplicates //! All ICAO codes, no duplicates
QSet<QString> allIcaoCodes(bool noUnspecified = true) const; QSet<QString> allIcaoCodes(bool noUnspecified = true) const;
//! All families, no duplicates
QSet<QString> allFamilies() const;
//! All manufacturers //! All manufacturers
QSet<QString> allManufacturers(bool onlyKnownDesignators = true) const; QSet<QString> allManufacturers(bool onlyKnownDesignators = true) const;
//! From our database JSON format //! 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
} // namespace } // namespace