mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-02 07:05:38 +08:00
Ref T97, use fuzzy search for aircraft ICAO
This commit is contained in:
committed by
Mathew Sutcliffe
parent
32abac5d94
commit
2093d9def2
@@ -290,7 +290,7 @@ namespace BlackMisc
|
|||||||
if (getEngineCount() != c.digitValue()) { return false; }
|
if (getEngineCount() != c.digitValue()) { return false; }
|
||||||
}
|
}
|
||||||
if (et == '*') { return true; }
|
if (et == '*') { return true; }
|
||||||
const QString cet = getEngineType();
|
const QString cet = this->getEngineType();
|
||||||
return cet.length() == 1 && cet.at(0) == et;
|
return cet.length() == 1 && cet.at(0) == et;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,22 +417,61 @@ namespace BlackMisc
|
|||||||
return hasValidCombinedType() && hasDesignator() && hasValidWtc() && hasManufacturer();
|
return hasValidCombinedType() && hasDesignator() && hasValidWtc() && hasManufacturer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftIcaoCode::matchesDesignator(const QString &designator) const
|
bool CAircraftIcaoCode::matchesDesignator(const QString &designator, int fuzzyMatch, int *result) const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT_X(fuzzyMatch >= -1 && fuzzyMatch <= 100, Q_FUNC_INFO, "fuzzyMatch range 0..100 or -1");
|
||||||
if (designator.isEmpty()) { return false; }
|
if (designator.isEmpty()) { return false; }
|
||||||
return designator.trimmed().toUpper() == this->m_designator;
|
const QString d = designator.trimmed().toUpper();
|
||||||
|
if (fuzzyMatch >= 0)
|
||||||
|
{
|
||||||
|
const int r = fuzzyShortStringComparision(this->getDesignator(), d) >= fuzzyMatch;
|
||||||
|
if (result) { *result = r; }
|
||||||
|
return r >= fuzzyMatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const bool e = this->getDesignator() == d;
|
||||||
|
if (result) { *result = e ? 100 : 0; }
|
||||||
|
return e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftIcaoCode::matchesIataCode(const QString &iata) const
|
bool CAircraftIcaoCode::matchesIataCode(const QString &iata, int fuzzyMatch, int *result) const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT_X(fuzzyMatch >= -1 && fuzzyMatch <= 100, Q_FUNC_INFO, "fuzzyMatch range 0..100 or -1");
|
||||||
if (iata.isEmpty()) { return false; }
|
if (iata.isEmpty()) { return false; }
|
||||||
return iata.trimmed().toUpper() == this->m_iataCode;
|
const QString i = iata.trimmed().toUpper();
|
||||||
|
if (fuzzyMatch >= 0)
|
||||||
|
{
|
||||||
|
const int r = fuzzyShortStringComparision(this->getIataCode(), i) >= fuzzyMatch;
|
||||||
|
if (result) { *result = r; }
|
||||||
|
return r >= fuzzyMatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const bool e = this->getIataCode() == i;
|
||||||
|
if (result) { *result = e ? 100 : 0; }
|
||||||
|
return e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftIcaoCode::matchesFamily(const QString &family) const
|
bool CAircraftIcaoCode::matchesFamily(const QString &family, int fuzzyMatch, int *result) const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT_X(fuzzyMatch >= -1 && fuzzyMatch <= 100, Q_FUNC_INFO, "fuzzyMatch range 0..100 or -1");
|
||||||
if (family.isEmpty()) { return false; }
|
if (family.isEmpty()) { return false; }
|
||||||
return family.trimmed().toUpper() == this->m_family;
|
const QString f = family.trimmed().toUpper();
|
||||||
|
if (fuzzyMatch >= 0)
|
||||||
|
{
|
||||||
|
const int r = fuzzyShortStringComparision(this->getFamily(), f) >= fuzzyMatch;
|
||||||
|
if (result) { *result = r; }
|
||||||
|
return r >= fuzzyMatch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const bool e = this->getFamily() == f;
|
||||||
|
if (result) { *result = e ? 100 : 0; }
|
||||||
|
return e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAircraftIcaoCode::matchesDesignatorOrIata(const QString &icaoOrIata) const
|
bool CAircraftIcaoCode::matchesDesignatorOrIata(const QString &icaoOrIata) const
|
||||||
|
|||||||
@@ -251,13 +251,14 @@ namespace BlackMisc
|
|||||||
bool hasCompleteData() const;
|
bool hasCompleteData() const;
|
||||||
|
|
||||||
//! Matches designator string?
|
//! Matches designator string?
|
||||||
bool matchesDesignator(const QString &designator) const;
|
bool matchesDesignator(const QString &designator, int fuzzyMatch = -1, int *result = nullptr) const;
|
||||||
|
|
||||||
//! Matches IATA string?
|
//! Matches IATA string?
|
||||||
bool matchesIataCode(const QString &iata) const;
|
//! \remark IATA codes are only 3 characters, so using fuzzy search might yield bad results
|
||||||
|
bool matchesIataCode(const QString &iata, int fuzzyMatch = -1, int *result = nullptr) const;
|
||||||
|
|
||||||
//! Matches family?
|
//! Matches family?
|
||||||
bool matchesFamily(const QString &family) const;
|
bool matchesFamily(const QString &family, int fuzzyMatch = -1, int *result = nullptr) const;
|
||||||
|
|
||||||
//! Matches ICAO or IATA code
|
//! Matches ICAO or IATA code
|
||||||
bool matchesDesignatorOrIata(const QString &icaoOrIata) const;
|
bool matchesDesignatorOrIata(const QString &icaoOrIata) const;
|
||||||
|
|||||||
@@ -25,15 +25,32 @@ namespace BlackMisc
|
|||||||
CSequence<CAircraftIcaoCode>(other)
|
CSequence<CAircraftIcaoCode>(other)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByDesignator(const QString &designator) const
|
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByDesignator(const QString &designator, int fuzzySearch) const
|
||||||
{
|
{
|
||||||
if (!CAircraftIcaoCode::isValidDesignator(designator)) { return CAircraftIcaoCodeList(); }
|
if (!fuzzySearch && !CAircraftIcaoCode::isValidDesignator(designator)) { return CAircraftIcaoCodeList(); }
|
||||||
|
if (fuzzySearch && designator.length() < 3) { return CAircraftIcaoCodeList(); }
|
||||||
return this->findBy([&](const CAircraftIcaoCode & code)
|
return this->findBy([&](const CAircraftIcaoCode & code)
|
||||||
{
|
{
|
||||||
return code.matchesDesignator(designator);
|
return code.matchesDesignator(designator, fuzzySearch);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAircraftIcaoCode CAircraftIcaoCodeList::findBestFuzzyMatchOrDefault(const QString &designator, int cutoff) const
|
||||||
|
{
|
||||||
|
if (designator.length() < 3) { return CAircraftIcaoCode(); }
|
||||||
|
int best = 0;
|
||||||
|
int current = 0;
|
||||||
|
CAircraftIcaoCode found;
|
||||||
|
const QString d(designator.trimmed().toUpper());
|
||||||
|
for (const CAircraftIcaoCode &code : * this)
|
||||||
|
{
|
||||||
|
if (!code.matchesDesignator(d, cutoff, ¤t)) { continue; }
|
||||||
|
if (current == 100.0) { return code; }
|
||||||
|
if (best < current) { found = code; }
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByValidDesignator() const
|
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByValidDesignator() const
|
||||||
{
|
{
|
||||||
return this->findBy([](const CAircraftIcaoCode & code)
|
return this->findBy([](const CAircraftIcaoCode & code)
|
||||||
@@ -88,21 +105,21 @@ namespace BlackMisc
|
|||||||
return icaosDesignator.isEmpty() ? icaosFamily : icaosDesignator;
|
return icaosDesignator.isEmpty() ? icaosFamily : icaosDesignator;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByIataCode(const QString &iata) const
|
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByIataCode(const QString &iata, int fuzzySearch) const
|
||||||
{
|
{
|
||||||
if (iata.isEmpty()) { return CAircraftIcaoCodeList(); }
|
if (iata.isEmpty()) { return CAircraftIcaoCodeList(); }
|
||||||
return this->findBy([&](const CAircraftIcaoCode & code)
|
return this->findBy([&](const CAircraftIcaoCode & code)
|
||||||
{
|
{
|
||||||
return code.matchesIataCode(iata);
|
return code.matchesIataCode(iata, fuzzySearch);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByFamily(const QString &family) const
|
CAircraftIcaoCodeList CAircraftIcaoCodeList::findByFamily(const QString &family, int fuzzySearch) const
|
||||||
{
|
{
|
||||||
if (family.isEmpty()) { return CAircraftIcaoCodeList(); }
|
if (family.isEmpty()) { return CAircraftIcaoCodeList(); }
|
||||||
return this->findBy([&](const CAircraftIcaoCode & code)
|
return this->findBy([&](const CAircraftIcaoCode & code)
|
||||||
{
|
{
|
||||||
return code.matchesFamily(family);
|
return code.matchesFamily(family, fuzzySearch);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,22 +355,15 @@ namespace BlackMisc
|
|||||||
codes = this->findByIataCode(designator);
|
codes = this->findByIataCode(designator);
|
||||||
if (!codes.isEmpty()) break;
|
if (!codes.isEmpty()) break;
|
||||||
|
|
||||||
// search by reduced length
|
// search fuzzy and restrict length
|
||||||
if (designator.length() >= 4)
|
const CAircraftIcaoCode bestMatch = this->findBestFuzzyMatchOrDefault(designator.length() < 5 ? designator : designator.left(5), 70);
|
||||||
{
|
if (bestMatch.hasValidDesignator()) { return bestMatch; }
|
||||||
codes = this->findByDesignator(designator.left(4));
|
|
||||||
if (!codes.isEmpty()) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// still empty, try to find by family
|
// still empty, try to find by family
|
||||||
codes = this->findByFamily(designator);
|
codes = this->findByFamily(designator);
|
||||||
if (!codes.isEmpty()) break;
|
if (!codes.isEmpty()) break;
|
||||||
|
|
||||||
// now try to find as ending
|
// by any description
|
||||||
codes = this->findEndingWith(designator);
|
|
||||||
if (!codes.isEmpty()) break;
|
|
||||||
|
|
||||||
// by any descriptionS
|
|
||||||
codes = this->findMatchingByAnyDescription(designator);
|
codes = this->findMatchingByAnyDescription(designator);
|
||||||
}
|
}
|
||||||
while (false);
|
while (false);
|
||||||
|
|||||||
@@ -46,13 +46,16 @@ namespace BlackMisc
|
|||||||
CAircraftIcaoCodeList(const CSequence<CAircraftIcaoCode> &other);
|
CAircraftIcaoCodeList(const CSequence<CAircraftIcaoCode> &other);
|
||||||
|
|
||||||
//! Find by designator
|
//! Find by designator
|
||||||
CAircraftIcaoCodeList findByDesignator(const QString &designator) const;
|
CAircraftIcaoCodeList findByDesignator(const QString &designator, int fuzzySearch = -1) const;
|
||||||
|
|
||||||
|
//! Find by designator
|
||||||
|
CAircraftIcaoCode findBestFuzzyMatchOrDefault(const QString &designator, int cutoff = 50) const;
|
||||||
|
|
||||||
//! Find by IATA code
|
//! Find by IATA code
|
||||||
CAircraftIcaoCodeList findByIataCode(const QString &iata) const;
|
CAircraftIcaoCodeList findByIataCode(const QString &iata, int fuzzySearch = -1) const;
|
||||||
|
|
||||||
//! Find by family
|
//! Find by family
|
||||||
CAircraftIcaoCodeList findByFamily(const QString &family) const;
|
CAircraftIcaoCodeList findByFamily(const QString &family, int fuzzySearch = -1) const;
|
||||||
|
|
||||||
//! Ones with a valid designator
|
//! Ones with a valid designator
|
||||||
CAircraftIcaoCodeList findByValidDesignator() const;
|
CAircraftIcaoCodeList findByValidDesignator() const;
|
||||||
@@ -67,7 +70,8 @@ namespace BlackMisc
|
|||||||
CAircraftIcaoCodeList findByDesignatorIataOrFamily(const QString &icaoIataOrFamily) const;
|
CAircraftIcaoCodeList findByDesignatorIataOrFamily(const QString &icaoIataOrFamily) const;
|
||||||
|
|
||||||
//! Find code ending with string, e.g. "738" finds "B738"
|
//! Find code ending with string, e.g. "738" finds "B738"
|
||||||
//! \remark many users use wrong ICAO designators, one typical mistake is "738" for "B737"
|
//! \remark many users use wrong ICAO designators, one typical mistake is "738" for "B737"
|
||||||
|
//! \remark consider to use findBestFuzzyMatchOrDefault
|
||||||
CAircraftIcaoCodeList findEndingWith(const QString &icaoEnding) const;
|
CAircraftIcaoCodeList findEndingWith(const QString &icaoEnding) const;
|
||||||
|
|
||||||
//! Find by manufacturer
|
//! Find by manufacturer
|
||||||
|
|||||||
Reference in New Issue
Block a user