Ref T242, utility functions for matching

* search among airline aircraft
* improved logging information
* search among airline ICAO aircraft (which aircraft does the airline use?)
* check ecosystem before merging with VATSIM data
This commit is contained in:
Klaus Basan
2018-02-07 05:21:41 +01:00
parent 10f942e702
commit e001b0338f
14 changed files with 231 additions and 27 deletions

View File

@@ -69,7 +69,7 @@ namespace BlackCore
break;
}
CMatchingUtils::addLogDetailsToList(log, callsign, QString("Two invalid airline ICAO codes '%1', '%2'").arg(primaryIcao, secondaryIcao), getLogCategories());
CMatchingUtils::addLogDetailsToList(log, callsign, QString("Two invalid airline ICAO codes (primary/secondary) '%1', '%2'").arg(primaryIcao, secondaryIcao), getLogCategories());
if (airlineFromCallsign)
{
const QString airlineSuffix = callsign.getAirlineSuffix();
@@ -94,8 +94,8 @@ namespace BlackCore
static const QString format("hh:mm:ss.zzz");
const QDateTime startTime = QDateTime::currentDateTimeUtc();
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QString("--- Start matching: UTC %1 ---").arg(startTime.toString(format)));
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QString("Matching uses model set of %1 models\n%2").arg(modelSet.size()).arg(modelSet.coverageSummary()));
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QString("Input model: '%1' '%2'").arg(remoteAircraft.getCallsignAsString(), remoteAircraft.getModel().toQString()));
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QString("Matching uses model set of %1 models\n%2").arg(modelSet.size()).arg(modelSet.extCoverageSummary(remoteAircraft.getModel())));
// Before I really search I check some special conditions
// 1) Manually set model (by user)
@@ -150,8 +150,8 @@ namespace BlackCore
Q_ASSERT_X(matchedModel.hasModelString(), Q_FUNC_INFO, "Missing model string");
Q_ASSERT_X(matchedModel.getModelType() != CAircraftModel::TypeUnknown, Q_FUNC_INFO, "Missing model type");
QDateTime endTime = QDateTime::currentDateTimeUtc();
qint64 matchingTime = startTime.msecsTo(endTime);
const QDateTime endTime = QDateTime::currentDateTimeUtc();
const qint64 matchingTime = startTime.msecsTo(endTime);
CMatchingUtils::addLogDetailsToList(log, remoteAircraft, QString("--- Matching end: UTC %1, time %2ms ---").arg(endTime.toString(format)).arg(matchingTime));
return matchedModel;
}
@@ -411,6 +411,7 @@ namespace BlackCore
{
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing sApp");
Q_ASSERT_X(sApp->getWebDataServices(), Q_FUNC_INFO, "No web services");
if (candidate.isEmpty()) { return ""; }
const QStringList designators = sApp->getWebDataServices()->getTelephonyDesignators();
if (designators.contains(candidate, Qt::CaseInsensitive))
@@ -423,6 +424,56 @@ namespace BlackCore
return "";
}
bool CAircraftMatcher::isKnowAircraftDesignator(const QString &candidate, const CCallsign &callsign, CStatusMessageList *log)
{
if (!CAircraftIcaoCode::isValidDesignator(candidate))
{
CMatchingUtils::addLogDetailsToList(log, callsign, QString("No valid ICAO designator '%1'").arg(candidate));
return false;
}
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing sApp");
Q_ASSERT_X(sApp->getWebDataServices(), Q_FUNC_INFO, "No web services");
const bool known = sApp->getWebDataServices()->containsAircraftIcaoDesignator(candidate);
static const QString sKnown("Known ICAO '%1'");
static const QString sUnknown("Unknown ICAO '%1'");
CMatchingUtils::addLogDetailsToList(log, callsign, known ? sKnown.arg(candidate) : sUnknown.arg(candidate));
return known;
}
CAircraftIcaoCode CAircraftMatcher::searchAmongAirlineAircraft(const QString &candidateString, const CAirlineIcaoCode &airline, const CCallsign &callsign, CStatusMessageList *log)
{
if (!airline.isLoadedFromDb())
{
CMatchingUtils::addLogDetailsToList(log, callsign, QString("No valid airline from DB '%1'").arg(airline.getDesignator()));
return CAircraftIcaoCode();
}
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Missing sApp");
Q_ASSERT_X(sApp->getWebDataServices(), Q_FUNC_INFO, "No web services");
const CAircraftIcaoCodeList aircraft = sApp->getWebDataServices()->getAircraftIcaoCodesForAirline(airline);
if (aircraft.isEmpty())
{
CMatchingUtils::addLogDetailsToList(log, callsign, QString("No aircraft known for airline '%1'").arg(airline.getDesignator()));
return CAircraftIcaoCode();
}
const QSet<QString> allIcaos = aircraft.allIcaoCodes();
const QString allIcaosStr = allIcaos.toList().join(", ");
CMatchingUtils::addLogDetailsToList(log, callsign, QString("Aircraft '%1' known for airline '%2'").arg(allIcaosStr, airline.getDesignator()));
const CAircraftIcaoCode code = aircraft.findBestFuzzyMatchOrDefault(candidateString);
if (code.hasValidDesignator())
{
CMatchingUtils::addLogDetailsToList(log, callsign, QString("Aircraft '%1' is best fuzzy search of '%2' for airline '%3'").arg(code.toQString(), candidateString, airline.getDesignator()));
return code;
}
return aircraft.front();
}
CAirlineIcaoCode CAircraftMatcher::callsignToAirline(const CCallsign &callsign, CStatusMessageList *log)
{
if (callsign.isEmpty() || !sApp || !sApp->getWebDataServices()) { return CAirlineIcaoCode(); }

View File

@@ -73,7 +73,7 @@ namespace BlackCore
const BlackMisc::Simulation::CSimulatedAircraft &remoteAircraft,
BlackMisc::CStatusMessageList *log = nullptr) const;
//! Return the airline ICAO being valid
//! Return an valid airline ICAO code
//! \threadsafe
static BlackMisc::Aviation::CAirlineIcaoCode failoverValidAirlineIcaoDesignator(
const BlackMisc::Aviation::CCallsign &callsign,
@@ -82,6 +82,7 @@ namespace BlackCore
//! Try to find the corresponding data in DB and get best information for given data
//! \threadsafe
//! \ingroup reverselookup
static BlackMisc::Simulation::CAircraftModel reverseLookupModel(
const BlackMisc::Aviation::CCallsign &callsign,
const BlackMisc::Aviation::CAircraftIcaoCode &networkAircraftIcao,
@@ -91,12 +92,14 @@ namespace BlackCore
//! Try to find the corresponding data in DB and get best information for following matching
//! \threadsafe
//! \ingroup reverselookup
static BlackMisc::Simulation::CAircraftModel reverseLookupModel(
const BlackMisc::Simulation::CAircraftModel &modelToLookup,
const QString &networkLiveryInfo, BlackMisc::CStatusMessageList *log = nullptr);
//! Try to find the DB corresponding ICAO code
//! \threadsafe
//! \ingroup reverselookup
static BlackMisc::Aviation::CAircraftIcaoCode reverseLookupAircraftIcao(
const BlackMisc::Aviation::CAircraftIcaoCode &icaoDesignator,
const BlackMisc::Aviation::CCallsign &logCallsign = BlackMisc::Aviation::CCallsign(),
@@ -104,27 +107,46 @@ namespace BlackCore
//! Try to find the DB corresponding ICAO code
//! \threadsafe
//! \ingroup reverselookup
static BlackMisc::Aviation::CAirlineIcaoCode reverseLookupAirlineIcao(
const BlackMisc::Aviation::CAirlineIcaoCode &icaoPattern,
const BlackMisc::Aviation::CCallsign &callsign = BlackMisc::Aviation::CCallsign(), BlackMisc::CStatusMessageList *log = nullptr);
//! Lookup of standard livery
//! \threadsafe
//! \ingroup reverselookup
static BlackMisc::Aviation::CLivery reverseLookupStandardLivery(
const BlackMisc::Aviation::CAirlineIcaoCode &airline,
const BlackMisc::Aviation::CCallsign &callsign, BlackMisc::CStatusMessageList *log = nullptr);
//! Lookup of airline name
//! \threadsafe
//! \ingroup reverselookup
static QString reverseLookupAirlineName(
const QString &candidate, const BlackMisc::Aviation::CCallsign &callsign = {}, BlackMisc::CStatusMessageList *log = nullptr);
//! Lookup of telephony designator
//! \threadsafe
//! \ingroup reverselookup
static QString reverseLookupTelephonyDesignator(
const QString &candidate, const BlackMisc::Aviation::CCallsign &callsign = {},
BlackMisc::CStatusMessageList *log = nullptr);
//! Is this designator known?
//! \threadsafe
static bool isKnowAircraftDesignator(
const QString &candidate, const BlackMisc::Aviation::CCallsign &callsign = {},
BlackMisc::CStatusMessageList *log = nullptr);
//! Search among the airline aircraft
//! \remark only works if an airline is know
//! \threadsafe
static BlackMisc::Aviation::CAircraftIcaoCode searchAmongAirlineAircraft(
const QString &icaoString,
const BlackMisc::Aviation::CAirlineIcaoCode &airline,
const BlackMisc::Aviation::CCallsign &callsign = {},
BlackMisc::CStatusMessageList *log = nullptr);
//! Turn callsign into airline
//! \threadsafe
static BlackMisc::Aviation::CAirlineIcaoCode callsignToAirline(const BlackMisc::Aviation::CCallsign &callsign, BlackMisc::CStatusMessageList *log = nullptr);

View File

@@ -971,7 +971,17 @@ namespace BlackCore
airlineIcao = CAircraftMatcher::reverseLookupAirlineIcao(airlineIcao, callsign, log);
}
const CAircraftIcaoCode aircraftIcao(aircraftIcaoString);
CAircraftIcaoCode aircraftIcao(aircraftIcaoString);
const bool knownAircraftIcao = CAircraftMatcher::isKnowAircraftDesignator(aircraftIcaoString, callsign, log);
if (airlineIcao.isLoadedFromDb() && !knownAircraftIcao)
{
// we have no valid aircraft ICAO, so we do a fuzzy search among those
CAircraftIcaoCode foundIcao = CAircraftMatcher::searchAmongAirlineAircraft(aircraftIcaoString, airlineIcao, callsign, log);
if (foundIcao.isLoadedFromDb()) { aircraftIcao = foundIcao; }
}
CMatchingUtils::addLogDetailsToList(log, callsign, QString("Quality of aircraft ICAO: %1").arg(aircraftIcao.toQString(true)), getLogCategories());
CMatchingUtils::addLogDetailsToList(log, callsign, QString("Quality of airline ICAO: %1").arg(airlineIcao.toQString(true)), getLogCategories());
return CAircraftMatcher::reverseLookupModel(callsign, aircraftIcao, airlineIcao, livery, modelString, type, log);
}
@@ -979,10 +989,14 @@ namespace BlackCore
{
const CCallsign callsign = aircraft.getCallsign();
Q_ASSERT_X(!callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign");
if (this->isAircraftInRange(callsign)) { return false; }
if (!sApp || sApp->isShuttingDown()) { return false; }
CSimulatedAircraft newAircraft(aircraft);
newAircraft.calculcateAndUpdateRelativeDistanceAndBearing(this->getOwnAircraftPosition()); // distance from myself
Q_ASSERT_X(sApp->hasWebDataServices(), Q_FUNC_INFO, "No web services");
sApp->getWebDataServices()->updateWithVatsimDataFileData(newAircraft);
// store
@@ -1345,9 +1359,16 @@ namespace BlackCore
return m_network && m_network->isConnected();
}
const CServer CAirspaceMonitor::getConnectedServer() const
{
if (!this->isConnected()) { return CServer(); }
return m_network->getPresetServer();
}
bool CAirspaceMonitor::supportsVatsimDataFile() const
{
return sApp && sApp->getWebDataServices() && sApp->getWebDataServices()->getVatsimDataFileReader();
const bool dataFile = sApp && sApp->getWebDataServices() && sApp->getWebDataServices()->getVatsimDataFileReader();
return dataFile && this->getConnectedServer().getEcosystem().isSystem(CEcosystem::VATSIM);
}
CLength CAirspaceMonitor::calculateDistanceToOwnAircraft(const CAircraftSituation &situation) const

View File

@@ -112,6 +112,20 @@ namespace BlackCore
return models.findByKey(dbKey);
}
QSet<QString> CModelDataReader::getAircraftDesignatorsForAirline(const CAirlineIcaoCode &code) const
{
if (!code.hasValidDesignator()) { return QSet<QString>(); }
const CAircraftModelList models(this->getModels());
return models.getAircraftDesignatorsForAirline(code);
}
CAircraftIcaoCodeList CModelDataReader::getAicraftIcaoCodesForAirline(const CAirlineIcaoCode &code) const
{
if (!code.hasValidDesignator()) { return CAircraftIcaoCodeList(); }
const CAircraftModelList models(this->getModels());
return models.getAicraftIcaoCodesForAirline(code);
}
CAircraftModelList CModelDataReader::getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode)
{
if (aircraftDesignator.isEmpty()) { return CAircraftModelList(); }
@@ -151,9 +165,9 @@ namespace BlackCore
return this->getModels().toDbKeySet();
}
QStringList CModelDataReader::getModelStringList() const
QStringList CModelDataReader::getModelStringList(bool sort) const
{
return this->getModels().getModelStringList(false);
return this->getModels().getModelStringList(sort);
}
bool CModelDataReader::areAllDataRead() const

