mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:10:04 +00:00 
			
		
		
		
	Add alert layer lines
This commit is contained in:
		
							parent
							
								
									037e0922b0
								
							
						
					
					
						commit
						b2d648e960
					
				
					 1 changed files with 186 additions and 7 deletions
				
			
		|  | @ -1,5 +1,8 @@ | |||
| #include <scwx/qt/map/alert_layer.hpp> | ||||
| #include <scwx/qt/gl/draw/geo_lines.hpp> | ||||
| #include <scwx/qt/manager/text_event_manager.hpp> | ||||
| #include <scwx/qt/settings/palette_settings.hpp> | ||||
| #include <scwx/qt/util/color.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <chrono> | ||||
|  | @ -20,6 +23,8 @@ namespace map | |||
| static const std::string logPrefix_ = "scwx::qt::map::alert_layer"; | ||||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||
| 
 | ||||
| static const boost::gil::rgba32f_pixel_t kBlack_ {0.0f, 0.0f, 0.0f, 1.0f}; | ||||
| 
 | ||||
| template<class Key> | ||||
| struct AlertTypeHash; | ||||
| 
 | ||||
|  | @ -29,7 +34,7 @@ struct AlertTypeHash<std::pair<awips::Phenomenon, bool>> | |||
|    size_t operator()(const std::pair<awips::Phenomenon, bool>& x) const; | ||||
| }; | ||||
| 
 | ||||
| class AlertLayerHandler : QObject | ||||
| class AlertLayerHandler : public QObject | ||||
| { | ||||
|    Q_OBJECT | ||||
| public: | ||||
|  | @ -92,26 +97,83 @@ public: | |||
|    std::mutex alertMutex_ {}; | ||||
| 
 | ||||
| signals: | ||||
|    void AlertAdded(const std::shared_ptr<SegmentRecord>& segmentRecord, | ||||
|                    awips::Phenomenon                     phenomenon); | ||||
|    void AlertUpdated(const std::shared_ptr<SegmentRecord>& segmentRecord); | ||||
|    void AlertsUpdated(awips::Phenomenon phenomenon, bool alertActive); | ||||
| }; | ||||
| 
 | ||||
| class AlertLayer::Impl | ||||
| { | ||||
| public: | ||||
|    explicit Impl([[maybe_unused]] std::shared_ptr<MapContext> context, | ||||
|                  awips::Phenomenon                            phenomenon) : | ||||
|        phenomenon_ {phenomenon} | ||||
|    explicit Impl(std::shared_ptr<MapContext> context, | ||||
|                  awips::Phenomenon           phenomenon) : | ||||
|        phenomenon_ {phenomenon}, | ||||
|        borders_ {{false, std::make_shared<gl::draw::GeoLines>(context)}, | ||||
|                  {true, std::make_shared<gl::draw::GeoLines>(context)}}, | ||||
|        lines_ {{false, std::make_shared<gl::draw::GeoLines>(context)}, | ||||
|                {true, std::make_shared<gl::draw::GeoLines>(context)}} | ||||
|    { | ||||
|    } | ||||
|    ~Impl() {}; | ||||
|       auto& paletteSettings = settings::PaletteSettings::Instance(); | ||||
| 
 | ||||
|    awips::Phenomenon phenomenon_; | ||||
|       for (auto alertActive : {false, true}) | ||||
|       { | ||||
|          lineColor_.emplace( | ||||
|             alertActive, | ||||
|             util::color::ToRgba8PixelT( | ||||
|                paletteSettings.alert_color(phenomenon_, alertActive) | ||||
|                   .GetValue())); | ||||
|       } | ||||
| 
 | ||||
|       ConnectSignals(); | ||||
|    } | ||||
|    ~Impl() { receiver_ = nullptr; }; | ||||
| 
 | ||||
|    void AddAlert( | ||||
|       const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord); | ||||
|    void UpdateAlert( | ||||
|       const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord); | ||||
|    void ConnectSignals(); | ||||
| 
 | ||||
|    static void AddLine(std::shared_ptr<gl::draw::GeoLines>&        lines, | ||||
|                        std::shared_ptr<gl::draw::GeoLineDrawItem>& di, | ||||
|                        const common::Coordinate&                   p1, | ||||
|                        const common::Coordinate&                   p2, | ||||
|                        boost::gil::rgba32f_pixel_t                 color, | ||||
|                        float                                       width, | ||||
|                        std::chrono::system_clock::time_point       startTime, | ||||
|                        std::chrono::system_clock::time_point       endTime); | ||||
|    static void | ||||
|    AddLines(std::shared_ptr<gl::draw::GeoLines>&   lines, | ||||
|             const std::vector<common::Coordinate>& coordinates, | ||||
|             boost::gil::rgba32_pixel_t             color, | ||||
|             float                                  width, | ||||
|             std::chrono::system_clock::time_point  startTime, | ||||
|             std::chrono::system_clock::time_point  endTime, | ||||
|             std::vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems); | ||||
| 
 | ||||
|    const awips::Phenomenon phenomenon_; | ||||
| 
 | ||||
|    std::unique_ptr<QObject> receiver_ {std::make_unique<QObject>()}; | ||||
| 
 | ||||
|    std::unordered_map<bool, std::shared_ptr<gl::draw::GeoLines>> borders_; | ||||
|    std::unordered_map<bool, std::shared_ptr<gl::draw::GeoLines>> lines_; | ||||
| 
 | ||||
|    std::unordered_map<bool, boost::gil::rgba8_pixel_t> lineColor_; | ||||
| }; | ||||
| 
 | ||||
| AlertLayer::AlertLayer(std::shared_ptr<MapContext> context, | ||||
|                        awips::Phenomenon           phenomenon) : | ||||
|     DrawLayer(context), p(std::make_unique<Impl>(context, phenomenon)) | ||||
| { | ||||
|    for (auto alertActive : {false, true}) | ||||
|    { | ||||
|       auto& borders = p->borders_.at(alertActive); | ||||
|       auto& lines   = p->lines_.at(alertActive); | ||||
| 
 | ||||
|       AddDrawItem(borders); | ||||
|       AddDrawItem(lines); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| AlertLayer::~AlertLayer() = default; | ||||
|  | @ -121,6 +183,18 @@ void AlertLayer::Initialize() | |||
|    logger_->debug("Initialize: {}", awips::GetPhenomenonText(p->phenomenon_)); | ||||
| 
 | ||||
|    DrawLayer::Initialize(); | ||||
| 
 | ||||
|    for (auto alertActive : {false, true}) | ||||
|    { | ||||
|       auto& borders = p->borders_.at(alertActive); | ||||
|       auto& lines   = p->lines_.at(alertActive); | ||||
| 
 | ||||
|       borders->StartLines(); | ||||
|       borders->FinishLines(); | ||||
| 
 | ||||
|       lines->StartLines(); | ||||
|       lines->FinishLines(); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void AlertLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
|  | @ -183,6 +257,8 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, | |||
|       if (segmentRecord->segmentEnd_ > segmentBegin) | ||||
|       { | ||||
|          segmentRecord->segmentEnd_ = segmentBegin; | ||||
| 
 | ||||
|          Q_EMIT AlertUpdated(segmentRecord); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|  | @ -210,6 +286,8 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, | |||
|       segmentsForKey.push_back(segmentRecord); | ||||
|       segmentsForType.push_back(segmentRecord); | ||||
| 
 | ||||
|       Q_EMIT AlertAdded(segmentRecord, phenomenon); | ||||
| 
 | ||||
|       alertsUpdated.emplace(phenomenon, alertActive); | ||||
|    } | ||||
| 
 | ||||
|  | @ -223,6 +301,107 @@ void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, | |||
|    } | ||||
| } | ||||
| 
 | ||||
| void AlertLayer::Impl::ConnectSignals() | ||||
| { | ||||
|    QObject::connect( | ||||
|       &AlertLayerHandler::Instance(), | ||||
|       &AlertLayerHandler::AlertAdded, | ||||
|       receiver_.get(), | ||||
|       [this]( | ||||
|          const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord, | ||||
|          awips::Phenomenon                                        phenomenon) | ||||
|       { | ||||
|          if (phenomenon == phenomenon_) | ||||
|          { | ||||
|             AddAlert(segmentRecord); | ||||
|          } | ||||
|       }); | ||||
| } | ||||
| 
 | ||||
| void AlertLayer::Impl::AddAlert( | ||||
|    const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord) | ||||
| { | ||||
|    auto& segment = segmentRecord->segment_; | ||||
| 
 | ||||
|    auto& vtec        = segment->header_->vtecString_.front(); | ||||
|    auto  action      = vtec.pVtec_.action(); | ||||
|    bool  alertActive = (action != awips::PVtec::Action::Canceled); | ||||
|    auto& startTime   = segmentRecord->segmentBegin_; | ||||
|    auto& endTime     = segmentRecord->segmentEnd_; | ||||
| 
 | ||||
|    auto& lineColor = lineColor_.at(alertActive); | ||||
|    auto& lines     = lines_.at(alertActive); | ||||
| 
 | ||||
|    const auto& coordinates = segment->codedLocation_->coordinates(); | ||||
| 
 | ||||
|    std::vector<std::shared_ptr<gl::draw::GeoLineDrawItem>> drawItems {}; | ||||
| 
 | ||||
|    AddLines(lines, coordinates, kBlack_, 5.0f, startTime, endTime, drawItems); | ||||
|    AddLines(lines, coordinates, lineColor, 3.0f, startTime, endTime, drawItems); | ||||
| 
 | ||||
|    lines->FinishLines(); | ||||
| } | ||||
| 
 | ||||
| void AlertLayer::Impl::UpdateAlert( | ||||
|    [[maybe_unused]] const std::shared_ptr<AlertLayerHandler::SegmentRecord>& | ||||
|       segmentRecord) | ||||
| { | ||||
|    // TODO
 | ||||
| } | ||||
| 
 | ||||
| void AlertLayer::Impl::AddLines( | ||||
|    std::shared_ptr<gl::draw::GeoLines>&                     lines, | ||||
|    const std::vector<common::Coordinate>&                   coordinates, | ||||
|    boost::gil::rgba32_pixel_t                               color, | ||||
|    float                                                    width, | ||||
|    std::chrono::system_clock::time_point                    startTime, | ||||
|    std::chrono::system_clock::time_point                    endTime, | ||||
|    std::vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems) | ||||
| { | ||||
|    for (std::size_t i = 0, j = 1; i < coordinates.size(); ++i, ++j) | ||||
|    { | ||||
|       if (j >= coordinates.size()) | ||||
|       { | ||||
|          j = 0; | ||||
| 
 | ||||
|          // Ignore repeated coordinates at the end
 | ||||
|          if (coordinates[i] == coordinates[j]) | ||||
|          { | ||||
|             break; | ||||
|          } | ||||
|       } | ||||
| 
 | ||||
|       auto di = lines->AddLine(); | ||||
|       AddLine(lines, | ||||
|               di, | ||||
|               coordinates[i], | ||||
|               coordinates[j], | ||||
|               color, | ||||
|               width, | ||||
|               startTime, | ||||
|               endTime); | ||||
| 
 | ||||
|       drawItems.push_back(di); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void AlertLayer::Impl::AddLine(std::shared_ptr<gl::draw::GeoLines>& lines, | ||||
|                                std::shared_ptr<gl::draw::GeoLineDrawItem>& di, | ||||
|                                const common::Coordinate&                   p1, | ||||
|                                const common::Coordinate&                   p2, | ||||
|                                boost::gil::rgba32f_pixel_t           color, | ||||
|                                float                                 width, | ||||
|                                std::chrono::system_clock::time_point startTime, | ||||
|                                std::chrono::system_clock::time_point endTime) | ||||
| { | ||||
|    lines->SetLineLocation( | ||||
|       di, p1.latitude_, p1.longitude_, p2.latitude_, p2.longitude_); | ||||
|    lines->SetLineModulate(di, color); | ||||
|    lines->SetLineWidth(di, width); | ||||
|    lines->SetLineStartTime(di, startTime); | ||||
|    lines->SetLineEndTime(di, endTime); | ||||
| } | ||||
| 
 | ||||
| AlertLayerHandler& AlertLayerHandler::Instance() | ||||
| { | ||||
|    static AlertLayerHandler alertLayerHandler_ {}; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat