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";
609 boolToYesNo(didRunAndModifyMatchingScript)));
612 const QDateTime endTime = QDateTime::currentDateTimeUtc();
613 const qint64 matchingTime = startTime.msecsTo(endTime);
614 static const QString em(
"--- Matching end: UTC %1, time %2ms ---");
621 const CAirlineIcaoCode &networkAirlineIcao,
const QString &networkLiveryInfo,
631 CAircraftModel model(networkModelString, type, {}, networkAircraftIcao, livery);
676 if (js.isEmpty() && log)
678 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Matching script is empty"));
686 const bool msReverse = (script == ReverseLookup);
688 static const QString logFileR =
690 static const QString logFileM =
695 CCallsign::addLogDetailsToList(
696 log, callsign, QStringLiteral(
"Matching script (%1): '%2'").arg(msToString(script), lf));
697 CCallsign::addLogDetailsToList(
699 QStringLiteral(
"Matching script input model (%1): '%2'").arg(inModel.
toQString(
true)));
700 CCallsign::addLogDetailsToList(
701 log, callsign, QStringLiteral(
"Matching script models: %1").arg(modelSet.
coverageSummary()));
726 const QJSValue jsInObject = engine.newQObject(&inObject);
727 engine.globalObject().setProperty(
"inObject", jsInObject);
730 const QJSValue jsOutObject = engine.newQObject(&outObject);
731 engine.globalObject().setProperty(
"outObject", jsOutObject);
734 const QJSValue jsMatchedObject = engine.newQObject(&matchedObject);
735 engine.globalObject().setProperty(
"matchedObject", jsMatchedObject);
738 const QJSValue jsModelSetObject = engine.newQObject(&modelSetObject);
739 engine.globalObject().setProperty(
"modelSet", jsModelSetObject);
742 const QJSValue jsWebServices = engine.newQObject(&webServices);
743 engine.globalObject().setProperty(
"webServices", jsWebServices);
745 QJSValue ms = engine.evaluate(js, msReverse ? logFileR : logFileM);
749 const QString msg = QStringLiteral(
"Matching script error: %1 '%2'")
750 .arg(ms.property(
"lineNumber").toInt())
753 if (log) { CCallsign::addLogDetailsToList(log, callsign, msg); }
759 const MSInOutValues *reverseModelProcessed = qobject_cast<const MSInOutValues *>(ms.toQObject());
761 if (!reverseModelProcessed->
isModified()) {
break; }
783 const QString modelString = reverseModelProcessed->
getModelString();
798 CCallsign::addLogDetailsToList(
800 QStringLiteral(
"Matching script using model from set: '%1'").arg(modelString));
803 rv.
model = modeSetModel;
847 CCallsign::addLogDetailsToList(
849 QStringLiteral(
"Matching script, changed airline ICAO: '%1' -> '%2'")
855 else if (ms.isString()) { logMessage = ms.toString(); }
863 if (log && !logMessage.
isEmpty())
865 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Matching script log: '%1'").arg(logMessage));
873 const QString &networkLiveryInfo,
901 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Model string looup disabled"));
918 const bool useNonDbEntries =
true;
920 modelString, callsign, modelSet, useNonDbEntries, log);
923 model = modelFromSet;
933 CCallsign::addLogDetailsToList(log, callsign,
934 QStringLiteral(
"Livery string with ids: '%1'").arg(ids.
toQString()));
941 CCallsign::addLogDetailsToList(
943 QStringLiteral(
"Ignoring livery ids '%1', because of setup").arg(ids.
toQString()));
950 CCallsign::addLogDetailsToList(log, callsign,
951 QStringLiteral(
"Model lookup with id %1 from triple ids '%2'")
968 CCallsign::addLogDetailsToList(
970 QStringLiteral(
"Aircraft ICAO lookup with id %1 from triple ids '%2'")
983 CCallsign::addLogDetailsToList(log, callsign,
984 QStringLiteral(
"Livery lookup with id %1 from triple ids '%2'")
1003 CCallsign::addLogDetailsToList(log, callsign,
1004 QStringLiteral(
"Set aircraft ICAO to '%1' from DB")
1014 CCallsign::addLogDetailsToList(
1016 QStringLiteral(
"Reverse lookup, ICAO '%1' not resolved from DB")
1033 QString liveryCode = networkLiveryInfo;
1037 liveryCode = CLivery::getStandardCode(airlineIcaoCode);
1040 if (CLivery::isValidCombinedCode(liveryCode))
1050 CCallsign::addLogDetailsToList(log, callsign,
1051 QStringLiteral(
"Reverse lookup of livery found '%1'")
1061 CCallsign::addLogDetailsToList(
1063 QStringLiteral(
"Reverse lookup of livery '%1' yielded no result")
1084 CCallsign::addLogDetailsToList(log, callsign,
1085 QStringLiteral(
"Set standardlivery `%1`")
1094 const CLivery liveryDummy(CLivery::getStandardCode(airlineIcaoCode), airlineIcaoCode,
1099 CCallsign::addLogDetailsToList(log, callsign,
1100 QStringLiteral(
"Generated livery, set livery `%1`")
1115 CCallsign::addLogDetailsToList(log, callsign,
1116 QStringLiteral(
"Using model: ICAO '%1', livery '%2', model '%3', type '%4'")
1125 const QString &networkLiveryInfo,
1135 CCallsign::addLogDetailsToList(log, cs,
1136 QStringLiteral(
"Matching script: Modified value and requested rerun"));
1142 return reverseModel;
1151 if (!doLookupString)
1155 CCallsign::addLogDetailsToList(
1157 QStringLiteral(
"Ignore model string in reverse lookup (disabled), ignoring '%1'").arg(modelString));
1167 CCallsign::addLogDetailsToList(
1169 QStringLiteral(
"Found model in DB for model string '%1' dist: '%2' descr.: '%3'")
1175 CCallsign::addLogDetailsToList(
1176 log, callsign, QStringLiteral(
"Did not find model in DB for model string '%1'").arg(modelString));
1194 if (modelString.isEmpty())
1198 CCallsign::addLogDetailsToList(
1199 log, callsign, QStringLiteral(
"Empty model string for lookup in %1 models").arg(modelSet.
size()));
1207 CCallsign::addLogDetailsToList(log, callsign,
1208 QStringLiteral(
"Empty models, ignoring '%1'").arg(modelString));
1218 CCallsign::addLogDetailsToList(
1220 QStringLiteral(
"Model '%1' not found in %2 models").arg(modelString).arg(modelSet.
size()));
1230 CCallsign::addLogDetailsToList(log, callsign,
1231 QStringLiteral(
"Found DB model in %1 models for model string '%2'")
1232 .arg(modelSet.
size())
1237 CCallsign::addLogDetailsToList(log, callsign,
1238 QStringLiteral(
"Found NON DB model in %1 models for model string '%2'")
1239 .arg(modelSet.
size())
1260 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Found model in DB for id '%1'").arg(
id));
1264 CCallsign::addLogDetailsToList(log, callsign,
1265 QStringLiteral(
"Did not find model in DB for id '%1'").arg(
id));
1286 if (CAircraftIcaoCode::isValidDesignator(designator))
1288 CCallsign::addLogDetailsToList(
1290 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1' did not find anything, using smart search")
1297 CCallsign::addLogDetailsToList(
1299 QStringLiteral(
"Reverse lookup of invalid ICAO code '%1' did not find anything so far")
1302 const QStringList parts(designator.split(
' '));
1303 for (
const QString &p : parts)
1305 CCallsign::addLogDetailsToList(
1307 QStringLiteral(
"Trying parts, now reverse lookup of aircraft ICAO '%1' using smart search")
1321 CCallsign::addLogDetailsToList(log, logCallsign,
1322 QStringLiteral(
"No DB data for ICAO '%1', valid ICAO?").arg(designator),
1330 CCallsign::addLogDetailsToList(
1331 log, logCallsign, QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', nothing found").arg(designator),
1335 else if (foundIcaos.
size() == 1)
1338 CCallsign::addLogDetailsToList(
1340 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', found one manufacturer '%2' in DB")
1348 Q_ASSERT_X(foundIcaos.
size() > 1, Q_FUNC_INFO,
"Wrong size");
1350 CCallsign::addLogDetailsToList(
1352 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', found %2 values (ambiguous): %3")
1354 .arg(foundIcaos.
size())
1357 if (maxManufacturer.second < foundIcaos.
size())
1360 CCallsign::addLogDetailsToList(log, logCallsign,
1361 QStringLiteral(
"Reducing by manufacturer '%1', now %2 values")
1362 .arg(maxManufacturer.first)
1363 .arg(foundIcaos.
size()),
1368 CCallsign::addLogDetailsToList(
1370 QStringLiteral(
"Reverse lookup of aircraft ICAO '%1', using ICAO '%2' with rank %3")
1386 CCallsign::addLogDetailsToList(log, logCallsign,
1387 QStringLiteral(
"Found aircraft ICAO in DB for id '%1'").arg(
id));
1391 CCallsign::addLogDetailsToList(log, logCallsign,
1392 QStringLiteral(
"Did not find aircraft ICAO in DB for id '%1'").arg(
id));
1407 CCallsign::addLogDetailsToList(
1409 QStringLiteral(
"Reverse lookup of airline ICAO '%1' and callsign '%2' found '%3' '%4' in DB")
1416 CCallsign::addLogDetailsToList(
1418 QStringLiteral(
"Reverse lookup of airline ICAO '%1' and callsign '%2', nothing found in DB")
1434 CCallsign::addLogDetailsToList(
1435 log, callsign, QStringLiteral(
"Reverse lookup of standard livery skipped, no airline designator"),
1446 CCallsign::addLogDetailsToList(log, callsign,
1447 QStringLiteral(
"Reverse lookup of standard livery for '%1' found '%2'")
1453 CCallsign::addLogDetailsToList(
1455 QStringLiteral(
"Not standard livery for airline '%1' in DB").arg(airline.
getDesignator()),
1470 CCallsign::addLogDetailsToList(log, logCallsign,
1471 QStringLiteral(
"Found livery in DB for id '%1'").arg(
id));
1475 CCallsign::addLogDetailsToList(log, logCallsign,
1476 QStringLiteral(
"Did not find livery in DB for id '%1'").arg(
id));
1504 if (candidate.isEmpty()) {
return {}; }
1506 if (names.contains(candidate, Qt::CaseInsensitive))
1508 CCallsign::addLogDetailsToList(log, callsign,
1509 QStringLiteral(
"Airline name '%1' found in DB").arg(candidate));
1513 CCallsign::addLogDetailsToList(log, callsign,
1514 QStringLiteral(
"Airline name '%1' not found in DB").arg(candidate));
1522 if (candidate.isEmpty()) {
return {}; }
1524 if (designators.contains(candidate, Qt::CaseInsensitive))
1526 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Airline name '%1' found").arg(candidate));
1530 CCallsign::addLogDetailsToList(log, callsign, QStringLiteral(
"Airline name '%1' not found").arg(candidate));
1538 if (!CAircraftIcaoCode::isValidDesignator(candidate))
1540 CCallsign::addLogDetailsToList(log, callsign,
1541 QStringLiteral(
"No valid ICAO designator '%1'").arg(candidate));
1546 static const QString sKnown(
"Known ICAO designator '%1'");
1547 static const QString sUnknown(
"Unknown ICAO designator '%1'");
1548 CCallsign::addLogDetailsToList(log, callsign, known ? sKnown.arg(candidate) : sUnknown.arg(candidate));
1557 static const QString sKnown(
"Known modelstring '%1'");
1558 static const QString sUnknown(
"Unknown modelstring '%1'");
1559 CCallsign::addLogDetailsToList(log, callsign, known ? sKnown.arg(candidate) : sUnknown.arg(candidate));
1570 CCallsign::addLogDetailsToList(
1571 log, callsign, QStringLiteral(
"No valid airline from DB '%1'").arg(airline.
getDesignator()));
1580 CCallsign::addLogDetailsToList(
1581 log, callsign, QStringLiteral(
"No aircraft known for airline '%1'").arg(airline.
getDesignator()));
1586 const QString allIcaosStr = allIcaos.values().join(
", ");
1587 CCallsign::addLogDetailsToList(
1589 QStringLiteral(
"Aircraft '%1' known for airline '%2'").arg(allIcaosStr, airline.
getDesignator()));
1594 CCallsign::addLogDetailsToList(log, callsign,
1595 QStringLiteral(
"Aircraft '%1' is best fuzzy search of '%2' for airline '%3'")
1600 return aircraft.
front();
1610 CCallsign::addLogDetailsToList(
1612 QStringLiteral(
"Turned callsign %1 into airline %2").arg(callsign.
asString(), icao.
getDesignator()),
1617 CCallsign::addLogDetailsToList(
1618 log, callsign, QStringLiteral(
"Cannot turn callsign %1 into airline").arg(callsign.
asString()),
1633 if (!forced && m_simulator == simulator && m_modelSet.
size() == modelsCleaned.
size())
1635 return m_modelSet.
size();
1642 QStringLiteral(
"Removed models for matcher, without string #: %1, excluded #: %2.").arg(r1).arg(r2);
1645 warnings += QStringLiteral(
" Without string: '%1'.")
1650 warnings += QStringLiteral(
" Excluded: '%1'.")
1660 CLogMessage(
this).
error(u
"No models for matching ('%1'), swift without a model set will not work!")
1663 else if (!duplicateModels.
isEmpty())
1665 CLogMessage(
this).
error(u
"Found model duplicate strings, check models: '%1'")
1676 m_modelSet = modelsCleaned;
1677 m_simulator = simulator;
1678 m_modelSetInfo = QStringLiteral(
"Set: '%1' entries: %2").arg(simulator.
toQString()).arg(modelsCleaned.
size());
1679 return models.
size();
1687 m_disabledModels.
push_back(removedModels);
1692 m_disabledModels = removedModels;
1704 m_defaultModel = defaultModel;
1709 const QString &aircraftIcao,
const QString &airlineIcao,
1710 const QString &livery)
1714 if (m_modelSet.
isEmpty()) {
return; }
1715 if (sessionId.isEmpty()) {
return; }
1716 if (aircraftIcao.isEmpty()) {
return; }
1718 QString description;
1721 description = QStringLiteral(
"ICAO: '%1' not known, typo?").arg(aircraftIcao);
1726 if (airlineIcao.isEmpty())
1735 CMatchingStatisticsEntry::Found :
1736 CMatchingStatisticsEntry::Missing;
1756 bool CAircraftMatcher::saveDisabledForMatchingModels()
1758 if (m_disabledModels.
isEmpty()) {
return false; }
1761 const QString ts = QDateTime::currentDateTimeUtc().toString(
"yyyyMMddHHmmss");
1765 QStringLiteral(
"removed models %1.json").arg(ts)));
1776 const CAircraftMatcherSetup::MatchingMode mode = setup.
getMatchingMode();
1777 CStatusMessageList *reduceLog = log && whatToLog.testFlag(MatchingLogStepwiseReduce) ? log :
nullptr;
1778 bool reduced =
false;
1781 if (mode.testFlag(CAircraftMatcherSetup::ByLivery))
1784 ifPossibleReduceByLiveryAndAircraftIcaoCode(remoteAircraft, matchedModels, reduced, log);
1785 if (reduced) {
break; }
1797 matchedModels = ifPossibleReduceByIcaoData(remoteAircraft, matchedModels, setup, reduced, log);
1805 if (mode.testFlag(CAircraftMatcherSetup::ByFamily))
1808 matchedModels = ifPossibleReduceByFamily(remoteAircraft, UsePseudoFamily, matchedModels, reduced,
1810 if (reduced) {
break; }
1821 matchedModels = categoryMatcher.
reduceByCategories(matchedModels, modelSet, setup, remoteAircraft,
1822 reduced, whatToLog, log);
1832 if (!reduced && remoteAircraft.
isVtol() && matchedModels.containsVtol() &&
1833 mode.testFlag(CAircraftMatcherSetup::ByVtol))
1835 matchedModels = matchedModels.findByVtolFlag(
true);
1837 log, remoteAircraft, QStringLiteral(
"Aircraft is VTOL, reduced to VTOL"),
getLogCategories());
1841 bool milFlagReduced =
false;
1844 matchedModels = ifPossibleReduceByMilitaryFlag(remoteAircraft, matchedModels, reduced, reduceLog);
1845 milFlagReduced =
true;
1850 matchedModels = ifPossibleReduceByMilitaryFlag(remoteAircraft, matchedModels, reduced, reduceLog);
1851 milFlagReduced =
true;
1855 if (mode.testFlag(CAircraftMatcherSetup::ByCombinedType))
1858 ifPossibleReduceByCombinedType(remoteAircraft, matchedModels, setup, reduced, reduceLog);
1859 if (reduced) {
break; }
1870 if (matchedModels.size() > 1 && mode.testFlag(CAircraftMatcherSetup::ByManufacturer))
1872 matchedModels = ifPossibleReduceByManufacturer(remoteAircraft, matchedModels,
1873 QStringLiteral(
"2nd trial to reduce by manufacturer. "),
1874 reduced, reduceLog);
1877 return matchedModels;
1883 int &maxScore, MatchingLog whatToLog,
1889 CStatusMessageList *scoreLog = log && whatToLog.testFlag(MatchingLogScoring) ? log :
nullptr;
1893 map = modelSet.
scoreFull(remoteAircraft.
getModel(), preferColorLiveries, noZeroScores, scoreLog);
1898 maxScore = map.lastKey();
1901 QStringLiteral(
"Scores: %1").arg(scoresToString(map)),
getLogCategories());
1903 QStringLiteral(
"Scoring with score %1 out of %2 models yielded %3 models")
1906 .arg(maxScoreAircraft.size()),
1908 return maxScoreAircraft;
1917 CStatusMessageList *combinedLog = log && whatToLog.testFlag(MatchingLogCombinedDefaultType) ? log :
nullptr;
1919 if (combinedType.isEmpty())
1924 return defaultModel;
1930 return defaultModel;
1934 u
"Searching by combined type with color livery '" % combinedType %
"'",
1940 u
"Found " % QString::number(matchedModels.
size()) %
1941 u
" by combined type w/color livery '" % combinedType %
"'",
1947 combinedLog, remoteAircraft, u
"Searching by combined type '" % combinedType %
"'",
getLogCategories());
1952 u
"Found " % QString::number(matchedModels.
size()) %
1953 u
" by combined '" % combinedType %
"'",
1959 if (matchedModels.
isEmpty()) {
return defaultModel; }
1960 return matchedModels.
front();
1967 CStatusMessageList *msLog = log && whatToLog.testFlag(MatchingLogModelstring) ? log :
nullptr;
1973 QStringLiteral(
"No model string, no exact match possible"));
1984 msLog, remoteAircraft, QStringLiteral(
"Found exact match for '%1'").arg(model.
getModelString()));
1989 msLog, remoteAircraft,
1990 QStringLiteral(
"No exact match for '%1'").arg(remoteAircraft.
getModelString()));
1999 CAircraftMatcher::ifPossibleReduceByLiveryAndAircraftIcaoCode(
const CSimulatedAircraft &remoteAircraft,
2009 log, remoteAircraft, QStringLiteral(
"No livery code, no reduction possible"),
getLogCategories());
2017 if (byLivery.isEmpty())
2036 const CAircraftMatcherSetup::MatchingMode mode = setup.
getMatchingMode();
2048 if (mode.testFlag(CAircraftMatcherSetup::ByIcaoOrderAirlineFirst))
2053 QStringLiteral(
"Reduce by airline first."), r1, log);
2054 models = ifPossibleReduceByAircraftOrFamily(remoteAircraft, UsePseudoFamily, models, setup,
2055 QStringLiteral(
"Reduce by aircraft ICAO second."), r2, log);
2057 if (reduced) {
return models; }
2064 ifPossibleReduceByAircraftOrFamily(remoteAircraft, UsePseudoFamily, inList, setup,
2065 QStringLiteral(
"Reduce by aircraft ICAO first."), r1, log);
2066 models = ifPossibleReduceByAirline(remoteAircraft, models, setup,
2067 QStringLiteral(
"Reduce aircraft ICAO by airline second."), r2, log);
2076 "No airline, no secondary search for airline/aircraft",
2080 else if (!r2 && mode.testFlag(CAircraftMatcherSetup::ByFamily))
2085 u
"No exact ICAO match of '" %
2087 u
"', will try family combination",
2094 ifPossibleReduceByFamily(remoteAircraft, UsePseudoFamily, inList, r3, usedFamily, log);
2095 models2nd = ifPossibleReduceByAirline(remoteAircraft, models2nd, setup,
2096 "Reduce family by airline second.", r3, log);
2103 u
"Found " % QString::number(models2nd.
sizeInt()) %
2104 " aircraft family/airline '" % usedFamily %
2135 bool allowPseudoFamily,
2141 if (!usedFamily.isEmpty())
2144 ifPossibleReduceByFamily(remoteAircraft, usedFamily, allowPseudoFamily, inList,
2145 QStringLiteral(
"real family from ICAO"), reduced, log);
2146 if (reduced) {
return matchedModels; }
2151 return ifPossibleReduceByFamily(remoteAircraft, usedFamily, allowPseudoFamily, inList,
2152 QStringLiteral(
"ICAO treated as family"), reduced, log);
2156 const QString &family,
bool allowPseudoFamily,
2162 if (family.isEmpty() && !allowPseudoFamily)
2183 if (foundByFamily.isEmpty())
2188 u
"Not found by family '" % family % u
"' (" % hint %
")");
2190 if (!allowPseudoFamily) {
return inList; }
2198 u
"Found by family '" % family % u
"' (" % hint % u
") size " %
2199 QString::number(foundByFamily.sizeInt()),
2205 if (allowPseudoFamily)
2215 u
"Not found by pseudo family '" % pseudo % u
"' (" % hint %
")");
2223 u
"Found by pseudo family '" % pseudo % u
"' (" % hint %
2224 u
") size " % QString::number(foundByCM.
sizeInt()),
2230 if (foundByCM.
isEmpty() && foundByFamily.isEmpty()) {
return inList; }
2234 if (!foundByFamily.isEmpty())
2238 foundByFamily.push_back(foundByCM);
2243 u
"Found by family (totally) '" % family % u
"' (" % hint % u
") size " %
2244 QString::number(foundByFamily.sizeInt()),
2247 return foundByFamily;
2252 const QString &info,
bool &reduced,
2272 info % u
" No manufacturer, cannot reduce " %
2273 QString::number(inList.
size()) % u
" entries",
2280 if (outList.isEmpty())
2285 log, remoteAircraft, info % u
" Not found '" % m % u
"', cannot reduce",
getLogCategories());
2293 log, remoteAircraft, info % u
" Reduced by '" % m % u
"' results: " % QString::number(outList.size()),
2309 CCallsign::addLogDetailsToList(log, logCallsign, info % u
" Empty input list, cannot reduce",
2320 CCallsign::addLogDetailsToList(log, logCallsign,
2321 info % u
" No manufacturer, cannot reduce " %
2322 QString::number(inList.
size()) % u
" entries",
2329 if (outList.isEmpty())
2333 CCallsign::addLogDetailsToList(log, logCallsign, info %
" Not found " % m %
", cannot reduce",
2341 CCallsign::addLogDetailsToList(log, logCallsign,
2342 info % u
" Reduced by " % m % u
" results: " % QString::number(outList.size()),
2351 const QString &info,
bool &reduced,
2370 info %
" No aircraft designator, cannot reduce " %
2371 QString::number(inList.
size()) %
" entries",
2379 if (outList.isEmpty())
2384 info % u
" Cannot reduce by '" %
2386 u
"' results: " % QString::number(outList.size()),
2395 info % u
" Reduced by '" %
2397 QString::number(outList.size()),
2409 const CAircraftModelList outList = ifPossibleReduceByAircraft(remoteAircraft, inList, info, reduced, log);
2410 if (reduced || !setup.
getMatchingMode().testFlag(CAircraftMatcherSetup::ByFamily)) {
return outList; }
2412 return ifPossibleReduceByFamily(remoteAircraft, allowPseudoFamily, inList, reduced, family, log);
2418 const QString &info,
bool &reduced,
2437 info % u
" No airline designator, cannot reduce " %
2438 QString::number(inList.
size()) % u
" entries",
2447 if (mode.testFlag(CAircraftMatcherSetup::ByAirlineGroupSameAsAirline) ||
2448 (outList.
isEmpty() || mode.testFlag(CAircraftMatcherSetup::ByAirlineGroupIfNoAirline)))
2457 log, remoteAircraft,
2459 QStringLiteral(
"No group models found by using airline group '%1'")
2461 QStringLiteral(
"Added %1 model(s) by using airline group '%2', all members: '%3'")
2475 info % u
" Cannot reduce by '" %
2477 QString::number(outList.
size()),
2486 info % u
" Reduced by '" %
2488 QString::number(outList.
size()),
2495 CAircraftModelList CAircraftMatcher::ifPossibleReduceModelsByAirlineNameTelephonyDesignator(
2504 CCallsign::addLogDetailsToList(log, cs, info % u
" Empty input list, cannot reduce",
getLogCategories());
2509 if (telephony.isEmpty() && airlineName.isEmpty())
2513 CCallsign::addLogDetailsToList(log, cs,
2514 info % u
" No name/telephony, cannot reduce " %
2515 QString::number(inList.
size()) % u
" entries",
2526 CCallsign::addLogDetailsToList(
2527 log, cs, info % QStringLiteral(
" cannot reduce by '%1'").arg(airlineName),
getLogCategories());
2536 CCallsign::addLogDetailsToList(log, cs, info % QStringLiteral(
" reduced by '%1'").arg(airlineName),
2540 if (step1Data.
size() == 1) {
return step1Data; }
2547 CCallsign::addLogDetailsToList(log, cs, info % QStringLiteral(
" cannot reduce by '%1'").arg(telephony),
2550 step2Data = step1Data;
2557 CCallsign::addLogDetailsToList(log, cs, info % QStringLiteral(
" reduced by '%1'").arg(telephony),
2594 if (modelsByCombinedCode.isEmpty())
2607 u
"Found by combined code " % cc % u
", possible " %
2608 QString::number(modelsByCombinedCode.size()),
2611 if (modelsByCombinedCode.size() > 1)
2613 modelsByCombinedCode =
2614 ifPossibleReduceByAirline(remoteAircraft, modelsByCombinedCode, setup,
2615 QStringLiteral(
"Combined code airline reduction. "), reduced, log);
2616 modelsByCombinedCode =
2617 ifPossibleReduceByManufacturer(remoteAircraft, modelsByCombinedCode,
2618 QStringLiteral(
"Combined code manufacturer reduction. "), reduced, log);
2621 return modelsByCombinedCode;
2631 const QString mil(military ?
"military" :
"civilian");
2632 if (byMilitaryFlag.isEmpty())
2645 u
"Models reduced to " % mil % u
" aircraft, size " %
2646 QString::number(byMilitaryFlag.size()),
2649 return byMilitaryFlag;
2667 log, remoteAircraft, u
"Models reduced to " % QString::number(vtolModels.
size()) % u
" VTOL aircraft",
2673 QString CAircraftMatcher::scoresToString(
const ScoredModels &scores,
int lastElements)
2675 if (scores.isEmpty()) {
return {}; }
2676 QMultiMapIterator<int, CAircraftModel> i(scores);
2680 while (i.hasPrevious() && c++ < lastElements)
2684 if (!str.isEmpty()) { str +=
'\n'; }
2685 str += QString::number(c) % u
": score: " % QString::number(i.key()) % u
" model: '" % m.getModelString() %
2686 u
"' aircraft: '" % m.getAircraftIcaoCodeDesignator() % u
"' livery: '" %
2687 m.getLivery().getCombinedCodePlusInfo() % u
'\'';
2693 const QString &airlineName,
2694 const QString &airlineTelephony,
bool useSwiftDbData,
2701 if (codes.
size() == 1) {
return codes.
front(); }
2704 bool reduced =
false;
2705 static const QString info(
"Try reducing airline '%1' by name/telephony '%2'/'%3'");
2707 cs, airlineName, airlineTelephony, QString(), reduced, info, log);
2711 bool CAircraftMatcher::isValidAirlineIcaoDesignator(
const QString &designator,
bool checkAgainstSwiftDb)
2713 if (!CAirlineIcaoCode::isValidAirlineDesignator(designator)) {
return false; }
2714 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::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 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::CAirlineIcaoCode getAirlineIcaoCodeForDbKey(int key) const
ICAO code for id.
swift::misc::aviation::CAircraftIcaoCodeList getAircraftIcaoCodesForDesignator(const QString &designator) const
ICAO codes for designator.
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::CAircraftIcaoCode getAircraftIcaoCodeForDbKey(int key) const
ICAO code for id.
swift::misc::aviation::CAircraftCategoryList getAircraftCategories() const
Aircraft categories.
swift::misc::aviation::CAirlineIcaoCode smartAirlineIcaoSelector(const swift::misc::aviation::CAirlineIcaoCode &icaoPattern, const swift::misc::aviation::CCallsign &callsign=swift::misc::aviation::CCallsign()) const
Smart airline selector.
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.
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.