View File

@@ -31,6 +31,7 @@
#include <QReadWriteLock>
#include <QString>
#include <QStringList>
#include <QSet>
class QNetworkReply;
@@ -87,6 +88,14 @@ namespace BlackCore
//! \threadsafe
BlackMisc::Simulation::CAircraftModel getModelForDbKey(int dbKey) const;
//! Get aircraft ICAO designators (e.g. B737, ..) for given airline
//! \threadsafe
QSet<QString> getAircraftDesignatorsForAirline(const BlackMisc::Aviation::CAirlineIcaoCode &code) const;
//! Get aircraft ICAO designators (e.g. B737, ..) for given airline
//! \threadsafe
BlackMisc::Aviation::CAircraftIcaoCodeList getAicraftIcaoCodesForAirline(const BlackMisc::Aviation::CAirlineIcaoCode &code) const;
//! Get model for designator/combined code
//! \threadsafe
BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode);
@@ -117,7 +126,7 @@ namespace BlackCore
//! Get model keys
//! \threadsafe
QStringList getModelStringList() const;
QStringList getModelStringList(bool sort = false) const;
//! All data read?
//! \threadsafe

View File

@@ -598,9 +598,9 @@ namespace BlackCore
return QSet<int>();
}
QStringList CWebDataServices::getModelStrings() const
QStringList CWebDataServices::getModelStrings(bool sort) const
{
if (m_modelDataReader) { return m_modelDataReader->getModelStringList(); }
if (m_modelDataReader) { return m_modelDataReader->getModelStringList(sort); }
return QStringList();
}
@@ -646,6 +646,20 @@ namespace BlackCore
return CAircraftIcaoCode();
}
QSet<QString> CWebDataServices::getAircraftDesignatorsForAirline(const CAirlineIcaoCode &airline) const
{
if (!airline.hasValidDesignator()) { return QSet<QString>(); }
if (m_modelDataReader) { return m_modelDataReader->getAircraftDesignatorsForAirline(airline); }
return QSet<QString>();
}
CAircraftIcaoCodeList CWebDataServices::getAircraftIcaoCodesForAirline(const CAirlineIcaoCode &airline) const
{
if (!airline.hasValidDesignator()) { return CAircraftIcaoCodeList(); }
if (m_modelDataReader) { return m_modelDataReader->getAicraftIcaoCodesForAirline(airline); }
return CAircraftIcaoCodeList();
}
bool CWebDataServices::containsAircraftIcaoDesignator(const QString &designator) const
{
if (designator.isEmpty()) { return false; }

View File

@@ -216,7 +216,7 @@ namespace BlackCore
//! Model strings
//! \threadsafe
QStringList getModelStrings() const;
QStringList getModelStrings(bool sort = false) const;
//! Model completer string
//! \threadsafe
@@ -246,6 +246,14 @@ namespace BlackCore
//! \threadsafe
BlackMisc::Aviation::CAircraftIcaoCode getAircraftIcaoCodeForDesignator(const QString &designator) const;
//! Aircraft ICAO designators for airline
//! \threadsafe
QSet<QString> getAircraftDesignatorsForAirline(const BlackMisc::Aviation::CAirlineIcaoCode &airline) const;
//! Aircraft ICAO codes for airline
//! \threadsafe
BlackMisc::Aviation::CAircraftIcaoCodeList getAircraftIcaoCodesForAirline(const BlackMisc::Aviation::CAirlineIcaoCode &airline) const;
//! Contains the given designator?
//! \threadsafe
bool containsAircraftIcaoDesignator(const QString &designator) const;