9 #include <QStringBuilder>
10 #include <QStringList>
30 using namespace swift::misc::aviation;
31 using namespace swift::misc::network;
32 using namespace swift::misc::simulation;
36 const QStringList &CAircraftMatcher::getLogCategories()
43 : QObject(parent), m_setup(setup)
59 if (m_setup == setup) {
return false; }
66 const CCallsign &callsign,
const QString &primaryIcao,
const QString &secondaryIcao,
bool airlineFromCallsign,
67 const QString &airlineName,
const QString &airlineTelephony,
bool useWebServices,
CStatusMessageList *log)
69 CCallsign::addLogDetailsToList(
71 QStringLiteral(
"Find airline designator from 1st: '%1' 2nd: '%2' callsign: '%3', use airline callsign: %4, "
72 "name: '%5' telephony: '%6' use web service: %7")
73 .arg(primaryIcao, secondaryIcao, callsign.
toQString(), boolToYesNo(airlineFromCallsign), airlineName,
74 airlineTelephony, boolToYesNo(useWebServices)),
78 if (CAircraftMatcher::isValidAirlineIcaoDesignator(primaryIcao, useWebServices))
80 CCallsign::addLogDetailsToList(log, callsign,
81 QStringLiteral(
"Using primary airline ICAO '%1'").arg(primaryIcao),
83 code = stringToAirlineIcaoObject(callsign, primaryIcao, airlineName, airlineTelephony, useWebServices,
87 if (CAircraftMatcher::isValidAirlineIcaoDesignator(secondaryIcao, useWebServices))
89 CCallsign::addLogDetailsToList(
91 QStringLiteral(
"Using secondary airline ICAO '%1', primary '%2' not valid")
92 .arg(secondaryIcao, primaryIcao),
94 code = stringToAirlineIcaoObject(callsign, secondaryIcao, airlineName, airlineTelephony, useWebServices,
99 CCallsign::addLogDetailsToList(
101 QStringLiteral(
"Two invalid airline ICAO codes (primary/secondary) '%1', '%2'")
102 .arg(primaryIcao, secondaryIcao),
104 if (airlineFromCallsign)
106 QString flightNumber;
108 if (airlinePrefix.isEmpty() || flightNumber.isEmpty())
110 CCallsign::addLogDetailsToList(
112 QStringLiteral(
"Callsign '%1' cannot be split in airline '%1'/ flight number '%2'")
113 .arg(callsign.
toQString(), flightNumber),
117 if (CAircraftMatcher::isValidAirlineIcaoDesignator(airlinePrefix, useWebServices))
119 CCallsign::addLogDetailsToList(log, callsign,
120 QStringLiteral(
"Using airline from callsign '%1', suffix: '%2'")
121 .arg(callsign.
toQString(), airlinePrefix),
123 code = stringToAirlineIcaoObject(callsign, airlinePrefix, airlineName, airlineTelephony,
124 useWebServices, log);
133 CCallsign::addLogDetailsToList(
134 log, callsign, QStringLiteral(
"Resolved to airline designator: %1").arg(code.
toQString(
true)));
139 CCallsign::addLogDetailsToList(
141 QStringLiteral(
"Cannot find airline designator from 1st: '%1' 2nd: '%2' callsign: '%3', use airline "
142 "callsign: %4, name: '%5' telephony: '%6' use web service: %7")
143 .arg(primaryIcao, secondaryIcao, callsign.
toQString(), boolToYesNo(airlineFromCallsign),
144 airlineName, airlineTelephony, boolToYesNo(useWebServices)),
152 const QString &secondaryIcao,
bool airlineFromCallsign,
153 const QString &airlineName,
const QString &airlineTelephony,
156 CCallsign::addLogDetailsToList(
158 QStringLiteral(
"Find airline designator from 1st: '%1' 2nd: '%2' callsign: '%3', use airline callsign: %4, "
159 "airline name: '%5' telephony: '%6', models: %7")
160 .arg(primaryIcao, secondaryIcao, callsign.
toQString(), boolToYesNo(airlineFromCallsign), airlineName,
166 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"No models to find airline from"));
170 static const QString info(
"Multiple models (%1) with airline ICAOs for '%2'");
174 bool reduced =
false;
175 if (!primaryIcao.isEmpty())
179 if (countPerAirline.size() == 1)
181 code = countPerAirline.firstKey();
182 CCallsign::addLogDetailsToList(log, callsign,
183 QStringLiteral(
"Found only 1 airline ICAO '%1' in %2 models")
184 .arg(countPerAirline.firstKey().getDesignatorDbKey())
190 if (!modelsWithAirline.
isEmpty())
192 if (modelsWithAirline.
size() > 1)
194 modelsWithAirline = CAircraftMatcher::ifPossibleReduceModelsByAirlineNameTelephonyDesignator(
195 callsign, airlineName, airlineTelephony, modelsWithAirline,
196 info.arg(modelsWithAirline.
size()).arg(primaryIcao), reduced, log);
199 CCallsign::addLogDetailsToList(log, callsign,
200 QStringLiteral(
"Using primary airline ICAO '%1' found '%2'")
207 if (!secondaryIcao.isEmpty())
211 if (countPerAirline.size() == 1)
213 code = countPerAirline.firstKey();
214 CCallsign::addLogDetailsToList(log, callsign,
215 QStringLiteral(
"Found only 1 airline ICAO '%1' in %2 models")
216 .arg(countPerAirline.firstKey().getDesignatorDbKey())
222 if (!modelsWithAirline.
isEmpty())
224 if (modelsWithAirline.
size() > 1)
226 modelsWithAirline = CAircraftMatcher::ifPossibleReduceModelsByAirlineNameTelephonyDesignator(
227 callsign, airlineName, airlineTelephony, modelsWithAirline,
228 info.arg(modelsWithAirline.
size()).arg(secondaryIcao), reduced, log);
231 CCallsign::addLogDetailsToList(log, callsign,
232 QStringLiteral(
"Using secondary airline ICAO '%1' found '%2'")
239 if (airlineFromCallsign)
241 QString flightNumber;
243 if (airlinePrefix.isEmpty() || flightNumber.isEmpty())
245 CCallsign::addLogDetailsToList(
247 QStringLiteral(
"Callsign '%1' cannot be split in airline '%1'/ flight number '%2'")
248 .arg(callsign.
toQString(), flightNumber),
255 if (countPerAirline.size() == 1)
257 code = countPerAirline.firstKey();
258 CCallsign::addLogDetailsToList(log, callsign,
259 QStringLiteral(
"Found only 1 airline ICAO '%1' in %2 models")
260 .arg(countPerAirline.firstKey().getDesignatorDbKey())
265 if (!modelsWithAirline.
isEmpty())
267 if (modelsWithAirline.
size() > 1)
269 modelsWithAirline = CAircraftMatcher::ifPossibleReduceModelsByAirlineNameTelephonyDesignator(
270 callsign, airlineName, airlineTelephony, modelsWithAirline,
271 info.arg(modelsWithAirline.
size()).arg(airlinePrefix), reduced, log);
274 CCallsign::addLogDetailsToList(log, callsign,
275 QStringLiteral(
"Using callsign airline ICAO '%1' found '%2'")
287 CCallsign::addLogDetailsToList(
288 log, callsign, QStringLiteral(
"Resolved to airline designator: %1").arg(code.
toQString(
true)));
292 CCallsign::addLogDetailsToList(
294 QStringLiteral(
"Cannot find airline designator from 1st: '%1' 2nd: '%2' callsign: '%3', use airline "
295 "callsign: %4, airline name: '%5' telephony: '%6', models: %7")
296 .arg(primaryIcao, secondaryIcao, callsign.
toQString(), boolToYesNo(airlineFromCallsign),
297 airlineName, airlineTelephony, models.
sizeString()),
304 const CCallsign &callsign,
const QString &primaryIcao,
const QString &secondaryIcao,
bool airlineFromCallsign,
305 const QString &airlineName,
const QString &airlineTelephony,
const CAircraftModelList &models,
310 CCallsign::addLogDetailsToList(
311 log, callsign, QStringLiteral(
"Using %1 models to resolve airline designator").arg(models.
size()));
313 callsign, primaryIcao, secondaryIcao, airlineFromCallsign, airlineName, airlineTelephony, models, log);
316 CCallsign::addLogDetailsToList(log, callsign,
317 QStringLiteral(
"Now using resolution of airline ICAO without specific models"));
319 callsign, primaryIcao, secondaryIcao, airlineFromCallsign, airlineName, airlineTelephony,
true, log);
328 static const QString format(
"hh:mm:ss.zzz");
329 static const QString m1(
"--- Start matching: UTC %1 ---");
330 static const QString m2(
"Input model: '%1' '%2'");
331 static const QString m3(
"Matching uses model set of %1 models\n%2");
332 static const QString m4(
"Setup %1");
333 static const QString summary(
"Matching summary\n"
334 "-----------------------------------------\n"
335 "- Combined: %1 -> %2\n"
336 "- Aircraft: %3 -> %4\n"
337 "- Airline: %5 -> %6\n"
338 "- Livery: %7 -> %8\n"
339 "- Model: %9 -> %10\n"
340 "- Script modifed value: %11\n"
341 "-----------------------------------------\n");
343 const QDateTime startTime = QDateTime::currentDateTimeUtc();
344 if (whatToLog == MatchingLogNothing) { log =
nullptr; }
345 if (log) { log->
clear(); }
364 bool resolvedInPrephase =
false;
371 matchedModel = remoteAircraft.
getModel();
372 resolvedInPrephase =
true;
377 QStringLiteral(
"No models for matching, using default"),
380 resolvedInPrephase =
true;
387 matchedModel = matchByExactModelString(remoteAircraft, modelSet, whatToLog, log);
391 u
"Exact match by model string '" %
394 resolvedInPrephase =
true;
404 if (!resolvedInPrephase)
408 static const QString noModelStr(
"Excluded %1 models without model string");
409 if (noString > 0 && log)
415 if (setup.
getMatchingMode().testFlag(CAircraftMatcherSetup::ExcludeNoDbData))
418 static const QString excludedStr(
"Excluded %1 models without DB key");
419 if (noDbKey > 0 && log)
425 if (setup.
getMatchingMode().testFlag(CAircraftMatcherSetup::ExcludeNoExcluded))
428 static const QString excludedStr(
"Excluded %1 models marked 'Excluded'");
429 if (excluded > 0 && log)
436 static const QString msInfo(
"Using '%1' with model set with %2 models");
445 case CAircraftMatcherSetup::MatchingStepwiseReduce:
446 candidates = CAircraftMatcher::getClosestMatchStepwiseReduceImplementation(
447 modelSet, setup, m_categoryMatcher, remoteAircraft, whatToLog, log);
449 case CAircraftMatcherSetup::MatchingScoreBased:
450 candidates = CAircraftMatcher::getClosestMatchScoreImplementation(modelSet, setup, remoteAircraft,
451 maxScore, whatToLog, log);
453 case CAircraftMatcherSetup::MatchingStepwiseReducePlusScoreBased:
455 candidates = CAircraftMatcher::getClosestMatchStepwiseReduceImplementation(
456 modelSet, setup, m_categoryMatcher, remoteAircraft, whatToLog, log);
457 candidates = CAircraftMatcher::getClosestMatchScoreImplementation(candidates, setup, remoteAircraft,
458 maxScore, whatToLog, log);
464 matchedModel = CAircraftMatcher::getCombinedTypeDefaultModel(modelSet, remoteAircraft,
470 switch (usedStrategy)
472 case CAircraftMatcherSetup::PickRandom:
475 case CAircraftMatcherSetup::PickByOrder:
482 case CAircraftMatcherSetup::PickFirst:
484 usedStrategy = CAircraftMatcherSetup::PickFirst;
485 matchedModel = candidates.
front();
493 QStringLiteral(
"Picking among %1 by strategy '%2'")
494 .arg(candidates.
size())
505 bool didRunAndModifyMatchingScript =
false;
509 QStringLiteral(
"Matching script: Matching stage script used"));
516 matchedModelMs = rv.
model;
517 didRunAndModifyMatchingScript =
true;
523 log, remoteAircraft, QStringLiteral(
"Matching script: Modified values and re-run requested"));
526 QStringLiteral(
"Matching script: Now using model: '%1'").arg(matchedModel.
toQString(
true)));
529 rerunAircraft.
setModel(matchedModelMs);
537 if (matchedModelMs.
hasModelString()) { matchedModel = matchedModelMs; }
543 "Matching script: Ignoring model without model string after running the script"));
551 QStringLiteral(
"Matching script: No matching stage script used"));
564 QStringLiteral(
"All matching yielded no result, VERY odd..."));
569 matchedModel = defaultModel;
575 QStringLiteral(
"Using default model '%1'").arg(matchedModel.
getModelString()));
584 QStringLiteral(
"Not even a default model. Giving up").arg(matchedModel.
getModelString()));
589 Q_ASSERT_X(!matchedModel.
getCallsign().
isEmpty(), Q_FUNC_INFO,
"Missing callsign for matched model");
594 static const QString nms =
"no model string";
610 const QDateTime endTime = QDateTime::currentDateTimeUtc();
611 const qint64 matchingTime = startTime.msecsTo(endTime);
612 static const QString em(
"--- Matching end: UTC %1, time %2ms ---");
619 const CAirlineIcaoCode &networkAirlineIcao,
const QString &networkLiveryInfo,
629 CAircraftModel model(networkModelString, type, {}, networkAircraftIcao, livery);
674 if (js.isEmpty() && log)
676 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Matching script is empty"));
684 const bool msReverse = (script == ReverseLookup);
686 static const QString logFileR =
688 static const QString logFileM =
693 CCallsign::addLogDetailsToList(
694 log, callsign, QStringLiteral(
"Matching script (%1): '%2'").arg(msToString(script), lf));
695 CCallsign::addLogDetailsToList(
697 QStringLiteral(
"Matching script input model (%1): '%2'").arg(inModel.
toQString(
true)));
698 CCallsign::addLogDetailsToList(
699 log, callsign, QStringLiteral(
"Matching script models: %1").arg(modelSet.
coverageSummary()));
724 const QJSValue jsInObject = engine.newQObject(&inObject);
725 engine.globalObject().setProperty(
"inObject", jsInObject);
728 const QJSValue jsOutObject = engine.newQObject(&outObject);
729 engine.globalObject().setProperty(
"outObject", jsOutObject);
732 const QJSValue jsMatchedObject = engine.newQObject(&matchedObject);
733 engine.globalObject().setProperty(
"matchedObject", jsMatchedObject);
736 const QJSValue jsModelSetObject = engine.newQObject(&modelSetObject);
737 engine.globalObject().setProperty(
"modelSet", jsModelSetObject);
740 const QJSValue jsWebServices = engine.newQObject(&webServices);
741 engine.globalObject().setProperty(
"webServices", jsWebServices);
743 QJSValue ms = engine.evaluate(js, msReverse ? logFileR : logFileM);
747 const QString msg = QStringLiteral(
"Matching script error: %1 '%2'")
748 .arg(ms.property(
"lineNumber").toInt())
751 if (log) { CCallsign::addLogDetailsToList(log, callsign, msg); }
757 const MSInOutValues *reverseModelProcessed = qobject_cast<const MSInOutValues *>(ms.toQObject());
759 if (!reverseModelProcessed->
isModified()) {
break; }
781 const QString modelString = reverseModelProcessed->
getModelString();
796 CCallsign::addLogDetailsToList(
798 QStringLiteral(
"Matching script using model from set: '%1'").arg(modelString));
801 rv.
model = modeSetModel;
845 CCallsign::addLogDetailsToList(
847 QStringLiteral(
"Matching script, changed airline ICAO: '%1' -> '%2'")
853 else if (ms.isString()) { logMessage = ms.toString(); }
861 if (log && !logMessage.
isEmpty())
863 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Matching script log: '%1'").arg(logMessage));
871 const QString &networkLiveryInfo,
899 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Model string looup disabled"));
916 const bool useNonDbEntries =
true;
918 modelString, callsign, modelSet, useNonDbEntries, log);
921 model = modelFromSet;
931 CCallsign::addLogDetailsToList(log, callsign,
932 QStringLiteral(
"Livery string with ids: '%1'").arg(ids.
toQString()));
939 CCallsign::addLogDetailsToList(
941 QStringLiteral(
"Ignoring livery ids '%1', because of setup").arg(ids.
toQString()));
948 CCallsign::addLogDetailsToList(log, callsign,
949 QStringLiteral(
"Model lookup with id %1 from triple ids '%2'")
966 CCallsign::addLogDetailsToList(
968 QStringLiteral(
"Aircraft ICAO lookup with id %1 from triple ids '%2'")
981 CCallsign::addLogDetailsToList(log, callsign,
982 QStringLiteral(
"Livery lookup with id %1 from triple ids '%2'")
1001 CCallsign::addLogDetailsToList(log, callsign,
1002 QStringLiteral(
"Set aircraft ICAO to '%1' from DB")
1012 CCallsign::addLogDetailsToList(
1014 QStringLiteral(
"Reverse lookup, ICAO '%1' not resolved from DB")
1031 QString liveryCode = networkLiveryInfo;
1035 liveryCode = CLivery::getStandardCode(airlineIcaoCode);
1038 if (CLivery::isValidCombinedCode(liveryCode))
1048 CCallsign::addLogDetailsToList(log, callsign,
1049 QStringLiteral(
"Reverse lookup of livery found '%1'")
1059 CCallsign::addLogDetailsToList(
1061 QStringLiteral(
"Reverse lookup of livery '%1' yielded no result")
1082 CCallsign::addLogDetailsToList(log, callsign,
1083 QStringLiteral(
"Set standardlivery `%1`")
1092 const CLivery liveryDummy(CLivery::getStandardCode(airlineIcaoCode), airlineIcaoCode,
1097 CCallsign::addLogDetailsToList(log, callsign,
1098 QStringLiteral(
"Generated livery, set livery `%1`")
1113 CCallsign::addLogDetailsToList(log, callsign,
1114 QStringLiteral(
"Using model: ICAO '%1', livery '%2', model '%3', type '%4'")
1123 const QString &networkLiveryInfo,
1133 CCallsign::addLogDetailsToList(log, cs,
1134 QStringLiteral(
"Matching script: Modified value and requested rerun"));
1140 return reverseModel;
1149 if (!doLookupString)
1153 CCallsign::addLogDetailsToList(
1155 QStringLiteral(
"Ignore model string in reverse lookup (disabled), ignoring '%1'").arg(modelString));
1165 CCallsign::addLogDetailsToList(
1167 QStringLiteral(
"Found model in DB for model string '%1' dist: '%2' descr.: '%3'")
1173 CCallsign::addLogDetailsToList(
1174 log, callsign, QStringLiteral(
"Did not find model in DB for model string '%1'").arg(modelString));
1192 if (modelString.isEmpty())
1196 CCallsign::addLogDetailsToList(
1197 log, callsign, QStringLiteral(
"Empty model string for lookup in %1 models").arg(modelSet.
size()));
1205 CCallsign::addLogDetailsToList(log, callsign,
1206 QStringLiteral(
"Empty models, ignoring '%1'").arg(modelString));
1216 CCallsign::addLogDetailsToList(
1218 QStringLiteral(
"Model '%1' not found in %2 models").arg(modelString).arg(modelSet.
size()));
1228 CCallsign::addLogDetailsToList(log, callsign,
1229 QStringLiteral(
"Found DB model in %1 models for model string '%2'")
1230 .arg(modelSet.
size())
1235 CCallsign::addLogDetailsToList(log, callsign,
1236 QStringLiteral(
"Found NON DB model in %1 models for model string '%2'")
1237 .arg(modelSet.
size())
1258 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Found model in DB for id '%1'").arg(
id));
1262 CCallsign::addLogDetailsToList(log, callsign,
1263 QStringLiteral(
"Did not find model in DB for id '%1'").arg(
id));
1284 if (CAircraftIcaoCode::isValidDesignator(designator))
1286 CCallsign::addLogDetailsToList(
1288 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1' did not find anything, using smart search")
1295 CCallsign::addLogDetailsToList(
1297 QStringLiteral(
"Reverse lookup of invalid ICAO code '%1' did not find anything so far")
1300 const QStringList parts(designator.split(
' '));
1301 for (
const QString &p : parts)
1303 CCallsign::addLogDetailsToList(
1305 QStringLiteral(
"Trying parts, now reverse lookup of aircraft ICAO '%1' using smart search")
1319 CCallsign::addLogDetailsToList(log, logCallsign,
1320 QStringLiteral(
"No DB data for ICAO '%1', valid ICAO?").arg(designator),
1328 CCallsign::addLogDetailsToList(
1329 log, logCallsign, QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', nothing found").arg(designator),
1333 else if (foundIcaos.
size() == 1)
1336 CCallsign::addLogDetailsToList(
1338 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', found one manufacturer '%2' in DB")
1346 Q_ASSERT_X(foundIcaos.
size() > 1, Q_FUNC_INFO,
"Wrong size");
1348 CCallsign::addLogDetailsToList(
1350 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', found %2 values (ambiguous): %3")
1352 .arg(foundIcaos.
size())
1355 if (maxManufacturer.second < foundIcaos.
size())
1358 CCallsign::addLogDetailsToList(log, logCallsign,
1359 QStringLiteral(
"Reducing by manufacturer '%1', now %2 values")
1360 .arg(maxManufacturer.first)
1361 .arg(foundIcaos.
size()),
1366 CCallsign::addLogDetailsToList(
1368 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', using ICAO '%2' with rank %3")
1384 CCallsign::addLogDetailsToList(log, logCallsign,
1385 QStringLiteral(
"Found aircraft ICAO in DB for id '%1'").arg(
id));
1389 CCallsign::addLogDetailsToList(log, logCallsign,
1390 QStringLiteral(
"Did not find aircraft ICAO in DB for id '%1'").arg(
id));
1405 CCallsign::addLogDetailsToList(
1407 QStringLiteral(
"Reverse lookup of airline ICAO '%1' and callsign '%2' found '%3' '%4' in DB")
1414 CCallsign::addLogDetailsToList(
1416 QStringLiteral(
"Reverse lookup of airline ICAO '%1' and callsign '%2', nothing found in DB")
1432 CCallsign::addLogDetailsToList(
1433 log, callsign, QStringLiteral(
"Reverse lookup of standard livery skipped, no airline designator"),
1444 CCallsign::addLogDetailsToList(log, callsign,
1445 QStringLiteral(
"Reverse lookup of standard livery for '%1' found '%2'")
1451 CCallsign::addLogDetailsToList(
1453 QStringLiteral(
"Not standard livery for airline '%1' in DB").arg(airline.
getDesignator()),
1468 CCallsign::addLogDetailsToList(log, logCallsign,
1469 QStringLiteral(
"Found livery in DB for id '%1'").arg(
id));
1473 CCallsign::addLogDetailsToList(log, logCallsign,
1474 QStringLiteral(
"Did not find livery in DB for id '%1'").arg(
id));
1502 if (candidate.isEmpty()) {
return {}; }
1504 if (names.contains(candidate, Qt::CaseInsensitive))
1506 CCallsign::addLogDetailsToList(log, callsign,
1507 QStringLiteral(
"Airline name '%1' found in DB").arg(candidate));
1511 CCallsign::addLogDetailsToList(log, callsign,
1512 QStringLiteral(
"Airline name '%1' not found in DB").arg(candidate));
1520 if (candidate.isEmpty()) {
return {}; }
1522 if (designators.contains(candidate, Qt::CaseInsensitive))
1524 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Airline name '%1' found").arg(candidate));
1528 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Airline name '%1' not found").arg(candidate));
1536 if (!CAircraftIcaoCode::isValidDesignator(candidate))
1538 CCallsign::addLogDetailsToList(log, callsign,
1539 QStringLiteral(
"No valid ICAO designator '%1'").arg(candidate));
1544 static const QString sKnown(
"Known ICAO designator '%1'");
1545 static const QString sUnknown(
"Unknown ICAO designator '%1'");
1546 CCallsign::addLogDetailsToList(log, callsign, known ? sKnown.arg(candidate) : sUnknown.arg(candidate));
1555 static const QString sKnown(
"Known modelstring '%1'");
1556 static const QString sUnknown(
"Unknown modelstring '%1'");
1557 CCallsign::addLogDetailsToList(log, callsign, known ? sKnown.arg(candidate) : sUnknown.arg(candidate));
1568 CCallsign::addLogDetailsToList(
1569 log, callsign, QStringLiteral(
"No valid airline from DB '%1'").arg(airline.
getDesignator()));
1578 CCallsign::addLogDetailsToList(
1579 log, callsign, QStringLiteral(
"No aircraft known for airline '%1'").arg(airline.
getDesignator()));
1584 const QString allIcaosStr = allIcaos.values().join(
", ");
1585 CCallsign::addLogDetailsToList(
1587 QStringLiteral(
"Aircraft '%1' known for airline '%2'").arg(allIcaosStr, airline.
getDesignator()));
1592 CCallsign::addLogDetailsToList(log, callsign,
1593 QStringLiteral(
"Aircraft '%1' is best fuzzy search of '%2' for airline '%3'")
1598 return aircraft.
front();
1608 CCallsign::addLogDetailsToList(
1610 QStringLiteral(
"Turned callsign %1 into airline %2").arg(callsign.
asString(), icao.
getDesignator()),
1615 CCallsign::addLogDetailsToList(
1616 log, callsign, QStringLiteral(
"Cannot turn callsign %1 into airline").arg(callsign.
asString()),
1631 if (!forced && m_simulator == simulator && m_modelSet.
size() == modelsCleaned.
size())
1633 return m_modelSet.
size();
1640 QStringLiteral(
"Removed models for matcher, without string #: %1, excluded #: %2.").arg(r1).arg(r2);
1643 warnings += QStringLiteral(
" Without string: '%1'.")
1648 warnings += QStringLiteral(
" Excluded: '%1'.")
1658 CLogMessage(
this).
error(u
"No models for matching ('%1'), swift without a model set will not work!")
1661 else if (!duplicateModels.
isEmpty())
1663 CLogMessage(
this).
error(u
"Found model duplicate strings, check models: '%1'")
1674 m_modelSet = modelsCleaned;
1675 m_simulator = simulator;
1676 m_modelSetInfo = QStringLiteral(
"Set: '%1' entries: %2").arg(simulator.
toQString()).arg(modelsCleaned.
size());
1677 return models.
size();
1685 m_disabledModels.
push_back(removedModels);
1690 m_disabledModels = removedModels;
1702 m_defaultModel = defaultModel;
1707 const QString &aircraftIcao,
const QString &airlineIcao,
1708 const QString &livery)
1712 if (m_modelSet.
isEmpty()) {
return; }
1713 if (sessionId.isEmpty()) {
return; }
1714 if (aircraftIcao.isEmpty()) {
return; }
1716 QString description;
1719 description = QStringLiteral(
"ICAO: '%1' not known, typo?").arg(aircraftIcao);
1724 if (airlineIcao.isEmpty())
1734 CMatchingStatisticsEntry::Found :
1735 CMatchingStatisticsEntry::Missing;
1740 CMatchingStatisticsEntry::Found :
1741 CMatchingStatisticsEntry::Missing;
1761 bool CAircraftMatcher::saveDisabledForMatchingModels()
1763 if (m_disabledModels.
isEmpty()) {
return false; }
1766 const QString ts = QDateTime::currentDateTimeUtc().toString(
"yyyyMMddHHmmss");
1770 QStringLiteral(
"removed models %1.json").arg(ts)));
1781 const CAircraftMatcherSetup::MatchingMode mode = setup.
getMatchingMode();
1782 CStatusMessageList *reduceLog = log && whatToLog.testFlag(MatchingLogStepwiseReduce) ? log :
nullptr;
1783 bool reduced =
false;
1786 if (mode.testFlag(CAircraftMatcherSetup::ByLivery))
1789 ifPossibleReduceByLiveryAndAircraftIcaoCode(remoteAircraft, matchedModels, reduced, log);
1790 if (reduced) {
break; }
1802 matchedModels = ifPossibleReduceByIcaoData(remoteAircraft, matchedModels, setup, reduced, log);
1810 if (mode.testFlag(CAircraftMatcherSetup::ByFamily))
1813 matchedModels = ifPossibleReduceByFamily(remoteAircraft, UsePseudoFamily, matchedModels, reduced,
1815 if (reduced) {
break; }
1826 matchedModels = categoryMatcher.
reduceByCategories(matchedModels, modelSet, setup, remoteAircraft,
1827 reduced, whatToLog, log);
1837 if (!reduced && remoteAircraft.
isVtol() && matchedModels.containsVtol() &&
1838 mode.testFlag(CAircraftMatcherSetup::ByVtol))
1840 matchedModels = matchedModels.findByVtolFlag(
true);
1842 log, remoteAircraft, QStringLiteral(
"Aircraft is VTOL, reduced to VTOL"),
getLogCategories());
1846 bool milFlagReduced =
false;
1849 matchedModels = ifPossibleReduceByMilitaryFlag(remoteAircraft, matchedModels, reduced, reduceLog);
1850 milFlagReduced =
true;
1855 matchedModels = ifPossibleReduceByMilitaryFlag(remoteAircraft, matchedModels, reduced, reduceLog);
1856 milFlagReduced =
true;
1860 if (mode.testFlag(CAircraftMatcherSetup::ByCombinedType))
1863 ifPossibleReduceByCombinedType(remoteAircraft, matchedModels, setup, reduced, reduceLog);
1864 if (reduced) {
break; }
1875 if (matchedModels.size() > 1 && mode.testFlag(CAircraftMatcherSetup::ByManufacturer))
1877 matchedModels = ifPossibleReduceByManufacturer(remoteAircraft, matchedModels,
1878 QStringLiteral(
"2nd trial to reduce by manufacturer. "),
1879 reduced, reduceLog);
1882 return matchedModels;
1888 int &maxScore, MatchingLog whatToLog,
1894 CStatusMessageList *scoreLog = log && whatToLog.testFlag(MatchingLogScoring) ? log :
nullptr;
1898 map = modelSet.
scoreFull(remoteAircraft.
getModel(), preferColorLiveries, noZeroScores, scoreLog);
1903 maxScore = map.lastKey();
1906 QStringLiteral(
"Scores: %1").arg(scoresToString(map)),
getLogCategories());
1908 QStringLiteral(
"Scoring with score %1 out of %2 models yielded %3 models")
1911 .arg(maxScoreAircraft.size()),
1913 return maxScoreAircraft;
1922 CStatusMessageList *combinedLog = log && whatToLog.testFlag(MatchingLogCombinedDefaultType) ? log :
nullptr;
1924 if (combinedType.isEmpty())
1929 return defaultModel;
1935 return defaultModel;
1939 u
"Searching by combined type with color livery '" % combinedType %
"'",
1945 u
"Found " % QString::number(matchedModels.
size()) %
1946 u
" by combined type w/color livery '" % combinedType %
"'",
1952 combinedLog, remoteAircraft, u
"Searching by combined type '" % combinedType %
"'",
getLogCategories());
1957 u
"Found " % QString::number(matchedModels.
size()) %
1958 u
" by combined '" % combinedType %
"'",
1964 if (matchedModels.
isEmpty()) {
return defaultModel; }
1965 return matchedModels.
front();
1972 CStatusMessageList *msLog = log && whatToLog.testFlag(MatchingLogModelstring) ? log :
nullptr;
1978 QStringLiteral(
"No model string, no exact match possible"));
1989 msLog, remoteAircraft, QStringLiteral(
"Found exact match for '%1'").arg(model.
getModelString()));
1994 msLog, remoteAircraft,
1995 QStringLiteral(
"No exact match for '%1'").arg(remoteAircraft.
getModelString()));
2004 CAircraftMatcher::ifPossibleReduceByLiveryAndAircraftIcaoCode(
const CSimulatedAircraft &remoteAircraft,
2014 log, remoteAircraft, QStringLiteral(
"No livery code, no reduction possible"),
getLogCategories());
2022 if (byLivery.isEmpty())
2041 const CAircraftMatcherSetup::MatchingMode mode = setup.
getMatchingMode();
2053 if (mode.testFlag(CAircraftMatcherSetup::ByIcaoOrderAirlineFirst))
2058 QStringLiteral(
"Reduce by airline first."), r1, log);
2059 models = ifPossibleReduceByAircraftOrFamily(remoteAircraft, UsePseudoFamily, models, setup,
2060 QStringLiteral(
"Reduce by aircraft ICAO second."), r2, log);
2062 if (reduced) {
return models; }
2069 ifPossibleReduceByAircraftOrFamily(remoteAircraft, UsePseudoFamily, inList, setup,
2070 QStringLiteral(
"Reduce by aircraft ICAO first."), r1, log);
2071 models = ifPossibleReduceByAirline(remoteAircraft, models, setup,
2072 QStringLiteral(
"Reduce aircraft ICAO by airline second."), r2, log);
2081 "No airline, no secondary search for airline/aircraft",
2085 else if (!r2 && mode.testFlag(CAircraftMatcherSetup::ByFamily))
2090 u
"No exact ICAO match of '" %
2092 u
"', will try family combination",
2099 ifPossibleReduceByFamily(remoteAircraft, UsePseudoFamily, inList, r3, usedFamily, log);
2100 models2nd = ifPossibleReduceByAirline(remoteAircraft, models2nd, setup,
2101 "Reduce family by airline second.", r3, log);
2108 u
"Found " % QString::number(models2nd.
sizeInt()) %
2109 " aircraft family/airline '" % usedFamily %
2140 bool allowPseudoFamily,
2146 if (!usedFamily.isEmpty())
2149 ifPossibleReduceByFamily(remoteAircraft, usedFamily, allowPseudoFamily, inList,
2150 QStringLiteral(
"real family from ICAO"), reduced, log);
2151 if (reduced) {
return matchedModels; }
2156 return ifPossibleReduceByFamily(remoteAircraft, usedFamily, allowPseudoFamily, inList,
2157 QStringLiteral(
"ICAO treated as family"), reduced, log);
2161 const QString &family,
bool allowPseudoFamily,
2167 if (family.isEmpty() && !allowPseudoFamily)
2188 if (foundByFamily.isEmpty())
2193 u
"Not found by family '" % family % u
"' (" % hint %
")");
2195 if (!allowPseudoFamily) {
return inList; }
2203 u
"Found by family '" % family % u
"' (" % hint % u
") size " %
2204 QString::number(foundByFamily.sizeInt()),
2210 if (allowPseudoFamily)
2220 u
"Not found by pseudo family '" % pseudo % u
"' (" % hint %
")");
2228 u
"Found by pseudo family '" % pseudo % u
"' (" % hint %
2229 u
") size " % QString::number(foundByCM.
sizeInt()),
2235 if (foundByCM.
isEmpty() && foundByFamily.isEmpty()) {
return inList; }
2239 if (!foundByFamily.isEmpty())
2243 foundByFamily.push_back(foundByCM);
2248 u
"Found by family (totally) '" % family % u
"' (" % hint % u
") size " %
2249 QString::number(foundByFamily.sizeInt()),
2252 return foundByFamily;
2257 const QString &info,
bool &reduced,
2277 info % u
" No manufacturer, cannot reduce " %
2278 QString::number(inList.
size()) % u
" entries",
2285 if (outList.isEmpty())
2290 log, remoteAircraft, info % u
" Not found '" % m % u
"', cannot reduce",
getLogCategories());
2298 log, remoteAircraft, info % u
" Reduced by '" % m % u
"' results: " % QString::number(outList.size()),
2314 CCallsign::addLogDetailsToList(log, logCallsign, info % u
" Empty input list, cannot reduce",
2325 CCallsign::addLogDetailsToList(log, logCallsign,
2326 info % u
" No manufacturer, cannot reduce " %
2327 QString::number(inList.
size()) % u
" entries",
2334 if (outList.isEmpty())
2338 CCallsign::addLogDetailsToList(log, logCallsign, info %
" Not found " % m %
", cannot reduce",
2346 CCallsign::addLogDetailsToList(log, logCallsign,
2347 info % u
" Reduced by " % m % u
" results: " % QString::number(outList.size()),
2356 const QString &info,
bool &reduced,
2375 info %
" No aircraft designator, cannot reduce " %
2376 QString::number(inList.
size()) %
" entries",
2384 if (outList.isEmpty())
2389 info % u
" Cannot reduce by '" %
2391 u
"' results: " % QString::number(outList.size()),
2400 info % u
" Reduced by '" %
2402 QString::number(outList.size()),
2414 const CAircraftModelList outList = ifPossibleReduceByAircraft(remoteAircraft, inList, info, reduced, log);
2415 if (reduced || !setup.
getMatchingMode().testFlag(CAircraftMatcherSetup::ByFamily)) {
return outList; }
2417 return ifPossibleReduceByFamily(remoteAircraft, allowPseudoFamily, inList, reduced, family, log);
2423 const QString &info,
bool &reduced,
2442 info % u
" No airline designator, cannot reduce " %
2443 QString::number(inList.
size()) % u
" entries",
2452 if (mode.testFlag(CAircraftMatcherSetup::ByAirlineGroupSameAsAirline) ||
2453 (outList.
isEmpty() || mode.testFlag(CAircraftMatcherSetup::ByAirlineGroupIfNoAirline)))
2462 log, remoteAircraft,
2464 QStringLiteral(
"No group models found by using airline group '%1'")
2466 QStringLiteral(
"Added %1 model(s) by using airline group '%2', all members: '%3'")
2480 info % u
" Cannot reduce by '" %
2482 QString::number(outList.
size()),
2491 info % u
" Reduced by '" %
2493 QString::number(outList.
size()),
2500 CAircraftModelList CAircraftMatcher::ifPossibleReduceModelsByAirlineNameTelephonyDesignator(
2509 CCallsign::addLogDetailsToList(log, cs, info % u
" Empty input list, cannot reduce",
getLogCategories());
2514 if (telephony.isEmpty() && airlineName.isEmpty())
2518 CCallsign::addLogDetailsToList(log, cs,
2519 info % u
" No name/telephony, cannot reduce " %
2520 QString::number(inList.
size()) % u
" entries",
2531 CCallsign::addLogDetailsToList(
2532 log, cs, info % QStringLiteral(
" cannot reduce by '%1'").arg(airlineName),
getLogCategories());
2541 CCallsign::addLogDetailsToList(log, cs, info % QStringLiteral(
" reduced by '%1'").arg(airlineName),
2545 if (step1Data.
size() == 1) {
return step1Data; }
2552 CCallsign::addLogDetailsToList(log, cs, info % QStringLiteral(
" cannot reduce by '%1'").arg(telephony),
2555 step2Data = step1Data;
2562 CCallsign::addLogDetailsToList(log, cs, info % QStringLiteral(
" reduced by '%1'").arg(telephony),
2599 if (modelsByCombinedCode.isEmpty())
2612 u
"Found by combined code " % cc % u
", possible " %
2613 QString::number(modelsByCombinedCode.size()),
2616 if (modelsByCombinedCode.size() > 1)
2618 modelsByCombinedCode =
2619 ifPossibleReduceByAirline(remoteAircraft, modelsByCombinedCode, setup,
2620 QStringLiteral(
"Combined code airline reduction. "), reduced, log);
2621 modelsByCombinedCode =
2622 ifPossibleReduceByManufacturer(remoteAircraft, modelsByCombinedCode,
2623 QStringLiteral(
"Combined code manufacturer reduction. "), reduced, log);
2626 return modelsByCombinedCode;
2636 const QString mil(military ?
"military" :
"civilian");
2637 if (byMilitaryFlag.isEmpty())
2650 u
"Models reduced to " % mil % u
" aircraft, size " %
2651 QString::number(byMilitaryFlag.size()),
2654 return byMilitaryFlag;
2672 log, remoteAircraft, u
"Models reduced to " % QString::number(vtolModels.
size()) % u
" VTOL aircraft",
2678 QString CAircraftMatcher::scoresToString(
const ScoredModels &scores,
int lastElements)
2680 if (scores.isEmpty()) {
return {}; }
2681 QMultiMapIterator<int, CAircraftModel> i(scores);
2685 while (i.hasPrevious() && c++ < lastElements)
2689 if (!str.isEmpty()) { str +=
'\n'; }
2690 str += QString::number(c) % u
": score: " % QString::number(i.key()) % u
" model: '" % m.getModelString() %
2691 u
"' aircraft: '" % m.getAircraftIcaoCodeDesignator() % u
"' livery: '" %
2692 m.getLivery().getCombinedCodePlusInfo() % u
'\'';
2698 const QString &airlineName,
2699 const QString &airlineTelephony,
bool useSwiftDbData,
2706 if (codes.
size() == 1) {
return codes.
front(); }
2709 bool reduced =
false;
2710 static const QString info(
"Try reducing airline '%1' by name/telephony '%2'/'%3'");
2712 cs, airlineName, airlineTelephony, QString(), reduced, info, log);
2716 bool CAircraftMatcher::isValidAirlineIcaoDesignator(
const QString &designator,
bool checkAgainstSwiftDb)
2718 if (!CAirlineIcaoCode::isValidAirlineDesignator(designator)) {
return false; }
2719 if (!checkAgainstSwiftDb) {
return true; }
QMultiMap< int, CAircraftModel > ScoredModels
Individual (matching) score for each model.
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
void setupChanged()
Setup changed.
static swift::misc::simulation::CAircraftModel reverseLookupModelId(int id, const swift::misc::aviation::CCallsign &callsign, swift::misc::CStatusMessageList *log)
Try to find model by id.
void evaluateStatisticsEntry(const QString &sessionId, const swift::misc::aviation::CCallsign &callsign, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery)
Evaluate if a statistics entry makes sense and add it.
static swift::misc::simulation::CAircraftModel reverseLookupModelStringInDB(const QString &modelString, const swift::misc::aviation::CCallsign &callsign, bool doLookupString, swift::misc::CStatusMessageList *log)
Try to find model by model string.
static swift::misc::aviation::CAirlineIcaoCode failoverValidAirlineIcaoDesignatorModelsFirst(const swift::misc::aviation::CCallsign &callsign, const QString &primaryIcao, const QString &secondaryIcao, bool airlineFromCallsign, const QString &airlineName, const QString &airlineTelephony, const swift::misc::simulation::CAircraftModelList &models, swift::misc::CStatusMessageList *log=nullptr)
Return an valid airline ICAO code from a given model list and use webservices if NOT found.
static QString reverseLookupTelephonyDesignator(const QString &candidate, const swift::misc::aviation::CCallsign &callsign={}, swift::misc::CStatusMessageList *log=nullptr)
Lookup of telephony designator.
static swift::misc::aviation::CAircraftIcaoCode reverseLookupAircraftIcaoId(int id, const swift::misc::aviation::CCallsign &logCallsign, swift::misc::CStatusMessageList *log=nullptr)
Lookup of ICAO by id.
static swift::misc::aviation::CAirlineIcaoCode reverseLookupAirlineIcao(const swift::misc::aviation::CAirlineIcaoCode &icaoPattern, const swift::misc::aviation::CCallsign &callsign={}, swift::misc::CStatusMessageList *log=nullptr)
Try to find the DB corresponding ICAO code.
void setDefaultModel(const swift::misc::simulation::CAircraftModel &defaultModel)
Set default model, can be set by driver specific for simulator.
static swift::misc::simulation::MatchingScriptReturnValues matchingScript(const QString &js, const swift::misc::simulation::CAircraftModel &inModel, const swift::misc::simulation::CAircraftModel &matchedModel, const swift::misc::simulation::CAircraftMatcherSetup &setup, const swift::misc::simulation::CAircraftModelList &modelSet, swift::misc::simulation::MatchingScript ms, swift::misc::CStatusMessageList *log)
Run the matching script.
static swift::misc::aviation::CLivery reverseLookupLiveryId(int id, const swift::misc::aviation::CCallsign &logCallsign, swift::misc::CStatusMessageList *log=nullptr)
Lookup of livery by id.
static swift::misc::simulation::CAircraftModel reverseLookupModelMs(const swift::misc::simulation::CAircraftModel &modelToLookup, const QString &networkLiveryInfo, const swift::misc::simulation::CAircraftMatcherSetup &setup, const swift::misc::simulation::CAircraftModelList &modelSet, swift::misc::CStatusMessageList *log)
Try to find the corresponding data in DB and get best information for following matching.
void addingRemoteModelFailed(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft)
Adding a model failed.
static QString reverseLookupAirlineName(const QString &candidate, const swift::misc::aviation::CCallsign &callsign={}, swift::misc::CStatusMessageList *log=nullptr)
Lookup of airline name.
static swift::misc::simulation::MatchingScriptReturnValues reverseLookupScript(const swift::misc::simulation::CAircraftModel &inModel, const swift::misc::simulation::CAircraftMatcherSetup &setup, const swift::misc::simulation::CAircraftModelList &modelSet, swift::misc::CStatusMessageList *log)
Run the network reverse lookup script.
static bool isKnownModelString(const QString &candidate, const swift::misc::aviation::CCallsign &callsign={}, swift::misc::CStatusMessageList *log=nullptr)
Is this aircraft designator known?
static swift::misc::aviation::CAircraftIcaoCode reverseLookupAircraftIcao(const swift::misc::aviation::CAircraftIcaoCode &icaoDesignator, const swift::misc::aviation::CCallsign &logCallsign={}, swift::misc::CStatusMessageList *log=nullptr)
Try to find the DB corresponding ICAO code.
static swift::misc::aviation::CAirlineIcaoCode callsignToAirline(const swift::misc::aviation::CCallsign &callsign, swift::misc::CStatusMessageList *log=nullptr)
Turn callsign into airline.
static swift::misc::aviation::CLivery reverseLookupStandardLivery(const swift::misc::aviation::CAirlineIcaoCode &airline, const swift::misc::aviation::CCallsign &callsign, swift::misc::CStatusMessageList *log=nullptr)
Lookup of standard livery.
static swift::misc::aviation::CAircraftIcaoCode searchAmongAirlineAircraft(const QString &icaoString, const swift::misc::aviation::CAirlineIcaoCode &airline, const swift::misc::aviation::CCallsign &callsign={}, swift::misc::CStatusMessageList *log=nullptr)
Search among the airline aircraft.
static swift::misc::simulation::MatchingScriptReturnValues matchingStageScript(const swift::misc::simulation::CAircraftModel &inModel, const swift::misc::simulation::CAircraftModel &matchedModel, const swift::misc::simulation::CAircraftMatcherSetup &setup, const swift::misc::simulation::CAircraftModelList &modelSet, swift::misc::CStatusMessageList *log)
Run the matching stage lookup script.
int setModelSet(const swift::misc::simulation::CAircraftModelList &models, const swift::misc::simulation::CSimulatorInfo &simulator, bool forced)
Set the models we want to use.
static swift::misc::aviation::CAirlineIcaoCode failoverValidAirlineIcaoDesignator(const swift::misc::aviation::CCallsign &callsign, const QString &primaryIcao, const QString &secondaryIcao, bool airlineFromCallsign, const QString &airlineName, const QString &airlineTelephony, bool useWebServices, swift::misc::CStatusMessageList *log=nullptr)
Return an valid airline ICAO code.
static swift::misc::simulation::CAircraftModel reverseLookupModelStringInSet(const QString &modelString, const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CAircraftModelList &modelSet, bool useNonDbEntries, swift::misc::CStatusMessageList *log)
Try to find model by model string in set.
virtual ~CAircraftMatcher()
Destructor.
static swift::misc::simulation::CAircraftModel reverseLookupModel(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftIcaoCode &networkAircraftIcao, const swift::misc::aviation::CAirlineIcaoCode &networkAirlineIcao, const QString &networkLiveryInfo, const QString &networkModelString, const swift::misc::simulation::CAircraftMatcherSetup &setup, const swift::misc::simulation::CAircraftModelList &modelSet, swift::misc::simulation::CAircraftModel::ModelType type, swift::misc::CStatusMessageList *log)
Try to find the corresponding data in DB and get best information for given data.
CAircraftMatcher(const swift::misc::simulation::CAircraftMatcherSetup &setup, QObject *parent=nullptr)
Constructor.
bool setSetup(const swift::misc::simulation::CAircraftMatcherSetup &setup)
Set the setup.
swift::misc::simulation::CAircraftModel getClosestMatch(const swift::misc::simulation::CSimulatedAircraft &remoteAircraft, swift::misc::simulation::MatchingLog whatToLog, swift::misc::CStatusMessageList *log, bool useMatchingScript) const
Get the closest matching aircraft model from set. Result depends on setup.
static int reverseLookupByIds(const swift::misc::simulation::DBTripleIds &ids, swift::misc::aviation::CAircraftIcaoCode &aircraftIcao, swift::misc::aviation::CLivery &livery, const swift::misc::aviation::CCallsign &logCallsign, swift::misc::CStatusMessageList *log=nullptr)
Lookup by ids.
void disableModelsForMatching(const swift::misc::simulation::CAircraftModelList &removedModels, bool incremental)
Remove a model for matching.
const swift::misc::simulation::CAircraftModel & getDefaultModel() const
Default model.
static const QStringList & getLogCategories()
Log categories.
static bool isKnownAircraftDesignator(const QString &candidate, const swift::misc::aviation::CCallsign &callsign={}, swift::misc::CStatusMessageList *log=nullptr)
Is this aircraft designator known?
void restoreDisabledModels()
Restore the models removed with CAircraftMatcher::disableModelForMatching.
bool hasWebDataServices() const
Web data services available?
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
swift::misc::aviation::CAirlineIcaoCode getAirlineIcaoCodeForDbKey(int id) const
ICAO code for id.
swift::misc::aviation::CAircraftIcaoCode smartAircraftIcaoSelector(const swift::misc::aviation::CAircraftIcaoCode &icao) const
Use an ICAO object to select the best complete ICAO object from DB for it.
bool containsModelString(const QString &modelString) const
Existing modelstring?
swift::misc::aviation::CAirlineIcaoCode findBestMatchByCallsign(const swift::misc::aviation::CCallsign &callsign) const
ICAO code for callsign (e.g. DLH123 -> DLH)
swift::misc::aviation::CAirlineIcaoCodeList getAirlineIcaoCodesForDesignator(const QString &designator) const
Airline ICAO codes for designator.
swift::misc::aviation::CAircraftIcaoCode getAircraftIcaoCodeForDbKey(int id) const
ICAO code for id.
swift::misc::aviation::CAircraftIcaoCode getAircraftIcaoCodeForDesignator(const QString &designator) const
ICAO code for designator.
swift::misc::aviation::CLivery getStdLiveryForAirlineCode(const swift::misc::aviation::CAirlineIcaoCode &icao) const
Standard livery for airline code.
swift::misc::aviation::CAircraftIcaoCodeList getAircraftIcaoCodesForAirline(const swift::misc::aviation::CAirlineIcaoCode &airline) const
Aircraft ICAO codes for airline.
swift::misc::aviation::CAircraftIcaoCodeList getAircraftIcaoCodesForDesignator(const QString &designator) const
ICAO codes for designator.
swift::misc::aviation::CAirlineIcaoCode smartAirlineIcaoSelector(const swift::misc::aviation::CAirlineIcaoCode &code, const swift::misc::aviation::CCallsign &callsign=swift::misc::aviation::CCallsign()) const
Smart airline selector.
swift::misc::simulation::CAircraftModel getModelForDbKey(int dbKey) const
Model for key if any.
void synchronizeDbCaches(swift::misc::network::CEntityFlags::Entity entities)
Synchronize all DB caches specified.
QStringList getTelephonyDesignators() const
Airline telephony designators.
swift::misc::simulation::CAircraftModel getModelForModelString(const QString &modelString) const
Model for model string if any.
swift::misc::aviation::CAircraftCategoryList getAircraftCategories() const
Aircraft categories.
bool containsAircraftIcaoDesignator(const QString &designator) const
Contains the given designator?
swift::misc::aviation::CLivery getLiveryForDbKey(int id) const
Livery for id.
swift::misc::aviation::CLivery getLiveryForCombinedCode(const QString &combinedCode) const
Livery for its combined code.
bool containsAirlineIcaoDesignator(const QString &designator) const
Contains the given designator?
swift::misc::aviation::CAirlineIcaoCode getAirlineIcaoCodeForUniqueDesignatorOrDefault(const QString &designator, bool preferOperatingAirlines) const
ICAO code if unique, otherwise default.
QStringList getAirlineNames() const
Airline names.
Encapsulates reading data from web sources.
QString toJsonString(QJsonDocument::JsonFormat format=QJsonDocument::Indented) const
Convenience function JSON as string.
static bool writeStringToFile(const QString &content, const QString &fileNameAndPath)
Write string to text file.
static QString appendFilePathsAndFixUnc(const QString &path1, const QString &path2)
Append file paths.
static QString appendFilePaths(const QString &path1, const QString &path2)
Append file paths.
static QString readFileToString(const QString &fileNameAndPath)
Read file into string.
static const QString & matching()
Matching.
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & validationWarning(const char16_t(&format)[N])
Set the severity to warning, providing a format string, and adding the validation category.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & validationInfo(const char16_t(&format)[N])
Set the severity to info, providing a format string, and adding the validation category.
T randomElement() const
Pick one random element.
size_type size() const
Returns number of elements in the sequence.
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
void push_back(const T &value)
Appends an element at the end of the sequence.
reference front()
Access the first element.
void clear()
Removes all elements in the sequence.
QString sizeString() const
Convenience function.
bool isEmpty() const
Synonym for empty.
int sizeInt() const
Avoid compiler warnings when using with int.
constexpr static auto SeverityError
Status severities.
constexpr static auto SeverityInfo
Status severities.
constexpr static auto SeverityWarning
Status severities.
Status messages, e.g. from Core -> GUI.
static const QString & logDirectory()
Directory for log files.
OBJ minOrderOrDefault() const
Object with min.order or default.
bool needsOrder() const
All order values set or missing some?
Value object encapsulating a list of ICAO codes.
Value object for ICAO classification.
QString getCombinedIcaoStringWithKey() const
Combined ICAO descriptive string with key.
const QString & getFamily() const
Family (e.g. A350)
const QString & getDesignator() const
Get ICAO designator, e.g. "B737".
QString getDesignatorDbKey() const
Designator and DB key.
bool hasValidDesignator() const
Valid aircraft designator?
const QString & getCombinedType() const
Get type, e.g. "L2J".
bool hasValidCombinedType() const
Combined type available?
const QString & getManufacturer() const
Get manufacturer, e.g. "Airbus".
QString getRankString() const
Ranking.
QString getDesignatorManufacturer() const
Designator + Manufacturer.
Value object encapsulating a list of ICAO codes.
CAircraftIcaoCodeList findByManufacturer(const QString &manufacturer) const
Find by manufacturer.
void sortByRank()
Sort by rank.
QSet< QString > allDesignators(bool noUnspecified=true) const
All ICAO codes, no duplicates.
CAircraftIcaoCode findBestFuzzyMatchOrDefault(const QString &designator, int cutoff=50) const
Find by designator.
QPair< QString, int > maxCountManufacturer() const
Uses countManufacturers to find "most important" manufacturer.
Value object for ICAO classification.
const QString & getGroupDesignator() const
Group designator.
QString getVDesignatorDbKey() const
Get VDesignator plus key.
QString getDesignatorDbKey() const
Designator and DB key.
const QString & getDesignator() const
Get airline, e.g. "DLH".
bool hasValidDesignator() const
Airline designator available?
const QString & getName() const
Get name, e.g. "Lufthansa".
bool hasGroupMembership() const
Are we a member of a group?
Value object encapsulating a list of ICAO codes.
CAirlineIcaoCodeList ifPossibleReduceNameTelephonyCountry(const swift::misc::aviation::CCallsign &cs, const QString &airlineName, const QString &telephony, const QString &countryIso, bool &reduced, const QString &logInfo, CStatusMessageList *log) const
Reduce by airline name/telephone designator, ISO country.
Value object encapsulating information of a callsign.
const QString & asString() const
Get callsign (normalized)
bool isEmpty() const
Is empty?
QString getAirlinePrefix() const
Airline suffix (e.g. DLH1234 -> DLH) if applicable.
Value object encapsulating information about an airpot.
bool setAirlineIcaoCode(const CAirlineIcaoCode &airlineIcao)
Airline ICAO code.
QString getCombinedCodePlusInfoAndId() const
Combined code, info, plus id.
const QString & getCombinedCode() const
Combined code.
bool hasCombinedCode() const
Livery combined code available?
QString getCombinedCodePlusInfo() const
Combined code plus info.
int removeObjectsWithoutDbKey()
Remove objects without key.
QString dbKeysAsString(const QString &separator) const
The DB keys as string.
bool isLoadedFromDb() const
Loaded from DB.
bool hasValidDbKey() const
Has valid DB key.
const QString & getDbKey() const
Get DB key.
QString toQString(bool i18n=false) const
Cast as QString.
bool doRunMsMatchingStageScript() const
Run the scripts.
bool removeFromSetIfFailed() const
Remove if failed?
bool isReverseLookupModelString() const
Reverse lookup.
MatchingMode getMatchingMode() const
Matching mode.
bool useCategoryMatching() const
Use category matching.
PickSimilarStrategy
How to pick among similar candiates.
const QString & getMsMatchingStageFile() const
Get matching files.
@ ScorePreferColorLiveries
prefer color liveries
@ ByIcaoData
ICAO airline and aircraft codes.
@ ScoreIgnoreZeros
zero scores are ignored
@ ByMilitary
military (in) will only search in military
@ ByCivilian
civilian (in) will only search in civilian
@ ByModelString
allow exact model string match
bool isReverseLookupSwiftLiveryIds() const
Reverse lookup.
bool doRunMsReverseLookupScript() const
Run the scripts.
void resetReverseLookup()
Reverse lookup.
MatchingAlgorithm getMatchingAlgorithm() const
Algorithm.
const QString & getMatchingAlgorithmAsString() const
Algorithm as string.
static const QString & strategyToString(PickSimilarStrategy strategy)
Strategy to string.
PickSimilarStrategy getPickStrategy() const
Strategy among equally suitable models.
const QString & getMsReverseLookupFile() const
Get matching files.
Aircraft model (used by another pilot, my models on disk)
const aviation::CCallsign & getCallsign() const
Corresponding callsign if applicable.
const aviation::CAirlineIcaoCode & getAirlineIcaoCode() const
Airline ICAO code.
bool hasManuallySetString() const
Model string which was manually set.
void setModelType(ModelType type)
Set type.
static DBTripleIds parseNetworkLiveryString(const QString &liveryString)
Split swift network string.
const aviation::CLivery & getLivery() const
Get livery.
@ TypeModelMatchingDefaultModel
a default model assigned by model matching
@ TypeOwnSimulatorModel
represents own simulator model (AI model, model on disk)
@ TypeReverseLookup
reverse lookup model
@ TypeModelMatching
model is result of model matching
const QString & getModelString() const
Model key, either queried or loaded from simulator model.
void setCallsign(const aviation::CCallsign &callsign)
Corresponding callsign if applicable.
const QString & getDescription() const
Descriptive text.
const CDistributor & getDistributor() const
Get distributor.
const aviation::CAircraftIcaoCode & getAircraftIcaoCode() const
Aircraft ICAO code.
ModelType getModelType() const
Model type.
QString getModelStringAndDbKey() const
Model string and DB key (if available)
const QString & getModelTypeAsString() const
Model type.
bool isMilitary() const
Military model?
bool hasModelString() const
Non empty model string?
void setLivery(const aviation::CLivery &livery)
Livery.
bool setAircraftIcaoCode(const aviation::CAircraftIcaoCode &aircraftIcaoCode)
Set aircraft ICAO code.
Value object encapsulating a list of aircraft models.
CAircraftModelList findByCombinedAndManufacturer(const aviation::CAircraftIcaoCode &icao) const
Combined type and manufacturer.
ScoredModels scoreFull(const CAircraftModel &remoteModel, bool preferColorLiveries, bool ignoreZeroScores=true, CStatusMessageList *log=nullptr) const
Score by aircraft ICAO code.
QStringList getModelStringList(bool sort=true) const
Model strings.
CAircraftModel findFirstByModelStringAliasOrDefault(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Find first by model string.
CAircraftModelList findByMilitaryFlag(bool military) const
Find by military flag, false returns civilian models.
CAircraftModelList findEmptyModelStrings() const
Find empty model strings.
int replaceOrAddModelsWithString(const CAircraftModelList &addOrReplaceList, Qt::CaseSensitivity sensitivity)
Replace or add based on model string.
CAircraftModel findFirstByModelStringOrDefault(const QString &modelString, Qt::CaseSensitivity sensitivity=Qt::CaseInsensitive) const
Find first by model string.
CAircraftModelList findByAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const
Find by designator and livery code.
int removeIfExcluded()
Remove if excluded CAircraftModel::Exclude.
QString coverageSummary(const QString &separator="\n") const
What kind of models are represented here?
CAircraftModelList findByAirlineGroup(const swift::misc::aviation::CAirlineIcaoCode &airline) const
Find by the corresponding airline group.
CAircraftModelList findByFamily(const QString &family) const
Models with aircraft family.
CAircraftModelList findByCombinedType(const QString &combinedType) const
Find by combined code, wildcards possible, e.g. L*P, *2J.
QMap< swift::misc::aviation::CAirlineIcaoCode, int > countPerAirlineIcao() const
Airline ICAO plus count.
QString coverageSummaryForModel(const CAircraftModel &checkModel, const QString &separator="\n") const
What kind of models are represented here?
QSet< QString > getAirlineVDesignators() const
Airline virtual designators.
CAircraftModelList findByManufacturer(const QString &manufacturer) const
Find by manufacturer.
CAircraftModelList findByIcaoDesignators(const aviation::CAircraftIcaoCode &aircraftIcaoCode, const aviation::CAirlineIcaoCode &airlineIcaoCode) const
Find by ICAO designators.
int removeModelsWithString(const CAircraftModelList &models, Qt::CaseSensitivity sensitivity)
Remove those models with given model strings.
int removeAllWithoutModelString()
Remove if having no model string.
CAircraftModelList findDuplicateModelStrings() const
Find duplicate model strings and return those models with at least 1 duplicate model string.
CAircraftModelList findByAirlineNamesOrTelephonyDesignator(const QString &name) const
Find by airline name and telephony, similar to CAirlineIcaoCodeList::findByNamesOrTelephonyDesignator...
aviation::CAirlineIcaoCode getAirlineWithMaxCount() const
The airline with the max count.
CAircraftModelList findByModelMode(CAircraftModel::ModelMode mode) const
Find by model mode.
CAircraftModelList findByCombinedTypeWithColorLivery(const QString &combinedType) const
Combined type and color livery.
bool containsModelsWithAircraftAndAirlineIcaoDesignator(const QString &aircraftDesignator, const QString &airlineDesignator) const
Contains any model with aircraft and airline ICAO designator?
CAircraftModelList findByVtolFlag(bool vtol) const
Find by VTOL flag, false returns non VTOL models.
bool containsVtol() const
Contains VTOL models?
Category matcher, uses the DB categories.
CAircraftModelList reduceByCategories(const CAircraftModelList &alreadyMatchedModels, const CAircraftModelList &modelSet, const CAircraftMatcherSetup &setup, const CSimulatedAircraft &remoteAircraft, bool &reduced, bool shortLog, CStatusMessageList *log=nullptr) const
Reduce by categories.
void setCategories(const aviation::CAircraftCategoryList &categories)
Used categories.
EntryType
Represents type of entry.
void addAircraftAirlineCombination(CMatchingStatisticsEntry::EntryType type, const QString &sessionId, const QString &modelSetId, const QString &description, const QString &aircraftDesignator, const QString &airlineDesignator, bool avoidDuplicates=true)
Add a combination, normally with no duplicates (in that case count is increased.
static void addLogDetailsToList(CStatusMessageList *log, const CSimulatedAircraft &remoteAircraft, const QString &message, const QStringList &extraCategories={}, CStatusMessage::StatusSeverity s=CStatusMessage::SeverityInfo)
Specialized log for matching / reverse lookup.
Comprehensive information of an aircraft.
const QString & getAirlineIcaoCodeDesignator() const
Airline ICAO code designator.
bool hasAirlineDesignator() const
Valid airline designator.
bool hasModelString() const
Has model string?
void setModel(const CAircraftModel &model)
Set model.
bool isMilitary() const
Is military aircraft.
bool hasCallsign() const
Callsign not empty, no further checks.
const aviation::CCallsign & getCallsign() const
Get callsign.
const aviation::CLivery & getLivery() const
Get livery.
bool hasAircraftDesignator() const
Valid designator?
const aviation::CAircraftIcaoCode & getAircraftIcaoCode() const
Get aircraft ICAO info.
const QString & getAircraftIcaoCombinedType() const
Aircraft ICAO combined code.
const QString & getAircraftIcaoCodeDesignator() const
Aircraft ICAO code designator.
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
QString getAirlineAndAircraftIcaoCodeDesignators() const
Aircraft and Airline ICAO code designators.
bool isVtol() const
VTOL aircraft?
QString getCallsignAsString() const
Get callsign.
const aviation::CAirlineIcaoCode & getAirlineIcaoCode() const
Airline ICAO code if any.
const QString & getModelString() const
Get model string.
Simple hardcoded info about the corresponding simulator.
bool isSingleSimulator() const
Single simulator selected.
const QString & getLogMessage() const
Log. message.
int getDbAircraftIcaoId() const
Values found in DB?
bool hasChangedLiveryId(const swift::misc::aviation::CLivery &livery) const
Changed values.
int getDbAirlineIcaoId() const
Values found in DB?
bool hasChangedModelString(const QString &modelString) const
Changed values.
bool hasChangedAircraftIcaoId(const swift::misc::aviation::CAircraftIcaoCode &aircraftIcao) const
Changed values.
bool hasChangedAirlineIcaoId(const swift::misc::aviation::CAirlineIcaoCode &airlineIcao) const
Changed values.
bool isRerun() const
Request re-run.
bool hasChangedAircraftIcao(const swift::misc::aviation::CAircraftIcaoCode &aircraftIcao) const
Changed values.
int getDbLiveryId() const
Values found in DB?
const QString & getModelString() const
Livery, airline, aircraft, model string.
bool isModified() const
Modified flag.
int getDbModelId() const
Values found in DB?
bool hasChangedAirlineIcao(const swift::misc::aviation::CAirlineIcaoCode &airlineIcao) const
Changed values.
bool hasChangedModelId(const swift::misc::simulation::CAircraftModel &model) const
Changed values.
const QString & getAirlineIcao() const
Livery, airline, aircraft, model string.
void evaluateChanges(const swift::misc::aviation::CAircraftIcaoCode &aircraft, const swift::misc::aviation::CAirlineIcaoCode &airline)
Changed values such as modified values.
const QString & getAircraftIcao() const
Livery, airline, aircraft, model string.
void initByAircraftAndAirline(const swift::misc::aviation::CAircraftIcaoCode &aircraft, const swift::misc::aviation::CAirlineIcaoCode &airline)
Init by aircraft/airline.
MatchingScript
Matching script type.
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString removeSurroundingApostrophes(const QString &in)
Remove surrounding apostrophes 'foo' -> foo.
SWIFT_MISC_EXPORT QString joinStringSet(const QSet< QString > &set, const QString &separator)
Convert string to bool.
SWIFT_MISC_EXPORT const QString & defaultIfEmpty(const QString &candidate, const QString &defaultIfEmpty)
Default string if string is empty.
const std::string & boolToYesNo(bool t)
Yes/no from bool.
QString toQString() const
Return as string.
int livery
livery id, by that I have airline id
int aircraft
aircraft ICAO id
swift::misc::simulation::CAircraftModel model
the model
bool runScriptAndModified() const
Did run the script with modified result.
bool rerun
rerun that matching part?
bool runScript
did we run the script
bool runScriptModifiedAndRerun() const
Did run the script, modified value and re-run requested.