mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-10 05:55:33 +08:00
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:
@@ -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(); }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user