From f4f195a5f488a8d6fce939aaacf0e037512468c3 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 9 Apr 2016 02:30:26 +0200 Subject: [PATCH] refs #614, matcher improvements * improved reduce functions * support for combined code * support for livery --- src/blackmisc/simulation/aircraftmatcher.cpp | 100 ++++++++++++++----- src/blackmisc/simulation/aircraftmatcher.h | 53 +++++----- 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/src/blackmisc/simulation/aircraftmatcher.cpp b/src/blackmisc/simulation/aircraftmatcher.cpp index 3cb2e58a4..f0dd7f13f 100644 --- a/src/blackmisc/simulation/aircraftmatcher.cpp +++ b/src/blackmisc/simulation/aircraftmatcher.cpp @@ -144,79 +144,129 @@ namespace BlackMisc { if (model.hasModelString()) { - this->logDetails(log, remoteAircraft, "Found exact match for " + model.getModelString()); + logDetails(log, remoteAircraft, "Found exact match for " + model.getModelString()); } else { - this->logDetails(log, remoteAircraft, "No exact match for " + model.getModelString()); + logDetails(log, remoteAircraft, "No exact match for " + model.getModelString()); } } model.setModelType(CAircraftModel::TypeModelMatching); return model; } - CAircraftModel CAircraftMatcher::matchModelsByIcaoData(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, bool ignoreAirline, CStatusMessageList *log) const + CAircraftModel CAircraftMatcher::matchByLiveryAndIcaoCode(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, CStatusMessageList *log) + { + if (!remoteAircraft.getLivery().hasCombinedCode()) + { + if (log) { logDetails(log, remoteAircraft, "No livery code, no match possible"); } + return CAircraftModel(); + } + + const CAircraftModelList byLivery(models.findByLiveryCode(remoteAircraft.getLivery())); + if (byLivery.isEmpty()) + { + if (log) { logDetails(log, remoteAircraft, "Not found by livery code " + remoteAircraft.getLivery().getCombinedCode()); } + return CAircraftModel(); + } + return matchModelsByIcaoData(remoteAircraft, byLivery, true, log); + } + + CAircraftModel CAircraftMatcher::matchByCombinedCode(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, bool relaxIfNotFound, CStatusMessageList *log) + { + CAircraftModel aircraftModel; + if (!remoteAircraft.getAircraftIcaoCode().hasValidCombinedType()) + { + if (log) { logDetails(log, remoteAircraft, "No valid combined code"); } + return aircraftModel; + } + + const QString cc = remoteAircraft.getAircraftIcaoCode().getCombinedType(); + CAircraftModelList byCombinedCode(models.findByCombinedCode(cc)); + if (byCombinedCode.isEmpty()) + { + if (log) { logDetails(log, remoteAircraft, "Not found by combined code " + cc); } + return CAircraftModel(); + } + + if (log) { logDetails(log, remoteAircraft, "Found by combined code " + cc + ", possible " + QString::number(byCombinedCode.size())); } + if (byCombinedCode.size() > 1) + { + byCombinedCode = ifPossibleReduceByAirline(remoteAircraft, byCombinedCode, "Combined code", log); + byCombinedCode = ifPossibleReduceByManufacturer(remoteAircraft, byCombinedCode, "Combined code", log); + } + aircraftModel = byCombinedCode.front(); + aircraftModel.setModelType(CAircraftModel::TypeModelMatching); + return aircraftModel; + } + + CAircraftModel CAircraftMatcher::matchModelsByIcaoData(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, bool ignoreAirline, CStatusMessageList *log) { CAircraftModel aircraftModel; if (!remoteAircraft.hasAircraftDesignator()) { - if (log) { this->logDetails(log, remoteAircraft, "No aircraft designator, skipping step"); } + if (log) { logDetails(log, remoteAircraft, "No aircraft designator, skipping step"); } return aircraftModel; } - BlackMisc::Simulation::CAircraftModelList mappingModels( - models.findByIcaoDesignators(remoteAircraft.getAircraftIcaoCode(), - ignoreAirline ? CAirlineIcaoCode() : remoteAircraft.getAirlineIcaoCode())); - if (!mappingModels.isEmpty()) + BlackMisc::Simulation::CAircraftModelList searchModels(models.findByIcaoDesignators( + remoteAircraft.getAircraftIcaoCode(), + ignoreAirline ? CAirlineIcaoCode() : remoteAircraft.getAirlineIcaoCode())); + + if (!searchModels.isEmpty()) { - aircraftModel = mappingModels.front(); - aircraftModel.setModelType(CAircraftModel::TypeModelMatching); if (log) { - this->logDetails(log, remoteAircraft, - "Possible aircraft " + QString::number(mappingModels.size()) + - ", found by ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + - (ignoreAirline ? "" : remoteAircraft.getAirlineIcaoCodeDesignator())); + logDetails(log, remoteAircraft, + "Possible aircraft " + QString::number(searchModels.size()) + + ", found by ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + + (ignoreAirline ? "" : remoteAircraft.getAirlineIcaoCodeDesignator())); } + if (searchModels.size() > 1) + { + searchModels = ifPossibleReduceByManufacturer(remoteAircraft, searchModels, "Match by ICAO", log); + } + aircraftModel = searchModels.front(); + aircraftModel.setModelType(CAircraftModel::TypeModelMatching); } else { - if (remoteAircraft.hasAircraftAndAirlineDesignator()) + if (!ignoreAirline && remoteAircraft.hasAircraftAndAirlineDesignator()) { // we have searched by aircraft and airline, bout not found anything if (log) { - this->logDetails(log, remoteAircraft, - "Not found by ICAO " + - remoteAircraft.getAircraftIcaoCodeDesignator() + " " + remoteAircraft.getAirlineIcaoCodeDesignator() + - " relaxing to only ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator()); + logDetails(log, remoteAircraft, + "Not found by ICAO " + + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + remoteAircraft.getAirlineIcaoCodeDesignator() + + " relaxing to only ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator()); } // recursive lookup by ignoring airline - return this->matchModelsByIcaoData(remoteAircraft, models, true, log); + return matchModelsByIcaoData(remoteAircraft, models, true, log); } - if (log) { this->logDetails(log, remoteAircraft, "Not found by ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + remoteAircraft.getAirlineIcaoCodeDesignator()); } + if (log) { logDetails(log, remoteAircraft, "Not found by ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + remoteAircraft.getAirlineIcaoCodeDesignator()); } } return aircraftModel; } - CAircraftModel CAircraftMatcher::matchByFamily(const CSimulatedAircraft &remoteAircraft, const QString &family, const CAircraftModelList &models, const QString &modelSource, CStatusMessageList *log) const + CAircraftModel CAircraftMatcher::matchByFamily(const CSimulatedAircraft &remoteAircraft, const QString &family, const CAircraftModelList &models, const QString &hint, CStatusMessageList *log) { // Use an algorithm to find the best match if (family.isEmpty()) { - if (log) { this->logDetails(log, remoteAircraft, "No family, skipping step"); } + if (log) { logDetails(log, remoteAircraft, "No family, skipping step (" + hint + ")"); } return CAircraftModel(); } if (models.isEmpty()) { - if (log) { this->logDetails(log, remoteAircraft, "No models in " + modelSource + " for family match"); } + if (log) { logDetails(log, remoteAircraft, "No models for family match (" + hint + ")"); } return CAircraftModel(); } CAircraftModelList found(models.findByFamily(family)); if (found.isEmpty()) { - if (log) { this->logDetails(log, remoteAircraft, "Not found by family " + family + " in " + modelSource); } + if (log) { logDetails(log, remoteAircraft, "Not found by family " + family + " (" + hint + ")"); } return CAircraftModel(); } diff --git a/src/blackmisc/simulation/aircraftmatcher.h b/src/blackmisc/simulation/aircraftmatcher.h index e9ea92070..e8f2d237c 100644 --- a/src/blackmisc/simulation/aircraftmatcher.h +++ b/src/blackmisc/simulation/aircraftmatcher.h @@ -61,16 +61,13 @@ namespace BlackMisc //! Get the closest matching aircraft model. //! Result depends on enabled modes. //! \sa MatchingModeFlag - //! \threadsafe CAircraftModel getClosestMatch(const CSimulatedAircraft &remoteAircraft, BlackMisc::CStatusMessageList *log = nullptr) const; //! Get the models - //! \threadsafe - BlackMisc::Simulation::CAircraftModelList getModels() const { return m_models.read(); } + BlackMisc::Simulation::CAircraftModelList getModelSet() const { return m_modelSet; } //! Set the models we want to use - //! \threadsafe - int setModels(const BlackMisc::Simulation::CAircraftModelList &models); + int setModelSet(const BlackMisc::Simulation::CAircraftModelList &models); //! Default model const BlackMisc::Simulation::CAircraftModel &getDefaultModel() const; @@ -79,34 +76,44 @@ namespace BlackMisc void setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel); private: - //! Init state - enum InitState - { - NotInitialized, - InitInProgress, - InitFinished - }; - //! Search in models by key (aka model string) //! \threadsafe - CAircraftModel matchByExactModelString(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, CStatusMessageList *log) const; + static CAircraftModel matchByExactModelString(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, CStatusMessageList *log); + + //! Search for exact livery + //! \threadsafe + static CAircraftModel matchByLiveryAndIcaoCode(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, CStatusMessageList *log); //! Installed models by ICAO data //! \threadsafe - CAircraftModel matchModelsByIcaoData(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, bool ignoreAirline, CStatusMessageList *log) const; + static CAircraftModel matchModelsByIcaoData(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, bool ignoreAirline, CStatusMessageList *log); + + //! Installed models by combined code (ie L2J, L1P, ...) + //! \threadsafe + static CAircraftModel matchByCombinedCode(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &models, bool relaxIfNotFound, CStatusMessageList *log); //! Find model by aircraft family - CAircraftModel matchByFamily(const CSimulatedAircraft &remoteAircraft, const QString &family, const CAircraftModelList &models, CStatusMessageList *log) const; + //! \threadsafe + static CAircraftModel matchByFamily(const CSimulatedAircraft &remoteAircraft, const QString &family, const CAircraftModelList &models, const QString &modelSource, CStatusMessageList *log); + + //! Reduce by manufacturer + //! \threadsafe + static CAircraftModelList ifPossibleReduceByManufacturer(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &inList, const QString &info, CStatusMessageList *log); + + //! Reduce by airline ICAO + //! \threadsafe + static CAircraftModelList ifPossibleReduceByAirline(const CSimulatedAircraft &remoteAircraft, const CAircraftModelList &inList, const QString &info, CStatusMessageList *log); //! Add to log. if applicable - void logDetails(BlackMisc::CStatusMessageList *log, - const CSimulatedAircraft &remoteAircraft, - const QString &message, - CStatusMessage::StatusSeverity s = CStatusMessage::SeverityInfo) const; + //! \treadsafe + static void logDetails(BlackMisc::CStatusMessageList *log, + const CSimulatedAircraft &remoteAircraft, + const QString &message, + CStatusMessage::StatusSeverity s = CStatusMessage::SeverityInfo); - MatchingMode m_matchingMode = All; - BlackMisc::Simulation::CAircraftModel m_defaultModel; //!< model to be used as default model - BlackMisc::LockFree m_models; //!< models used for model matching + MatchingMode m_matchingMode = All; + BlackMisc::Simulation::CAircraftModel m_defaultModel; //!< model to be used as default model + BlackMisc::Simulation::CAircraftModelList m_modelSet; //!< models used for model matching }; } } // namespace