Metar, slight style adjustments

This commit is contained in:
Klaus Basan
2019-12-27 13:19:07 +01:00
committed by Mat Sutcliffe
parent a924b5e78b
commit a6a787fdd7
5 changed files with 105 additions and 65 deletions

View File

@@ -136,11 +136,17 @@ namespace BlackCore
// some check for obvious errors // some check for obvious errors
if (line.contains("<html")) { continue; } if (line.contains("<html")) { continue; }
const CMetar metar = m_metarDecoder.decode(line); const CMetar metar = m_metarDecoder.decode(line);
if (metar != CMetar()) { metars.push_back(metar); } if (metar != CMetar())
else { invalidLines++; } {
metars.push_back(metar);
}
else
{
invalidLines++;
}
} }
CLogMessage(this).info(u"METARs: %1 Metars (invalid %2) from '%3'" )<< metars.size() << invalidLines << metarUrl; CLogMessage(this).info(u"METARs: %1 Metars (invalid %2) from '%3'") << metars.size() << invalidLines << metarUrl;
{ {
QWriteLocker l(&m_lock); QWriteLocker l(&m_lock);
m_metars = metars; m_metars = metars;

View File

@@ -48,7 +48,7 @@ namespace BlackMisc
void CMetar::setDayTime(int reportDay, const PhysicalQuantities::CTime &reportTime) void CMetar::setDayTime(int reportDay, const PhysicalQuantities::CTime &reportTime)
{ {
m_reportDay = reportDay; m_reportDay = reportDay;
m_reportTime = reportTime; m_reportTime = reportTime;
} }

View File

@@ -146,19 +146,19 @@ namespace BlackMisc
static CMetar CAVOK(); static CMetar CAVOK();
private: private:
QString m_metarMessage; QString m_metarMessage;
ReportType m_reportType = METAR; ReportType m_reportType = METAR;
Aviation::CAirportIcaoCode m_airport; Aviation::CAirportIcaoCode m_airport;
int m_reportDay = 0; int m_reportDay = 0;
PhysicalQuantities::CTime m_reportTime; PhysicalQuantities::CTime m_reportTime;
bool m_isAutomated = false; bool m_isAutomated = false;
CWindLayer m_windLayer; CWindLayer m_windLayer;
PhysicalQuantities::CLength m_visibility; PhysicalQuantities::CLength m_visibility;
CPresentWeatherList m_presentWeathers; CPresentWeatherList m_presentWeathers;
CCloudLayerList m_cloudLayers; CCloudLayerList m_cloudLayers;
PhysicalQuantities::CTemperature m_temperature; PhysicalQuantities::CTemperature m_temperature;
PhysicalQuantities::CTemperature m_dewPoint; PhysicalQuantities::CTemperature m_dewPoint;
PhysicalQuantities::CPressure m_altimeter; PhysicalQuantities::CPressure m_altimeter;
BLACK_METACLASS( BLACK_METACLASS(
CMetar, CMetar,

View File

@@ -8,7 +8,6 @@
//! \cond PRIVATE //! \cond PRIVATE
#include "blackmisc/aviation/airporticaocode.h" #include "blackmisc/aviation/airporticaocode.h"
#include "blackmisc/aviation/altitude.h" #include "blackmisc/aviation/altitude.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
@@ -48,15 +47,22 @@ namespace BlackMisc
class IMetarDecoderPart class IMetarDecoderPart
{ {
public: public:
virtual ~IMetarDecoderPart(); //! Destructor
protected: virtual ~IMetarDecoderPart() {}
virtual bool isRepeatable() const { return false; }
virtual const QRegularExpression &getRegExp() const = 0; //! Decoder type ("name")
virtual bool validateAndSet(const QRegularExpressionMatch &match, CMetar &metar) const = 0;
virtual bool isMandatory() const = 0;
virtual QString getDecoderType() const = 0; virtual QString getDecoderType() const = 0;
protected:
//! The regular expression used for parsing
virtual const QRegularExpression &getRegExp() const = 0;
virtual bool isRepeatable() const { return false; }
virtual bool validateAndSet(const QRegularExpressionMatch &match, CMetar &metar) const = 0;
virtual bool isMandatory() const = 0;
public: public:
//! Parse METAR string
bool parse(QString &metarString, CMetar &metar) bool parse(QString &metarString, CMetar &metar)
{ {
bool isValid = false; bool isValid = false;
@@ -71,7 +77,11 @@ namespace BlackMisc
if (match.hasMatch()) if (match.hasMatch())
{ {
// If invalid data, we return straight away // If invalid data, we return straight away
if (!validateAndSet(match, metar)) return false; if (!validateAndSet(match, metar))
{
return false;
}
// Remove the captured part // Remove the captured part
metarString.replace(re, QString()); metarString.replace(re, QString());
isValid = true; isValid = true;
@@ -87,17 +97,18 @@ namespace BlackMisc
if (!isValid) if (!isValid)
{ {
CLogMessage(static_cast<CMetarDecoder*>(nullptr)).debug() << "Failed to match" << getDecoderType() << "in remaining METAR:" << metarString; CLogMessage(static_cast<CMetarDecoder *>(nullptr)).debug() << "Failed to match" << getDecoderType() << "in remaining METAR:" << metarString;
} }
return isValid; return isValid;
} }
}; };
IMetarDecoderPart::~IMetarDecoderPart() //! METAR report type
{ }
class CMetarDecoderReportType : public IMetarDecoderPart class CMetarDecoderReportType : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "ReportType"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -115,7 +126,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "ReportType"; }
private: private:
const QHash<QString, CMetar::ReportType> &getReportTypeHash() const const QHash<QString, CMetar::ReportType> &getReportTypeHash() const
@@ -131,6 +141,9 @@ namespace BlackMisc
class CMetarDecoderAirport : public IMetarDecoderPart class CMetarDecoderAirport : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "Airport"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -147,41 +160,45 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return true; } virtual bool isMandatory() const override { return true; }
virtual QString getDecoderType() const override { return "Airport"; }
}; };
class CMetarDecoderDayTime : public IMetarDecoderPart class CMetarDecoderDayTime : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "DayTime"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
static const QRegularExpression re (QStringLiteral("^(?<day>\\d{2})(?<hour>\\d{2})(?<minute>\\d{2})Z ")); static const QRegularExpression re(QStringLiteral("^(?<day>\\d{2})(?<hour>\\d{2})(?<minute>\\d{2})Z "));
return re; return re;
} }
bool validateAndSet(const QRegularExpressionMatch &match, CMetar &metar) const override bool validateAndSet(const QRegularExpressionMatch &match, CMetar &metar) const override
{ {
bool ok = false; bool ok = false;
int day = match.captured("day").toInt(&ok); int day = match.captured("day").toInt(&ok);
int hour = match.captured("hour").toInt(&ok); int hour = match.captured("hour").toInt(&ok);
int minute = match.captured("minute").toInt(&ok); int minute = match.captured("minute").toInt(&ok);
if (!ok) return false; if (!ok) return false;
if (day < 1 || day > 31) return false; if (day < 1 || day > 31) return false;
if (hour < 0 || hour > 23) return false; if (hour < 0 || hour > 23) return false;
if (minute < 0 || minute > 59) return false; if (minute < 0 || minute > 59) return false;
BlackMisc::PhysicalQuantities::CTime time(hour, minute, 0); PhysicalQuantities::CTime time(hour, minute, 0);
metar.setDayTime(day, time); metar.setDayTime(day, time);
return true; return true;
} }
virtual bool isMandatory() const override { return true; } virtual bool isMandatory() const override { return true; }
virtual QString getDecoderType() const override { return "DayTime"; }
}; };
class CMetarDecoderStatus : public IMetarDecoderPart class CMetarDecoderStatus : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "Status"; }
protected: protected:
// Possible matches: // Possible matches:
// * (AUTO) - Automatic Station Indicator // * (AUTO) - Automatic Station Indicator
@@ -202,11 +219,13 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "Status"; }
}; };
class CMetarDecoderWind : public IMetarDecoderPart class CMetarDecoderWind : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "Wind"; }
protected: protected:
const QHash<QString, CSpeedUnit> &getWindUnitHash() const const QHash<QString, CSpeedUnit> &getWindUnitHash() const
{ {
@@ -265,7 +284,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "Wind"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -286,6 +304,9 @@ namespace BlackMisc
class CMetarDecoderVariationsWindDirection : public IMetarDecoderPart class CMetarDecoderVariationsWindDirection : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "WindDirection"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -313,7 +334,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "WindDirection"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -330,8 +350,10 @@ namespace BlackMisc
class CMetarDecoderVisibility : public IMetarDecoderPart class CMetarDecoderVisibility : public IMetarDecoderPart
{ {
protected: public:
virtual QString getDecoderType() const override { return "Visibility"; }
protected:
const QHash<QString, QString> &getCardinalDirections() const const QHash<QString, QString> &getCardinalDirections() const
{ {
static const QHash<QString, QString> hash = static const QHash<QString, QString> hash =
@@ -350,7 +372,6 @@ namespace BlackMisc
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
static const QRegularExpression re(getRegExpImpl()); static const QRegularExpression re(getRegExpImpl());
return re; return re;
} }
@@ -401,7 +422,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "Visibility"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -428,6 +448,9 @@ namespace BlackMisc
class CMetarDecoderRunwayVisualRange : public IMetarDecoderPart class CMetarDecoderRunwayVisualRange : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "RunwayVisualRange"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -448,14 +471,13 @@ namespace BlackMisc
CLengthUnit lengthUnit = CLengthUnit::m(); CLengthUnit lengthUnit = CLengthUnit::m();
if (match.captured("unit") == "FT") lengthUnit = CLengthUnit::ft(); if (match.captured("unit") == "FT") lengthUnit = CLengthUnit::ft();
// Ignore for now until we make use of it. // Ignore for now until we make use of it.
Q_UNUSED(metar); Q_UNUSED(metar)
Q_UNUSED(runwayVisibility); Q_UNUSED(runwayVisibility)
Q_UNUSED(lengthUnit); Q_UNUSED(lengthUnit)
return true; return true;
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "RunwayVisualRange"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -483,6 +505,9 @@ namespace BlackMisc
class CMetarDecoderPresentWeather : public IMetarDecoderPart class CMetarDecoderPresentWeather : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "PresentWeather"; }
protected: protected:
const QHash<QString, CPresentWeather::Intensity> &getIntensityHash() const const QHash<QString, CPresentWeather::Intensity> &getIntensityHash() const
{ {
@@ -573,7 +598,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "PresentWeather"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -599,6 +623,9 @@ namespace BlackMisc
class CMetarDecoderCloud : public IMetarDecoderPart class CMetarDecoderCloud : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "Cloud"; }
protected: protected:
const QStringList &getClearSkyTokens() const const QStringList &getClearSkyTokens() const
{ {
@@ -662,7 +689,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "Cloud"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -683,6 +709,9 @@ namespace BlackMisc
class CMetarDecoderVerticalVisibility : public IMetarDecoderPart class CMetarDecoderVerticalVisibility : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "VerticalVisibility"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -697,7 +726,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "VerticalVisibility"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -711,6 +739,9 @@ namespace BlackMisc
class CMetarDecoderTemperature : public IMetarDecoderPart class CMetarDecoderTemperature : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "Temperature"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -753,7 +784,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "Temperature"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -772,8 +802,10 @@ namespace BlackMisc
class CMetarDecoderPressure : public IMetarDecoderPart class CMetarDecoderPressure : public IMetarDecoderPart
{ {
protected: public:
virtual QString getDecoderType() const override { return "Pressure"; }
protected:
const QHash<QString, CPressureUnit> &getPressureUnits() const const QHash<QString, CPressureUnit> &getPressureUnits() const
{ {
static const QHash<QString, CPressureUnit> hash = static const QHash<QString, CPressureUnit> hash =
@@ -821,7 +853,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "Pressure"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -840,6 +871,9 @@ namespace BlackMisc
class CMetarDecoderRecentWeather : public IMetarDecoderPart class CMetarDecoderRecentWeather : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "RecentWeather"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -854,7 +888,6 @@ namespace BlackMisc
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "RecentWeather"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -872,14 +905,17 @@ namespace BlackMisc
} }
const QStringList m_descriptor = QStringList { "MI", "BC", "PR", "DR", "BL", "SH", "TS", "FZ" }; const QStringList m_descriptor = QStringList { "MI", "BC", "PR", "DR", "BL", "SH", "TS", "FZ" };
const QStringList m_phenomina = QStringList { "DZ", "RA", "SN", "SG", "IC", "PE", "GR", "GS", const QStringList m_phenomina = QStringList { "DZ", "RA", "SN", "SG", "IC", "PE", "GR", "GS",
"BR", "FG", "FU", "VA", "IC", "DU", "SA", "HZ", "BR", "FG", "FU", "VA", "IC", "DU", "SA", "HZ",
"PY", "PO", "SQ", "FC", "SS", "DS" "PY", "PO", "SQ", "FC", "SS", "DS"
}; };
}; };
class CMetarDecoderWindShear : public IMetarDecoderPart class CMetarDecoderWindShear : public IMetarDecoderPart
{ {
public:
virtual QString getDecoderType() const override { return "WindShear"; }
protected: protected:
const QRegularExpression &getRegExp() const override const QRegularExpression &getRegExp() const override
{ {
@@ -893,15 +929,14 @@ namespace BlackMisc
if (!runwayAsString.isEmpty()) if (!runwayAsString.isEmpty())
{ {
// Ignore for now until we make use of it. // Ignore for now until we make use of it.
Q_UNUSED(runwayAsString); Q_UNUSED(runwayAsString)
Q_UNUSED(metar); Q_UNUSED(metar)
} }
return true; return true;
} }
virtual bool isMandatory() const override { return false; } virtual bool isMandatory() const override { return false; }
virtual QString getDecoderType() const override { return "WindShear"; }
private: private:
QString getRegExpImpl() const QString getRegExpImpl() const
@@ -921,8 +956,7 @@ namespace BlackMisc
} }
CMetarDecoder::~CMetarDecoder() CMetarDecoder::~CMetarDecoder()
{ { }
}
CMetar CMetarDecoder::decode(const QString &metarString) const CMetar CMetarDecoder::decode(const QString &metarString) const
{ {
@@ -933,7 +967,8 @@ namespace BlackMisc
{ {
if (!decoder->parse(metarStringCopy, metar)) if (!decoder->parse(metarStringCopy, metar))
{ {
CLogMessage(this).debug() << "Invalid METAR:" << metarString; const QString type = decoder->getDecoderType();
CLogMessage(this).debug() << "Invalid METAR:" << metarString << type;
return CMetar(); return CMetar();
} }
} }

View File

@@ -23,7 +23,6 @@ namespace BlackMisc
{ {
namespace Weather namespace Weather
{ {
class IMetarDecoderPart; class IMetarDecoderPart;
//! Metar Decoder //! Metar Decoder
@@ -36,7 +35,7 @@ namespace BlackMisc
CMetarDecoder(); CMetarDecoder();
//! Default destructor //! Default destructor
~CMetarDecoder(); virtual ~CMetarDecoder() override;
//! Decode metar //! Decode metar
CMetar decode(const QString &metarString) const; CMetar decode(const QString &metarString) const;