mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:40:06 +00:00 
			
		
		
		
	Allow selection of different level 2 products
This commit is contained in:
		
							parent
							
								
									7c606b85ff
								
							
						
					
					
						commit
						951710dcfe
					
				
					 9 changed files with 174 additions and 60 deletions
				
			
		|  | @ -18,8 +18,22 @@ namespace main | |||
| 
 | ||||
| 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) : | ||||
|     QMainWindow(parent), ui(new Ui::MainWindow) | ||||
|     QMainWindow(parent), | ||||
|     p(std::make_unique<MainWindowImpl>(this)), | ||||
|     ui(new Ui::MainWindow) | ||||
| { | ||||
|    ui->setupUi(this); | ||||
| 
 | ||||
|  | @ -27,9 +41,11 @@ MainWindow::MainWindow(QWidget* parent) : | |||
|    settings.setCacheDatabasePath("/tmp/mbgl-cache.db"); | ||||
|    settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024); | ||||
| 
 | ||||
|    ui->centralwidget->layout()->addWidget(new map::MapWidget(settings)); | ||||
|    p->map_ = new map::MapWidget(settings); | ||||
| 
 | ||||
|    // Add Level2 Products
 | ||||
|    ui->centralwidget->layout()->addWidget(p->map_); | ||||
| 
 | ||||
|    // Add Level 2 Products
 | ||||
|    QLayout* level2Layout = new ui::FlowLayout(); | ||||
|    ui->level2Products->setLayout(level2Layout); | ||||
| 
 | ||||
|  | @ -41,6 +57,10 @@ MainWindow::MainWindow(QWidget* parent) : | |||
|       toolButton->setStatusTip( | ||||
|          tr(common::GetLevel2Description(product).c_str())); | ||||
|       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); | ||||
| } | ||||
| 
 | ||||
| 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 qt
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ class MainWindow : public QMainWindow | |||
| { | ||||
|    Q_OBJECT | ||||
| 
 | ||||
|    friend class MainWindowImpl; | ||||
| 
 | ||||
| public: | ||||
|    MainWindow(QWidget* parent = nullptr); | ||||
|    ~MainWindow(); | ||||
|  | @ -27,7 +29,8 @@ public: | |||
|    void showEvent(QShowEvent* event) override; | ||||
| 
 | ||||
| private: | ||||
|    Ui::MainWindow* ui; | ||||
|    std::unique_ptr<MainWindowImpl> p; | ||||
|    Ui::MainWindow*                 ui; | ||||
| }; | ||||
| 
 | ||||
| } // namespace main
 | ||||
|  |  | |||
|  | @ -44,6 +44,9 @@ public: | |||
|        settings_(settings), | ||||
|        map_(), | ||||
|        radarProductManager_ {std::make_shared<manager::RadarProductManager>()}, | ||||
|        radarProductLayer_ {nullptr}, | ||||
|        radarProductView_ {nullptr}, | ||||
|        overlayLayer_ {nullptr}, | ||||
|        lastPos_(), | ||||
|        frameDraws_(0) | ||||
|    { | ||||
|  | @ -57,6 +60,11 @@ public: | |||
| 
 | ||||
|    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_; | ||||
| 
 | ||||
|    uint64_t frameDraws_; | ||||
|  | @ -73,6 +81,8 @@ MapWidget::MapWidget(const QMapboxGLSettings& settings) : | |||
|    { | ||||
|       p->radarProductManager_->LoadLevel2Data(ar2vFile.toUtf8().constData()); | ||||
|    } | ||||
| 
 | ||||
|    SelectRadarProduct(common::Level2Product::Reflectivity); | ||||
| } | ||||
| 
 | ||||
