Allow selection of different level 2 products

This commit is contained in:
Dan Paulat 2021-11-05 22:58:53 -05:00
parent 7c606b85ff
commit 951710dcfe
9 changed files with 174 additions and 60 deletions

View file

@ -18,8 +18,22 @@ namespace main
static const std::string logPrefix_ = "[scwx::qt::main::main_window] "; static const std::string logPrefix_ = "[scwx::qt::main::main_window] ";
class MainWindowImpl
{
public:
explicit MainWindowImpl(MainWindow* mainWindow) : mainWindow_(mainWindow) {}
~MainWindowImpl() = default;
void SelectRadarProduct(common::Level2Product product);
MainWindow* mainWindow_;
map::MapWidget* map_;
};
MainWindow::MainWindow(QWidget* parent) : MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent), ui(new Ui::MainWindow) QMainWindow(parent),
p(std::make_unique<MainWindowImpl>(this)),
ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -27,7 +41,9 @@ MainWindow::MainWindow(QWidget* parent) :
settings.setCacheDatabasePath("/tmp/mbgl-cache.db"); settings.setCacheDatabasePath("/tmp/mbgl-cache.db");
settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024); settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024);
ui->centralwidget->layout()->addWidget(new map::MapWidget(settings)); p->map_ = new map::MapWidget(settings);
ui->centralwidget->layout()->addWidget(p->map_);
// Add Level 2 Products // Add Level 2 Products
QLayout* level2Layout = new ui::FlowLayout(); QLayout* level2Layout = new ui::FlowLayout();
@ -41,6 +57,10 @@ MainWindow::MainWindow(QWidget* parent) :
toolButton->setStatusTip( toolButton->setStatusTip(
tr(common::GetLevel2Description(product).c_str())); tr(common::GetLevel2Description(product).c_str()));
level2Layout->addWidget(toolButton); level2Layout->addWidget(toolButton);
connect(toolButton, &QToolButton::clicked, this, [=]() {
p->SelectRadarProduct(product);
});
} }
} }
@ -76,6 +96,31 @@ void MainWindow::showEvent(QShowEvent* event)
resizeDocks({ui->radarToolboxDock}, {150}, Qt::Horizontal); resizeDocks({ui->radarToolboxDock}, {150}, Qt::Horizontal);
} }
void MainWindowImpl::SelectRadarProduct(common::Level2Product product)
{
const std::string& productName = common::GetLevel2Name(product);
BOOST_LOG_TRIVIAL(debug)
<< logPrefix_ << "Selecting Level 2 radar product: " << productName;
for (QToolButton* toolButton :
mainWindow_->ui->level2Products->findChildren<QToolButton*>())
{
if (toolButton->text().toStdString() == productName)
{
toolButton->setCheckable(true);
toolButton->setChecked(true);
}
else
{
toolButton->setChecked(false);
toolButton->setCheckable(false);
}
}
map_->SelectRadarProduct(product);
}
} // namespace main } // namespace main
} // namespace qt } // namespace qt
} // namespace scwx } // namespace scwx

View file

@ -20,6 +20,8 @@ class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
friend class MainWindowImpl;
public: public:
MainWindow(QWidget* parent = nullptr); MainWindow(QWidget* parent = nullptr);
~MainWindow(); ~MainWindow();
@ -27,6 +29,7 @@ public:
void showEvent(QShowEvent* event) override; void showEvent(QShowEvent* event) override;
private: private:
std::unique_ptr<MainWindowImpl> p;
Ui::MainWindow* ui; Ui::MainWindow* ui;
}; };

View file

