diff --git a/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp b/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp index fb826ca5..cbc7da0c 100644 --- a/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/radar_product_layer.cpp @@ -395,14 +395,24 @@ bool RadarProductLayer::RunMousePicking( std::string suffix {}; std::string hoverText; - std::shared_ptr colorTable = - radarProductView->color_table(); - - if (colorTable != nullptr) + // Determine units from radar product view + units = radarProductView->units(); + if (!units.empty()) { - // Scale data value according to the color table, and get units - f = f * colorTable->scale() + colorTable->offset(); - units = colorTable->units(); + f = f * radarProductView->unit_scale(); + } + else + { + std::shared_ptr colorTable = + radarProductView->color_table(); + + if (colorTable != nullptr) + { + // Scale data value according to the color table, and get + // units + f = f * colorTable->scale() + colorTable->offset(); + units = colorTable->units(); + } } if (code.has_value() && diff --git a/scwx-qt/source/scwx/qt/types/unit_types.cpp b/scwx-qt/source/scwx/qt/types/unit_types.cpp index 308107aa..fb242dd7 100644 --- a/scwx-qt/source/scwx/qt/types/unit_types.cpp +++ b/scwx-qt/source/scwx/qt/types/unit_types.cpp @@ -4,6 +4,7 @@ #include #include +#include namespace scwx { @@ -15,8 +16,8 @@ namespace types static const std::unordered_map accumulationUnitsAbbreviation_ {{AccumulationUnits::Inches, "in"}, {AccumulationUnits::Millimeters, "mm"}, - {AccumulationUnits::User, "?"}, - {AccumulationUnits::Unknown, "?"}}; + {AccumulationUnits::User, ""}, + {AccumulationUnits::Unknown, ""}}; static const std::unordered_map accumulationUnitsName_ {{AccumulationUnits::Inches, "Inches"}, @@ -27,8 +28,8 @@ static const std::unordered_map static const std::unordered_map echoTopsUnitsAbbreviation_ {{EchoTopsUnits::Kilofeet, "kft"}, {EchoTopsUnits::Kilometers, "km"}, - {EchoTopsUnits::User, "?"}, - {EchoTopsUnits::Unknown, "?"}}; + {EchoTopsUnits::User, ""}, + {EchoTopsUnits::Unknown, ""}}; static const std::unordered_map echoTopsUnitsName_ { {EchoTopsUnits::Kilofeet, "Kilofeet"}, @@ -41,8 +42,8 @@ static const std::unordered_map {SpeedUnits::Knots, "kts"}, {SpeedUnits::MilesPerHour, "mph"}, {SpeedUnits::MetersPerSecond, "m/s"}, - {SpeedUnits::User, "?"}, - {SpeedUnits::Unknown, "?"}}; + {SpeedUnits::User, ""}, + {SpeedUnits::Unknown, ""}}; static const std::unordered_map speedUnitsName_ { {SpeedUnits::KilometersPerHour, "Kilometers per hour"}, @@ -52,6 +53,18 @@ static const std::unordered_map speedUnitsName_ { {SpeedUnits::User, "User-defined"}, {SpeedUnits::Unknown, "?"}}; +static constexpr auto speedUnitsBase_ = units::meters_per_second {1.0f}; +static const std::unordered_map speedUnitsScale_ { + {SpeedUnits::KilometersPerHour, + (speedUnitsBase_ / units::kilometers_per_hour {1.0f})}, + {SpeedUnits::Knots, (speedUnitsBase_ / units::knots {1.0f})}, + {SpeedUnits::MilesPerHour, + (speedUnitsBase_ / units::miles_per_hour {1.0f})}, + {SpeedUnits::MetersPerSecond, + (speedUnitsBase_ / units::meters_per_second {1.0f})}, + {SpeedUnits::User, 1.0f}, + {SpeedUnits::Unknown, 1.0f}}; + SCWX_GET_ENUM(AccumulationUnits, GetAccumulationUnitsFromName, accumulationUnitsName_) @@ -88,6 +101,11 @@ const std::string& GetSpeedUnitsName(SpeedUnits units) return speedUnitsName_.at(units); } +float GetSpeedUnitsScale(SpeedUnits units) +{ + return speedUnitsScale_.at(units); +} + } // namespace types } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/unit_types.hpp b/scwx-qt/source/scwx/qt/types/unit_types.hpp index 2d844a40..f0c2147f 100644 --- a/scwx-qt/source/scwx/qt/types/unit_types.hpp +++ b/scwx-qt/source/scwx/qt/types/unit_types.hpp @@ -58,6 +58,7 @@ EchoTopsUnits GetEchoTopsUnitsFromName(const std::string& name); const std::string& GetSpeedUnitsAbbreviation(SpeedUnits units); const std::string& GetSpeedUnitsName(SpeedUnits units); SpeedUnits GetSpeedUnitsFromName(const std::string& name); +float GetSpeedUnitsScale(SpeedUnits units); } // namespace types } // namespace qt diff --git a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp index f0199c4b..7fd8df11 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -68,17 +70,33 @@ public: savedScale_ {0.0f}, savedOffset_ {0.0f} { + auto& unitSettings = settings::UnitSettings::Instance(); + coordinates_.resize(kMaxCoordinates_); SetProduct(product); + + speedUnitsCallbackUuid_ = + unitSettings.speed_units().RegisterValueChangedCallback( + [this](const std::string& value) { UpdateSpeedUnits(value); }); + + UpdateSpeedUnits(unitSettings.speed_units().GetValue()); } - ~Level2ProductViewImpl() { threadPool_.join(); }; + ~Level2ProductViewImpl() + { + auto& unitSettings = settings::UnitSettings::Instance(); + unitSettings.speed_units().UnregisterValueChangedCallback( + speedUnitsCallbackUuid_); + + threadPool_.join(); + }; void ComputeCoordinates(std::shared_ptr radarData); void SetProduct(const std::string& productName); void SetProduct(common::Level2Product product); + void UpdateSpeedUnits(const std::string& name); Level2ProductView* self_; @@ -116,6 +134,9 @@ public: std::shared_ptr savedColorTable_; float savedScale_; float savedOffset_; + + boost::uuids::uuid speedUnitsCallbackUuid_ {}; + types::SpeedUnits speedUnits_ {types::SpeedUnits::Unknown}; }; Level2ProductView::Level2ProductView( @@ -221,6 +242,36 @@ std::chrono::system_clock::time_point Level2ProductView::sweep_time() const return p->sweepTime_; } +float Level2ProductView::unit_scale() const +{ + switch (p->dataBlockType_) + { + case wsr88d::rda::DataBlockType::MomentVel: + case wsr88d::rda::DataBlockType::MomentSw: + return types::GetSpeedUnitsScale(p->speedUnits_); + + default: + break; + } + + return 1.0f; +} + +std::string Level2ProductView::units() const +{ + switch (p->dataBlockType_) + { + case wsr88d::rda::DataBlockType::MomentVel: + case wsr88d::rda::DataBlockType::MomentSw: + return types::GetSpeedUnitsAbbreviation(p->speedUnits_); + + default: + break; + } + + return {}; +} + uint16_t Level2ProductView::vcp() const { return p->vcp_; @@ -323,6 +374,11 @@ void Level2ProductViewImpl::SetProduct(common::Level2Product product) } } +void Level2ProductViewImpl::UpdateSpeedUnits(const std::string& name) +{ + speedUnits_ = types::GetSpeedUnitsFromName(name); +} + void Level2ProductView::UpdateColorTableLut() { if (p->momentDataBlock0_ == nullptr || // diff --git a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp index 22dd4325..9e25a254 100644 --- a/scwx-qt/source/scwx/qt/view/level2_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level2_product_view.hpp @@ -35,6 +35,8 @@ public: 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& vertices() const override; diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp index 812fffbb..cca7d1c0 100644 --- a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp @@ -143,6 +143,16 @@ uint16_t Level3ProductView::color_table_max() const } } +float Level3ProductView::unit_scale() const +{ + return 1.0f; +} + +std::string Level3ProductView::units() const +{ + return {}; +} + std::shared_ptr Level3ProductView::graphic_product_message() const { diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.hpp b/scwx-qt/source/scwx/qt/view/level3_product_view.hpp index ce4af875..e836c6e0 100644 --- a/scwx-qt/source/scwx/qt/view/level3_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.hpp @@ -30,6 +30,8 @@ public: color_table_lut() const override; std::uint16_t color_table_min() const override; std::uint16_t color_table_max() const override; + float unit_scale() const override; + std::string units() const override; void LoadColorTable(std::shared_ptr colorTable) override; diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp index 5122c26a..c695a9e5 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -42,8 +42,10 @@ public: virtual float elevation() const; virtual float range() const; virtual std::chrono::system_clock::time_point sweep_time() const; - virtual std::uint16_t vcp() const = 0; - virtual const std::vector& vertices() const = 0; + virtual float unit_scale() const = 0; + virtual std::string units() const = 0; + virtual std::uint16_t vcp() const = 0; + virtual const std::vector& vertices() const = 0; std::shared_ptr radar_product_manager() const; std::chrono::system_clock::time_point selected_time() const;