Extend GFS data and CGridPoint with surface pressure and temperature

This commit is contained in:
Roland Winklmeier
2016-03-28 21:09:01 +02:00
parent 9c869a16df
commit 5801962a99
6 changed files with 88 additions and 25 deletions

View File

@@ -32,33 +32,40 @@ void CWeatherDataPrinter::ps_printWeatherData(const BlackMisc::Weather::CWeather
{ {
qtout << "Latitude:" << gridPoint.getPosition().latitude().toQString() << endl; qtout << "Latitude:" << gridPoint.getPosition().latitude().toQString() << endl;
qtout << "Longitude:" << gridPoint.getPosition().longitude().toQString() << endl; qtout << "Longitude:" << gridPoint.getPosition().longitude().toQString() << endl;
qtout << " Surface Pressure: " << gridPoint.getSurfacePressure().toQString() << endl;
CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers(); CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers();
temperatureLayers.sort([](const CTemperatureLayer &a, const CTemperatureLayer &b) { return a.getLevel() < b.getLevel(); }); temperatureLayers.sort([](const CTemperatureLayer &a, const CTemperatureLayer &b) { return a.getLevel() < b.getLevel(); });
CWindLayerList windLayers = gridPoint.getWindLayers(); qtout << " Temperature Layers: " << endl;
windLayers.sort([](const CWindLayer &a, const CWindLayer &b) { return a.getLevel() < b.getLevel(); }); for (const auto &temperatureLayer : as_const(temperatureLayers))
if (temperatureLayers.size() != windLayers.size()) { continue; }
for (int i = 0; i < temperatureLayers.size(); i++)
{ {
const CTemperatureLayer temperatureLayer = temperatureLayers[i]; qtout << " Level: " << temperatureLayer.getLevel().toQString() << endl;
const CWindLayer windLayer = windLayers[i]; qtout << " Temperature: " << temperatureLayer.getTemperature().toQString() << endl;
qtout << " Level: " << temperatureLayer.getLevel().toQString() << endl; qtout << " Relative Humidity: " << temperatureLayer.getRelativeHumidity() << " %" << endl;
qtout << " Temperature: " << temperatureLayer.getTemperature().toQString() << endl;
qtout << " Relative Humidity: " << temperatureLayer.getRelativeHumidity() << " %" << endl;
qtout << " Wind: " << windLayer.getDirection().toQString() << " at " << windLayer.getSpeed().toQString() << endl;
} }
qtout << endl; qtout << endl;
qtout << " Clouds: " << endl; CWindLayerList windLayers = gridPoint.getWindLayers();
windLayers.sort([](const CWindLayer &a, const CWindLayer &b) { return a.getLevel() < b.getLevel(); });
qtout << " Wind Layers: " << endl;
for (const auto &windLayer : as_const(windLayers))
{
qtout << " Level: " << windLayer.getLevel().toQString() << endl;
qtout << " Wind: " << windLayer.getDirection().toQString() << " at " << windLayer.getSpeed().toQString() << endl;
}
qtout << endl;
qtout << " Cloud Layers: " << endl;
CCloudLayerList cloudLayers = gridPoint.getCloudLayers(); CCloudLayerList cloudLayers = gridPoint.getCloudLayers();
cloudLayers.sort([](const CCloudLayer &a, const CCloudLayer &b) { return a.getBase() < b.getBase(); }); cloudLayers.sort([](const CCloudLayer &a, const CCloudLayer &b) { return a.getBase() < b.getBase(); });
for (int i = 0; i < cloudLayers.size(); i++) for (int i = 0; i < cloudLayers.size(); i++)
{ {
const CCloudLayer &cloudLayer = cloudLayers[i]; const CCloudLayer &cloudLayer = cloudLayers[i];
qtout << " Top: " << cloudLayer.getTop().toQString() << endl; qtout << " Top: " << cloudLayer.getTop().toQString() << endl;
qtout << " Coverage: " << cloudLayer.getCoveragePercent() << " %" << endl;
qtout << " Precipitation type: " << cloudLayer.getPrecipitation() << endl;
qtout << " Precipitation rate: " << cloudLayer.getPrecipitationRate() << endl;
qtout << " Base: " << cloudLayer.getBase().toQString() << endl; qtout << " Base: " << cloudLayer.getBase().toQString() << endl;
qtout << " Coverage: " << cloudLayer.getCoveragePercent() << " %" << endl;
} }
qtout << endl << endl; qtout << endl << endl;
} }

View File

@@ -30,13 +30,15 @@ namespace BlackMisc
const CCloudLayerList &cloudLayers, const CCloudLayerList &cloudLayers,
const CTemperatureLayerList &temperatureLayers, const CTemperatureLayerList &temperatureLayers,
const CVisibilityLayerList &visibilityLayers, const CVisibilityLayerList &visibilityLayers,
const CWindLayerList &windLayers) : const CWindLayerList &windLayers,
const CPressure &surfacePressure) :
m_identifier(identifier), m_identifier(identifier),
m_position(position), m_position(position),
m_cloudLayers(cloudLayers), m_cloudLayers(cloudLayers),
m_temperatureLayers(temperatureLayers), m_temperatureLayers(temperatureLayers),
m_visibilityLayers(visibilityLayers), m_visibilityLayers(visibilityLayers),
m_windLayers(windLayers) m_windLayers(windLayers),
m_surfacePressure(surfacePressure)
{ } { }
void CGridPoint::copyWeatherDataFrom(const CGridPoint &other) void CGridPoint::copyWeatherDataFrom(const CGridPoint &other)
@@ -45,6 +47,7 @@ namespace BlackMisc
setTemperatureLayers(other.getTemperatureLayers()); setTemperatureLayers(other.getTemperatureLayers());
setVisibilityLayers(other.getVisibilityLayers()); setVisibilityLayers(other.getVisibilityLayers());
setWindLayers(other.getWindLayers()); setWindLayers(other.getWindLayers());
setSurfacePressure(other.getSurfacePressure());
} }
CVariant CGridPoint::propertyByIndex(const BlackMisc::CPropertyIndex &index) const CVariant CGridPoint::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
@@ -63,6 +66,8 @@ namespace BlackMisc
return CVariant::fromValue(m_temperatureLayers); return CVariant::fromValue(m_temperatureLayers);
case IndexWindLayers: case IndexWindLayers:
return CVariant::fromValue(m_windLayers); return CVariant::fromValue(m_windLayers);
case IndexSurfacePressure:
return CVariant::fromValue(m_surfacePressure);
default: default:
return CValueObject::propertyByIndex(index); return CValueObject::propertyByIndex(index);
} }
@@ -80,7 +85,6 @@ namespace BlackMisc
case IndexPosition: case IndexPosition:
setPosition(variant.value<CCoordinateGeodetic>()); setPosition(variant.value<CCoordinateGeodetic>());
break; break;
break;
case IndexCloudLayers: case IndexCloudLayers:
setCloudLayers(variant.value<CCloudLayerList>()); setCloudLayers(variant.value<CCloudLayerList>());
break; break;
@@ -90,6 +94,9 @@ namespace BlackMisc
case IndexWindLayers: case IndexWindLayers:
setWindLayers(variant.value<CWindLayerList>()); setWindLayers(variant.value<CWindLayerList>());
break; break;
case IndexSurfacePressure:
setSurfacePressure(variant.value<CPressure>());
break;
default: default:
CValueObject::setPropertyByIndex(variant, index); CValueObject::setPropertyByIndex(variant, index);
break; break;

