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())
{
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();
}

View File

@@ -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<BlackMisc::Simulation::CAircraftModelList> 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