From 1dbc68a7d9052bc588bbf7ba06d720699a9dd34a Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 9 Apr 2022 09:22:27 -0500 Subject: [PATCH] Refactoring common level 3 product view functions to new parent class --- scwx-qt/scwx-qt.cmake | 2 + .../scwx/qt/view/level3_product_view.cpp | 225 ++++++++++++++++++ .../scwx/qt/view/level3_product_view.hpp | 52 ++++ .../scwx/qt/view/level3_radial_view.cpp | 177 +------------- .../scwx/qt/view/level3_radial_view.hpp | 16 +- 5 files changed, 285 insertions(+), 187 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/view/level3_product_view.cpp create mode 100644 scwx-qt/source/scwx/qt/view/level3_product_view.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 723cd221..e3b78660 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -105,10 +105,12 @@ set(SRC_UTIL source/scwx/qt/util/font.cpp source/scwx/qt/util/font_buffer.cpp source/scwx/qt/util/json.cpp) set(HDR_VIEW source/scwx/qt/view/level2_product_view.hpp + source/scwx/qt/view/level3_product_view.hpp source/scwx/qt/view/level3_radial_view.hpp source/scwx/qt/view/radar_product_view.hpp source/scwx/qt/view/radar_product_view_factory.hpp) set(SRC_VIEW source/scwx/qt/view/level2_product_view.cpp + source/scwx/qt/view/level3_product_view.cpp source/scwx/qt/view/level3_radial_view.cpp source/scwx/qt/view/radar_product_view.cpp source/scwx/qt/view/radar_product_view_factory.cpp) diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp new file mode 100644 index 00000000..97d403a1 --- /dev/null +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp @@ -0,0 +1,225 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace view +{ + +static const std::string logPrefix_ = "[scwx::qt::view::level3_product_view] "; + +static constexpr uint16_t RANGE_FOLDED = 1u; + +class Level3ProductViewImpl +{ +public: + explicit Level3ProductViewImpl(const std::string& product) : + product_ {product}, + graphicMessage_ {nullptr}, + colorTable_ {}, + colorTableLut_ {}, + colorTableMin_ {2}, + colorTableMax_ {254}, + savedColorTable_ {nullptr}, + savedScale_ {0.0f}, + savedOffset_ {0.0f} + { + } + ~Level3ProductViewImpl() = default; + + std::string product_; + + std::shared_ptr graphicMessage_; + + std::shared_ptr colorTable_; + std::vector colorTableLut_; + uint16_t colorTableMin_; + uint16_t colorTableMax_; + + std::shared_ptr savedColorTable_; + float savedScale_; + float savedOffset_; +}; + +Level3ProductView::Level3ProductView(const std::string& product) : + p(std::make_unique(product)) +{ +} +Level3ProductView::~Level3ProductView() = default; + +const std::vector& +Level3ProductView::color_table() const +{ + if (p->colorTableLut_.size() == 0) + { + return RadarProductView::color_table(); + } + else + { + return p->colorTableLut_; + } +} + +uint16_t Level3ProductView::color_table_min() const +{ + if (p->colorTableLut_.size() == 0) + { + return RadarProductView::color_table_min(); + } + else + { + return p->colorTableMin_; + } +} + +uint16_t Level3ProductView::color_table_max() const +{ + if (p->colorTableLut_.size() == 0) + { + return RadarProductView::color_table_max(); + } + else + { + return p->colorTableMax_; + } +} + +std::shared_ptr +Level3ProductView::graphic_product_message() const +{ + return p->graphicMessage_; +} + +void Level3ProductView::set_graphic_product_message( + std::shared_ptr gpm) +{ + p->graphicMessage_ = gpm; +} + +common::RadarProductGroup Level3ProductView::GetRadarProductGroup() const +{ + return common::RadarProductGroup::Level3; +} + +std::string Level3ProductView::GetRadarProductName() const +{ + return p->product_; +} + +void Level3ProductView::LoadColorTable( + std::shared_ptr colorTable) +{ + p->colorTable_ = colorTable; + UpdateColorTable(); +} + +void Level3ProductView::Update() +{ + util::async([=]() { ComputeSweep(); }); +} + +void Level3ProductView::UpdateColorTable() +{ + if (p->graphicMessage_ == nullptr || // + p->colorTable_ == nullptr || // + !p->colorTable_->IsValid()) + { + // Nothing to update + return; + } + + std::shared_ptr descriptionBlock = + p->graphicMessage_->description_block(); + + if (descriptionBlock == nullptr) + { + // No description block + return; + } + + float offset = descriptionBlock->offset(); + float scale = descriptionBlock->scale(); + uint16_t threshold = descriptionBlock->threshold(); + + if (p->savedColorTable_ == p->colorTable_ && // + p->savedOffset_ == offset && // + p->savedScale_ == scale) + { + // The color table LUT does not need updated + return; + } + + // If the threshold is 2, the range min should be set to 1 for range folding + uint16_t rangeMin = std::min(1, threshold); + uint16_t rangeMax = descriptionBlock->number_of_levels(); + + boost::integer_range dataRange = + boost::irange(rangeMin, rangeMax + 1); + + std::vector& lut = p->colorTableLut_; + lut.resize(rangeMax - rangeMin + 1); + lut.shrink_to_fit(); + + std::for_each(std::execution::par_unseq, + dataRange.begin(), + dataRange.end(), + [&](uint16_t i) + { + if (i == RANGE_FOLDED && threshold > RANGE_FOLDED) + { + lut[i - *dataRange.begin()] = p->colorTable_->rf_color(); + } + else + { + float f; + + // Different products use different scale/offset formulas + switch (descriptionBlock->product_code()) + { + case 159: + case 161: + case 163: + case 167: + case 168: + case 170: + case 172: + case 173: + case 174: + case 175: + case 176: + f = (i - offset) / scale; + break; + + default: + f = i * scale + offset; + break; + } + + lut[i - *dataRange.begin()] = p->colorTable_->Color(f); + } + }); + + p->colorTableMin_ = rangeMin; + p->colorTableMax_ = rangeMax; + + p->savedColorTable_ = p->colorTable_; + p->savedOffset_ = offset; + p->savedScale_ = scale; + + emit ColorTableUpdated(); +} + +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.hpp b/scwx-qt/source/scwx/qt/view/level3_product_view.hpp new file mode 100644 index 00000000..ba0e9d15 --- /dev/null +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace view +{ + +class Level3ProductViewImpl; + +class Level3ProductView : public RadarProductView +{ + Q_OBJECT + +public: + explicit Level3ProductView(const std::string& product); + ~Level3ProductView(); + + const std::vector& color_table() const override; + uint16_t color_table_min() const override; + uint16_t color_table_max() const override; + + void LoadColorTable(std::shared_ptr colorTable) override; + void Update() override; + + common::RadarProductGroup GetRadarProductGroup() const override; + std::string GetRadarProductName() const override; + +protected: + std::shared_ptr + graphic_product_message() const; + void set_graphic_product_message( + std::shared_ptr gpm); + + void UpdateColorTable() override; + +private: + std::unique_ptr p; +}; + +} // namespace view +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp b/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp index d147c580..17ec442b 100644 --- a/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_radial_view.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -32,19 +31,11 @@ public: product_ {product}, radarProductManager_ {radarProductManager}, selectedTime_ {}, - graphicMessage_ {nullptr}, latitude_ {}, longitude_ {}, range_ {}, vcp_ {}, - sweepTime_ {}, - colorTable_ {}, - colorTableLut_ {}, - colorTableMin_ {2}, - colorTableMax_ {254}, - savedColorTable_ {nullptr}, - savedScale_ {0.0f}, - savedOffset_ {0.0f} + sweepTime_ {} { } ~Level3RadialViewImpl() = default; @@ -54,8 +45,6 @@ public: std::chrono::system_clock::time_point selectedTime_; - std::shared_ptr graphicMessage_; - std::vector vertices_; std::vector dataMoments8_; @@ -65,62 +54,17 @@ public: uint16_t vcp_; std::chrono::system_clock::time_point sweepTime_; - - std::shared_ptr colorTable_; - std::vector colorTableLut_; - uint16_t colorTableMin_; - uint16_t colorTableMax_; - - std::shared_ptr savedColorTable_; - float savedScale_; - float savedOffset_; }; Level3RadialView::Level3RadialView( const std::string& product, std::shared_ptr radarProductManager) : + Level3ProductView(product), p(std::make_unique(product, radarProductManager)) { } Level3RadialView::~Level3RadialView() = default; -const std::vector& -Level3RadialView::color_table() const -{ - if (p->colorTableLut_.size() == 0) - { - return RadarProductView::color_table(); - } - else - { - return p->colorTableLut_; - } -} - -uint16_t Level3RadialView::color_table_min() const -{ - if (p->colorTableLut_.size() == 0) - { - return RadarProductView::color_table_min(); - } - else - { - return p->colorTableMin_; - } -} - -uint16_t Level3RadialView::color_table_max() const -{ - if (p->colorTableLut_.size() == 0) - { - return RadarProductView::color_table_max(); - } - else - { - return p->colorTableMax_; - } -} - float Level3RadialView::range() const { return p->range_; @@ -141,16 +85,6 @@ const std::vector& Level3RadialView::vertices() const return p->vertices_; } -common::RadarProductGroup Level3RadialView::GetRadarProductGroup() const -{ - return common::RadarProductGroup::Level3; -} - -std::string Level3RadialView::GetRadarProductName() const -{ - return p->product_; -} - std::tuple Level3RadialView::GetMomentData() const { const void* data; @@ -164,114 +98,11 @@ std::tuple Level3RadialView::GetMomentData() const return std::tie(data, dataSize, componentSize); } -void Level3RadialView::LoadColorTable( - std::shared_ptr colorTable) -{ - p->colorTable_ = colorTable; - UpdateColorTable(); -} - void Level3RadialView::SelectTime(std::chrono::system_clock::time_point time) { p->selectedTime_ = time; } -void Level3RadialView::Update() -{ - util::async([=]() { ComputeSweep(); }); -} - -void Level3RadialView::UpdateColorTable() -{ - if (p->graphicMessage_ == nullptr || // - p->colorTable_ == nullptr || // - !p->colorTable_->IsValid()) - { - // Nothing to update - return; - } - - std::shared_ptr descriptionBlock = - p->graphicMessage_->description_block(); - - if (descriptionBlock == nullptr) - { - // No description block - return; - } - - float offset = descriptionBlock->offset(); - float scale = descriptionBlock->scale(); - uint16_t threshold = descriptionBlock->threshold(); - - if (p->savedColorTable_ == p->colorTable_ && // - p->savedOffset_ == offset && // - p->savedScale_ == scale) - { - // The color table LUT does not need updated - return; - } - - // If the threshold is 2, the range min should be set to 1 for range folding - uint16_t rangeMin = std::min(1, threshold); - uint16_t rangeMax = descriptionBlock->number_of_levels(); - - boost::integer_range dataRange = - boost::irange(rangeMin, rangeMax + 1); - - std::vector& lut = p->colorTableLut_; - lut.resize(rangeMax - rangeMin + 1); - lut.shrink_to_fit(); - - std::for_each(std::execution::par_unseq, - dataRange.begin(), - dataRange.end(), - [&](uint16_t i) - { - if (i == RANGE_FOLDED && threshold > RANGE_FOLDED) - { - lut[i - *dataRange.begin()] = p->colorTable_->rf_color(); - } - else - { - float f; - - // Different products use different scale/offset formulas - switch (descriptionBlock->product_code()) - { - case 159: - case 161: - case 163: - case 167: - case 168: - case 170: - case 172: - case 173: - case 174: - case 175: - case 176: - f = (i - offset) / scale; - break; - - default: - f = i * scale + offset; - break; - } - - lut[i - *dataRange.begin()] = p->colorTable_->Color(f); - } - }); - - p->colorTableMin_ = rangeMin; - p->colorTableMax_ = rangeMax; - - p->savedColorTable_ = p->colorTable_; - p->savedOffset_ = offset; - p->savedScale_ = scale; - - emit ColorTableUpdated(); -} - void Level3RadialView::ComputeSweep() { BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "ComputeSweep()"; @@ -293,12 +124,12 @@ void Level3RadialView::ComputeSweep() << logPrefix_ << "Graphic Product Message not found"; return; } - else if (gpm == p->graphicMessage_) + else if (gpm == graphic_product_message()) { // Skip if this is the message we previously processed return; } - p->graphicMessage_ = gpm; + set_graphic_product_message(gpm); // A message with radial data should have a Product Description Block and // Product Symbology Block diff --git a/scwx-qt/source/scwx/qt/view/level3_radial_view.hpp b/scwx-qt/source/scwx/qt/view/level3_radial_view.hpp index a1134d80..39c58c9e 100644 --- a/scwx-qt/source/scwx/qt/view/level3_radial_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level3_radial_view.hpp @@ -1,9 +1,7 @@ #pragma once -#include -#include +#include #include -#include #include #include @@ -18,7 +16,7 @@ namespace view class Level3RadialViewImpl; -class Level3RadialView : public RadarProductView +class Level3RadialView : public Level3ProductView { Q_OBJECT @@ -28,29 +26,19 @@ public: std::shared_ptr radarProductManager); ~Level3RadialView(); - const std::vector& color_table() const override; - uint16_t color_table_min() const override; - uint16_t color_table_max() const override; float range() const override; std::chrono::system_clock::time_point sweep_time() const override; uint16_t vcp() const override; const std::vector& vertices() const override; - void LoadColorTable(std::shared_ptr colorTable) override; void SelectTime(std::chrono::system_clock::time_point time) override; - void Update() override; - common::RadarProductGroup GetRadarProductGroup() const override; - std::string GetRadarProductName() const override; std::tuple GetMomentData() const override; static std::shared_ptr Create(const std::string& product, std::shared_ptr radarProductManager); -protected: - void UpdateColorTable() override; - protected slots: void ComputeSweep() override;