View File

@@ -20,6 +20,7 @@
#include "blackmisc/weather/temperaturelayerlist.h" #include "blackmisc/weather/temperaturelayerlist.h"
#include "blackmisc/weather/visibilitylayerlist.h" #include "blackmisc/weather/visibilitylayerlist.h"
#include "blackmisc/weather/windlayerlist.h" #include "blackmisc/weather/windlayerlist.h"
#include "blackmisc/pq/pressure.h"
namespace BlackMisc namespace BlackMisc
{ {
@@ -38,7 +39,8 @@ namespace BlackMisc
IndexPosition, IndexPosition,
IndexCloudLayers, IndexCloudLayers,
IndexTemperatureLayers, IndexTemperatureLayers,
IndexWindLayers IndexWindLayers,
IndexSurfacePressure
}; };
//! Default constructor. //! Default constructor.
@@ -54,7 +56,8 @@ namespace BlackMisc
const CCloudLayerList &cloudLayers, const CCloudLayerList &cloudLayers,
const CTemperatureLayerList &temperatureLayers, const CTemperatureLayerList &temperatureLayers,
const CVisibilityLayerList &visibilityLayers, const CVisibilityLayerList &visibilityLayers,
const CWindLayerList &windLayers); const CWindLayerList &windLayers,
const PhysicalQuantities::CPressure &surfacePressure);
//! Set identifier //! Set identifier
void setIdentifier(const QString &identifier) { m_identifier = identifier; } void setIdentifier(const QString &identifier) { m_identifier = identifier; }
@@ -95,6 +98,12 @@ namespace BlackMisc
//! Copies all weather data from other without modifying identifier and position. //! Copies all weather data from other without modifying identifier and position.
void copyWeatherDataFrom(const CGridPoint &other); void copyWeatherDataFrom(const CGridPoint &other);
//! Set surface pressure
void setSurfacePressure(const PhysicalQuantities::CPressure &pressure) { m_surfacePressure = pressure; }
//! Get surface pressure
PhysicalQuantities::CPressure getSurfacePressure() const { return m_surfacePressure; }
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex //! \copydoc BlackMisc::Mixin::Index::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
@@ -112,6 +121,7 @@ namespace BlackMisc
CTemperatureLayerList m_temperatureLayers; CTemperatureLayerList m_temperatureLayers;
CVisibilityLayerList m_visibilityLayers; CVisibilityLayerList m_visibilityLayers;
CWindLayerList m_windLayers; CWindLayerList m_windLayers;
PhysicalQuantities::CPressure m_surfacePressure = { 1013.25, PhysicalQuantities::CPressureUnit::hPa() };
BLACK_METACLASS( BLACK_METACLASS(
CGridPoint, CGridPoint,
@@ -120,7 +130,8 @@ namespace BlackMisc
BLACK_METAMEMBER(cloudLayers), BLACK_METAMEMBER(cloudLayers),
BLACK_METAMEMBER(temperatureLayers), BLACK_METAMEMBER(temperatureLayers),
BLACK_METAMEMBER(visibilityLayers), BLACK_METAMEMBER(visibilityLayers),
BLACK_METAMEMBER(windLayers) BLACK_METAMEMBER(windLayers),
BLACK_METAMEMBER(surfacePressure)
); );
}; };
} // namespace } // namespace

View File

@@ -72,7 +72,8 @@ namespace BlackMisc
CCloudLayerList { cloudLayer }, CCloudLayerList { cloudLayer },
CTemperatureLayerList { temperatureLayer }, CTemperatureLayerList { temperatureLayer },
CVisibilityLayerList { visibilityLayer } , CVisibilityLayerList { visibilityLayer } ,
CWindLayerList { windLayer } CWindLayerList { windLayer },
{ 1013.25, PhysicalQuantities::CPressureUnit::hPa() }
}; };
static const CWeatherGrid weatherGrid = { gridPointGLOB }; static const CWeatherGrid weatherGrid = { gridPointGLOB };
@@ -123,7 +124,8 @@ namespace BlackMisc
CCloudLayerList { cloudLayer1, cloudLayer2 }, CCloudLayerList { cloudLayer1, cloudLayer2 },
CTemperatureLayerList { temperatureLayer }, CTemperatureLayerList { temperatureLayer },
CVisibilityLayerList { visibilityLayer }, CVisibilityLayerList { visibilityLayer },
CWindLayerList { windLayer1, windLayer2 } CWindLayerList { windLayer1, windLayer2 },
{ 1013.25, PhysicalQuantities::CPressureUnit::hPa() }
}; };
static const CWeatherGrid weatherGrid({ gridPointGLOB }); static const CWeatherGrid weatherGrid({ gridPointGLOB });

View File

@@ -245,6 +245,11 @@ namespace BlackWxPlugin
for (const GfsGridPoint &gfsGridPoint : m_gfsWeatherGrid) for (const GfsGridPoint &gfsGridPoint : m_gfsWeatherGrid)
{ {
CTemperatureLayerList temperatureLayers; CTemperatureLayerList temperatureLayers;
CAltitude surfaceAltitude (0, CAltitude::AboveGround, CLengthUnit::defaultUnit());
CTemperatureLayer surfaceTemperature(surfaceAltitude, CTemperature(gfsGridPoint.surfaceTemperature, CTemperatureUnit::K()), {}, {});
temperatureLayers.insert(surfaceTemperature);
CWindLayerList windLayers; CWindLayerList windLayers;
for (auto isobaricLayerIt = gfsGridPoint.isobaricLayers.begin(); isobaricLayerIt != gfsGridPoint.isobaricLayers.end(); ++isobaricLayerIt) for (auto isobaricLayerIt = gfsGridPoint.isobaricLayers.begin(); isobaricLayerIt != gfsGridPoint.isobaricLayers.end(); ++isobaricLayerIt)
{ {
@@ -283,10 +288,12 @@ namespace BlackWxPlugin
cloudLayers.insert(cloudLayer); cloudLayers.insert(cloudLayer);
} }
auto surfacePressure = PhysicalQuantities::CPressure { gfsGridPoint.surfacePressure, PhysicalQuantities::CPressureUnit::Pa() };
CLatitude latitude(gfsGridPoint.latitude, CAngleUnit::deg()); CLatitude latitude(gfsGridPoint.latitude, CAngleUnit::deg());
CLongitude longitude(gfsGridPoint.longitude, CAngleUnit::deg()); CLongitude longitude(gfsGridPoint.longitude, CAngleUnit::deg());
auto position = CCoordinateGeodetic { latitude, longitude, {0} }; auto position = CCoordinateGeodetic { latitude, longitude, {0} };
BlackMisc::Weather::CGridPoint gridPoint(position, cloudLayers, temperatureLayers, {}, windLayers); BlackMisc::Weather::CGridPoint gridPoint({}, position, cloudLayers, temperatureLayers, {}, windLayers, surfacePressure);
m_weatherGrid.insert(gridPoint); m_weatherGrid.insert(gridPoint);
} }
} }
@@ -467,8 +474,10 @@ namespace BlackWxPlugin
return; return;
} }
// http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_temp4-0.shtml
g2int parameterCategory = gfld->ipdtmpl[0]; g2int parameterCategory = gfld->ipdtmpl[0];
g2int parameterNumber = gfld->ipdtmpl[1]; g2int parameterNumber = gfld->ipdtmpl[1];
g2int typeFirstFixedSurface = gfld->ipdtmpl[9];
g2int valueFirstFixedSurface = gfld->ipdtmpl[11]; g2int valueFirstFixedSurface = gfld->ipdtmpl[11];
std::array<g2int, 2> key { { parameterCategory, parameterNumber } }; std::array<g2int, 2> key { { parameterCategory, parameterNumber } };
@@ -479,9 +488,21 @@ namespace BlackWxPlugin
return; return;
} }
double level = std::round(millibarToLevel(valueFirstFixedSurface)); double level = 0;
auto parameterValue = m_grib2ParameterTable[key]; switch (typeFirstFixedSurface)
{
case GroundOrWaterSurface:
level = 0;
break;
case IsobaricSurface:
level = std::round(millibarToLevel(valueFirstFixedSurface));
break;
default:
CLogMessage(this).warning("Unexpected first fixed surface type: %1") << typeFirstFixedSurface;
return;
}
auto parameterValue = m_grib2ParameterTable[key];
switch (parameterValue.code) switch (parameterValue.code)
{ {
case TMP: case TMP:
@@ -499,6 +520,7 @@ namespace BlackWxPlugin
case PRMSL: case PRMSL:
break; break;
case PRES: case PRES:
setCloudPressure(gfld->fld, level);
break; break;
default: default:
Q_ASSERT(false); Q_ASSERT(false);
@@ -563,7 +585,8 @@ namespace BlackWxPlugin
{ {
for (auto gridPointIt = m_gfsWeatherGrid.begin(); gridPointIt < m_gfsWeatherGrid.end(); ++gridPointIt) for (auto gridPointIt = m_gfsWeatherGrid.begin(); gridPointIt < m_gfsWeatherGrid.end(); ++gridPointIt)
{ {
gridPointIt->isobaricLayers[level].temperature = fld[gridPointIt->fieldPosition]; if (level > 0) { gridPointIt->isobaricLayers[level].temperature = fld[gridPointIt->fieldPosition]; }
else { gridPointIt->surfaceTemperature = fld[gridPointIt->fieldPosition]; }
} }
} }
@@ -623,6 +646,15 @@ namespace BlackWxPlugin
} }
} }
void CWeatherDataGfs::setCloudPressure(const g2float *fld, double level)
{
for (auto gridPointIt = m_gfsWeatherGrid.begin(); gridPointIt < m_gfsWeatherGrid.end(); ++gridPointIt)
{
if (level > 0) { /* todo */ }
else { gridPointIt->surfacePressure = fld[gridPointIt->fieldPosition]; }
}
}
void CWeatherDataGfs::setSurfaceRain(const g2float *fld) void CWeatherDataGfs::setSurfaceRain(const g2float *fld)
{ {
for (auto gridPointIt = m_gfsWeatherGrid.begin(); gridPointIt < m_gfsWeatherGrid.end(); ++gridPointIt) for (auto gridPointIt = m_gfsWeatherGrid.begin(); gridPointIt < m_gfsWeatherGrid.end(); ++gridPointIt)

View File

@@ -78,6 +78,7 @@ namespace BlackWxPlugin
enum Grib2FixedSurfaceTypes enum Grib2FixedSurfaceTypes
{ {
GroundOrWaterSurface = 1,
IsobaricSurface = 100, IsobaricSurface = 100,
LowCloudBottomLevel = 212, LowCloudBottomLevel = 212,
LowCloudTopLevel = 213, LowCloudTopLevel = 213,
@@ -123,6 +124,8 @@ namespace BlackWxPlugin
QHash<double, GfsIsobaricLayer> isobaricLayers; QHash<double, GfsIsobaricLayer> isobaricLayers;
double surfaceRainRate = 0; double surfaceRainRate = 0;
double surfaceSnowRate = 0; double surfaceSnowRate = 0;
double surfacePressure = 0;
double surfaceTemperature = 0;
}; };
QUrl getDownloadUrl() const; QUrl getDownloadUrl() const;
@@ -138,6 +141,7 @@ namespace BlackWxPlugin
void setWindU(const g2float *fld, double level); void setWindU(const g2float *fld, double 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 setCloudPressure(const g2float *fld, double level);
void setSurfaceRain(const g2float *fld); void setSurfaceRain(const g2float *fld);
void setSurfaceSnow(const g2float *fld); void setSurfaceSnow(const g2float *fld);