@ -44,6 +44,9 @@ public:
settings_(settings), settings_(settings),
map_(), map_(),
radarProductManager_ {std::make_shared<manager::RadarProductManager>()}, radarProductManager_ {std::make_shared<manager::RadarProductManager>()},
radarProductLayer_ {nullptr},
radarProductView_ {nullptr},
overlayLayer_ {nullptr},
lastPos_(), lastPos_(),
frameDraws_(0) frameDraws_(0)
{ {
@ -57,6 +60,11 @@ public:
std::shared_ptr<manager::RadarProductManager> radarProductManager_; std::shared_ptr<manager::RadarProductManager> radarProductManager_;
std::shared_ptr<common::ColorTable> colorTable_;
std::shared_ptr<view::RadarProductView> radarProductView_;
std::shared_ptr<RadarProductLayer> radarProductLayer_;
std::shared_ptr<OverlayLayer> overlayLayer_;
QPointF lastPos_; QPointF lastPos_;
uint64_t frameDraws_; uint64_t frameDraws_;
@ -73,6 +81,8 @@ MapWidget::MapWidget(const QMapboxGLSettings& settings) :
{ {
p->radarProductManager_->LoadLevel2Data(ar2vFile.toUtf8().constData()); p->radarProductManager_->LoadLevel2Data(ar2vFile.toUtf8().constData());
} }
SelectRadarProduct(common::Level2Product::Reflectivity);
} }
MapWidget::~MapWidget() MapWidget::~MapWidget()
@ -82,6 +92,27 @@ MapWidget::~MapWidget()
makeCurrent(); makeCurrent();
} }
void MapWidget::SelectRadarProduct(common::Level2Product product)
{
p->radarProductView_ =
view::RadarProductViewFactory::Create(product, p->radarProductManager_);
p->radarProductView_->Initialize();
QString colorTableFile = qgetenv("COLOR_TABLE");
if (!colorTableFile.isEmpty())
{
std::shared_ptr<common::ColorTable> colorTable =
common::ColorTable::Load(colorTableFile.toUtf8().constData());
p->radarProductView_->LoadColorTable(colorTable);
}
if (p->map_ != nullptr)
{
AddLayers();
}
}
qreal MapWidget::pixelRatio() qreal MapWidget::pixelRatio()
{ {
return devicePixelRatioF(); return devicePixelRatioF();
@ -105,24 +136,29 @@ void MapWidget::changeStyle()
void MapWidget::AddLayers() void MapWidget::AddLayers()
{ {
std::shared_ptr<view::RadarProductView> radarProductView = // TODO: Improve this
view::RadarProductViewFactory::Create("L2REF", p->radarProductManager_); if (p->map_->layerExists("rangeCircleLayer"))
radarProductView->Initialize();
QString colorTableFile = qgetenv("COLOR_TABLE");
if (!colorTableFile.isEmpty())
{ {
std::shared_ptr<common::ColorTable> colorTable = p->map_->removeLayer("rangeCircleLayer");
common::ColorTable::Load(colorTableFile.toUtf8().constData()); }
radarProductView->LoadColorTable(colorTable); if (p->map_->sourceExists("rangeCircleSource"))
{
p->map_->removeSource("rangeCircleSource");
}
if (p->map_->layerExists("radar"))
{
p->map_->removeLayer("radar");
}
if (p->map_->layerExists("overlay"))
{
p->map_->removeLayer("overlay");
} }
// QMapboxGL::addCustomLayer will take ownership of the QScopedPointer // QMapboxGL::addCustomLayer will take ownership of the QScopedPointer
QScopedPointer<QMapbox::CustomLayerHostInterface> pHost( QScopedPointer<QMapbox::CustomLayerHostInterface> pHost(
new RadarProductLayer(radarProductView, p->gl_)); new RadarProductLayer(p->radarProductView_, p->gl_));
QScopedPointer<QMapbox::CustomLayerHostInterface> pOverlayHost( QScopedPointer<QMapbox::CustomLayerHostInterface> pOverlayHost(
new OverlayLayer(radarProductView, p->gl_)); new OverlayLayer(p->radarProductView_, p->gl_));
QString before = "ferry"; QString before = "ferry";

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <scwx/common/products.hpp>
#include <memory> #include <memory>
#include <QMapboxGL> #include <QMapboxGL>
@ -29,6 +31,8 @@ public:
explicit MapWidget(const QMapboxGLSettings&); explicit MapWidget(const QMapboxGLSettings&);
~MapWidget(); ~MapWidget();
void SelectRadarProduct(common::Level2Product product);
private: private:
void changeStyle(); void changeStyle();
qreal pixelRatio(); qreal pixelRatio();

View file

@ -17,14 +17,22 @@ static const std::string logPrefix_ = "[scwx::qt::view::level2_product_view] ";
static constexpr uint32_t VERTICES_PER_BIN = 6; static constexpr uint32_t VERTICES_PER_BIN = 6;
static constexpr uint32_t VALUES_PER_VERTEX = 2; static constexpr uint32_t VALUES_PER_VERTEX = 2;
static const std::unordered_map<std::string, wsr88d::rda::DataBlockType> static const std::unordered_map<common::Level2Product,
blockTypes_ {{PRODUCT_L2_REF, wsr88d::rda::DataBlockType::MomentRef}, wsr88d::rda::DataBlockType>
{PRODUCT_L2_VEL, wsr88d::rda::DataBlockType::MomentVel}, blockTypes_ {
{PRODUCT_L2_SW, wsr88d::rda::DataBlockType::MomentSw}, {common::Level2Product::Reflectivity,
{PRODUCT_L2_ZDR, wsr88d::rda::DataBlockType::MomentZdr}, wsr88d::rda::DataBlockType::MomentRef},
{PRODUCT_L2_PHI, wsr88d::rda::DataBlockType::MomentPhi}, {common::Level2Product::Velocity, wsr88d::rda::DataBlockType::MomentVel},
{PRODUCT_L2_RHO, wsr88d::rda::DataBlockType::MomentRho}, {common::Level2Product::SpectrumWidth,
{PRODUCT_L2_CFP, wsr88d::rda::DataBlockType::MomentCfp}}; wsr88d::rda::DataBlockType::MomentSw},
{common::Level2Product::DifferentialReflectivity,
wsr88d::rda::DataBlockType::MomentZdr},
{common::Level2Product::DifferentialPhase,
wsr88d::rda::DataBlockType::MomentPhi},
{common::Level2Product::CorrelationCoefficient,
wsr88d::rda::DataBlockType::MomentRho},
{common::Level2Product::ClutterFilterPowerRemoved,
wsr88d::rda::DataBlockType::MomentCfp}};
static std::chrono::system_clock::time_point static std::chrono::system_clock::time_point
TimePoint(uint16_t modifiedJulianDate, uint32_t milliseconds); TimePoint(uint16_t modifiedJulianDate, uint32_t milliseconds);
@ -33,11 +41,14 @@ class Level2ProductViewImpl
{ {
public: public:
explicit Level2ProductViewImpl( explicit Level2ProductViewImpl(
const std::string& productName, common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager) : std::shared_ptr<manager::RadarProductManager> radarProductManager) :
radarProductManager_ {radarProductManager}, sweepTime_ {}, colorTable_ {} product_ {product},
radarProductManager_ {radarProductManager},
sweepTime_ {},
colorTable_ {}
{ {
auto it = blockTypes_.find(productName); auto it = blockTypes_.find(product);
if (it != blockTypes_.end()) if (it != blockTypes_.end())
{ {
@ -45,13 +56,14 @@ public:
} }
else else
{ {
BOOST_LOG_TRIVIAL(warning) BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Unknown product: \""
<< logPrefix_ << "Unknown product: \"" << productName << "\""; << common::GetLevel2Name(product) << "\"";
dataBlockType_ = wsr88d::rda::DataBlockType::Unknown; dataBlockType_ = wsr88d::rda::DataBlockType::Unknown;
} }
} }
~Level2ProductViewImpl() = default; ~Level2ProductViewImpl() = default;
common::Level2Product product_;
wsr88d::rda::DataBlockType dataBlockType_; wsr88d::rda::DataBlockType dataBlockType_;
std::shared_ptr<manager::RadarProductManager> radarProductManager_; std::shared_ptr<manager::RadarProductManager> radarProductManager_;
@ -65,9 +77,9 @@ public:
}; };
Level2ProductView::Level2ProductView( Level2ProductView::Level2ProductView(
const std::string& productName, common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager) : std::shared_ptr<manager::RadarProductManager> radarProductManager) :
p(std::make_unique<Level2ProductViewImpl>(productName, radarProductManager)) p(std::make_unique<Level2ProductViewImpl>(product, radarProductManager))
{ {
connect(radarProductManager.get(), connect(radarProductManager.get(),
&manager::RadarProductManager::Level2DataLoaded, &manager::RadarProductManager::Level2DataLoaded,
@ -169,14 +181,21 @@ void Level2ProductView::ComputeSweep()
// TODO: Pick this based on view settings // TODO: Pick this based on view settings
auto radarData = level2Data->radar_data()[0]; auto radarData = level2Data->radar_data()[0];
auto momentData0 = radarData[0]->moment_data_block(p->dataBlockType_);
if (momentData0 == nullptr)
{
BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "No moment data for "
<< common::GetLevel2Name(p->product_);
return;
}
p->sweepTime_ = TimePoint(radarData[0]->modified_julian_date(), p->sweepTime_ = TimePoint(radarData[0]->modified_julian_date(),
radarData[0]->collection_time()); radarData[0]->collection_time());
// Calculate vertices // Calculate vertices
timer.start(); timer.start();
auto momentData0 = radarData[0]->moment_data_block(p->dataBlockType_);
// Setup vertex vector // Setup vertex vector
std::vector<float>& vertices = p->vertices_; std::vector<float>& vertices = p->vertices_;
const size_t radials = radarData.size(); const size_t radials = radarData.size();
@ -382,10 +401,10 @@ void Level2ProductView::ComputeSweep()
} }
std::shared_ptr<Level2ProductView> Level2ProductView::Create( std::shared_ptr<Level2ProductView> Level2ProductView::Create(
const std::string& productName, common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager) std::shared_ptr<manager::RadarProductManager> radarProductManager)
{ {
return std::make_shared<Level2ProductView>(productName, radarProductManager); return std::make_shared<Level2ProductView>(product, radarProductManager);
} }
static std::chrono::system_clock::time_point static std::chrono::system_clock::time_point

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <scwx/common/color_table.hpp> #include <scwx/common/color_table.hpp>
#include <scwx/common/products.hpp>
#include <scwx/qt/manager/radar_product_manager.hpp> #include <scwx/qt/manager/radar_product_manager.hpp>
#include <scwx/qt/view/radar_product_view.hpp> #include <scwx/qt/view/radar_product_view.hpp>
@ -15,14 +16,6 @@ namespace qt
namespace view namespace view
{ {
const std::string PRODUCT_L2_REF = "L2REF";
const std::string PRODUCT_L2_VEL = "L2VEL";
const std::string PRODUCT_L2_SW = "L2SW";
const std::string PRODUCT_L2_ZDR = "L2ZDR";
const std::string PRODUCT_L2_PHI = "L2PHI";
const std::string PRODUCT_L2_RHO = "L2RHO";
const std::string PRODUCT_L2_CFP = "L2CFP";
class Level2ProductViewImpl; class Level2ProductViewImpl;
class Level2ProductView : public RadarProductView class Level2ProductView : public RadarProductView
@ -31,7 +24,7 @@ class Level2ProductView : public RadarProductView
public: public:
explicit Level2ProductView( explicit Level2ProductView(
const std::string& productName, common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager); std::shared_ptr<manager::RadarProductManager> radarProductManager);
~Level2ProductView(); ~Level2ProductView();
@ -44,7 +37,7 @@ public:
std::tuple<const void*, size_t, size_t> GetMomentData() const; std::tuple<const void*, size_t, size_t> GetMomentData() const;
static std::shared_ptr<Level2ProductView> static std::shared_ptr<Level2ProductView>
Create(const std::string& productName, Create(common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager); std::shared_ptr<manager::RadarProductManager> radarProductManager);
protected slots: protected slots:

View file

@ -18,34 +18,43 @@ typedef std::function<std::shared_ptr<RadarProductView>(
std::shared_ptr<manager::RadarProductManager> radarProductManager)> std::shared_ptr<manager::RadarProductManager> radarProductManager)>
CreateRadarProductFunction; CreateRadarProductFunction;
static const std::unordered_map<std::string, CreateRadarProductFunction>
create_ {{PRODUCT_L2_REF, Level2ProductView::Create},
{PRODUCT_L2_VEL, Level2ProductView::Create},
{PRODUCT_L2_SW, Level2ProductView::Create},
{PRODUCT_L2_ZDR, Level2ProductView::Create},
{PRODUCT_L2_PHI, Level2ProductView::Create},
{PRODUCT_L2_RHO, Level2ProductView::Create},
{PRODUCT_L2_CFP, Level2ProductView::Create}};
std::shared_ptr<RadarProductView> RadarProductViewFactory::Create( std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
const std::string& productGroup,
const std::string& productName, const std::string& productName,
std::shared_ptr<manager::RadarProductManager> radarProductManager) std::shared_ptr<manager::RadarProductManager> radarProductManager)
{ {
std::shared_ptr<RadarProductView> view = nullptr; std::shared_ptr<RadarProductView> view = nullptr;
if (create_.find(productName) == create_.end()) if (productGroup == "L2")
{
common::Level2Product product = common::GetLevel2Product(productName);
if (product == common::Level2Product::Unknown)
{ {
BOOST_LOG_TRIVIAL(warning) BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Unknown radar product: " << productName; << logPrefix_ << "Unknown Level 2 radar product: " << productName;
} }
else else
{ {
view = create_.at(productName)(productName, radarProductManager); view = Create(product, radarProductManager);
}
}
else
{
BOOST_LOG_TRIVIAL(warning)
<< logPrefix_ << "Unknown radar product group: " << productGroup;
} }
return view; return view;
} }
std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager)
{
return Level2ProductView::Create(product, radarProductManager);
}
} // namespace view } // namespace view
} // namespace qt } // namespace qt
} // namespace scwx } // namespace scwx

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <scwx/common/products.hpp>
#include <scwx/qt/manager/radar_product_manager.hpp> #include <scwx/qt/manager/radar_product_manager.hpp>
#include <scwx/qt/view/radar_product_view.hpp> #include <scwx/qt/view/radar_product_view.hpp>
@ -27,7 +28,11 @@ private:
public: public:
static std::shared_ptr<RadarProductView> static std::shared_ptr<RadarProductView>
Create(const std::string& productName, Create(const std::string& productGroup,
const std::string& productName,
std::shared_ptr<manager::RadarProductManager> radarProductManager);
static std::shared_ptr<RadarProductView>
Create(common::Level2Product product,
std::shared_ptr<manager::RadarProductManager> radarProductManager); std::shared_ptr<manager::RadarProductManager> radarProductManager);
}; };

View file

@ -146,7 +146,7 @@ const void* MomentDataBlock::data_moments() const
switch (p->dataWordSize_) switch (p->dataWordSize_)
{ {
case 8: dataMoments = p->momentGates8_.data(); break; case 8: dataMoments = p->momentGates8_.data(); break;
case 16: dataMoments = p->momentGates8_.data(); break; case 16: dataMoments = p->momentGates16_.data(); break;
default: dataMoments = nullptr; break; default: dataMoments = nullptr; break;
} }