mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:20:06 +00:00 
			
		
		
		
	Draw bounding boxes around alerts
This commit is contained in:
		
							parent
							
								
									241f910220
								
							
						
					
					
						commit
						80baa8350d
					
				
					 4 changed files with 267 additions and 2 deletions
				
			
		|  | @ -64,7 +64,8 @@ set(SRC_MANAGER source/scwx/qt/manager/radar_product_manager.cpp | ||||||
|                 source/scwx/qt/manager/resource_manager.cpp |                 source/scwx/qt/manager/resource_manager.cpp | ||||||
|                 source/scwx/qt/manager/settings_manager.cpp |                 source/scwx/qt/manager/settings_manager.cpp | ||||||
|                 source/scwx/qt/manager/text_event_manager.cpp) |                 source/scwx/qt/manager/text_event_manager.cpp) | ||||||
| set(HDR_MAP source/scwx/qt/map/color_table_layer.hpp | set(HDR_MAP source/scwx/qt/map/alert_layer.hpp | ||||||
|  |             source/scwx/qt/map/color_table_layer.hpp | ||||||
|             source/scwx/qt/map/draw_layer.hpp |             source/scwx/qt/map/draw_layer.hpp | ||||||
|             source/scwx/qt/map/generic_layer.hpp |             source/scwx/qt/map/generic_layer.hpp | ||||||
|             source/scwx/qt/map/layer_wrapper.hpp |             source/scwx/qt/map/layer_wrapper.hpp | ||||||
|  | @ -74,7 +75,8 @@ set(HDR_MAP source/scwx/qt/map/color_table_layer.hpp | ||||||
|             source/scwx/qt/map/overlay_layer.hpp |             source/scwx/qt/map/overlay_layer.hpp | ||||||
|             source/scwx/qt/map/radar_product_layer.hpp |             source/scwx/qt/map/radar_product_layer.hpp | ||||||
|             source/scwx/qt/map/radar_range_layer.hpp) |             source/scwx/qt/map/radar_range_layer.hpp) | ||||||
| set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp | set(SRC_MAP source/scwx/qt/map/alert_layer.cpp | ||||||
|  |             source/scwx/qt/map/color_table_layer.cpp | ||||||
|             source/scwx/qt/map/draw_layer.cpp |             source/scwx/qt/map/draw_layer.cpp | ||||||
|             source/scwx/qt/map/generic_layer.cpp |             source/scwx/qt/map/generic_layer.cpp | ||||||
|             source/scwx/qt/map/layer_wrapper.cpp |             source/scwx/qt/map/layer_wrapper.cpp | ||||||
|  |  | ||||||
							
								
								
									
										227
									
								
								scwx-qt/source/scwx/qt/map/alert_layer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								scwx-qt/source/scwx/qt/map/alert_layer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,227 @@ | ||||||
|  | #include <scwx/qt/map/alert_layer.hpp> | ||||||
|  | #include <scwx/qt/manager/text_event_manager.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace map | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::map::alert_layer"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | static QMapbox::Coordinate | ||||||
|  | GetMapboxCoordinate(const common::Coordinate& coordinate); | ||||||
|  | static QMapbox::Coordinates | ||||||
|  | GetMapboxCoordinates(const awips::CodedLocation& codedLocation); | ||||||
|  | 
 | ||||||
|  | class AlertLayerHandler : public QObject | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  | public: | ||||||
|  |    explicit AlertLayerHandler() : | ||||||
|  |        alertSource_ {{"type", "geojson"}, | ||||||
|  |                      {"data", QVariant::fromValue(QList<QMapbox::Feature> {})}} | ||||||
|  |    { | ||||||
|  |       connect(&manager::TextEventManager::Instance(), | ||||||
|  |               &manager::TextEventManager::AlertUpdated, | ||||||
|  |               this, | ||||||
|  |               &AlertLayerHandler::HandleAlert); | ||||||
|  |    } | ||||||
|  |    ~AlertLayerHandler() = default; | ||||||
|  | 
 | ||||||
|  |    static AlertLayerHandler& Instance(); | ||||||
|  | 
 | ||||||
|  |    QList<QMapbox::Feature>* FeatureList(); | ||||||
|  |    void HandleAlert(const types::TextEventKey& key, size_t messageIndex); | ||||||
|  | 
 | ||||||
|  |    QVariantMap alertSource_; | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |    void AlertsUpdated(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class AlertLayerImpl : public QObject | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  | public: | ||||||
|  |    explicit AlertLayerImpl(std::shared_ptr<MapContext> context) : | ||||||
|  |        context_ {context} | ||||||
|  |    { | ||||||
|  |       connect(&AlertLayerHandler::Instance(), | ||||||
|  |               &AlertLayerHandler::AlertsUpdated, | ||||||
|  |               this, | ||||||
|  |               &AlertLayerImpl::UpdateSource); | ||||||
|  |    } | ||||||
|  |    ~AlertLayerImpl() = default; | ||||||
|  | 
 | ||||||
|  |    void UpdateSource(); | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<MapContext> context_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | AlertLayer::AlertLayer(std::shared_ptr<MapContext> context) : | ||||||
|  |     DrawLayer(context), p(std::make_unique<AlertLayerImpl>(context)) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AlertLayer::~AlertLayer() = default; | ||||||
|  | 
 | ||||||
|  | void AlertLayer::Initialize() | ||||||
|  | { | ||||||
|  |    logger_->debug("Initialize()"); | ||||||
|  | 
 | ||||||
|  |    DrawLayer::Initialize(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AlertLayer::Render(const QMapbox::CustomLayerRenderParameters& params) | ||||||
|  | { | ||||||
|  |    gl::OpenGLFunctions& gl = context()->gl(); | ||||||
|  | 
 | ||||||
|  |    DrawLayer::Render(params); | ||||||
|  | 
 | ||||||
|  |    SCWX_GL_CHECK_ERROR(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AlertLayer::Deinitialize() | ||||||
|  | { | ||||||
|  |    logger_->debug("Deinitialize()"); | ||||||
|  | 
 | ||||||
|  |    DrawLayer::Deinitialize(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AlertLayer::AddLayers(const std::string& before) | ||||||
|  | { | ||||||
|  |    logger_->debug("AddLayers()"); | ||||||
|  | 
 | ||||||
|  |    auto map = p->context_->map().lock(); | ||||||
|  |    if (map == nullptr) | ||||||
|  |    { | ||||||
|  |       return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (map->layerExists("alertPolygonLayerBg")) | ||||||
|  |    { | ||||||
|  |       map->removeLayer("alertPolygonLayerBg"); | ||||||
|  |    } | ||||||
|  |    if (map->layerExists("alertPolygonLayerFg")) | ||||||
|  |    { | ||||||
|  |       map->removeLayer("alertPolygonLayerFg"); | ||||||
|  |    } | ||||||
|  |    if (map->sourceExists("alertPolygon")) | ||||||
|  |    { | ||||||
|  |       map->removeSource("alertPolygon"); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    map->addSource("alertPolygon", AlertLayerHandler::Instance().alertSource_); | ||||||
|  | 
 | ||||||
|  |    map->addLayer({{"id", "alertPolygonLayerBg"}, | ||||||
|  |                   {"type", "line"}, | ||||||
|  |                   {"source", "alertPolygon"}}, | ||||||
|  |                  QString::fromStdString(before)); | ||||||
|  |    map->setLayoutProperty("alertPolygonLayerBg", "line-join", "round"); | ||||||
|  |    map->setLayoutProperty("alertPolygonLayerBg", "line-cap", "round"); | ||||||
|  |    map->setPaintProperty( | ||||||
|  |       "alertPolygonLayerBg", "line-color", "rgba(0, 0, 0, 255)"); | ||||||
|  |    map->setPaintProperty("alertPolygonLayerBg", "line-width", "5"); | ||||||
|  | 
 | ||||||
|  |    map->addLayer({{"id", "alertPolygonLayerFg"}, | ||||||
|  |                   {"type", "line"}, | ||||||
|  |                   {"source", "alertPolygon"}}, | ||||||
|  |                  QString::fromStdString(before)); | ||||||
|  |    map->setLayoutProperty("alertPolygonLayerFg", "line-join", "round"); | ||||||
|  |    map->setLayoutProperty("alertPolygonLayerFg", "line-cap", "round"); | ||||||
|  |    map->setPaintProperty( | ||||||
|  |       "alertPolygonLayerFg", "line-color", "rgba(255, 0, 0, 255)"); | ||||||
|  |    map->setPaintProperty("alertPolygonLayerFg", "line-width", "3"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QList<QMapbox::Feature>* AlertLayerHandler::FeatureList() | ||||||
|  | { | ||||||
|  |    return reinterpret_cast<QList<QMapbox::Feature>*>( | ||||||
|  |       alertSource_["data"].data()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AlertLayerHandler::HandleAlert(const types::TextEventKey& key, | ||||||
|  |                                     size_t                     messageIndex) | ||||||
|  | { | ||||||
|  |    auto message = | ||||||
|  |       manager::TextEventManager::Instance().message_list(key).at(messageIndex); | ||||||
|  |    bool alertUpdated = false; | ||||||
|  | 
 | ||||||
|  |    // TODO: Remove previous items
 | ||||||
|  | 
 | ||||||
|  |    for (auto segment : message->segments()) | ||||||
|  |    { | ||||||
|  |       if (!segment->codedLocation_.has_value()) | ||||||
|  |       { | ||||||
|  |          continue; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Add alert location to polygon list
 | ||||||
|  |       auto mapboxCoordinates = | ||||||
|  |          GetMapboxCoordinates(segment->codedLocation_.value()); | ||||||
|  | 
 | ||||||
|  |       FeatureList()->push_back( | ||||||
|  |          {QMapbox::Feature::PolygonType, | ||||||
|  |           std::initializer_list<QMapbox::CoordinatesCollection> { | ||||||
|  |              std::initializer_list<QMapbox::Coordinates> { | ||||||
|  |                 {mapboxCoordinates}}}}); | ||||||
|  | 
 | ||||||
|  |       alertUpdated = true; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (alertUpdated) | ||||||
|  |    { | ||||||
|  |       emit AlertsUpdated(); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AlertLayerImpl::UpdateSource() | ||||||
|  | { | ||||||
|  |    auto map = context_->map().lock(); | ||||||
|  |    if (map == nullptr) | ||||||
|  |    { | ||||||
|  |       return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    map->updateSource("alertPolygon", | ||||||
|  |                      AlertLayerHandler::Instance().alertSource_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AlertLayerHandler& AlertLayerHandler::Instance() | ||||||
|  | { | ||||||
|  |    static AlertLayerHandler alertLayerHandler {}; | ||||||
|  |    return alertLayerHandler; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static QMapbox::Coordinate | ||||||
|  | GetMapboxCoordinate(const common::Coordinate& coordinate) | ||||||
|  | { | ||||||
|  |    return {coordinate.latitude_, coordinate.longitude_}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static QMapbox::Coordinates | ||||||
|  | GetMapboxCoordinates(const awips::CodedLocation& codedLocation) | ||||||
|  | { | ||||||
|  |    auto                 scwxCoordinates = codedLocation.coordinates(); | ||||||
|  |    QMapbox::Coordinates mapboxCoordinates(scwxCoordinates.size() + 1u); | ||||||
|  | 
 | ||||||
|  |    std::transform(scwxCoordinates.cbegin(), | ||||||
|  |                   scwxCoordinates.cend(), | ||||||
|  |                   mapboxCoordinates.begin(), | ||||||
|  |                   [](auto& coordinate) -> QMapbox::Coordinate | ||||||
|  |                   { return GetMapboxCoordinate(coordinate); }); | ||||||
|  | 
 | ||||||
|  |    mapboxCoordinates.back() = GetMapboxCoordinate(scwxCoordinates.front()); | ||||||
|  | 
 | ||||||
|  |    return mapboxCoordinates; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace map
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | 
 | ||||||
|  | #include "alert_layer.moc" | ||||||
							
								
								
									
										32
									
								
								scwx-qt/source/scwx/qt/map/alert_layer.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								scwx-qt/source/scwx/qt/map/alert_layer.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/qt/map/draw_layer.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace map | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class AlertLayerImpl; | ||||||
|  | 
 | ||||||
|  | class AlertLayer : public DrawLayer | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit AlertLayer(std::shared_ptr<MapContext> context); | ||||||
|  |    ~AlertLayer(); | ||||||
|  | 
 | ||||||
|  |    void Initialize() override final; | ||||||
|  |    void Render(const QMapbox::CustomLayerRenderParameters&) override final; | ||||||
|  |    void Deinitialize() override final; | ||||||
|  | 
 | ||||||
|  |    void AddLayers(const std::string& before = {}); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    std::unique_ptr<AlertLayerImpl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace map
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| #include <scwx/qt/gl/gl.hpp> | #include <scwx/qt/gl/gl.hpp> | ||||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | #include <scwx/qt/manager/radar_product_manager.hpp> | ||||||
| #include <scwx/qt/manager/settings_manager.hpp> | #include <scwx/qt/manager/settings_manager.hpp> | ||||||
|  | #include <scwx/qt/map/alert_layer.hpp> | ||||||
| #include <scwx/qt/map/color_table_layer.hpp> | #include <scwx/qt/map/color_table_layer.hpp> | ||||||
| #include <scwx/qt/map/layer_wrapper.hpp> | #include <scwx/qt/map/layer_wrapper.hpp> | ||||||
| #include <scwx/qt/map/overlay_layer.hpp> | #include <scwx/qt/map/overlay_layer.hpp> | ||||||
|  | @ -59,6 +60,7 @@ public: | ||||||
|        layerList_ {}, |        layerList_ {}, | ||||||
|        radarProductManager_ {nullptr}, |        radarProductManager_ {nullptr}, | ||||||
|        radarProductLayer_ {nullptr}, |        radarProductLayer_ {nullptr}, | ||||||
|  |        alertLayer_ {std::make_shared<AlertLayer>(context_)}, | ||||||
|        overlayLayer_ {nullptr}, |        overlayLayer_ {nullptr}, | ||||||
|        colorTableLayer_ {nullptr}, |        colorTableLayer_ {nullptr}, | ||||||
|        autoRefreshEnabled_ {true}, |        autoRefreshEnabled_ {true}, | ||||||
|  | @ -104,6 +106,7 @@ public: | ||||||
|    std::shared_ptr<common::ColorTable> colorTable_; |    std::shared_ptr<common::ColorTable> colorTable_; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<RadarProductLayer> radarProductLayer_; |    std::shared_ptr<RadarProductLayer> radarProductLayer_; | ||||||
|  |    std::shared_ptr<AlertLayer>        alertLayer_; | ||||||
|    std::shared_ptr<OverlayLayer>      overlayLayer_; |    std::shared_ptr<OverlayLayer>      overlayLayer_; | ||||||
|    std::shared_ptr<ColorTableLayer>   colorTableLayer_; |    std::shared_ptr<ColorTableLayer>   colorTableLayer_; | ||||||
| 
 | 
 | ||||||
|  | @ -522,6 +525,7 @@ void MapWidget::AddLayers() | ||||||
|       p->AddLayer("colorTable", p->colorTableLayer_); |       p->AddLayer("colorTable", p->colorTableLayer_); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    p->alertLayer_->AddLayers("colorTable"); | ||||||
|    p->overlayLayer_ = std::make_shared<OverlayLayer>(p->context_); |    p->overlayLayer_ = std::make_shared<OverlayLayer>(p->context_); | ||||||
|    p->AddLayer("overlay", p->overlayLayer_); |    p->AddLayer("overlay", p->overlayLayer_); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat