From 1243d6e93a39c134aa89226ac9aaee2117c1195e Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 9 Sep 2018 02:34:58 +0200 Subject: [PATCH] Ref T323, better parsing of altitude values - assume "24000" also as FL - epsilon comparison - use 0-9 char functions - style --- src/blackcore/vatsim/networkvatlib.cpp | 48 +++++++++++++++++++------- src/blackmisc/aviation/altitude.cpp | 36 ++++++++++++------- src/blackmisc/aviation/altitude.h | 2 +- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/blackcore/vatsim/networkvatlib.cpp b/src/blackcore/vatsim/networkvatlib.cpp index cfe9f1aee..c4afd2804 100644 --- a/src/blackcore/vatsim/networkvatlib.cpp +++ b/src/blackcore/vatsim/networkvatlib.cpp @@ -1243,15 +1243,15 @@ namespace BlackCore void CNetworkVatlib::onInfoQueryRequestReceived(VatFsdClient *, const char *callsignString, VatClientQueryType type, const char *, void *cbvar) { - auto *self = cbvar_cast(cbvar); + QPointer self(cbvar_cast(cbvar)); const CCallsign callsign(self->fromFSD(callsignString)); switch (type) { case vatClientQueryFreq: - QTimer::singleShot(0, self, [ = ]() { self->replyToFrequencyQuery(callsign); }); + QTimer::singleShot(0, self, [ = ]() { if (self) self->replyToFrequencyQuery(callsign); }); break; case vatClientQueryName: - QTimer::singleShot(0, self, [ = ]() { self->replyToNameQuery(callsign); }); + QTimer::singleShot(0, self, [ = ]() { if (self) self->replyToNameQuery(callsign); }); break; default: break; @@ -1326,17 +1326,41 @@ namespace BlackCore } auto *self = cbvar_cast(cbvar); - QString cruiseAltString = self->fromFSD(fp->cruiseAltitude); - thread_local const QRegularExpression withUnit("\\D+"); - if (!cruiseAltString.isEmpty() && !withUnit.match(cruiseAltString).hasMatch()) + QString cruiseAltString = self->fromFSD(fp->cruiseAltitude).trimmed(); + if (!cruiseAltString.isEmpty() && is09OnlyString(cruiseAltString)) { - cruiseAltString += "ft"; + int ca = cruiseAltString.toInt(); + // we have a 0-9 only string + // we assume values like 24000 as FL + // RefT323, also major tool such as PFPX and Simbrief do so + if (rules == CFlightPlan::IFR) + { + if (ca >= 1000) + { + cruiseAltString = QStringLiteral("FL") % QString::number(ca / 100); + } + else + { + cruiseAltString = QStringLiteral("FL") % cruiseAltString; + } + } + else // VFR + { + if (ca >= 5000) + { + cruiseAltString = QStringLiteral("FL") % QString::number(ca / 100); + } + else + { + cruiseAltString = cruiseAltString % QStringLiteral("ft"); + } + } } CAltitude cruiseAlt; - cruiseAlt.parseFromString(cruiseAltString); + cruiseAlt.parseFromString(cruiseAltString, CPqString::SeparatorsBestGuess); const QString depTimePlanned = QString("0000").append(QString::number(fp->departTime)).right(4); - const QString depTimeActual = QString("0000").append(QString::number(fp->departTimeActual)).right(4); + const QString depTimeActual = QString("0000").append(QString::number(fp->departTimeActual)).right(4); const CCallsign callsign(self->fromFSD(callsignChar), CCallsign::Aircraft); const CFlightPlan flightPlan( @@ -1347,10 +1371,10 @@ namespace BlackCore self->fromFSD(fp->alternateAirport), fromStringUtc(depTimePlanned, "hhmm"), fromStringUtc(depTimeActual, "hhmm"), - CTime(fp->enrouteHrs * 60 + fp->enrouteMins, BlackMisc::PhysicalQuantities::CTimeUnit::min()), - CTime(fp->fuelHrs * 60 + fp->fuelMins, BlackMisc::PhysicalQuantities::CTimeUnit::min()), + CTime(fp->enrouteHrs * 60 + fp->enrouteMins, CTimeUnit::min()), + CTime(fp->fuelHrs * 60 + fp->fuelMins, CTimeUnit::min()), cruiseAlt, - CSpeed(fp->trueCruisingSpeed, BlackMisc::PhysicalQuantities::CSpeedUnit::kts()), + CSpeed(fp->trueCruisingSpeed, CSpeedUnit::kts()), rules, self->fromFSD(fp->route), self->fromFSD(fp->remarks) diff --git a/src/blackmisc/aviation/altitude.cpp b/src/blackmisc/aviation/altitude.cpp index 81363c88c..4800c1777 100644 --- a/src/blackmisc/aviation/altitude.cpp +++ b/src/blackmisc/aviation/altitude.cpp @@ -11,6 +11,7 @@ #include "blackmisc/pq/measurementunit.h" #include "blackmisc/pq/constants.h" #include "blackmisc/pq/pqstring.h" +#include "blackmisc/math/mathutils.h" #include "blackmisc/comparefunctions.h" #include "blackmisc/iconlist.h" #include "blackmisc/icons.h" @@ -20,6 +21,7 @@ #include using namespace BlackMisc::PhysicalQuantities; +using namespace BlackMisc::Math; namespace BlackMisc { @@ -73,7 +75,7 @@ namespace BlackMisc static const QString n("null"); if (this->isNull()) { return n; } - if (this->m_datum == FlightLevel) + if (m_datum == FlightLevel) { static const QString fls("FL%1"); const int fl = qRound(this->CLength::value(CLengthUnit::ft()) / 100.0); @@ -88,14 +90,14 @@ namespace BlackMisc void CAltitude::toFlightLevel() { - Q_ASSERT(this->m_datum == MeanSeaLevel || this->m_datum == FlightLevel); - this->m_datum = FlightLevel; + Q_ASSERT(m_datum == MeanSeaLevel || m_datum == FlightLevel); + m_datum = FlightLevel; } void CAltitude::toMeanSeaLevel() { - Q_ASSERT(this->m_datum == MeanSeaLevel || this->m_datum == FlightLevel); - this->m_datum = MeanSeaLevel; + Q_ASSERT(m_datum == MeanSeaLevel || m_datum == FlightLevel); + m_datum = MeanSeaLevel; } void CAltitude::convertToPressureAltitude(const CPressure &seaLevelPressure) @@ -129,13 +131,23 @@ namespace BlackMisc QString v = value.trimmed(); // special case FL - if (v.contains("FL", Qt::CaseInsensitive)) + if (v.contains("FL", Qt::CaseInsensitive) || v.startsWith("F")) { - v = v.replace("FL", "", Qt::CaseInsensitive).trimmed(); + v = char09OnlyString(value); bool ok = false; - double dv = v.toDouble(&ok) * 100.0; - const CAltitude a(ok ? dv : 0.0, FlightLevel, - ok ? CLengthUnit::ft() : nullptr); + const int dv = v.toInt(&ok) * 100; + const CAltitude a(ok ? dv : 0.0, FlightLevel, ok ? CLengthUnit::ft() : nullptr); + *this = a; + return; + } + + // special case A (altitude + if (v.contains("ALT", Qt::CaseInsensitive) || v.startsWith("A")) + { + v = char09OnlyString(value); + bool ok = false; + const int dv = v.toInt(&ok) * 100; + const CAltitude a(ok ? dv : 0.0, MeanSeaLevel, ok ? CLengthUnit::ft() : nullptr); *this = a; return; } @@ -282,7 +294,7 @@ namespace BlackMisc if (msgs) { msgs->push_back(CStatusMessage(this).validationError("FL range is 10-999")); } return false; } - if (fmod(flInt, 5) != 0) + if (!CMathUtils::epsilonZero(fmod(flInt, 5))) { if (msgs) { msgs->push_back(CStatusMessage(this).validationError("FL needs to end with 0 or 5")); } return false; @@ -295,8 +307,6 @@ namespace BlackMisc QString CAltitude::asFpAltitudeString() const { if (this->isNull()) { return QStringLiteral(""); } - - if (this->isFlightLevel()) { if (this->getUnit() == CLengthUnit::m()) diff --git a/src/blackmisc/aviation/altitude.h b/src/blackmisc/aviation/altitude.h index 02de8d8c7..ea18edd52 100644 --- a/src/blackmisc/aviation/altitude.h +++ b/src/blackmisc/aviation/altitude.h @@ -101,7 +101,7 @@ namespace BlackMisc } //! Altitude as string - CAltitude(const QString &altitudeAsString, PhysicalQuantities::CPqString::SeparatorMode mode = PhysicalQuantities::CPqString::SeparatorsLocale); + CAltitude(const QString &altitudeAsString, PhysicalQuantities::CPqString::SeparatorMode mode = PhysicalQuantities::CPqString::SeparatorsBestGuess); //! Constructor by CLength CAltitude(const PhysicalQuantities::CLength &altitude, ReferenceDatum datum) : CLength(altitude), m_datum(datum) {}