swift
liverylist.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include "misc/predicates.h"
7 #include "misc/range.h"
8 
9 using namespace swift::misc::aviation;
10 
11 SWIFT_DEFINE_SEQUENCE_MIXINS(swift::misc::aviation, CLivery, CLiveryList)
12 
13 namespace swift::misc::aviation
14 {
16 
18 
20  {
21  QString icaoCode(icao.trimmed().toUpper());
22  if (icaoCode.isEmpty()) { return CLiveryList(); }
23  return this->findBy(&CLivery::getAirlineIcaoCodeDesignator, icaoCode);
24  }
25 
27  {
28  if (this->isEmpty() || !icao.hasValidDesignator()) { return CLivery(); }
29  CLiveryList candidates;
30  for (const CLivery &livery : *this)
31  {
32  if (!livery.isAirlineStandardLivery()) { continue; }
33  const CAirlineIcaoCode livIcao = livery.getAirlineIcaoCode();
34  if (livIcao.isDbEqual(icao)) { return livery; }
35  if (livIcao.getVDesignator() != icao.getVDesignator()) { continue; }
36  if (icao.getName().size() > 5 && livery.getDescription().contains(icao.getName(), Qt::CaseInsensitive))
37  {
38  return livery;
39  }
40  candidates.push_back(livery);
41  }
42 
43  if (candidates.size() < 2) { return candidates.frontOrDefault(); }
44  const CLiveryList operatingAirlines = candidates.findBy(&CLivery::isAirlineOperating, true);
45  if (!operatingAirlines.isEmpty()) { return operatingAirlines.frontOrDefault(); }
46  return candidates.frontOrDefault();
47  }
48 
50  {
51  const QString icaoDesignator(icao.trimmed().toUpper());
52  if (icaoDesignator.isEmpty()) { return CLivery(); }
53  return this->findFirstByOrDefault([&](const CLivery &livery) {
54  if (!livery.isAirlineStandardLivery()) { return false; }
55  return livery.getAirlineIcaoCode().matchesVDesignator(icaoDesignator);
56  });
57  }
58 
60  {
61  if (containedString.isEmpty()) { return CLiveryList(); }
62  return this->findBy([&](const CLivery &livery) {
63  // keep isAirlineStandardLivery first (faster)
64  return livery.isAirlineStandardLivery() && livery.isContainedInSimplifiedAirlineName(containedString);
65  });
66  }
67 
69  {
70  if (candidate.isEmpty()) { return CLiveryList(); }
71  return this->findBy([&](const CLivery &livery) {
72  // keep isAirlineStandardLivery first (faster)
73  return livery.isAirlineStandardLivery() &&
75  });
76  }
77 
79  {
80  if (!fuselage.isValid() || !tail.isValid()) { return CLivery(); }
81  return this->findFirstByOrDefault([&](const CLivery &livery) {
82  if (!livery.isColorLivery()) { return false; }
83  return livery.matchesColors(fuselage, tail);
84  });
85  }
86 
88  {
89  if (!fuselage.isValid() || !tail.isValid()) { return CLivery(); }
90  CLivery bestMatch;
91  double bestDistance = 1.0;
92  for (const CLivery &livery : *this)
93  {
94  if (!livery.isColorLivery()) { continue; }
95  const double d = livery.getColorDistance(fuselage, tail);
96  if (d == 0.0) { return livery; } // exact match
97  if (d < bestDistance)
98  {
99  bestMatch = livery;
100  bestDistance = d;
101  }
102  }
103  return bestMatch;
104  }
105 
106  CLivery CLiveryList::findByCombinedCode(const QString &combinedCode) const
107  {
108  if (!CLivery::isValidCombinedCode(combinedCode)) { return CLivery(); }
109  return this->findFirstByOrDefault(
110  [&](const CLivery &livery) { return livery.matchesCombinedCode(combinedCode); });
111  }
112 
113  QStringList CLiveryList::getCombinedCodes(bool sort) const
114  {
115  if (this->isEmpty()) { return QStringList(); }
117  if (sort) { codes.sort(); }
118  return codes;
119  }
120 
121  QStringList CLiveryList::getCombinedCodesPlusInfo(bool sort) const
122  {
123  if (this->isEmpty()) { return QStringList(); }
125  if (sort) { codes.sort(); }
126  return codes;
127  }
128 
129  QStringList CLiveryList::getCombinedCodesPlusInfoAndId(bool sort) const
130  {
131  if (this->isEmpty()) { return QStringList(); }
133  if (sort) { codes.sort(); }
134  return codes;
135  }
136 
138  {
139  CAirlineIcaoCodeList icaos;
140  for (const CLivery &livery : *this) { icaos.push_back(livery.getAirlineIcaoCode()); }
141  return icaos;
142  }
143 
145  {
146  // multiple searches are slow, maybe we can performance optimize this
147  // in the future
148 
149  // first try on id, that would be perfect
150  if (liveryPattern.hasValidDbKey()) { return liveryPattern; }
151 
152  // by combined code
153  if (liveryPattern.hasCombinedCode())
154  {
155  const QString cc(liveryPattern.getCombinedCode());
156  const CLivery l(this->findByCombinedCode(cc));
157  if (l.hasCompleteData()) { return l; }
158  }
159 
160  // by airline
161  if (liveryPattern.hasValidAirlineDesignator())
162  {
163  const QString icao(liveryPattern.getAirlineIcaoCodeDesignator());
164  const CLivery l(this->findStdLiveryByAirlineIcaoVDesignator(icao));
165  if (l.hasCompleteData()) { return l; }
166 
167  // lenient search by assuming that a virtual airline is not annotated by "V"
168  // VHDU not found, but HDU
169  const CLiveryList liveries = this->findByAirlineIcaoDesignator(icao);
170  if (liveries.size() == 1) { return liveries.front(); }
171  if (liveries.size() > 1)
172  {
173  if (liveryPattern.hasAirlineName())
174  {
175  // reduce by name
176  const CLiveryList liveriesByName =
177  liveries.findStdLiveriesBySimplifiedAirlineName(liveryPattern.getAirlineName());
178  if (!liveriesByName.isEmpty()) { return liveriesByName.front(); }
179  }
180  return liveries.front();
181  }
182  }
183 
184  // lenient search by name contained (slow)
185  if (liveryPattern.getAirlineIcaoCode().hasName())
186  {
187  const QString search(liveryPattern.getAirlineIcaoCode().getSimplifiedName());
188  const CLiveryList liveries(this->findStdLiveriesByNamesOrTelephonyDesignator(search));
189  if (!liveries.isEmpty()) { return liveries.front(); }
190  }
191  return CLivery();
192  }
193 
195  const CAirlineIcaoCodeList &relatedAirlines)
196  {
197  AirlineIcaoIdMap airlineIcaos = relatedAirlines.toIdMap();
198 
199  CLiveryList models;
200  for (const QJsonValue &value : array)
201  {
202  models.push_back(CLivery::fromDatabaseJsonCaching(value.toObject(), airlineIcaos));
203  }
204  return models;
205  }
206 } // namespace swift::misc::aviation
auto findFirstByOrDefault(Predicate p, const Value &def) const
Return a copy of the first element for which a given predicate returns true, or a default value if th...
Definition: range.h:70
auto transform(F function) const
Return a new container generated by applying some transformation function to all elements of this one...
Definition: range.h:403
bool isValid() const
Valid?
Definition: rgbcolor.cpp:140
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
const_reference frontOrDefault() const
Access the first element, or a default-initialized value if the sequence is empty.
Definition: sequence.h:239
CSequence findBy(Predicate p) const
Return a copy containing only those elements for which a given predicate returns true.
Definition: sequence.h:398
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
reference front()
Access the first element.
Definition: sequence.h:225
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Value object for ICAO classification.
QString getSimplifiedName() const
Get a simplified upper case name for searching by removing all characters except A-Z.
bool hasValidDesignator() const
Airline designator available?
bool matchesVDesignator(const QString &designator) const
Matches v-designator string?
bool matchesNamesOrTelephonyDesignator(const QString &candidate) const
Relaxed check by name or telephony designator (aka callsign, not to be confused with CCallsign)
QString getVDesignator() const
Get airline, e.g. "DLH", but "VMVA" for virtual airlines.
const QString & getName() const
Get name, e.g. "Lufthansa".
bool hasName() const
Has (airline) name?
Value object encapsulating a list of ICAO codes.
AirlineIcaoIdMap toIdMap() const
To id map.
Value object encapsulating information about an airpot.
Definition: livery.h:29
const QString & getAirlineIcaoCodeDesignator() const
Corresponding airline designator, if any.
Definition: livery.h:68
bool hasAirlineName() const
Has airline name?
Definition: livery.cpp:159
double getColorDistance(const CLivery &otherLivery) const
Color distance 0..1 (0 is best)
Definition: livery.cpp:182
bool matchesCombinedCode(const QString &candidate) const
Matches combined code.
Definition: livery.cpp:101
const CAirlineIcaoCode & getAirlineIcaoCode() const
Corresponding airline, if any.
Definition: livery.h:65
QString getCombinedCodePlusInfoAndId() const
Combined code, info, plus id.
Definition: livery.cpp:71
static bool isValidCombinedCode(const QString &candidate)
Valid combined code string?
Definition: livery.cpp:282
bool hasValidAirlineDesignator() const
Airline available?
Definition: livery.cpp:157
const QString & getAirlineName() const
Get corresponding airline name.
Definition: livery.h:86
bool isAirlineOperating() const
Is airline operating?
Definition: livery.cpp:169
bool hasCompleteData() const
Complete data?
Definition: livery.cpp:126
bool isAirlineStandardLivery() const
Livery representing airline standard livery.
Definition: livery.cpp:174
const QString & getCombinedCode() const
Combined code.
Definition: livery.h:71
bool matchesColors(const CRgbColor &fuselage, const CRgbColor &tail) const
Matches colors.
Definition: livery.cpp:108
const QString & getDescription() const
Get description.
Definition: livery.h:83
static CLivery fromDatabaseJsonCaching(const QJsonObject &json, AirlineIcaoIdMap &airlineIcaos, const QString &prefix=QString("liv_"))
Object from JSON caching.
Definition: livery.cpp:235
bool isContainedInSimplifiedAirlineName(const QString &candidate) const
Does simplified airline name contain the candidate.
Definition: livery.cpp:76
bool hasCombinedCode() const
Livery combined code available?
Definition: livery.cpp:161
bool isColorLivery() const
Color livery?
Definition: livery.cpp:180
QString getCombinedCodePlusInfo() const
Combined code plus info.
Definition: livery.cpp:60
Value object for a list of airports.
Definition: liverylist.h:29
QStringList getCombinedCodesPlusInfo(bool sort=false) const
All combined codes plus more info.
Definition: liverylist.cpp:121
CLiveryList findStdLiveriesByNamesOrTelephonyDesignator(const QString &candidate) const
By names or telephony designator(aka callsign)
Definition: liverylist.cpp:68
CAirlineIcaoCodeList getAirlines() const
All aircraft codes.
Definition: liverylist.cpp:137
QStringList getCombinedCodes(bool sort=false) const
All combined codes.
Definition: liverylist.cpp:113
CLiveryList findByAirlineIcaoDesignator(const QString &icao) const
Find livery by airline.
Definition: liverylist.cpp:19
static CLiveryList fromDatabaseJsonCaching(const QJsonArray &array, const CAirlineIcaoCodeList &relatedAirlines={})
Caching version from DB data.
Definition: liverylist.cpp:194
CLivery smartLiverySelector(const CLivery &liveryPattern) const
Find by multiple criteria.
Definition: liverylist.cpp:144
CLivery findColorLiveryOrDefault(const CRgbColor &fuselage, const CRgbColor &tail) const
Search for colors.
Definition: liverylist.cpp:78
CLivery findClosestColorLiveryOrDefault(const CRgbColor &fuselage, const CRgbColor &tail) const
Search for colors.
Definition: liverylist.cpp:87
QStringList getCombinedCodesPlusInfoAndId(bool sort=false) const
All combined codes plus more info.
Definition: liverylist.cpp:129
CLivery findStdLiveryByAirlineIcaoVDesignator(const QString &icao) const
Find livery by airline.
Definition: liverylist.cpp:49
CLiveryList()
Default constructor.
Definition: liverylist.cpp:15
CLiveryList findStdLiveriesBySimplifiedAirlineName(const QString &containedString) const
By simplified name.
Definition: liverylist.cpp:59
CLivery findByCombinedCode(const QString &combinedCode) const
Find livery by combined code.
Definition: liverylist.cpp:106
bool isDbEqual(const IDatastoreObjectWithIntegerKey &other) const
Same DB key and hence equal.
Definition: datastore.h:105
bool hasValidDbKey() const
Has valid DB key.
Definition: datastore.h:102
auto MemberTransform(T memberFunc)
Returns a function object that returns the value returned by one of it's argument member functions.
Definition: predicates.h:54
#define SWIFT_DEFINE_SEQUENCE_MIXINS(Namespace, T, List)
Explicit template definition of mixins for a CSequence subclass.
Definition: sequence.h:63