From 3b25781a06f920e500f51099e41becdbae384c66 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 7 Dec 2016 03:01:18 +0100 Subject: [PATCH] refs #825, utility functions * allow to prefer color liveries (idea: when no airline is found, a neutral livery looks better) * pick randomly among equal scores --- src/blackmisc/aviation/livery.cpp | 20 ++++++++++++++----- src/blackmisc/aviation/livery.h | 2 +- src/blackmisc/simulation/aircraftmodel.cpp | 4 ++-- src/blackmisc/simulation/aircraftmodel.h | 2 +- .../simulation/aircraftmodellist.cpp | 15 +++++++++++++- src/blackmisc/simulation/aircraftmodellist.h | 3 +++ 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/blackmisc/aviation/livery.cpp b/src/blackmisc/aviation/livery.cpp index fec548e2e..4355a2e00 100644 --- a/src/blackmisc/aviation/livery.cpp +++ b/src/blackmisc/aviation/livery.cpp @@ -393,7 +393,7 @@ namespace BlackMisc return this->getCombinedCodePlusInfo(); } - int CLivery::calculateScore(const CLivery &otherLivery) const + int CLivery::calculateScore(const CLivery &otherLivery, bool preferColorLiveries) const { int score = 0; if (this->isLoadedFromDb() && otherLivery.isLoadedFromDb() && (this->getCombinedCode() == otherLivery.getCombinedCode())) @@ -402,14 +402,24 @@ namespace BlackMisc } else { - score += 0.35 * this->getAirlineIcaoCode().calculateScore(otherLivery.getAirlineIcaoCode()); + const double multiplier = preferColorLiveries ? 0.10 : 0.35; + score += multiplier * this->getAirlineIcaoCode().calculateScore(otherLivery.getAirlineIcaoCode()); } - // 0..50 so far + // max. 0..35 so far if (score == 0) { return 0; } - if (this->isAirlineStandardLivery()) { score += 10; } + if (this->isAirlineStandardLivery() && !preferColorLiveries) { score += 10; } - // 0..60 so far + // overrate non airline liveries + if (preferColorLiveries) + { + if (this->isColorLivery() || !this->hasValidAirlineDesignator()) + { + score += 20; + } + } + + // 0..45 so far if (!this->hasValidColors()) { return score; } const double cd = this->getColorDistance(otherLivery); // 0..1 if (cd == 0) diff --git a/src/blackmisc/aviation/livery.h b/src/blackmisc/aviation/livery.h index d0888457a..61f94613a 100644 --- a/src/blackmisc/aviation/livery.h +++ b/src/blackmisc/aviation/livery.h @@ -175,7 +175,7 @@ namespace BlackMisc //! Score by comparison to another livery 0..100 //! \remark normally used with liveries preselect by airline ICAO code - int calculateScore(const CLivery &otherLivery) const; + int calculateScore(const CLivery &otherLivery, bool preferColorLiveries = false) const; //! Object from JSON static CLivery fromDatabaseJson(const QJsonObject &json, const QString &prefix = QString("liv_")); diff --git a/src/blackmisc/simulation/aircraftmodel.cpp b/src/blackmisc/simulation/aircraftmodel.cpp index ac8b8ec72..a82eaa277 100644 --- a/src/blackmisc/simulation/aircraftmodel.cpp +++ b/src/blackmisc/simulation/aircraftmodel.cpp @@ -629,10 +629,10 @@ namespace BlackMisc this->m_modelString.startsWith(modelString, sensitivity); } - int CAircraftModel::calculateScore(const CAircraftModel &compareModel) const + int CAircraftModel::calculateScore(const CAircraftModel &compareModel, bool preferColorLiveries) const { int score = this->getAircraftIcaoCode().calculateScore(compareModel.getAircraftIcaoCode()); - score += this->getLivery().calculateScore(compareModel.getLivery()); + score += this->getLivery().calculateScore(compareModel.getLivery(), preferColorLiveries); return 0.5 * score; } diff --git a/src/blackmisc/simulation/aircraftmodel.h b/src/blackmisc/simulation/aircraftmodel.h index 75b94b505..b43554fd9 100644 --- a/src/blackmisc/simulation/aircraftmodel.h +++ b/src/blackmisc/simulation/aircraftmodel.h @@ -356,7 +356,7 @@ namespace BlackMisc bool matchesModelString(const QString &modelString, Qt::CaseSensitivity sensitivity) const; //! Calculate score - int calculateScore(const CAircraftModel &compareModel) const; + int calculateScore(const CAircraftModel &compareModel, bool preferColorLiveries) const; //! Validate BlackMisc::CStatusMessageList validate(bool withNestedObjects) const; diff --git a/src/blackmisc/simulation/aircraftmodellist.cpp b/src/blackmisc/simulation/aircraftmodellist.cpp index bbbd739f0..78d129247 100644 --- a/src/blackmisc/simulation/aircraftmodellist.cpp +++ b/src/blackmisc/simulation/aircraftmodellist.cpp @@ -58,6 +58,16 @@ namespace BlackMisc return this->contains(&CAircraftModel::getCallsign, callsign); } + bool CAircraftModelList::containsCombinedType(const QString &combinedType) const + { + if (combinedType.isEmpty()) { return false; } + const QString ct(combinedType.toUpper().trimmed()); + return this->containsBy([ & ](const CAircraftModel & model) + { + return model.getAircraftIcaoCode().getCombinedType() == ct; + }); + } + bool CAircraftModelList::containsModelsWithAircraftAndAirlineDesignator(const QString &aircraftDesignator, const QString &airlineDesignator) const { return this->contains(&CAircraftModel::getAircraftIcaoCodeDesignator, aircraftDesignator, &CAircraftModel::getAirlineIcaoCodeDesignator, airlineDesignator); @@ -531,9 +541,12 @@ namespace BlackMisc ScoredModels CAircraftModelList::scoreFull(const CAircraftModel &remoteModel, bool ignoreZeroScores) const { ScoredModels scoreMap; + // prefer colors if there is no airline + const bool hasAirlineDesignator = remoteModel.hasAirlineDesignator() && this->contains(&CAircraftModel::getAirlineIcaoCodeDesignator, remoteModel.getAirlineIcaoCodeDesignator()); + const bool preferColorLiveries = !hasAirlineDesignator; for (const CAircraftModel &model : *this) { - const int score = model.calculateScore(remoteModel); + const int score = model.calculateScore(remoteModel, preferColorLiveries); if (ignoreZeroScores && score < 1) { continue; } scoreMap.insertMulti(score, model); } diff --git a/src/blackmisc/simulation/aircraftmodellist.h b/src/blackmisc/simulation/aircraftmodellist.h index 6ef60a724..630b6cae0 100644 --- a/src/blackmisc/simulation/aircraftmodellist.h +++ b/src/blackmisc/simulation/aircraftmodellist.h @@ -71,6 +71,9 @@ namespace BlackMisc //! Contains model for callsign bool containsCallsign(const BlackMisc::Aviation::CCallsign &callsign) const; + //! Contains given combined type + bool containsCombinedType(const QString &combinedType) const; + //! Contains any model with aircraft and airline designator bool containsModelsWithAircraftAndAirlineDesignator(const QString &aircraftDesignator, const QString &airlineDesignator) const;