| MapWidget::~MapWidget() | ||||
|  | @ -82,6 +92,27 @@ MapWidget::~MapWidget() | |||
|    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() | ||||
| { | ||||
|    return devicePixelRatioF(); | ||||
|  | @ -105,24 +136,29 @@ void MapWidget::changeStyle() | |||
| 
 | ||||
| void MapWidget::AddLayers() | ||||
| { | ||||
|    std::shared_ptr<view::RadarProductView> radarProductView = | ||||
|       view::RadarProductViewFactory::Create("L2REF", p->radarProductManager_); | ||||
| 
 | ||||
|    radarProductView->Initialize(); | ||||
| 
 | ||||
|    QString colorTableFile = qgetenv("COLOR_TABLE"); | ||||
|    if (!colorTableFile.isEmpty()) | ||||
|    // TODO: Improve this
 | ||||
|    if (p->map_->layerExists("rangeCircleLayer")) | ||||
|    { | ||||
|       std::shared_ptr<common::ColorTable> colorTable = | ||||
|          common::ColorTable::Load(colorTableFile.toUtf8().constData()); | ||||
|       radarProductView->LoadColorTable(colorTable); | ||||
|       p->map_->removeLayer("rangeCircleLayer"); | ||||
|    } | ||||
|    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
 | ||||
|    QScopedPointer<QMapbox::CustomLayerHostInterface> pHost( | ||||
|       new RadarProductLayer(radarProductView, p->gl_)); | ||||
|       new RadarProductLayer(p->radarProductView_, p->gl_)); | ||||
|    QScopedPointer<QMapbox::CustomLayerHostInterface> pOverlayHost( | ||||
|       new OverlayLayer(radarProductView, p->gl_)); | ||||
|       new OverlayLayer(p->radarProductView_, p->gl_)); | ||||
| 
 | ||||
|    QString before = "ferry"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/common/products.hpp> | ||||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| #include <QMapboxGL> | ||||
|  | @ -29,6 +31,8 @@ public: | |||
|    explicit MapWidget(const QMapboxGLSettings&); | ||||
|    ~MapWidget(); | ||||
| 
 | ||||
|    void SelectRadarProduct(common::Level2Product product); | ||||
| 
 | ||||
| private: | ||||
|    void  changeStyle(); | ||||
|    qreal pixelRatio(); | ||||
|  |  | |||
|  | @ -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 VALUES_PER_VERTEX = 2; | ||||
| 
 | ||||
