mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 03:20:05 +00:00 
			
		
		
		
	Merge pull request #418 from AdenKoperczak/modify_tilt_selection
This commit is contained in:
		
						commit
						44c37a8435
					
				
					 15 changed files with 380 additions and 220 deletions
				
			
		|  | @ -139,6 +139,8 @@ public: | |||
|    } | ||||
|    ~MainWindowImpl() | ||||
|    { | ||||
|       homeRadarConnection_.disconnect(); | ||||
| 
 | ||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|       auto& customStyleUrl       = generalSettings.custom_style_url(); | ||||
|  | @ -239,6 +241,8 @@ public: | |||
|         layerActions_ {}; | ||||
|    bool layerActionsInitialized_ {false}; | ||||
| 
 | ||||
|    boost::signals2::scoped_connection homeRadarConnection_ {}; | ||||
| 
 | ||||
|    std::vector<map::MapWidget*> maps_; | ||||
| 
 | ||||
|    std::chrono::system_clock::time_point selectedTime_ {}; | ||||
|  | @ -267,6 +271,7 @@ MainWindow::MainWindow(QWidget* parent) : | |||
|    ui->vcpLabel->setVisible(false); | ||||
|    ui->vcpValueLabel->setVisible(false); | ||||
|    ui->vcpDescriptionLabel->setVisible(false); | ||||
|    ui->saveRadarProductsButton->setVisible(true); | ||||
| 
 | ||||
|    p->radarSitePresetsMenu_ = new QMenu(this); | ||||
|    ui->radarSitePresetsButton->setMenu(p->radarSitePresetsMenu_); | ||||
|  | @ -326,6 +331,8 @@ MainWindow::MainWindow(QWidget* parent) : | |||
|       ui->smoothRadarDataCheckBox); | ||||
|    p->mapSettingsGroup_->GetContentsLayout()->addWidget( | ||||
|       ui->trackLocationCheckBox); | ||||
|    p->mapSettingsGroup_->GetContentsLayout()->addWidget( | ||||
|       ui->saveRadarProductsButton); | ||||
|    ui->radarToolboxScrollAreaContents->layout()->replaceWidget( | ||||
|       ui->mapSettingsGroupBox, p->mapSettingsGroup_); | ||||
|    ui->mapSettingsGroupBox->setVisible(false); | ||||
|  | @ -1124,6 +1131,21 @@ void MainWindowImpl::ConnectOtherSignals() | |||
|               // Turn on location tracking
 | ||||
|               positionManager_->TrackLocation(trackingEnabled); | ||||
|            }); | ||||
|    connect( | ||||
|       mainWindow_->ui->saveRadarProductsButton, | ||||
|       &QAbstractButton::clicked, | ||||
|       mainWindow_, | ||||
|       [this]() | ||||
|       { | ||||
|          auto& mapSettings = settings::MapSettings::Instance(); | ||||
|          for (std::size_t i = 0; i < maps_.size(); i++) | ||||
|          { | ||||
|             const auto& map = maps_.at(i); | ||||
|             mapSettings.radar_product_group(i).StageValue( | ||||
|                common::GetRadarProductGroupName(map->GetRadarProductGroup())); | ||||
|             mapSettings.radar_product(i).StageValue(map->GetRadarProductName()); | ||||
|          } | ||||
|       }); | ||||
|    connect(level2ProductsWidget_, | ||||
|            &ui::Level2ProductsWidget::RadarProductSelected, | ||||
|            mainWindow_, | ||||
|  | @ -1255,6 +1277,28 @@ void MainWindowImpl::ConnectOtherSignals() | |||
|               timeLabel_->setVisible(true); | ||||
|            }); | ||||
|    clockTimer_.start(1000); | ||||
| 
 | ||||
|    auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
|    homeRadarConnection_ = | ||||
|       generalSettings.default_radar_site().changed_signal().connect( | ||||
|          [this]() | ||||
|          { | ||||
|             const std::shared_ptr<config::RadarSite> radarSite = | ||||
|                activeMap_->GetRadarSite(); | ||||
|             const std::string homeRadarSite = | ||||
|                settings::GeneralSettings::Instance() | ||||
|                   .default_radar_site() | ||||
|                   .GetValue(); | ||||
|             if (radarSite == nullptr) | ||||
|             { | ||||
|                mainWindow_->ui->saveRadarProductsButton->setVisible(false); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                mainWindow_->ui->saveRadarProductsButton->setVisible( | ||||
|                   radarSite->id() == homeRadarSite); | ||||
|             } | ||||
|          }); | ||||
| } | ||||
| 
 | ||||
