refs #614, matcher improvements

* improved reduce functions
* support for combined code
* support for livery
This commit is contained in:
Klaus Basan
2016-04-09 02:30:26 +02:00
parent d83e9c0c91
commit f4f195a5f4
2 changed files with 105 additions and 48 deletions

View File

@@ -144,79 +144,129 @@ namespace BlackMisc
{ {
if (model.hasModelString()) if (model.hasModelString())
{ {
this->logDetails(log, remoteAircraft, "Found exact match for " + model.getModelString()); logDetails(log, remoteAircraft, "Found exact match for " + model.getModelString());
} }
else else
{ {
this->logDetails(log, remoteAircraft, "No exact match for " + model.getModelString()); logDetails(log, remoteAircraft, "No exact match for " + model.getModelString());
} }
} }
model.setModelType(CAircraftModel::TypeModelMatching); model.setModelType(CAircraftModel::TypeModelMatching);
return model; 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; CAircraftModel aircraftModel;
if (!remoteAircraft.hasAircraftDesignator()) 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; return aircraftModel;
} }
BlackMisc::Simulation::CAircraftModelList mappingModels( BlackMisc::Simulation::CAircraftModelList searchModels(models.findByIcaoDesignators(
models.findByIcaoDesignators(remoteAircraft.getAircraftIcaoCode(), remoteAircraft.getAircraftIcaoCode(),
ignoreAirline ? CAirlineIcaoCode() : remoteAircraft.getAirlineIcaoCode())); ignoreAirline ? CAirlineIcaoCode() : remoteAircraft.getAirlineIcaoCode()));
if (!mappingModels.isEmpty())
if (!searchModels.isEmpty())
{ {
aircraftModel = mappingModels.front();
aircraftModel.setModelType(CAircraftModel::TypeModelMatching);
if (log) if (log)
{ {
this->logDetails(log, remoteAircraft, logDetails(log, remoteAircraft,
"Possible aircraft " + QString::number(mappingModels.size()) + "Possible aircraft " + QString::number(searchModels.size()) +
", found by ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + ", found by ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator() + " " +
(ignoreAirline ? "" : remoteAircraft.getAirlineIcaoCodeDesignator())); (ignoreAirline ? "" : remoteAircraft.getAirlineIcaoCodeDesignator()));
} }
if (searchModels.size() > 1)
{
searchModels = ifPossibleReduceByManufacturer(remoteAircraft, searchModels, "Match by ICAO", log);
}
aircraftModel = searchModels.front();
aircraftModel.setModelType(CAircraftModel::TypeModelMatching);
} }
else else
{ {
if (remoteAircraft.hasAircraftAndAirlineDesignator()) if (!ignoreAirline && remoteAircraft.hasAircraftAndAirlineDesignator())
{ {
// we have searched by aircraft and airline, bout not found anything // we have searched by aircraft and airline, bout not found anything
if (log) if (log)
{ {
this->logDetails(log, remoteAircraft, logDetails(log, remoteAircraft,
"Not found by ICAO " + "Not found by ICAO " +
remoteAircraft.getAircraftIcaoCodeDesignator() + " " + remoteAircraft.getAirlineIcaoCodeDesignator() + remoteAircraft.getAircraftIcaoCodeDesignator() + " " + remoteAircraft.getAirlineIcaoCodeDesignator() +
" relaxing to only ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator()); " relaxing to only ICAO " + remoteAircraft.getAircraftIcaoCodeDesignator());
} }
// recursive lookup by ignoring airline // 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; 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 // Use an algorithm to find the best match
if (family.isEmpty()) 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(); return CAircraftModel();
} }
if (models.isEmpty()) 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(); return CAircraftModel();
} }
CAircraftModelList found(models.findByFamily(family)); CAircraftModelList found(models.findByFamily(family));
if (found.isEmpty()) 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(); return CAircraftModel();
} }

View File

@@ -61,16 +61,13 @@ namespace BlackMisc
//! Get the closest matching aircraft model. //! Get the closest matching aircraft model.
//! Result depends on enabled modes. //! Result depends on enabled modes.
//! \sa MatchingModeFlag //! \sa MatchingModeFlag
//! \threadsafe
CAircraftModel getClosestMatch(const CSimulatedAircraft &remoteAircraft, BlackMisc::CStatusMessageList *log = nullptr) const; CAircraftModel getClosestMatch(const CSimulatedAircraft &remoteAircraft, BlackMisc::CStatusMessageList *log = nullptr) const;
//! Get the models //! Get the models
//! \threadsafe BlackMisc::Simulation::CAircraftModelList getModelSet() const { return m_modelSet; }
BlackMisc::Simulation::CAircraftModelList getModels() const { return m_models.read(); }
//! Set the models we want to use //! Set the models we want to use
//! \threadsafe int setModelSet(const BlackMisc::Simulation::CAircraftModelList &models);
int setModels(const BlackMisc::Simulation::CAircraftModelList &models);
//! Default model //! Default model
const BlackMisc::Simulation::CAircraftModel &getDefaultModel() const; const BlackMisc::Simulation::CAircraftModel &getDefaultModel() const;
@@ -79,34 +76,44 @@ namespace BlackMisc
void setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel); void setDefaultModel(const BlackMisc::Simulation::CAircraftModel &defaultModel);
private: private:
//! Init state
enum InitState
{
NotInitialized,
InitInProgress,
InitFinished
};
//! Search in models by key (aka model string) //! Search in models by key (aka model string)
//! \threadsafe //! \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 //! Installed models by ICAO data
//! \threadsafe //! \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 //! 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 //! Add to log. if applicable
void logDetails(BlackMisc::CStatusMessageList *log, //! \treadsafe
const CSimulatedAircraft &remoteAircraft, static void logDetails(BlackMisc::CStatusMessageList *log,
const QString &message, const CSimulatedAircraft &remoteAircraft,
CStatusMessage::StatusSeverity s = CStatusMessage::SeverityInfo) const; const QString &message,
CStatusMessage::StatusSeverity s = CStatusMessage::SeverityInfo);
MatchingMode m_matchingMode = All; MatchingMode m_matchingMode = All;
BlackMisc::Simulation::CAircraftModel m_defaultModel; //!< model to be used as default model BlackMisc::Simulation::CAircraftModel m_defaultModel; //!< model to be used as default model
BlackMisc::LockFree<BlackMisc::Simulation::CAircraftModelList> m_models; //!< models used for model matching BlackMisc::Simulation::CAircraftModelList m_modelSet; //!< models used for model matching
}; };
} }
} // namespace } // namespace