Selectable elevation cuts

This commit is contained in:
Dan Paulat 2021-11-14 22:41:25 -06:00
parent 19f1207384
commit e76ac3bc36
15 changed files with 230 additions and 51 deletions

View file

@ -3,6 +3,7 @@
#include <scwx/qt/map/map_widget.hpp>
#include <scwx/qt/ui/flow_layout.hpp>
#include <scwx/common/characters.hpp>
#include <scwx/common/products.hpp>
#include <QToolButton>
@ -18,16 +19,25 @@ namespace main
static const std::string logPrefix_ = "[scwx::qt::main::main_window] ";
class MainWindowImpl
class MainWindowImpl : public QObject
{
Q_OBJECT
public:
explicit MainWindowImpl(MainWindow* mainWindow) : mainWindow_(mainWindow) {}
explicit MainWindowImpl(MainWindow* mainWindow) :
mainWindow_ {mainWindow}, map_ {nullptr}, elevationCuts_ {}
{
}
~MainWindowImpl() = default;
void InitializeConnections();
void SelectRadarProduct(common::Level2Product product);
void UpdateRadarProductSettings(map::MapWidget* mapWidget);
MainWindow* mainWindow_;
map::MapWidget* map_;
std::vector<float> elevationCuts_;
};
MainWindow::MainWindow(QWidget* parent) :
@ -62,6 +72,11 @@ MainWindow::MainWindow(QWidget* parent) :
p->SelectRadarProduct(product);
});
}
QLayout* elevationLayout = new ui::FlowLayout();
ui->elevationSettings->setLayout(elevationLayout);
p->InitializeConnections();
}
MainWindow::~MainWindow()
@ -96,6 +111,16 @@ void MainWindow::showEvent(QShowEvent* event)
resizeDocks({ui->radarToolboxDock}, {150}, Qt::Horizontal);
}
void MainWindowImpl::InitializeConnections()
{
connect(
map_,
&map::MapWidget::RadarSweepUpdated,
this,
[this]() { UpdateRadarProductSettings(map_); },
Qt::QueuedConnection);
}
void MainWindowImpl::SelectRadarProduct(common::Level2Product product)
{
const std::string& productName = common::GetLevel2Name(product);
@ -121,6 +146,61 @@ void MainWindowImpl::SelectRadarProduct(common::Level2Product product)
map_->SelectRadarProduct(product);
}
void MainWindowImpl::UpdateRadarProductSettings(map::MapWidget* mapWidget)
{
float currentElevation = mapWidget->GetElevation();
std::vector<float> elevationCuts = mapWidget->GetElevationCuts();
if (elevationCuts_ == elevationCuts)
{
return;
}
for (QToolButton* toolButton :
mainWindow_->ui->elevationSettings->findChildren<QToolButton*>())
{
delete toolButton;
}
QLayout* layout = mainWindow_->ui->elevationSettings->layout();
// Create elevation cut tool buttons
for (float elevationCut : elevationCuts)
{
QToolButton* toolButton = new QToolButton();
toolButton->setText(QString::number(elevationCut, 'f', 1) +
common::Characters::DEGREE);
layout->addWidget(toolButton);
connect(toolButton, &QToolButton::clicked, this, [=]() {
mapWidget->SelectElevation(elevationCut);
});
}
// Update toolbox active item to render
QToolBox* toolbox = mainWindow_->ui->radarToolbox;
int currentIndex = toolbox->currentIndex();
toolbox->setCurrentWidget(mainWindow_->ui->productSettingsPage);
toolbox->setCurrentIndex(currentIndex);
// Set each elevation cut's tool button to the same size
int elevationCutMaxWidth = 0;
for (QToolButton* widget :
mainWindow_->ui->elevationSettings->findChildren<QToolButton*>())
{
elevationCutMaxWidth = std::max(elevationCutMaxWidth, widget->width());
}
for (QToolButton* widget :
mainWindow_->ui->elevationSettings->findChildren<QToolButton*>())
{
widget->setMinimumWidth(elevationCutMaxWidth);
}
elevationCuts_ = elevationCuts;
}
} // namespace main
} // namespace qt
} // namespace scwx
#include "main_window.moc"

View file

@ -180,17 +180,20 @@ void RadarProductManager::LoadLevel2Data(const std::string& filename)
emit Level2DataLoaded();
}
std::pair<float, std::shared_ptr<wsr88d::rda::ElevationScan>>
std::tuple<std::shared_ptr<wsr88d::rda::ElevationScan>,
float,
std::vector<float>>
RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
float elevation,
std::chrono::system_clock::time_point time)
{
float elevationFound = 0.0f;
std::shared_ptr<wsr88d::rda::ElevationScan> radarData = nullptr;
std::shared_ptr<wsr88d::rda::ElevationScan> radarData = nullptr;
float elevationCut = 0.0f;
std::vector<float> elevationCuts;
if (p->level2VolumeScans_.size() > 0)
{
std::tie(elevationFound, radarData) =
std::tie(radarData, elevationCut, elevationCuts) =
p->level2VolumeScans_.crbegin()->second->GetElevationScan(
dataBlockType, elevation, time);
}
@ -205,7 +208,7 @@ RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
});
}
return std::make_pair(elevationFound, radarData);
return std::tie(radarData, elevationCut, elevationCuts);
}
} // namespace manager

View file

@ -33,7 +33,9 @@ public:
void Initialize();
void LoadLevel2Data(const std::string& filename);
std::pair<float, std::shared_ptr<wsr88d::rda::ElevationScan>>
std::tuple<std::shared_ptr<wsr88d::rda::ElevationScan>,
float,
std::vector<float>>
GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
float elevation,
std::chrono::system_clock::time_point time = {});

View file

@ -88,23 +88,33 @@ MapWidget::~MapWidget()
makeCurrent();
}
float MapWidget::GetElevation() const
{
return p->radarProductView_->elevation();
}
std::vector<float> MapWidget::GetElevationCuts() const
{
return p->radarProductView_->GetElevationCuts();
}
void MapWidget::SelectElevation(float elevation)
{
p->radarProductView_->SelectElevation(elevation);
}
void MapWidget::SelectRadarProduct(common::Level2Product product)
{
p->radarProductView_ =
view::RadarProductViewFactory::Create(product, p->radarProductManager_);
float currentElevation = 0.0f;
p->radarProductView_->Initialize();
std::string colorTableFile =
manager::SettingsManager::palette_settings()->palette(
common::GetLevel2Palette(product));
if (!colorTableFile.empty())
if (p->radarProductView_ != nullptr)
{
std::shared_ptr<common::ColorTable> colorTable =
common::ColorTable::Load(colorTableFile);
p->radarProductView_->LoadColorTable(colorTable);
currentElevation = p->radarProductView_->elevation();
}
p->radarProductView_ = view::RadarProductViewFactory::Create(
product, currentElevation, p->radarProductManager_);
connect(
p->radarProductView_.get(),
&view::RadarProductView::ColorTableUpdated,
@ -118,9 +128,22 @@ void MapWidget::SelectRadarProduct(common::Level2Product product)
[&]() {
RadarRangeLayer::Update(p->map_, p->radarProductView_->range());
update();
emit RadarSweepUpdated();
},
Qt::QueuedConnection);
p->radarProductView_->Initialize();
std::string colorTableFile =
manager::SettingsManager::palette_settings()->palette(
common::GetLevel2Palette(product));
if (!colorTableFile.empty())
{
std::shared_ptr<common::ColorTable> colorTable =
common::ColorTable::Load(colorTableFile);
p->radarProductView_->LoadColorTable(colorTable);
}
if (p->map_ != nullptr)
{
AddLayers();

View file

@ -31,7 +31,10 @@ public:
explicit MapWidget(const QMapboxGLSettings&);
~MapWidget();
void SelectRadarProduct(common::Level2Product product);
float GetElevation() const;
std::vector<float> GetElevationCuts() const;
void SelectElevation(float elevation);
void SelectRadarProduct(common::Level2Product product);
private:
void changeStyle();
@ -53,6 +56,9 @@ private:
private slots:
void mapChanged(QMapboxGL::MapChange);
signals:
void RadarSweepUpdated();
};
} // namespace map

View file

@ -1,5 +1,6 @@
#include <scwx/qt/view/level2_product_view.hpp>
#include <scwx/common/constants.hpp>
#include <scwx/util/threads.hpp>
#include <scwx/util/time.hpp>
#include <boost/log/trivial.hpp>
@ -41,13 +42,17 @@ class Level2ProductViewImpl
public:
explicit Level2ProductViewImpl(
common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
product_ {product},
radarProductManager_ {radarProductManager},
selectedElevation_ {elevation},
elevationScan_ {nullptr},
momentDataBlock0_ {nullptr},
latitude_ {},
longitude_ {},
elevation_ {},
elevationCut_ {},
elevationCuts_ {},
range_ {},
sweepTime_ {},
colorTable_ {},
@ -74,6 +79,9 @@ public:
wsr88d::rda::DataBlockType dataBlockType_;
std::shared_ptr<manager::RadarProductManager> radarProductManager_;
float selectedElevation_;
std::shared_ptr<wsr88d::rda::ElevationScan> elevationScan_;
std::shared_ptr<wsr88d::rda::MomentDataBlock> momentDataBlock0_;
std::vector<float> vertices_;
@ -81,10 +89,11 @@ public:
std::vector<uint16_t> dataMoments16_;
std::vector<uint8_t> cfpMoments_;
float latitude_;
float longitude_;
float elevation_;
float range_;
float latitude_;
float longitude_;
float elevationCut_;
std::vector<float> elevationCuts_;
float range_;
std::chrono::system_clock::time_point sweepTime_;
@ -100,8 +109,10 @@ public:
Level2ProductView::Level2ProductView(
common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager) :
p(std::make_unique<Level2ProductViewImpl>(product, radarProductManager))
p(std::make_unique<Level2ProductViewImpl>(
product, elevation, radarProductManager))
{
connect(radarProductManager.get(),
&manager::RadarProductManager::Level2DataLoaded,
@ -127,7 +138,7 @@ Level2ProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const
float Level2ProductView::elevation() const
{
return p->elevation_;
return p->elevationCut_;
}
float Level2ProductView::range() const
@ -145,6 +156,11 @@ const std::vector<float>& Level2ProductView::vertices() const
return p->vertices_;
}
std::vector<float> Level2ProductView::GetElevationCuts() const
{
return p->elevationCuts_;
}
std::tuple<const void*, size_t, size_t> Level2ProductView::GetMomentData() const
{
const void* data;
@ -190,6 +206,12 @@ void Level2ProductView::LoadColorTable(
UpdateColorTable();
}
void Level2ProductView::SelectElevation(float elevation)
{
p->selectedElevation_ = elevation;
util::async([=]() { ComputeSweep(); });
}
void Level2ProductView::UpdateColorTable()
{
if (p->momentDataBlock0_ == nullptr || //
@ -246,6 +268,7 @@ void Level2ProductView::UpdateColorTable()
std::vector<boost::gil::rgba8_pixel_t>& lut = p->colorTableLut_;
lut.resize(rangeMax - rangeMin + 1);
lut.shrink_to_fit();
std::for_each(std::execution::par_unseq,
dataRange.begin(),
@ -283,12 +306,12 @@ void Level2ProductView::ComputeSweep()
return;
}
// TODO: Pick this based on view settings
float elevation;
std::shared_ptr<wsr88d::rda::ElevationScan> radarData;
std::tie(elevation, radarData) =
p->radarProductManager_->GetLevel2Data(p->dataBlockType_, 0.0f);
if (radarData == nullptr)
std::tie(radarData, p->elevationCut_, p->elevationCuts_) =
p->radarProductManager_->GetLevel2Data(p->dataBlockType_,
p->selectedElevation_);
if (radarData == nullptr || radarData == p->elevationScan_)
{
return;
}
@ -303,6 +326,7 @@ void Level2ProductView::ComputeSweep()
auto radarData0 = (*radarData)[0];
auto momentData0 = radarData0->moment_data_block(p->dataBlockType_);
p->elevationScan_ = radarData;
p->momentDataBlock0_ = momentData0;
if (momentData0 == nullptr)
@ -318,7 +342,6 @@ void Level2ProductView::ComputeSweep()
auto volumeData0 = radarData0->volume_data_block();
p->latitude_ = volumeData0->latitude();
p->longitude_ = volumeData0->longitude();
p->elevation_ = elevation;
p->range_ =
momentData0->data_moment_range() +
momentData0->data_moment_range_sample_interval() * (gates - 0.5f);
@ -533,19 +556,23 @@ void Level2ProductView::ComputeSweep()
}
}
vertices.resize(vIndex);
vertices.shrink_to_fit();
if (momentData0->data_word_size() == 8)
{
dataMoments8.resize(mIndex);
dataMoments8.shrink_to_fit();
}
else
{
dataMoments16.resize(mIndex);
dataMoments16.shrink_to_fit();
}
if (cfpMoments.size() > 0)
{
cfpMoments.resize(mIndex);
cfpMoments.shrink_to_fit();
}
timer.stop();
@ -559,9 +586,11 @@ void Level2ProductView::ComputeSweep()
std::shared_ptr<Level2ProductView> Level2ProductView::Create(
common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager)
{
return std::make_shared<Level2ProductView>(product, radarProductManager);
return std::make_shared<Level2ProductView>(
product, elevation, radarProductManager);
}
} // namespace view

View file

@ -25,6 +25,7 @@ class Level2ProductView : public RadarProductView
public:
explicit Level2ProductView(
common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager);
~Level2ProductView();
@ -36,12 +37,15 @@ public:
const std::vector<float>& vertices() const override;
void LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) override;
void SelectElevation(float elevation) override;
std::vector<float> GetElevationCuts() const override;
std::tuple<const void*, size_t, size_t> GetMomentData() const override;
std::tuple<const void*, size_t, size_t> GetCfpMomentData() const override;
static std::shared_ptr<Level2ProductView>
Create(common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager);
protected:

View file

@ -60,6 +60,13 @@ void RadarProductView::Initialize()
ComputeSweep();
}
void RadarProductView::SelectElevation(float elevation) {}
std::vector<float> RadarProductView::GetElevationCuts() const
{
return {};
}
std::tuple<const void*, size_t, size_t>
RadarProductView::GetCfpMomentData() const
{

View file

@ -35,7 +35,9 @@ public:
void Initialize();
virtual void
LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) = 0;
virtual void SelectElevation(float elevation);
virtual std::vector<float> GetElevationCuts() const;
virtual std::tuple<const void*, size_t, size_t> GetMomentData() const = 0;
virtual std::tuple<const void*, size_t, size_t> GetCfpMomentData() const;

View file

@ -21,6 +21,7 @@ typedef std::function<std::shared_ptr<RadarProductView>(
std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
const std::string& productGroup,
const std::string& productName,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager)
{
std::shared_ptr<RadarProductView> view = nullptr;
@ -36,7 +37,7 @@ std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
}
else
{
view = Create(product, radarProductManager);
view = Create(product, elevation, radarProductManager);
}
}
else
@ -50,9 +51,10 @@ std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
std::shared_ptr<RadarProductView> RadarProductViewFactory::Create(
common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager)
{
return Level2ProductView::Create(product, radarProductManager);
return Level2ProductView::Create(product, elevation, radarProductManager);
}
} // namespace view

View file

@ -30,9 +30,11 @@ public:
static std::shared_ptr<RadarProductView>
Create(const std::string& productGroup,
const std::string& productName,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager);
static std::shared_ptr<RadarProductView>
Create(common::Level2Product product,
float elevation,
std::shared_ptr<manager::RadarProductManager> radarProductManager);
};