| void MainWindowImpl::InitializeLayerDisplayActions() | ||||
|  | @ -1509,6 +1553,8 @@ void MainWindowImpl::UpdateRadarProductSettings() | |||
| void MainWindowImpl::UpdateRadarSite() | ||||
| { | ||||
|    std::shared_ptr<config::RadarSite> radarSite = activeMap_->GetRadarSite(); | ||||
|    const std::string                  homeRadarSite = | ||||
|       settings::GeneralSettings::Instance().default_radar_site().GetValue(); | ||||
| 
 | ||||
|    if (radarSite != nullptr) | ||||
|    { | ||||
|  | @ -1523,6 +1569,9 @@ void MainWindowImpl::UpdateRadarSite() | |||
|          radarSite->location_name().c_str()); | ||||
| 
 | ||||
|       timelineManager_->SetRadarSite(radarSite->id()); | ||||
| 
 | ||||
|       mainWindow_->ui->saveRadarProductsButton->setVisible(radarSite->id() == | ||||
|                                                            homeRadarSite); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|  | @ -1530,6 +1579,7 @@ void MainWindowImpl::UpdateRadarSite() | |||
| 
 | ||||
|       mainWindow_->ui->radarSiteValueLabel->setVisible(false); | ||||
|       mainWindow_->ui->radarLocationLabel->setVisible(false); | ||||
|       mainWindow_->ui->saveRadarProductsButton->setVisible(false); | ||||
| 
 | ||||
|       timelineManager_->SetRadarSite("?"); | ||||
|    } | ||||
|  |  | |||
|  | @ -155,8 +155,8 @@ | |||
|          <rect> | ||||
|           <x>0</x> | ||||
|           <y>0</y> | ||||
|           <width>190</width> | ||||
|           <height>680</height> | ||||
|           <width>205</width> | ||||
|           <height>701</height> | ||||
|          </rect> | ||||
|         </property> | ||||
|         <layout class="QVBoxLayout" name="verticalLayout_6"> | ||||
|  | @ -181,32 +181,24 @@ | |||
|             <enum>QFrame::Shadow::Raised</enum> | ||||
|            </property> | ||||
|            <layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0"> | ||||
|             <item row="0" column="2"> | ||||
|              <widget class="QLabel" name="radarSiteValueLabel"> | ||||
|               <property name="sizePolicy"> | ||||
|                <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> | ||||
|                 <horstretch>0</horstretch> | ||||
|                 <verstretch>0</verstretch> | ||||
|                </sizepolicy> | ||||
|               </property> | ||||
|             <item row="3" column="2" colspan="3"> | ||||
|              <widget class="QLabel" name="vcpValueLabel"> | ||||
|               <property name="text"> | ||||
|                <string notr="true">KLSX</string> | ||||
|                <string notr="true">35</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="3" column="0" colspan="2"> | ||||
|              <widget class="QLabel" name="vcpLabel"> | ||||
|               <property name="sizePolicy"> | ||||
|                <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> | ||||
|                 <horstretch>0</horstretch> | ||||
|                 <verstretch>0</verstretch> | ||||
|                </sizepolicy> | ||||
|               </property> | ||||
|               <property name="toolTip"> | ||||
|                <string>Volume Coverage Pattern</string> | ||||
|               </property> | ||||
|             <item row="4" column="2" colspan="3"> | ||||
|              <widget class="QLabel" name="vcpDescriptionLabel"> | ||||
|               <property name="text"> | ||||
|                <string>VCP</string> | ||||
|                <string>Clear Air Mode</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="1" column="2" colspan="3"> | ||||
|              <widget class="QLabel" name="radarLocationLabel"> | ||||
|               <property name="text"> | ||||
|                <string notr="true">St. Louis, MO</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|  | @ -271,34 +263,6 @@ | |||
|               </layout> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="0" column="0" colspan="2"> | ||||
|              <widget class="QLabel" name="radarSiteLabel"> | ||||
|               <property name="text"> | ||||
|                <string>Radar Site</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="1" column="2" colspan="3"> | ||||
|              <widget class="QLabel" name="radarLocationLabel"> | ||||
|               <property name="text"> | ||||
|                <string notr="true">St. Louis, MO</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="3" column="2" colspan="3"> | ||||
|              <widget class="QLabel" name="vcpValueLabel"> | ||||
|               <property name="text"> | ||||
|                <string notr="true">35</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="4" column="2" colspan="3"> | ||||
|              <widget class="QLabel" name="vcpDescriptionLabel"> | ||||
|               <property name="text"> | ||||
|                <string>Clear Air Mode</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="0" column="3"> | ||||
|              <widget class="QToolButton" name="radarSiteSelectButton"> | ||||
|               <property name="maximumSize"> | ||||
|  | @ -312,6 +276,42 @@ | |||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="3" column="0" colspan="2"> | ||||
|              <widget class="QLabel" name="vcpLabel"> | ||||
|               <property name="sizePolicy"> | ||||
|                <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> | ||||
|                 <horstretch>0</horstretch> | ||||
|                 <verstretch>0</verstretch> | ||||
|                </sizepolicy> | ||||
|               </property> | ||||
|               <property name="toolTip"> | ||||
|                <string>Volume Coverage Pattern</string> | ||||
|               </property> | ||||
|               <property name="text"> | ||||
|                <string>VCP</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="0" column="0" colspan="2"> | ||||
|              <widget class="QLabel" name="radarSiteLabel"> | ||||
|               <property name="text"> | ||||
|                <string>Radar Site</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item row="0" column="2"> | ||||
|              <widget class="QLabel" name="radarSiteValueLabel"> | ||||
|               <property name="sizePolicy"> | ||||
|                <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> | ||||
|                 <horstretch>0</horstretch> | ||||
|                 <verstretch>0</verstretch> | ||||
|                </sizepolicy> | ||||
|               </property> | ||||
|               <property name="text"> | ||||
|                <string notr="true">KLSX</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|            </layout> | ||||
|           </widget> | ||||
|          </item> | ||||
|  | @ -345,6 +345,13 @@ | |||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QPushButton" name="saveRadarProductsButton"> | ||||
|               <property name="text"> | ||||
|                <string>Set As Default Products</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|            </layout> | ||||
|           </widget> | ||||
|          </item> | ||||
|  |  | |||
|  | @ -98,7 +98,8 @@ public: | |||
|        prevLongitude_ {0.0}, | ||||
|        prevZoom_ {0.0}, | ||||
|        prevBearing_ {0.0}, | ||||
|        prevPitch_ {0.0} | ||||
|        prevPitch_ {0.0}, | ||||
|        tiltsToIndices_ {} | ||||
|    { | ||||
|       // Create views
 | ||||
|       auto overlayProductView = std::make_shared<view::OverlayProductView>(); | ||||
|  | @ -273,6 +274,9 @@ public: | |||
|    bool productAvailabilityUpdated_ {false}; | ||||
|    bool productAvailabilityProductSelected_ {false}; | ||||
| 
 | ||||
|    std::unordered_map<std::string, size_t> tiltsToIndices_; | ||||
|    size_t                                  currentTiltIndex_ {0}; | ||||
| 
 | ||||
| public slots: | ||||
|    void Update(); | ||||
| }; | ||||
|  | @ -611,7 +615,7 @@ common::Level3ProductCategoryMap MapWidget::GetAvailableLevel3Categories() | |||
|    } | ||||
| } | ||||
| 
 | ||||
| float MapWidget::GetElevation() const | ||||
| std::optional<float> MapWidget::GetElevation() const | ||||
| { | ||||
|    auto radarProductView = p->context_->radar_product_view(); | ||||
| 
 | ||||
|  | @ -621,7 +625,7 @@ float MapWidget::GetElevation() const | |||
|    } | ||||
|    else | ||||
|    { | ||||
|       return 0.0f; | ||||
|       return {}; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
|  | @ -829,6 +833,17 @@ void MapWidget::SelectRadarProduct(common::RadarProductGroup group, | |||
|       productCode = common::GetLevel3ProductCodeByAwipsId(productName); | ||||
|    } | ||||
| 
 | ||||
|    if (group == common::RadarProductGroup::Level3) | ||||
|    { | ||||
|       const auto& tiltIndex = p->tiltsToIndices_.find(productName); | ||||
|       p->currentTiltIndex_ = | ||||
|          tiltIndex != p->tiltsToIndices_.cend() ? tiltIndex->second : 0; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       p->currentTiltIndex_ = 0; | ||||
|    } | ||||
| 
 | ||||
|    if (radarProductView == nullptr || | ||||
|        radarProductView->GetRadarProductGroup() != group || | ||||
|        (radarProductView->GetRadarProductGroup() == | ||||
|  | @ -933,11 +948,6 @@ void MapWidget::SelectRadarSite(std::shared_ptr<config::RadarSite> radarSite, | |||
|       if (radarProductView != nullptr) | ||||
|       { | ||||
|          radarProductView->set_radar_product_manager(p->radarProductManager_); | ||||
|          SelectRadarProduct(radarProductView->GetRadarProductGroup(), | ||||
|                             radarProductView->GetRadarProductName(), | ||||
|                             0, | ||||
|                             radarProductView->selected_time(), | ||||
|                             false); | ||||
|       } | ||||
| 
 | ||||
|       p->AddLayers(); | ||||
|  | @ -1756,6 +1766,24 @@ void MapWidgetImpl::RadarProductManagerConnect() | |||
|               this, | ||||
|               [this]() | ||||
|               { | ||||
|                  const common::Level3ProductCategoryMap& categoryMap = | ||||
|                     widget_->GetAvailableLevel3Categories(); | ||||
| 
 | ||||
|                  tiltsToIndices_.clear(); | ||||
|                  for (const auto& category : categoryMap) | ||||
|                  { | ||||
|                     for (const auto& product : category.second) | ||||
|                     { | ||||
|                        for (size_t tiltIndex = 0; | ||||
|                             tiltIndex < product.second.size(); | ||||
|                             tiltIndex++) | ||||
|                        { | ||||
|                           tiltsToIndices_.emplace(product.second[tiltIndex], | ||||
|                                                   tiltIndex); | ||||
|                        } | ||||
|                     } | ||||
|                  } | ||||
| 
 | ||||
|                  productAvailabilityUpdated_ = true; | ||||
|                  CheckLevel3Availability(); | ||||
|                  Q_EMIT widget_->Level3ProductsChanged(); | ||||
|  | @ -2058,7 +2086,7 @@ void MapWidgetImpl::CheckLevel3Availability() | |||
|     * has been updated | ||||
|     * | ||||
|     * productAvailabilityProductSelected_ Only update once the radar site is | ||||
|     * fully selected, including the current product | ||||
|     * fully selected | ||||
|     */ | ||||
|    if (!(productAvailabilityCheckNeeded_ && productAvailabilityUpdated_ && | ||||
|          productAvailabilityProductSelected_)) | ||||
|  | @ -2067,9 +2095,21 @@ void MapWidgetImpl::CheckLevel3Availability() | |||
|    } | ||||
|    productAvailabilityCheckNeeded_ = false; | ||||
| 
 | ||||
|    // Get radar product view for fallback and level2 selection
 | ||||
|    auto radarProductView = context_->radar_product_view(); | ||||
|    if (radarProductView == nullptr) | ||||
|    { | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    // Only do this for level3 products
 | ||||
|    if (widget_->GetRadarProductGroup() != common::RadarProductGroup::Level3) | ||||
|    { | ||||
|       widget_->SelectRadarProduct(radarProductView->GetRadarProductGroup(), | ||||
|                                   radarProductView->GetRadarProductName(), | ||||
|                                   0, | ||||
|                                   radarProductView->selected_time(), | ||||
|                                   false); | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|  | @ -2083,6 +2123,12 @@ void MapWidgetImpl::CheckLevel3Availability() | |||
|       common::GetLevel3CategoryByProduct(productName); | ||||
|    if (productCategory == common::Level3ProductCategory::Unknown) | ||||
|    { | ||||
|       // Default to the same as already selected
 | ||||
|       widget_->SelectRadarProduct(radarProductView->GetRadarProductGroup(), | ||||
|                                   radarProductView->GetRadarProductName(), | ||||
|                                   0, | ||||
|                                   radarProductView->selected_time(), | ||||
|                                   false); | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|  | @ -2090,38 +2136,53 @@ void MapWidgetImpl::CheckLevel3Availability() | |||
|    // Has no products in this category, do not change categories
 | ||||
|    if (availableProductsIt == categoryMap.cend()) | ||||
|    { | ||||
|       // Default to the same as already selected
 | ||||
|       widget_->SelectRadarProduct(radarProductView->GetRadarProductGroup(), | ||||
|                                   radarProductView->GetRadarProductName(), | ||||
|                                   0, | ||||
|                                   radarProductView->selected_time(), | ||||
|                                   false); | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    const auto& availableProducts = availableProductsIt->second; | ||||
|    const auto& availableTiltsIt  = availableProducts.find(productName); | ||||
| 
 | ||||
|    const auto& availableTilts = | ||||
|       availableTiltsIt == availableProducts.cend() ? | ||||
|          // Does not have the same product, but has others in the same category.
 | ||||
|          // Switch to the default product and tilt in this category.
 | ||||
|    if (availableTiltsIt == availableProducts.cend()) | ||||
|    { | ||||
|       widget_->SelectRadarProduct( | ||||
|          common::RadarProductGroup::Level3, | ||||
|          common::GetLevel3CategoryDefaultProduct(productCategory, categoryMap), | ||||
|          0, | ||||
|          widget_->GetSelectedTime()); | ||||
|       return; | ||||
|    } | ||||
|          availableProducts.at(common::GetLevel3ProductByAwipsId( | ||||
|             common::GetLevel3CategoryDefaultProduct(productCategory, | ||||
|                                                     categoryMap))) : | ||||
|          // Has the same product
 | ||||
|          availableTiltsIt->second; | ||||
| 
 | ||||
|    const auto& availableTilts = availableTiltsIt->second; | ||||
|    const auto& tilt           = std::ranges::find_if( | ||||
|       availableTilts, | ||||
|       [productTilt](const std::string& tilt) { return productTilt == tilt; }); | ||||
|    // Tilt is not available, set it to first tilt
 | ||||
|    if (tilt == availableTilts.cend() && availableTilts.size() > 0) | ||||
|    // Try to match the tilt to the last tilt.
 | ||||
|    if (currentTiltIndex_ < availableTilts.size()) | ||||
|    { | ||||
|       widget_->SelectRadarProduct(common::RadarProductGroup::Level3, | ||||
|                                   availableTilts[0], | ||||
|                                   availableTilts[currentTiltIndex_], | ||||
|                                   0, | ||||
|                                   widget_->GetSelectedTime()); | ||||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    // Tilt is available, no change needed
 | ||||
|    else if (availableTilts.size() > 0) | ||||
|    { | ||||
|       widget_->SelectRadarProduct(common::RadarProductGroup::Level3, | ||||
|                                   availableTilts[availableTilts.size() - 1], | ||||
|                                   0, | ||||
|                                   widget_->GetSelectedTime()); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // No tilts available in this case, default to the same as already
 | ||||
|       // selected
 | ||||
|       widget_->SelectRadarProduct(radarProductView->GetRadarProductGroup(), | ||||
|                                   radarProductView->GetRadarProductName(), | ||||
|                                   0, | ||||
|                                   radarProductView->selected_time(), | ||||
|                                   false); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| } // namespace map
 | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| 
 | ||||
| #include <chrono> | ||||
| #include <memory> | ||||
| #include <optional> | ||||
| 
 | ||||
| #include <qmaplibre.hpp> | ||||
| 
 | ||||
|  | @ -41,7 +42,7 @@ public: | |||
| 
 | ||||
|    [[nodiscard]] common::Level3ProductCategoryMap | ||||
|                                            GetAvailableLevel3Categories(); | ||||
|    [[nodiscard]] float                     GetElevation() const; | ||||
|    [[nodiscard]] std::optional<float>      GetElevation() const; | ||||
|    [[nodiscard]] std::vector<float>        GetElevationCuts() const; | ||||
|    [[nodiscard]] std::vector<std::string>  GetLevel3Products(); | ||||
|    [[nodiscard]] std::string               GetMapStyle() const; | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <scwx/common/characters.hpp> | ||||
| #include <scwx/qt/gl/draw/geo_icons.hpp> | ||||
| #include <scwx/qt/gl/draw/icons.hpp> | ||||
| #include <scwx/qt/gl/draw/rectangle.hpp> | ||||
|  | @ -426,7 +427,9 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
|    if (radarProductView != nullptr) | ||||
|    { | ||||
|       // Render product name
 | ||||
|       std::string productName = radarProductView->GetRadarProductName(); | ||||
|       const std::string productName = radarProductView->GetRadarProductName(); | ||||
|       const std::optional<float> elevation = radarProductView->elevation(); | ||||
| 
 | ||||
|       if (productName.length() > 0 && !productName.starts_with('?')) | ||||
|       { | ||||
|          ImGui::SetNextWindowPos(ImVec2 {0.0f, 0.0f}); | ||||
|  | @ -434,7 +437,21 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) | |||
|                       nullptr, | ||||
|                       ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | | ||||
|                          ImGuiWindowFlags_AlwaysAutoResize); | ||||
| 
 | ||||
|          if (elevation.has_value()) | ||||
|          { | ||||
|             const std::string elevationString = | ||||
|                (QString::number(*elevation, 'f', 1) + | ||||
|                 common::Characters::DEGREE) | ||||
|                   .toStdString(); | ||||
|             ImGui::TextUnformatted( | ||||
|                fmt::format("{} ({})", productName, elevationString).c_str()); | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             ImGui::TextUnformatted(productName.c_str()); | ||||
|          } | ||||
| 
 | ||||
|          ImGui::End(); | ||||
|       } | ||||
|    } | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ public: | |||
|             { | ||||
|                common::RadarProductGroup radarProductGroup = | ||||
|                   common::GetRadarProductGroup( | ||||
|                      map_.at(i).radarProductGroup_.GetValue()); | ||||
|                      map_.at(i).radarProductGroup_.GetStagedOrValue()); | ||||
| 
 | ||||
|                if (radarProductGroup == common::RadarProductGroup::Level2) | ||||
|                { | ||||
|  | @ -193,6 +193,8 @@ bool MapSettings::Shutdown() | |||
| 
 | ||||
|       dataChanged |= mapRecordSettings.mapStyle_.Commit(); | ||||
|       dataChanged |= mapRecordSettings.smoothingEnabled_.Commit(); | ||||
|       dataChanged |= mapRecordSettings.radarProductGroup_.Commit(); | ||||
|       dataChanged |= mapRecordSettings.radarProduct_.Commit(); | ||||
|    } | ||||
| 
 | ||||
|    return dataChanged; | ||||
|  |  | |||
|  | @ -242,7 +242,9 @@ void Level2SettingsWidget::UpdateElevationSelection(float elevation) | |||
| 
 | ||||
| void Level2SettingsWidget::UpdateSettings(map::MapWidget* activeMap) | ||||
| { | ||||
|    float              currentElevation = activeMap->GetElevation(); | ||||
|    std::optional<float> currentElevationOption = activeMap->GetElevation(); | ||||
|    const float          currentElevation = | ||||
|       currentElevationOption.has_value() ? *currentElevationOption : 0.0f; | ||||
|    std::vector<float> elevationCuts    = activeMap->GetElevationCuts(); | ||||
| 
 | ||||
|    if (p->elevationCuts_ != elevationCuts) | ||||
|  |  | |||
|  | @ -271,7 +271,7 @@ uint16_t Level2ProductView::color_table_max() const | |||
|    } | ||||
| } | ||||
| 
 | ||||
| float Level2ProductView::elevation() const | ||||
| std::optional<float> Level2ProductView::elevation() const | ||||
| { | ||||
|    return p->elevationCut_; | ||||
| } | ||||
|  |  | |||
|  | @ -8,11 +8,7 @@ | |||
| #include <memory> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace view | ||||
| namespace scwx::qt::view | ||||
| { | ||||
| 
 | ||||
| class Level2ProductView : public RadarProductView | ||||
|  | @ -23,38 +19,47 @@ public: | |||
|    explicit Level2ProductView( | ||||
|       common::Level2Product                         product, | ||||
|       std::shared_ptr<manager::RadarProductManager> radarProductManager); | ||||
|    ~Level2ProductView(); | ||||
|    ~Level2ProductView() override; | ||||
| 
 | ||||
|    std::shared_ptr<common::ColorTable> color_table() const override; | ||||
|    const std::vector<boost::gil::rgba8_pixel_t>& | ||||
|    Level2ProductView(const Level2ProductView&)            = delete; | ||||
|    Level2ProductView(Level2ProductView&&)                 = delete; | ||||
|    Level2ProductView& operator=(const Level2ProductView&) = delete; | ||||
|    Level2ProductView& operator=(Level2ProductView&&)      = delete; | ||||
| 
 | ||||
|    [[nodiscard]] std::shared_ptr<common::ColorTable> | ||||
|    color_table() const override; | ||||
|    [[nodiscard]] const std::vector<boost::gil::rgba8_pixel_t>& | ||||
|                                       color_table_lut() const override; | ||||
|    std::uint16_t                         color_table_min() const override; | ||||
|    std::uint16_t                         color_table_max() const override; | ||||
|    float                                 elevation() const override; | ||||
|    float                                 range() const override; | ||||
|    std::chrono::system_clock::time_point sweep_time() const override; | ||||
|    float                                 unit_scale() const override; | ||||
|    std::string                           units() const override; | ||||
|    std::uint16_t                         vcp() const override; | ||||
|    const std::vector<float>&             vertices() const override; | ||||
|    [[nodiscard]] std::uint16_t        color_table_min() const override; | ||||
|    [[nodiscard]] std::uint16_t        color_table_max() const override; | ||||
|    [[nodiscard]] std::optional<float> elevation() const override; | ||||
|    [[nodiscard]] float                range() const override; | ||||
|    [[nodiscard]] std::chrono::system_clock::time_point | ||||
|                                            sweep_time() const override; | ||||
|    [[nodiscard]] float                     unit_scale() const override; | ||||
|    [[nodiscard]] std::string               units() const override; | ||||
|    [[nodiscard]] std::uint16_t             vcp() const override; | ||||
|    [[nodiscard]] const std::vector<float>& vertices() const override; | ||||
| 
 | ||||
|    void LoadColorTable(std::shared_ptr<common::ColorTable> colorTable) override; | ||||
|    void SelectElevation(float elevation) override; | ||||
|    void SelectProduct(const std::string& productName) override; | ||||
| 
 | ||||
|    common::RadarProductGroup GetRadarProductGroup() const override; | ||||
|    std::string               GetRadarProductName() const override; | ||||
|    std::vector<float>        GetElevationCuts() const override; | ||||
|    std::tuple<const void*, std::size_t, std::size_t> | ||||
|    [[nodiscard]] common::RadarProductGroup | ||||
|                                     GetRadarProductGroup() const override; | ||||
|    [[nodiscard]] std::string        GetRadarProductName() const override; | ||||
|    [[nodiscard]] std::vector<float> GetElevationCuts() const override; | ||||
|    [[nodiscard]] std::tuple<const void*, std::size_t, std::size_t> | ||||
|    GetMomentData() const override; | ||||
|    std::tuple<const void*, std::size_t, std::size_t> | ||||
|    [[nodiscard]] std::tuple<const void*, std::size_t, std::size_t> | ||||
|    GetCfpMomentData() const override; | ||||
| 
 | ||||
|    std::optional<std::uint16_t> | ||||
|    [[nodiscard]] std::optional<std::uint16_t> | ||||
|    GetBinLevel(const common::Coordinate& coordinate) const override; | ||||
|    std::optional<wsr88d::DataLevelCode> | ||||
|    [[nodiscard]] std::optional<wsr88d::DataLevelCode> | ||||
|    GetDataLevelCode(std::uint16_t level) const override; | ||||
|    std::optional<float> GetDataValue(std::uint16_t level) const override; | ||||
|    [[nodiscard]] std::optional<float> | ||||
|    GetDataValue(std::uint16_t level) const override; | ||||
| 
 | ||||
|    static std::shared_ptr<Level2ProductView> | ||||
|    Create(common::Level2Product                         product, | ||||
|  | @ -75,6 +80,4 @@ private: | |||
|    std::unique_ptr<Impl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace view
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::view
 | ||||
|  |  | |||
|  | @ -67,6 +67,7 @@ public: | |||
| 
 | ||||
|    float         latitude_; | ||||
|    float         longitude_; | ||||
|    std::optional<float> elevation_ {}; | ||||
|    float         range_; | ||||
|    std::uint16_t vcp_; | ||||
| 
 | ||||
|  | @ -91,6 +92,11 @@ boost::asio::thread_pool& Level3RadialView::thread_pool() | |||
|    return p->threadPool_; | ||||
| } | ||||
| 
 | ||||
| std::optional<float> Level3RadialView::elevation() const | ||||
| { | ||||
|    return p->elevation_; | ||||
| } | ||||
| 
 | ||||
| float Level3RadialView::range() const | ||||
| { | ||||
|    return p->range_; | ||||
|  | @ -306,6 +312,10 @@ void Level3RadialView::ComputeSweep() | |||
|    p->latitude_  = descriptionBlock->latitude_of_radar(); | ||||
|    p->longitude_ = descriptionBlock->longitude_of_radar(); | ||||
|    p->range_     = descriptionBlock->range(); | ||||
|    p->elevation_ = | ||||
|       descriptionBlock->has_elevation() ? | ||||
|          static_cast<float>(descriptionBlock->elevation().value()) : | ||||
|          std::optional<float> {}; | ||||
|    p->sweepTime_ = | ||||
|       scwx::util::TimePoint(descriptionBlock->volume_scan_date(), | ||||
|                             descriptionBlock->volume_scan_start_time() * 1000); | ||||
|  |  | |||
|  | @ -6,11 +6,7 @@ | |||
| #include <memory> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace view | ||||
| namespace scwx::qt::view | ||||
| { | ||||
| 
 | ||||
| class Level3RadialView : public Level3ProductView | ||||
|  | @ -21,17 +17,24 @@ public: | |||
|    explicit Level3RadialView( | ||||
|       const std::string&                            product, | ||||
|       std::shared_ptr<manager::RadarProductManager> radarProductManager); | ||||
|    ~Level3RadialView(); | ||||
|    ~Level3RadialView() override; | ||||
| 
 | ||||
|    float                                 range() const override; | ||||
|    std::chrono::system_clock::time_point sweep_time() const override; | ||||
|    std::uint16_t                         vcp() const override; | ||||
|    const std::vector<float>&             vertices() const override; | ||||
|    Level3RadialView(const Level3RadialView&)            = delete; | ||||
|    Level3RadialView(Level3RadialView&&)                 = delete; | ||||
|    Level3RadialView& operator=(const Level3RadialView&) = delete; | ||||
|    Level3RadialView& operator=(Level3RadialView&&)      = delete; | ||||
| 
 | ||||
|    std::tuple<const void*, std::size_t, std::size_t> | ||||
|    [[nodiscard]] std::optional<float> elevation() const override; | ||||
|    [[nodiscard]] float                range() const override; | ||||
|    [[nodiscard]] std::chrono::system_clock::time_point | ||||
|                                            sweep_time() const override; | ||||
|    [[nodiscard]] std::uint16_t             vcp() const override; | ||||
|    [[nodiscard]] const std::vector<float>& vertices() const override; | ||||
| 
 | ||||
|    [[nodiscard]] std::tuple<const void*, std::size_t, std::size_t> | ||||
|    GetMomentData() const override; | ||||
| 
 | ||||
|    std::optional<std::uint16_t> | ||||
|    [[nodiscard]] std::optional<std::uint16_t> | ||||
|    GetBinLevel(const common::Coordinate& coordinate) const override; | ||||
| 
 | ||||
|    static std::shared_ptr<Level3RadialView> | ||||
|  | @ -49,6 +52,4 @@ private: | |||
|    std::unique_ptr<Impl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace view
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::view
 | ||||
|  |  | |||
|  | @ -85,9 +85,9 @@ std::uint16_t RadarProductView::color_table_max() const | |||
|    return kDefaultColorTableMax_; | ||||
| } | ||||
| 
 | ||||
| float RadarProductView::elevation() const | ||||
| std::optional<float> RadarProductView::elevation() const | ||||
| { | ||||
|    return 0.0f; | ||||
|    return {}; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<manager::RadarProductManager> | ||||
|  |  | |||
|  | @ -16,11 +16,7 @@ | |||
| #include <QObject> | ||||
| #include <boost/asio/thread_pool.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| namespace view | ||||
| namespace scwx::qt::view | ||||
| { | ||||
| 
 | ||||
| class RadarProductViewImpl; | ||||
|  | @ -32,20 +28,27 @@ class RadarProductView : public QObject | |||
| public: | ||||
|    explicit RadarProductView( | ||||
|       std::shared_ptr<manager::RadarProductManager> radarProductManager); | ||||
|    virtual ~RadarProductView(); | ||||
|    ~RadarProductView() override; | ||||
| 
 | ||||
|    virtual std::shared_ptr<common::ColorTable> color_table() const = 0; | ||||
|    virtual const std::vector<boost::gil::rgba8_pixel_t>& | ||||
|    RadarProductView(const RadarProductView&)            = delete; | ||||
|    RadarProductView(RadarProductView&&)                 = delete; | ||||
|    RadarProductView& operator=(const RadarProductView&) = delete; | ||||
|    RadarProductView& operator=(RadarProductView&&)      = delete; | ||||
| 
 | ||||
|    [[nodiscard]] virtual std::shared_ptr<common::ColorTable> | ||||
|    color_table() const = 0; | ||||
|    [[nodiscard]] virtual const std::vector<boost::gil::rgba8_pixel_t>& | ||||
|                                               color_table_lut() const; | ||||
|    virtual std::uint16_t                         color_table_min() const; | ||||
|    virtual std::uint16_t                         color_table_max() const; | ||||
|    virtual float                                 elevation() const; | ||||
|    virtual float                                 range() const; | ||||
|    virtual std::chrono::system_clock::time_point sweep_time() const; | ||||
|    virtual float                                 unit_scale() const = 0; | ||||
|    virtual std::string                           units() const      = 0; | ||||
|    virtual std::uint16_t                         vcp() const        = 0; | ||||
|    virtual const std::vector<float>&             vertices() const   = 0; | ||||
|    [[nodiscard]] virtual std::uint16_t        color_table_min() const; | ||||
|    [[nodiscard]] virtual std::uint16_t        color_table_max() const; | ||||
|    [[nodiscard]] virtual std::optional<float> elevation() const; | ||||
|    [[nodiscard]] virtual float                range() const; | ||||
|    [[nodiscard]] virtual std::chrono::system_clock::time_point | ||||
|                                                    sweep_time() const; | ||||
|    [[nodiscard]] virtual float                     unit_scale() const = 0; | ||||
|    [[nodiscard]] virtual std::string               units() const      = 0; | ||||
|    [[nodiscard]] virtual std::uint16_t             vcp() const        = 0; | ||||
|    [[nodiscard]] virtual const std::vector<float>& vertices() const   = 0; | ||||
| 
 | ||||
|    [[nodiscard]] std::shared_ptr<manager::RadarProductManager> | ||||
|    radar_product_manager() const; | ||||
|  | @ -66,24 +69,26 @@ public: | |||
|    void         SelectTime(std::chrono::system_clock::time_point time); | ||||
|    void         Update(); | ||||
| 
 | ||||
|    bool IsInitialized() const; | ||||
|    [[nodiscard]] bool IsInitialized() const; | ||||
| 
 | ||||
|    virtual common::RadarProductGroup GetRadarProductGroup() const = 0; | ||||
|    virtual std::string               GetRadarProductName() const  = 0; | ||||
|    virtual std::vector<float>        GetElevationCuts() const; | ||||
|    virtual std::tuple<const void*, std::size_t, std::size_t> | ||||
|    [[nodiscard]] virtual common::RadarProductGroup | ||||
|                                             GetRadarProductGroup() const = 0; | ||||
|    [[nodiscard]] virtual std::string        GetRadarProductName() const  = 0; | ||||
|    [[nodiscard]] virtual std::vector<float> GetElevationCuts() const; | ||||
|    [[nodiscard]] virtual std::tuple<const void*, std::size_t, std::size_t> | ||||
|    GetMomentData() const = 0; | ||||
|    virtual std::tuple<const void*, std::size_t, std::size_t> | ||||
|    [[nodiscard]] virtual std::tuple<const void*, std::size_t, std::size_t> | ||||
|    GetCfpMomentData() const; | ||||
| 
 | ||||
|    virtual std::optional<std::uint16_t> | ||||
|    [[nodiscard]] virtual std::optional<std::uint16_t> | ||||
|    GetBinLevel(const common::Coordinate& coordinate) const = 0; | ||||
|    virtual std::optional<wsr88d::DataLevelCode> | ||||
|    [[nodiscard]] virtual std::optional<wsr88d::DataLevelCode> | ||||
|    GetDataLevelCode(std::uint16_t level) const = 0; | ||||
|    virtual std::optional<float> GetDataValue(std::uint16_t level) const     = 0; | ||||
|    virtual bool                 IgnoreUnits() const; | ||||
|    [[nodiscard]] virtual std::optional<float> | ||||
|                               GetDataValue(std::uint16_t level) const = 0; | ||||
|    [[nodiscard]] virtual bool IgnoreUnits() const; | ||||
| 
 | ||||
|    virtual std::vector<std::pair<std::string, std::string>> | ||||
|    [[nodiscard]] virtual std::vector<std::pair<std::string, std::string>> | ||||
|    GetDescriptionFields() const; | ||||
| 
 | ||||
| protected: | ||||
|  | @ -105,6 +110,4 @@ private: | |||
|    std::unique_ptr<RadarProductViewImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace view
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::qt::view
 | ||||
|  |  | |||
|  | @ -9,11 +9,7 @@ | |||
| 
 | ||||
| #include <units/angle.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace wsr88d | ||||
| { | ||||
| namespace rpg | ||||
| namespace scwx::wsr88d::rpg | ||||
| { | ||||
| 
 | ||||
| class ProductDescriptionBlockImpl; | ||||
|  | @ -22,7 +18,7 @@ class ProductDescriptionBlock : public awips::Message | |||
| { | ||||
| public: | ||||
|    explicit ProductDescriptionBlock(); | ||||
|    ~ProductDescriptionBlock(); | ||||
|    ~ProductDescriptionBlock() override; | ||||
| 
 | ||||
|    ProductDescriptionBlock(const ProductDescriptionBlock&)            = delete; | ||||
|    ProductDescriptionBlock& operator=(const ProductDescriptionBlock&) = delete; | ||||
|  | @ -30,57 +26,59 @@ public: | |||
|    ProductDescriptionBlock(ProductDescriptionBlock&&) noexcept; | ||||
|    ProductDescriptionBlock& operator=(ProductDescriptionBlock&&) noexcept; | ||||
| 
 | ||||
|    int16_t  block_divider() const; | ||||
|    float    latitude_of_radar() const; | ||||
|    float    longitude_of_radar() const; | ||||
|    int16_t  height_of_radar() const; | ||||
|    int16_t  product_code() const; | ||||
|    uint16_t operational_mode() const; | ||||
|    uint16_t volume_coverage_pattern() const; | ||||
|    int16_t  sequence_number() const; | ||||
|    uint16_t volume_scan_number() const; | ||||
|    uint16_t volume_scan_date() const; | ||||
|    uint32_t volume_scan_start_time() const; | ||||
|    uint16_t generation_date_of_product() const; | ||||
|    uint32_t generation_time_of_product() const; | ||||
|    uint16_t elevation_number() const; | ||||
|    uint16_t data_level_threshold(size_t i) const; | ||||
|    uint8_t  version() const; | ||||
|    uint8_t  spot_blank() const; | ||||
|    uint32_t offset_to_symbology() const; | ||||
|    uint32_t offset_to_graphic() const; | ||||
|    uint32_t offset_to_tabular() const; | ||||
|    [[nodiscard]] int16_t  block_divider() const; | ||||
|    [[nodiscard]] float    latitude_of_radar() const; | ||||
|    [[nodiscard]] float    longitude_of_radar() const; | ||||
|    [[nodiscard]] int16_t  height_of_radar() const; | ||||
|    [[nodiscard]] int16_t  product_code() const; | ||||
|    [[nodiscard]] uint16_t operational_mode() const; | ||||
|    [[nodiscard]] uint16_t volume_coverage_pattern() const; | ||||
|    [[nodiscard]] int16_t  sequence_number() const; | ||||
|    [[nodiscard]] uint16_t volume_scan_number() const; | ||||
|    [[nodiscard]] uint16_t volume_scan_date() const; | ||||
|    [[nodiscard]] uint32_t volume_scan_start_time() const; | ||||
|    [[nodiscard]] uint16_t generation_date_of_product() const; | ||||
|    [[nodiscard]] uint32_t generation_time_of_product() const; | ||||
|    [[nodiscard]] uint16_t elevation_number() const; | ||||
|    [[nodiscard]] uint16_t data_level_threshold(size_t i) const; | ||||
|    [[nodiscard]] uint8_t  version() const; | ||||
|    [[nodiscard]] uint8_t  spot_blank() const; | ||||
|    [[nodiscard]] uint32_t offset_to_symbology() const; | ||||
|    [[nodiscard]] uint32_t offset_to_graphic() const; | ||||
|    [[nodiscard]] uint32_t offset_to_tabular() const; | ||||
| 
 | ||||
|    float    range() const; | ||||
|    uint16_t range_raw() const; | ||||
|    float    x_resolution() const; | ||||
|    uint16_t x_resolution_raw() const; | ||||
|    float    y_resolution() const; | ||||
|    uint16_t y_resolution_raw() const; | ||||
|    [[nodiscard]] float    range() const; | ||||
|    [[nodiscard]] uint16_t range_raw() const; | ||||
|    [[nodiscard]] float    x_resolution() const; | ||||
|    [[nodiscard]] uint16_t x_resolution_raw() const; | ||||
|    [[nodiscard]] float    y_resolution() const; | ||||
|    [[nodiscard]] uint16_t y_resolution_raw() const; | ||||
| 
 | ||||
|    uint16_t threshold() const; | ||||
|    float    offset() const; | ||||
|    float    scale() const; | ||||
|    uint16_t number_of_levels() const; | ||||
|    [[nodiscard]] uint16_t threshold() const; | ||||
|    [[nodiscard]] float    offset() const; | ||||
|    [[nodiscard]] float    scale() const; | ||||
|    [[nodiscard]] uint16_t number_of_levels() const; | ||||
| 
 | ||||
|    std::optional<DataLevelCode> data_level_code(std::uint8_t level) const; | ||||
|    std::optional<float>         data_value(std::uint8_t level) const; | ||||
|    [[nodiscard]] std::optional<DataLevelCode> | ||||
|                                       data_level_code(std::uint8_t level) const; | ||||
|    [[nodiscard]] std::optional<float> data_value(std::uint8_t level) const; | ||||
| 
 | ||||
|    std::uint16_t log_start() const; | ||||
|    float         log_offset() const; | ||||
|    float         log_scale() const; | ||||
|    [[nodiscard]] std::uint16_t log_start() const; | ||||
|    [[nodiscard]] float         log_offset() const; | ||||
|    [[nodiscard]] float         log_scale() const; | ||||
| 
 | ||||
|    float gr_scale() const; | ||||
|    [[nodiscard]] float gr_scale() const; | ||||
| 
 | ||||
|    std::uint8_t data_mask() const; | ||||
|    std::uint8_t topped_mask() const; | ||||
|    [[nodiscard]] std::uint8_t data_mask() const; | ||||
|    [[nodiscard]] std::uint8_t topped_mask() const; | ||||
| 
 | ||||
|    units::angle::degrees<double> elevation() const; | ||||
|    [[nodiscard]] units::angle::degrees<double> elevation() const; | ||||
|    [[nodiscard]] bool                          has_elevation() const; | ||||
| 
 | ||||
|    bool IsCompressionEnabled() const; | ||||
|    bool IsDataLevelCoded() const; | ||||
|    [[nodiscard]] bool IsCompressionEnabled() const; | ||||
|    [[nodiscard]] bool IsDataLevelCoded() const; | ||||
| 
 | ||||
|    size_t data_size() const override; | ||||
|    [[nodiscard]] size_t data_size() const override; | ||||
| 
 | ||||
|    bool Parse(std::istream& is) override; | ||||
| 
 | ||||
|  | @ -90,6 +88,4 @@ private: | |||
|    std::unique_ptr<ProductDescriptionBlockImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace rpg
 | ||||
| } // namespace wsr88d
 | ||||
| } // namespace scwx
 | ||||
| } // namespace scwx::wsr88d::rpg
 | ||||
|  |  | |||
|  | @ -724,14 +724,21 @@ units::angle::degrees<double> ProductDescriptionBlock::elevation() const | |||
| { | ||||
|    double elevation = 0.0; | ||||
| 
 | ||||
|    if (p->elevationNumber_ > 0) | ||||
|    if (has_elevation()) | ||||
|    { | ||||
|       elevation = p->parameters_[2] * 0.1; | ||||
|       // Elevation is given in tenths of a degree
 | ||||
|       // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||
|       elevation = static_cast<int16_t>(p->parameters_[2]) * 0.1; | ||||
|    } | ||||
| 
 | ||||
|    return units::angle::degrees<double> {elevation}; | ||||
| } | ||||
| 
 | ||||
| bool ProductDescriptionBlock::has_elevation() const | ||||
| { | ||||
|    return p->elevationNumber_ > 0; | ||||
| } | ||||
| 
 | ||||
| bool ProductDescriptionBlock::IsCompressionEnabled() const | ||||
| { | ||||
|    bool isCompressed = false; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat