mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-29 21:00:06 +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);
|
||||
// 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;
|
||||
}
|
||||
|
||||
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)
|
||||
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.
|
||||
availableProducts.at(common::GetLevel3ProductByAwipsId(
|
||||
common::GetLevel3CategoryDefaultProduct(productCategory,
|
||||
categoryMap))) :
|
||||
// Has the same product
|
||||
availableTiltsIt->second;
|
||||
|
||||
// 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);
|
||||
ImGui::TextUnformatted(productName.c_str());
|
||||
|
||||
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>&
|
||||
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;
|
||||
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;
|
||||
[[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>
|
||||
GetDataLevelCode(std::uint16_t level) const override;
|
||||
std::optional<float> GetDataValue(std::uint16_t level) const override;
|
||||
[[nodiscard]] std::optional<wsr88d::DataLevelCode>
|
||||
GetDataLevelCode(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>&
|
||||
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;
|
||||
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;
|
||||
[[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>
|
||||
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<wsr88d::DataLevelCode>
|
||||
GetDataLevelCode(std::uint16_t level) const = 0;
|
||||
[[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