Ref T786, weather checks

* avoid NULL distances
* avoid incomplete requests
This commit is contained in:
Klaus Basan
2020-04-20 19:15:20 +02:00
committed by Mat Sutcliffe
parent 5ef25d4a41
commit 4af35e92c1
3 changed files with 63 additions and 15 deletions

View File

@@ -71,6 +71,17 @@ namespace BlackCore
void CWeatherManager::requestWeatherGrid(const CWeatherGrid &initialWeatherGrid, const CIdentifier &identifier) void CWeatherManager::requestWeatherGrid(const CWeatherGrid &initialWeatherGrid, const CIdentifier &identifier)
{ {
if (identifier.isNull() || initialWeatherGrid.isEmpty() || initialWeatherGrid.frontOrDefault().getPosition().isNull())
{
if (CBuildConfig::isLocalDeveloperDebugBuild())
{
BLACK_VERIFY_X(!identifier.isNull(), Q_FUNC_INFO, "Missing callback");
BLACK_VERIFY_X(!initialWeatherGrid.isEmpty(), Q_FUNC_INFO, "Empty grid, need position");
BLACK_VERIFY_X(!initialWeatherGrid.frontOrDefault().getPosition().isNull(), Q_FUNC_INFO, "NULL position");
}
return;
}
const WeatherRequest weatherRequest { {}, identifier, initialWeatherGrid, {} }; const WeatherRequest weatherRequest { {}, identifier, initialWeatherGrid, {} };
this->appendRequest(weatherRequest); this->appendRequest(weatherRequest);
@@ -80,9 +91,17 @@ namespace BlackCore
void CWeatherManager::requestWeatherGrid(const CWeatherGrid &initialWeatherGrid, void CWeatherManager::requestWeatherGrid(const CWeatherGrid &initialWeatherGrid,
const CSlot<void(const CWeatherGrid &)> &callback) const CSlot<void(const CWeatherGrid &)> &callback)
{
if (!callback || initialWeatherGrid.isEmpty() || initialWeatherGrid.frontOrDefault().getPosition().isNull())
{
if (CBuildConfig::isLocalDeveloperDebugBuild())
{ {
BLACK_VERIFY_X(callback, Q_FUNC_INFO, "Missing callback"); BLACK_VERIFY_X(callback, Q_FUNC_INFO, "Missing callback");
if (!callback) { return; } BLACK_VERIFY_X(!initialWeatherGrid.isEmpty(), Q_FUNC_INFO, "Empty grid, need position");
BLACK_VERIFY_X(!initialWeatherGrid.frontOrDefault().getPosition().isNull(), Q_FUNC_INFO, "NULL position");
}
return;
}
if (m_isWeatherClear) if (m_isWeatherClear)
{ {

View File

@@ -6,7 +6,7 @@ TARGET = weatherdatagfs
TEMPLATE = lib TEMPLATE = lib
CONFIG += plugin shared CONFIG += plugin shared
CONFIG += blackmisc blackcore CONFIG += blackmisc blackcore blackconfig
DEPENDPATH += . $$SourceRoot/src DEPENDPATH += . $$SourceRoot/src
INCLUDEPATH += . $$SourceRoot/src INCLUDEPATH += . $$SourceRoot/src

View File

@@ -8,10 +8,12 @@
#include "weatherdatagfs.h" #include "weatherdatagfs.h"
#include "blackcore/application.h" #include "blackcore/application.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/math/mathutils.h"
#include "blackmisc/geo/coordinategeodetic.h" #include "blackmisc/geo/coordinategeodetic.h"
#include "blackmisc/pq/temperature.h" #include "blackmisc/pq/temperature.h"
#include "blackmisc/math/mathutils.h"
#include "blackmisc/verify.h"
#include "blackmisc/logmessage.h"
#include "blackconfig/buildconfig.h"
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
@@ -19,6 +21,7 @@
#include <QStringBuilder> #include <QStringBuilder>
#include <cmath> #include <cmath>
using namespace BlackConfig;
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
using namespace BlackMisc::Geo; using namespace BlackMisc::Geo;
@@ -334,6 +337,9 @@ namespace BlackWxPlugin
m_gfsWeatherGrid.clear(); m_gfsWeatherGrid.clear();
m_weatherGrid.clear(); m_weatherGrid.clear();
// Messages should be 76. This is a combination
// of requested values (e.g. temperature, clouds etc) at specific layers (2 mbar, 10 mbar, surface).
constexpr int maxMessages = 76;
int messageNo = 0; int messageNo = 0;
g2int iseek = 0; g2int iseek = 0;
for (;;) for (;;)
@@ -384,9 +390,18 @@ namespace BlackWxPlugin
messageNo++; messageNo++;
} }
CLogMessage(this).debug() << "Parsed" << messageNo << "GRIB messages."; // validate
CLogMessage(this).debug() << "Obtained" << m_gfsWeatherGrid.size() << "grid points."; if (messageNo > maxMessages && CBuildConfig::isLocalDeveloperDebugBuild())
{
// as discussed this means a format change
BLACK_VERIFY_X(false, Q_FUNC_INFO, "Format change in GRIB, too many messages");
}
const int weatherGridPointsNo = m_gfsWeatherGrid.size();
CLogMessage(this).debug() << "Parsed" << messageNo << "GRIB messages.";
CLogMessage(this).debug() << "Obtained" << weatherGridPointsNo << "grid points.";
constexpr int maxPoints = 200;
for (const GfsGridPoint &gfsGridPoint : as_const(m_gfsWeatherGrid)) for (const GfsGridPoint &gfsGridPoint : as_const(m_gfsWeatherGrid))
{ {
if (QThread::currentThread()->isInterruptionRequested()) { return false; } if (QThread::currentThread()->isInterruptionRequested()) { return false; }
@@ -438,11 +453,19 @@ namespace BlackWxPlugin
auto pressureAtMsl = PhysicalQuantities::CPressure { gfsGridPoint.pressureAtMsl, PhysicalQuantities::CPressureUnit::Pa() }; auto pressureAtMsl = PhysicalQuantities::CPressure { gfsGridPoint.pressureAtMsl, PhysicalQuantities::CPressureUnit::Pa() };
CLatitude latitude(gfsGridPoint.latitude, CAngleUnit::deg()); const CLatitude latitude(gfsGridPoint.latitude, CAngleUnit::deg());
CLongitude longitude(gfsGridPoint.longitude, CAngleUnit::deg()); const CLongitude longitude(gfsGridPoint.longitude, CAngleUnit::deg());
auto position = CCoordinateGeodetic { latitude, longitude }; const auto position = CCoordinateGeodetic { latitude, longitude };
const CGridPoint gridPoint({}, position, cloudLayers, temperatureLayers, {}, windLayers, pressureAtMsl); const CGridPoint gridPoint({}, position, cloudLayers, temperatureLayers, {}, windLayers, pressureAtMsl);
m_weatherGrid.push_back(gridPoint); m_weatherGrid.push_back(gridPoint);
if (m_weatherGrid.size() >= maxPoints)
{
// too many points lead to extreme memory consumption and CPU usage
// we stop here, no use case so far in swift where we need that
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Too many grid points");
CLogMessage(this).warning(u"Too many weather grid points: %1") << m_weatherGrid.size();
break;
}
} }
return true; return true;
@@ -602,15 +625,21 @@ namespace BlackWxPlugin
{ {
for (const CGridPoint &fixedGridPoint : as_const(m_grid)) for (const CGridPoint &fixedGridPoint : as_const(m_grid))
{ {
const auto distance = calculateGreatCircleDistance(gridPointPosition, fixedGridPoint.getPosition()).value(CLengthUnit::m()); const CLength distance = calculateGreatCircleDistance(gridPointPosition, fixedGridPoint.getPosition());
const auto maxRange = m_maxRange.value(CLengthUnit::m()); if (distance.isNull())
if (distance < maxRange) {
BLACK_VERIFY_X(!CBuildConfig::isLocalDeveloperDebugBuild(), Q_FUNC_INFO, "Suspicious value, why is that?");
}
else
{
if (distance < m_maxRange)
{ {
m_gfsWeatherGrid.append(gridPoint); m_gfsWeatherGrid.append(gridPoint);
break; break;
} }
} }
} }
}
} // for } // for
} // for } // for
} // if } // if