diff --git a/scwx-qt/source/scwx/qt/map/alert_layer.cpp b/scwx-qt/source/scwx/qt/map/alert_layer.cpp index cc8bc29b..c0842758 100644 --- a/scwx-qt/source/scwx/qt/map/alert_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/alert_layer.cpp @@ -111,25 +111,27 @@ signals: class AlertLayer::Impl { public: + struct LineData + { + boost::gil::rgba32f_pixel_t borderColor_ {}; + boost::gil::rgba32f_pixel_t highlightColor_ {}; + boost::gil::rgba32f_pixel_t lineColor_ {}; + + std::size_t borderWidth_ {}; + std::size_t highlightWidth_ {}; + std::size_t lineWidth_ {}; + }; + explicit Impl(AlertLayer* self, std::shared_ptr context, awips::Phenomenon phenomenon) : self_ {self}, phenomenon_ {phenomenon}, + ibw_ {awips::ibw::GetImpactBasedWarningInfo(phenomenon)}, geoLines_ {{false, std::make_shared(context)}, {true, std::make_shared(context)}} { - auto& paletteSettings = settings::PaletteSettings::Instance(); - - for (auto alertActive : {false, true}) - { - lineColor_.emplace( - alertActive, - util::color::ToRgba32fPixelT( - paletteSettings.alert_color(phenomenon_, alertActive) - .GetValue())); - } - + UpdateLineData(); ConnectSignals(); ScheduleRefresh(); } @@ -158,6 +160,9 @@ public: const QPointF& mouseGlobalPos); void ScheduleRefresh(); + LineData& GetLineData(std::shared_ptr& segment); + void UpdateLineData(); + void AddLine(std::shared_ptr& geoLines, std::shared_ptr& di, const common::Coordinate& p1, @@ -177,6 +182,8 @@ public: boost::container::stable_vector< std::shared_ptr>& drawItems); + static LineData CreateLineData(const settings::LineSettings& lineSettings); + boost::asio::thread_pool threadPool_ {1u}; AlertLayer* self_; @@ -184,7 +191,8 @@ public: boost::asio::system_timer refreshTimer_ {threadPool_}; std::mutex refreshMutex_; - const awips::Phenomenon phenomenon_; + const awips::Phenomenon phenomenon_; + const awips::ibw::ImpactBasedWarningInfo& ibw_; std::unique_ptr receiver_ {std::make_unique()}; @@ -199,7 +207,10 @@ public: segmentsByLine_; std::mutex linesMutex_ {}; - std::unordered_map lineColor_; + std::unordered_map + threatCategoryLineData_; + LineData observedLineData_ {}; + LineData tornadoPossibleLineData_ {}; std::chrono::system_clock::time_point selectedTime_ {}; @@ -445,8 +456,8 @@ void AlertLayer::Impl::AddAlert( auto& startTime = segmentRecord->segmentBegin_; auto& endTime = segmentRecord->segmentEnd_; - auto& lineColor = lineColor_.at(alertActive); - auto& geoLines = geoLines_.at(alertActive); + auto& lineData = GetLineData(segment); + auto& geoLines = geoLines_.at(alertActive); const auto& coordinates = segment->codedLocation_->coordinates(); @@ -462,30 +473,51 @@ void AlertLayer::Impl::AddAlert( // If draw items were added if (drawItems.second) { + const float borderWidth = lineData.borderWidth_; + const float highlightWidth = lineData.highlightWidth_; + const float lineWidth = lineData.lineWidth_; + + const float totalHighlightWidth = lineWidth + (highlightWidth * 2.0f); + const float totalBorderWidth = totalHighlightWidth + (borderWidth * 2.0f); + + constexpr bool borderHover = true; + constexpr bool highlightHover = false; + constexpr bool lineHover = false; + // Add border AddLines(geoLines, coordinates, - kBlack_, - 5.0f, + lineData.borderColor_, + totalBorderWidth, startTime, endTime, - true, + borderHover, drawItems.first->second); - // Add only border to segmentsByLine_ + // Add border to segmentsByLine_ for (auto& di : drawItems.first->second) { segmentsByLine_.insert({di, segmentRecord}); } + // Add highlight + AddLines(geoLines, + coordinates, + lineData.highlightColor_, + totalHighlightWidth, + startTime, + endTime, + highlightHover, + drawItems.first->second); + // Add line AddLines(geoLines, coordinates, - lineColor, - 3.0f, + lineData.lineColor_, + lineWidth, startTime, endTime, - false, + lineHover, drawItems.first->second); } } @@ -638,6 +670,71 @@ void AlertLayer::Impl::HandleGeoLinesHover( } } +AlertLayer::Impl::LineData +AlertLayer::Impl::CreateLineData(const settings::LineSettings& lineSettings) +{ + return LineData {.borderColor_ {lineSettings.GetBorderColorRgba32f()}, + .highlightColor_ {lineSettings.GetHighlightColorRgba32f()}, + .lineColor_ {lineSettings.GetLineColorRgba32f()}, + .borderWidth_ {static_cast( + lineSettings.border_width().GetValue())}, + .highlightWidth_ {static_cast( + lineSettings.highlight_width().GetValue())}, + .lineWidth_ {static_cast( + lineSettings.line_width().GetValue())}}; +} + +void AlertLayer::Impl::UpdateLineData() +{ + auto& alertPalette = + settings::PaletteSettings().Instance().alert_palette(phenomenon_); + + for (auto threatCategory : ibw_.threatCategories_) + { + auto& palette = alertPalette.threat_category(threatCategory); + threatCategoryLineData_.insert_or_assign(threatCategory, + CreateLineData(palette)); + } + + if (ibw_.hasObservedTag_) + { + observedLineData_ = CreateLineData(alertPalette.observed()); + } + + if (ibw_.hasTornadoPossibleTag_) + { + tornadoPossibleLineData_ = + CreateLineData(alertPalette.tornado_possible()); + } +} + +AlertLayer::Impl::LineData& +AlertLayer::Impl::GetLineData(std::shared_ptr& segment) +{ + for (auto& threatCategory : ibw_.threatCategories_) + { + if (segment->threatCategory_ == threatCategory) + { + if (threatCategory == awips::ibw::ThreatCategory::Base) + { + if (ibw_.hasObservedTag_ && segment->observed_) + { + return observedLineData_; + } + + if (ibw_.hasTornadoPossibleTag_ && segment->tornadoPossible_) + { + return tornadoPossibleLineData_; + } + } + + return threatCategoryLineData_.at(threatCategory); + } + } + + return threatCategoryLineData_.at(awips::ibw::ThreatCategory::Base); +}; + AlertLayerHandler& AlertLayerHandler::Instance() { static AlertLayerHandler alertLayerHandler_ {}; diff --git a/scwx-qt/source/scwx/qt/settings/line_settings.cpp b/scwx-qt/source/scwx/qt/settings/line_settings.cpp index 105be812..45337fa2 100644 --- a/scwx-qt/source/scwx/qt/settings/line_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/line_settings.cpp @@ -104,6 +104,21 @@ SettingsVariable& LineSettings::line_width() const return p->lineWidth_; } +boost::gil::rgba32f_pixel_t LineSettings::GetBorderColorRgba32f() const +{ + return util::color::ToRgba32fPixelT(p->borderColor_.GetValue()); +} + +boost::gil::rgba32f_pixel_t LineSettings::GetHighlightColorRgba32f() const +{ + return util::color::ToRgba32fPixelT(p->highlightColor_.GetValue()); +} + +boost::gil::rgba32f_pixel_t LineSettings::GetLineColorRgba32f() const +{ + return util::color::ToRgba32fPixelT(p->lineColor_.GetValue()); +} + void LineSettings::StageValues(boost::gil::rgba8_pixel_t borderColor, boost::gil::rgba8_pixel_t highlightColor, boost::gil::rgba8_pixel_t lineColor, diff --git a/scwx-qt/source/scwx/qt/settings/line_settings.hpp b/scwx-qt/source/scwx/qt/settings/line_settings.hpp index bc9a9cb8..6f6988a2 100644 --- a/scwx-qt/source/scwx/qt/settings/line_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/line_settings.hpp @@ -35,6 +35,10 @@ public: SettingsVariable& highlight_width() const; SettingsVariable& line_width() const; + boost::gil::rgba32f_pixel_t GetBorderColorRgba32f() const; + boost::gil::rgba32f_pixel_t GetHighlightColorRgba32f() const; + boost::gil::rgba32f_pixel_t GetLineColorRgba32f() const; + void StageValues(boost::gil::rgba8_pixel_t borderColor, boost::gil::rgba8_pixel_t highlightColor, boost::gil::rgba8_pixel_t lineColor,