| static const std::unordered_map<std::string, wsr88d::rda::DataBlockType> | ||||
|    blockTypes_ {{PRODUCT_L2_REF, wsr88d::rda::DataBlockType::MomentRef}, | ||||
|                 {PRODUCT_L2_VEL, wsr88d::rda::DataBlockType::MomentVel}, | ||||
|                 {PRODUCT_L2_SW, wsr88d::rda::DataBlockType::MomentSw}, | ||||
|                 {PRODUCT_L2_ZDR, wsr88d::rda::DataBlockType::MomentZdr}, | ||||
|                 {PRODUCT_L2_PHI, wsr88d::rda::DataBlockType::MomentPhi}, | ||||
|                 {PRODUCT_L2_RHO, wsr88d::rda::DataBlockType::MomentRho}, | ||||
|                 {PRODUCT_L2_CFP, wsr88d::rda::DataBlockType::MomentCfp}}; | ||||
| static const std::unordered_map<common::Level2Product, | ||||
|                                 wsr88d::rda::DataBlockType> | ||||
|    blockTypes_ { | ||||
|       {common::Level2Product::Reflectivity, | ||||
|        wsr88d::rda::DataBlockType::MomentRef}, | ||||
|       {common::Level2Product::Velocity, wsr88d::rda::DataBlockType::MomentVel}, | ||||
|       {common::Level2Product::SpectrumWidth, | ||||
|        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 | ||||
| TimePoint(uint16_t modifiedJulianDate, uint32_t milliseconds); | ||||
|  | @ -33,11 +41,14 @@ class Level2ProductViewImpl | |||
| { | ||||
| public: | ||||
|    explicit Level2ProductViewImpl( | ||||
|       const std::string&                            productName, | ||||
|       common::Level2Product                         product, | ||||
|       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()) | ||||
|       { | ||||
|  | @ -45,13 +56,14 @@ public: | |||
|       } | ||||
|       else | ||||
|       { | ||||
|          BOOST_LOG_TRIVIAL(warning) | ||||
|             << logPrefix_ << "Unknown product: \"" << productName << "\""; | ||||
|          BOOST_LOG_TRIVIAL(warning) << logPrefix_ << "Unknown product: \"" | ||||
|                                     << common::GetLevel2Name(product) << "\""; | ||||
|          dataBlockType_ = wsr88d::rda::DataBlockType::Unknown; | ||||
|       } | ||||
|    } | ||||
|    ~Level2ProductViewImpl() = default; | ||||
| 
 | ||||
|    common::Level2Product                         product_; | ||||
|    wsr88d::rda::DataBlockType                    dataBlockType_; | ||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager_; | ||||
| 
 | ||||
|  | @ -65,9 +77,9 @@ public: | |||
| }; | ||||
| 
 | ||||
| Level2ProductView::Level2ProductView( | ||||
|    const std::string&                            productName, | ||||
|    common::Level2Product                         product, | ||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) : | ||||
|     p(std::make_unique<Level2ProductViewImpl>(productName, radarProductManager)) | ||||
|     p(std::make_unique<Level2ProductViewImpl>(product, radarProductManager)) | ||||
| { | ||||
|    connect(radarProductManager.get(), | ||||
|            &manager::RadarProductManager::Level2DataLoaded, | ||||
|  | @ -169,14 +181,21 @@ void Level2ProductView::ComputeSweep() | |||
|    // TODO: Pick this based on view settings
 | ||||
|    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(), | ||||
|                              radarData[0]->collection_time()); | ||||
| 
 | ||||
|    // Calculate vertices
 | ||||
|    timer.start(); | ||||
| 
 | ||||
|    auto momentData0 = radarData[0]->moment_data_block(p->dataBlockType_); | ||||
| 
 | ||||
|    // Setup vertex vector
 | ||||
|    std::vector<float>& vertices = p->vertices_; | ||||
|    const size_t        radials  = radarData.size(); | ||||
|  | @ -382,10 +401,10 @@ void Level2ProductView::ComputeSweep() | |||
| } | ||||
| 
 | ||||
| std::shared_ptr<Level2ProductView> Level2ProductView::Create( | ||||
|    const std::string&                            productName, | ||||
|    common::Level2Product                         product, | ||||
|    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 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/common/color_table.hpp> | ||||
| #include <scwx/common/products.hpp> | ||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | ||||
| #include <scwx/qt/view/radar_product_view.hpp> | ||||
| 
 | ||||
|  | @ -15,14 +16,6 @@ namespace qt | |||
| 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 Level2ProductView : public RadarProductView | ||||
|  | @ -31,7 +24,7 @@ class Level2ProductView : public RadarProductView | |||
| 
 | ||||
| public: | ||||
|    explicit Level2ProductView( | ||||
|       const std::string&                            productName, | ||||
|       common::Level2Product                         product, | ||||
|       std::shared_ptr<manager::RadarProductManager> radarProductManager); | ||||
|    ~Level2ProductView(); | ||||
| 
 | ||||
|  | @ -44,7 +37,7 @@ public: | |||
|    std::tuple<const void*, size_t, size_t> GetMomentData() const; | ||||
| 
 | ||||
|    static std::shared_ptr<Level2ProductView> | ||||
|    Create(const std::string&                            productName, | ||||
|    Create(common::Level2Product                         product, | ||||
|           std::shared_ptr<manager::RadarProductManager> radarProductManager); | ||||
| 
 | ||||
| protected slots: | ||||
|  |  | |||
|  | @ -18,34 +18,43 @@ typedef std::function<std::shared_ptr<RadarProductView>( | |||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager)> | ||||
|    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( | ||||
|    const std::string&                            productGroup, | ||||
|    const std::string&                            productName, | ||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) | ||||
| { | ||||
|    std::shared_ptr<RadarProductView> view = nullptr; | ||||
| 
 | ||||
|    if (create_.find(productName) == create_.end()) | ||||
|    if (productGroup == "L2") | ||||
|    { | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Unknown radar product: " << productName; | ||||
|       common::Level2Product product = common::GetLevel2Product(productName); | ||||
| 
 | ||||
|       if (product == common::Level2Product::Unknown) | ||||
|       { | ||||
|          BOOST_LOG_TRIVIAL(warning) | ||||
|             << logPrefix_ << "Unknown Level 2 radar product: " << productName; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          view = Create(product, radarProductManager); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       view = create_.at(productName)(productName, radarProductManager); | ||||
|       BOOST_LOG_TRIVIAL(warning) | ||||
|          << logPrefix_ << "Unknown radar product group: " << productGroup; | ||||
|    } | ||||
| 
 | ||||
|    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 qt
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/common/products.hpp> | ||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | ||||
| #include <scwx/qt/view/radar_product_view.hpp> | ||||
| 
 | ||||
|  | @ -27,7 +28,11 @@ private: | |||
| 
 | ||||
| public: | ||||
|    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); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat