[GFS] Move GFS structs out of CWeatherDataGfs

In the same step, change doubles to floats since this is what GFS provides.
This commit is contained in:
Roland Rossgotterer
2019-02-19 17:34:06 +01:00
committed by Mat Sutcliffe
parent 5b10abd63d
commit 220b271b34
2 changed files with 130 additions and 117 deletions

View File

@@ -30,6 +30,92 @@ namespace BlackWxPlugin
{ {
namespace Gfs namespace Gfs
{ {
//! \cond PRIVATE
enum Grib2CloudLevel
{
LowCloud,
MiddleCloud,
HighCloud
};
enum Grib2ParameterCode
{
UNKNOWN,
TMP,
RH,
UGRD,
VGRD,
PRATE,
PRES,
PRMSL,
TCDC,
CRAIN,
CSNOW
};
enum Grib2FixedSurfaceTypes
{
GroundOrWaterSurface = 1,
IsobaricSurface = 100,
MeanSeaLevel = 101,
LowCloudBottomLevel = 212,
LowCloudTopLevel = 213,
LowCloudLayer = 214,
MiddleCloudBottomLevel = 222,
MiddleCloudTopLevel = 223,
MiddleCloudLayer = 224,
HighCloudBottomLevel = 232,
HighCloudTopLevel = 233,
HighCloudLayer = 234
};
struct Grib2ParameterValue
{
Grib2ParameterValue() = default;
Grib2ParameterValue(Grib2ParameterCode code_, const QString &name_, const QString &unit_) : code(code_), name(name_), unit(unit_) {}
Grib2ParameterCode code = UNKNOWN;
QString name;
QString unit;
};
struct GfsIsobaricLayer
{
float temperature = 0.0;
float relativeHumidity = 0.0;
float windU = 0.0;
float windV = 0.0;
};
inline bool operator==(const GfsIsobaricLayer& lhs, const GfsIsobaricLayer& rhs)
{
return qFuzzyCompare(lhs.temperature, rhs.temperature) &&
qFuzzyCompare(lhs.relativeHumidity, rhs.relativeHumidity) &&
qFuzzyCompare(lhs.windU, rhs.windU) &&
qFuzzyCompare(lhs.windV, rhs.windV);
}
struct GfsCloudLayer
{
float bottomLevelPressure = 0.0;
float topLevelPressure = 0.0;
float totalCoverage = 0.0;
float topLevelTemperature = 0.0;
};
struct GfsGridPoint
{
float latitude = 0.0;
float longitude = 0.0;
int fieldPosition = 0;
QHash<int, GfsCloudLayer> cloudLayers;
QHash<float, GfsIsobaricLayer> isobaricLayers;
float surfaceRain = 0;
float surfaceSnow = 0;
float surfacePrecipitationRate = 0;
float pressureAtMsl = 0.0;
};
//! \endcond
const CWeatherDataGfs::Grib2ParameterTable CWeatherDataGfs::m_grib2ParameterTable const CWeatherDataGfs::Grib2ParameterTable CWeatherDataGfs::m_grib2ParameterTable
{ {
{ { {0, 0} }, { TMP, "Temperature", "K" } }, { { {0, 0} }, { TMP, "Temperature", "K" } },
@@ -45,7 +131,7 @@ namespace BlackWxPlugin
}; };
// https://physics.stackexchange.com/questions/333475/how-to-calculate-altitude-from-current-temperature-and-pressure // https://physics.stackexchange.com/questions/333475/how-to-calculate-altitude-from-current-temperature-and-pressure
double calculateAltitudeFt(double seaLevelPressurePa, double atmosphericPressurePa, double temperatureK) double calculateAltitudeFt(float seaLevelPressurePa, float atmosphericPressurePa, float temperatureK)
{ {
double altitude = (std::pow(seaLevelPressurePa / atmosphericPressurePa, 0.19022) - 1) * temperatureK * 3.28084 / 0.0065; double altitude = (std::pow(seaLevelPressurePa / atmosphericPressurePa, 0.19022) - 1) * temperatureK * 3.28084 / 0.0065;
return altitude; return altitude;
@@ -288,9 +374,9 @@ namespace BlackWxPlugin
CTemperatureLayerList temperatureLayers; CTemperatureLayerList temperatureLayers;
CWindLayerList windLayers; CWindLayerList windLayers;
for (const GfsIsobaricLayer &isobaricLayer : gfsGridPoint.isobaricLayers) for (const GfsIsobaricLayer &isobaricLayer : gfsGridPoint.isobaricLayers)
{ {
double level = gfsGridPoint.isobaricLayers.key(isobaricLayer); float level = gfsGridPoint.isobaricLayers.key(isobaricLayer);
double altitudeFt = calculateAltitudeFt(gfsGridPoint.pressureAtMsl, level, isobaricLayer.temperature); double altitudeFt = calculateAltitudeFt(gfsGridPoint.pressureAtMsl, level, isobaricLayer.temperature);
CAltitude altitude(altitudeFt, CAltitude::MeanSeaLevel, CLengthUnit::ft()); CAltitude altitude(altitudeFt, CAltitude::MeanSeaLevel, CLengthUnit::ft());
@@ -389,21 +475,21 @@ namespace BlackWxPlugin
int npnts = gfld->ngrdpts; int npnts = gfld->ngrdpts;
int nx = gfld->igdtmpl[7]; int nx = gfld->igdtmpl[7];
int ny = gfld->igdtmpl[8]; int ny = gfld->igdtmpl[8];
double units = 0.000001; float units = 0.000001f;
double latitude1 = gfld->igdtmpl[11] * units; float latitude1 = gfld->igdtmpl[11] * units;
double longitude1 = gfld->igdtmpl[12] * units; float longitude1 = gfld->igdtmpl[12] * units;
int nres = gfld->igdtmpl[13]; int nres = gfld->igdtmpl[13];
double latitude2 = gfld->igdtmpl[14] * units; float latitude2 = gfld->igdtmpl[14] * units;
double longitude2 = gfld->igdtmpl[15] * units; float longitude2 = gfld->igdtmpl[15] * units;
double dlatitude = gfld->igdtmpl[16] * units; float dlatitude = gfld->igdtmpl[16] * units;
double dlongitude = gfld->igdtmpl[17] * units; float dlongitude = gfld->igdtmpl[17] * units;
if (latitude1 < -90.0 || latitude2 < -90.0 || latitude1 > 90.0 || latitude2 > 90.0) if (latitude1 < -90.0f || latitude2 < -90.0f || latitude1 > 90.0f || latitude2 > 90.0f)
{ {
CLogMessage(this).warning(u"Invalid grid definition: lat1 = %1 - lat2 = %2") << latitude1 << latitude2; CLogMessage(this).warning(u"Invalid grid definition: lat1 = %1 - lat2 = %2") << latitude1 << latitude2;
return; return;
} }
if (longitude1 < 0.0 || longitude2 < 0.0 || longitude1 > 360.0 || longitude2 > 360.0) if (longitude1 < 0.0f || longitude2 < 0.0f || longitude1 > 360.0f || longitude2 > 360.0f)
{ {
CLogMessage(this).warning(u"Invalid grid definition: lon1 = %1 - lon2 = %2") << longitude1 << longitude2; CLogMessage(this).warning(u"Invalid grid definition: lon1 = %1 - lon2 = %2") << longitude1 << longitude2;
return; return;
@@ -415,8 +501,8 @@ namespace BlackWxPlugin
} }
// Scan direction is North -> South // Scan direction is North -> South
double north = latitude1; float north = latitude1;
double south = latitude2; float south = latitude2;
if (south > north) if (south > north)
{ {
@@ -424,13 +510,13 @@ namespace BlackWxPlugin
return; return;
} }
double dy = 0; float dy = 0.0f;
if (ny != 1) if (ny != 1)
{ {
dy = (north - south) / (ny - 1.0); dy = (north - south) / (ny - 1.0f);
if (nres & 16) if (nres & 16)
{ {
if (fabs(dy - dlatitude) > 0.001) if (fabs(dy - dlatitude) > 0.001f)
{ {
CLogMessage(this).warning(u"Invalid grid definition: delta latitude is inconsistent"); CLogMessage(this).warning(u"Invalid grid definition: delta latitude is inconsistent");
return; return;
@@ -443,24 +529,24 @@ namespace BlackWxPlugin
} }
// Scan direction is West -> East // Scan direction is West -> East
double west = longitude1; float west = longitude1;
double east = longitude2; float east = longitude2;
if (east <= west) { east += 360.0; } if (east <= west) { east += 360.0f; }
if (east - west > 360.0) { east -= 360.0; } if (east - west > 360.0f) { east -= 360.0f; }
if (west < 0) if (west < 0)
{ {
west += 360.0; west += 360.0f;
east += 360.0; east += 360.0f;
} }
double dx = 0; float dx = 0;
if (nx != 1) if (nx != 1)
{ {
dx = (east - west) / (nx - 1); dx = (east - west) / (nx - 1);
dx = fabs(dx); dx = fabs(dx);
if (nres & 32) if (nres & 32)
{ {
if (fabs(dx - fabs(dlongitude)) > 0.001) if (fabs(dx - fabs(dlongitude)) > 0.001f)
{ {
CLogMessage(this).warning(u"Invalid grid definition: delta longitude is inconsistent"); CLogMessage(this).warning(u"Invalid grid definition: delta longitude is inconsistent");
return; return;
@@ -483,8 +569,8 @@ namespace BlackWxPlugin
GfsGridPoint gridPoint; GfsGridPoint gridPoint;
gridPoint.latitude = latitude1 - iy * dy; gridPoint.latitude = latitude1 - iy * dy;
gridPoint.longitude = longitude1 + ix * dx; gridPoint.longitude = longitude1 + ix * dx;
if (gridPoint.longitude >= 360.0) { gridPoint.longitude -= 360.0; } if (gridPoint.longitude >= 360.0f) { gridPoint.longitude -= 360.0f; }
if (gridPoint.longitude < 0.0) { gridPoint.longitude += 360.0; } if (gridPoint.longitude < 0.0f) { gridPoint.longitude += 360.0f; }
gridPoint.fieldPosition = ix + i; gridPoint.fieldPosition = ix + i;
CCoordinateGeodetic gridPointPosition(gridPoint.latitude, gridPoint.longitude, 0); CCoordinateGeodetic gridPointPosition(gridPoint.latitude, gridPoint.longitude, 0);
if (m_maxRange == CLength()) if (m_maxRange == CLength())
@@ -531,7 +617,7 @@ namespace BlackWxPlugin
return; return;
} }
double level = 0.0; float level = 0.0;
switch(typeFirstFixedSurface) switch(typeFirstFixedSurface)
{ {
@@ -600,7 +686,7 @@ namespace BlackWxPlugin
} }
} }
void CWeatherDataGfs::setTemperature(const g2float *fld, double level) void CWeatherDataGfs::setTemperature(const g2float *fld, float level)
{ {
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
@@ -608,7 +694,7 @@ namespace BlackWxPlugin
} }
} }
void CWeatherDataGfs::setHumidity(const g2float *fld, double level) void CWeatherDataGfs::setHumidity(const g2float *fld, float level)
{ {
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
@@ -616,7 +702,7 @@ namespace BlackWxPlugin
} }
} }
void CWeatherDataGfs::setWindV(const g2float *fld, double level) void CWeatherDataGfs::setWindV(const g2float *fld, float level)
{ {
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
@@ -624,7 +710,7 @@ namespace BlackWxPlugin
} }
} }
void CWeatherDataGfs::setWindU(const g2float *fld, double level) void CWeatherDataGfs::setWindU(const g2float *fld, float level)
{ {
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
@@ -636,7 +722,7 @@ namespace BlackWxPlugin
{ {
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
if (fld[gridPoint.fieldPosition] > 0.0) { gridPoint.cloudLayers[level].totalCoverage = fld[gridPoint.fieldPosition]; } if (fld[gridPoint.fieldPosition] > 0.0f) { gridPoint.cloudLayers[level].totalCoverage = fld[gridPoint.fieldPosition]; }
} }
} }
@@ -645,7 +731,7 @@ namespace BlackWxPlugin
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
static const g2float minimumLayer = 0.0; static const g2float minimumLayer = 0.0;
double levelPressure = std::numeric_limits<double>::quiet_NaN(); float levelPressure = std::numeric_limits<float>::quiet_NaN();
g2float fieldValue = fld[gridPoint.fieldPosition]; g2float fieldValue = fld[gridPoint.fieldPosition];
// A value of 9.999e20 is undefined. Check that the pressure value is below // A value of 9.999e20 is undefined. Check that the pressure value is below
if (fieldValue < 9.998e20f) { levelPressure = fld[gridPoint.fieldPosition]; } if (fieldValue < 9.998e20f) { levelPressure = fld[gridPoint.fieldPosition]; }
@@ -672,7 +758,7 @@ namespace BlackWxPlugin
{ {
for (auto &gridPoint : m_gfsWeatherGrid) for (auto &gridPoint : m_gfsWeatherGrid)
{ {
double temperature = std::numeric_limits<double>::quiet_NaN(); float temperature = std::numeric_limits<float>::quiet_NaN();
g2float fieldValue = fld[gridPoint.fieldPosition]; g2float fieldValue = fld[gridPoint.fieldPosition];
if (fieldValue < 9.998e20f) { temperature = fld[gridPoint.fieldPosition]; } if (fieldValue < 9.998e20f) { temperature = fld[gridPoint.fieldPosition]; }
switch (surfaceType) switch (surfaceType)

View File

@@ -32,6 +32,10 @@ namespace BlackWxPlugin
{ {
namespace Gfs namespace Gfs
{ {
struct Grib2ParameterKey;
struct Grib2ParameterValue;
struct GfsGridPoint;
/*! /*!
* GFS implemenation * GFS implemenation
*/ */
@@ -44,7 +48,7 @@ namespace BlackWxPlugin
CWeatherDataGfs(QObject *parent = nullptr); CWeatherDataGfs(QObject *parent = nullptr);
//! Destructor //! Destructor
virtual ~CWeatherDataGfs(); virtual ~CWeatherDataGfs() override;
//! \copydoc BlackCore::IWeatherData::fetchWeatherData //! \copydoc BlackCore::IWeatherData::fetchWeatherData
virtual void fetchWeatherData(const BlackMisc::Weather::CWeatherGrid &grid, virtual void fetchWeatherData(const BlackMisc::Weather::CWeatherGrid &grid,
@@ -59,82 +63,6 @@ namespace BlackWxPlugin
virtual BlackMisc::Weather::CWeatherGrid getWeatherData() const override; virtual BlackMisc::Weather::CWeatherGrid getWeatherData() const override;
private: private:
enum Grib2CloudLevel
{
LowCloud,
MiddleCloud,
HighCloud
};
enum Grib2ParameterCode
{
UNKNOWN,
TMP,
RH,
UGRD,
VGRD,
PRATE,
PRES,
PRMSL,
TCDC,
CRAIN,
CSNOW
};
enum Grib2FixedSurfaceTypes
{
GroundOrWaterSurface = 1,
IsobaricSurface = 100,
MeanSeaLevel = 101,
LowCloudBottomLevel = 212,
LowCloudTopLevel = 213,
LowCloudLayer = 214,
MiddleCloudBottomLevel = 222,
MiddleCloudTopLevel = 223,
MiddleCloudLayer = 224,
HighCloudBottomLevel = 232,
HighCloudTopLevel = 233,
HighCloudLayer = 234
};
struct Grib2ParameterValue
{
Grib2ParameterValue() = default;
Grib2ParameterValue(Grib2ParameterCode code_, const QString &name_, const QString &unit_) : code(code_), name(name_), unit(unit_) {}
Grib2ParameterCode code = UNKNOWN;
QString name;
QString unit;
};
struct GfsIsobaricLayer
{
double temperature = 0.0;
double relativeHumidity = 0.0;
double windU = 0.0;
double windV = 0.0;
};
struct GfsCloudLayer
{
double bottomLevelPressure = 0.0;
double topLevelPressure = 0.0;
double totalCoverage = 0.0;
double topLevelTemperature = 0.0;
};
struct GfsGridPoint
{
double latitude = 0.0;
double longitude = 0.0;
int fieldPosition = 0;
QHash<int, GfsCloudLayer> cloudLayers;
QHash<double, GfsIsobaricLayer> isobaricLayers;
double surfaceRain = 0;
double surfaceSnow = 0;
double surfacePrecipitationRate = 0;
double pressureAtMsl = 0.0;
};
//! Asyncronous fetching finished //! Asyncronous fetching finished
//! \threadsafe //! \threadsafe
void fetchingWeatherDataFinished(); void fetchingWeatherDataFinished();
@@ -146,10 +74,10 @@ namespace BlackWxPlugin
void createWeatherGrid(const gribfield *gfld); void createWeatherGrid(const gribfield *gfld);
void handleProductDefinitionTemplate40(const gribfield *gfld); void handleProductDefinitionTemplate40(const gribfield *gfld);
void handleProductDefinitionTemplate48(const gribfield *gfld); void handleProductDefinitionTemplate48(const gribfield *gfld);
void setTemperature(const g2float *fld, double level); void setTemperature(const g2float *fld, float level);
void setHumidity(const g2float *fld, double level); void setHumidity(const g2float *fld, float level);
void setWindV(const g2float *fld, double level); void setWindV(const g2float *fld, float level);
void setWindU(const g2float *fld, double level); void setWindU(const g2float *fld, float level);
void setCloudCoverage(const g2float *fld, int level); void setCloudCoverage(const g2float *fld, int level);
void setCloudLevel(const g2float *fld, int surfaceType, int level); void setCloudLevel(const g2float *fld, int surfaceType, int level);
void setCloudTemperature(const g2float *fld, int surfaceType, int level); void setCloudTemperature(const g2float *fld, int surfaceType, int level);
@@ -186,7 +114,6 @@ namespace BlackWxPlugin
public: public:
//! \copydoc BlackCore::IWeatherDataFactory::create() //! \copydoc BlackCore::IWeatherDataFactory::create()
virtual BlackCore::IWeatherData *create(QObject *parent = nullptr) override; virtual BlackCore::IWeatherData *create(QObject *parent = nullptr) override;
}; };
} // ns } // ns