diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp index 978f37d8..ff3da32f 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.cpp @@ -109,7 +109,7 @@ bool PlacefileManager::placefile_thresholded(const std::string& name) return false; } -std::shared_ptr +std::shared_ptr PlacefileManager::placefile(const std::string& name) { std::shared_lock lock(p->placefileRecordLock_); diff --git a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp index 5776bb48..c2cf2d45 100644 --- a/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp +++ b/scwx-qt/source/scwx/qt/manager/placefile_manager.hpp @@ -22,7 +22,7 @@ public: bool placefile_enabled(const std::string& name); bool placefile_thresholded(const std::string& name); - std::shared_ptr placefile(const std::string& name); + std::shared_ptr placefile(const std::string& name); void set_placefile_enabled(const std::string& name, bool enabled); void set_placefile_thresholded(const std::string& name, bool thresholded); diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp index 710da1e9..d318ad3d 100644 --- a/scwx-qt/source/scwx/qt/map/map_widget.cpp +++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -124,12 +125,16 @@ public: void RadarProductManagerDisconnect(); void RadarProductViewConnect(); void RadarProductViewDisconnect(); + void RemovePlacefileLayer(const std::string& placefileName); void SetRadarSite(const std::string& radarSite); + void UpdatePlacefileLayers(); bool UpdateStoredMapParameters(); common::Level2Product GetLevel2ProductOrDefault(const std::string& productName) const; + static std::string GetPlacefileLayerName(const std::string& placefileName); + boost::asio::thread_pool threadPool_ {1u}; boost::uuids::uuid uuid_; @@ -158,6 +163,9 @@ public: std::shared_ptr placefileLayer_; std::shared_ptr colorTableLayer_; + std::set enabledPlacefiles_ {}; + std::list> placefileLayers_ {}; + bool autoRefreshEnabled_; bool autoUpdateEnabled_; @@ -199,11 +207,28 @@ void MapWidgetImpl::ConnectSignals() connect(placefileManager_.get(), &manager::PlacefileManager::PlacefileEnabled, widget_, - [this]() { widget_->update(); }); + [this](const std::string& name, bool enabled) + { + if (enabled && !enabledPlacefiles_.contains(name)) + { + enabledPlacefiles_.emplace(name); + UpdatePlacefileLayers(); + } + else if (!enabled && enabledPlacefiles_.contains(name)) + { + enabledPlacefiles_.erase(name); + RemovePlacefileLayer(name); + } + widget_->update(); + }); connect(placefileManager_.get(), &manager::PlacefileManager::PlacefileRenamed, widget_, - [this]() { widget_->update(); }); + [this]() + { + // TODO + widget_->update(); + }); connect(placefileManager_.get(), &manager::PlacefileManager::PlacefileUpdated, widget_, @@ -679,6 +704,7 @@ void MapWidget::AddLayers() p->map_->removeLayer(id.c_str()); } p->layerList_.clear(); + p->placefileLayers_.clear(); auto radarProductView = p->context_->radar_product_view(); @@ -724,13 +750,68 @@ void MapWidget::AddLayers() p->alertLayer_->AddLayers("colorTable"); - p->placefileLayer_ = std::make_shared(p->context_); - p->AddLayer("placefile", p->placefileLayer_); + p->UpdatePlacefileLayers(); p->overlayLayer_ = std::make_shared(p->context_); p->AddLayer("overlay", p->overlayLayer_); } +void MapWidgetImpl::RemovePlacefileLayer(const std::string& placefileName) +{ + std::string layerName = GetPlacefileLayerName(placefileName); + + // Remove layer from map + map_->removeLayer(layerName.c_str()); + + // Remove layer from internal layer list + auto layerIt = std::find(layerList_.begin(), layerList_.end(), layerName); + if (layerIt != layerList_.end()) + { + layerList_.erase(layerIt); + } + + // Determine if a layer exists for the placefile + auto placefileIt = + std::find_if(placefileLayers_.begin(), + placefileLayers_.end(), + [&placefileName](auto& layer) + { return placefileName == layer->placefile_name(); }); + if (placefileIt != placefileLayers_.end()) + { + placefileLayers_.erase(placefileIt); + } +} + +void MapWidgetImpl::UpdatePlacefileLayers() +{ + // Loop through enabled placefiles + for (auto& placefileName : enabledPlacefiles_) + { + // Determine if a layer exists for the placefile + auto it = std::find_if(placefileLayers_.begin(), + placefileLayers_.end(), + [&placefileName](auto& layer) { + return placefileName == layer->placefile_name(); + }); + + // If the layer doesn't exist, create it + if (it == placefileLayers_.end()) + { + std::shared_ptr placefileLayer = + std::make_shared(context_, placefileName); + placefileLayers_.push_back(placefileLayer); + AddLayer( + GetPlacefileLayerName(placefileName), placefileLayer, "colorTable"); + } + } +} + +std::string +MapWidgetImpl::GetPlacefileLayerName(const std::string& placefileName) +{ + return fmt::format("placefile-{}", placefileName); +} + void MapWidgetImpl::AddLayer(const std::string& id, std::shared_ptr layer, const std::string& before) diff --git a/scwx-qt/source/scwx/qt/map/placefile_layer.cpp b/scwx-qt/source/scwx/qt/map/placefile_layer.cpp index 6030e264..2838e4ec 100644 --- a/scwx-qt/source/scwx/qt/map/placefile_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/placefile_layer.cpp @@ -24,12 +24,19 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_); class PlacefileLayer::Impl { public: - explicit Impl(std::shared_ptr context) : + explicit Impl(PlacefileLayer* self, + std::shared_ptr context, + const std::string& placefileName) : + self_ {self}, + placefileName_ {placefileName}, placefileIcons_ {std::make_shared(context)} { + ConnectSignals(); } ~Impl() = default; + void ConnectSignals(); + void RenderIconDrawItem(const QMapLibreGL::CustomLayerRenderParameters& params, const std::shared_ptr& di); @@ -44,6 +51,11 @@ public: float x, float y); + PlacefileLayer* self_; + + std::string placefileName_; + bool dirty_ {true}; + std::uint32_t textId_ {}; glm::vec2 mapScreenCoordLocation_ {}; float mapScale_ {1.0f}; @@ -55,14 +67,43 @@ public: std::shared_ptr placefileIcons_; }; -PlacefileLayer::PlacefileLayer(std::shared_ptr context) : - DrawLayer(context), p(std::make_unique(context)) +PlacefileLayer::PlacefileLayer(std::shared_ptr context, + const std::string& placefileName) : + DrawLayer(context), + p(std::make_unique(this, context, placefileName)) { AddDrawItem(p->placefileIcons_); } PlacefileLayer::~PlacefileLayer() = default; +void PlacefileLayer::Impl::ConnectSignals() +{ + auto placefileManager = manager::PlacefileManager::Instance(); + + QObject::connect(placefileManager.get(), + &manager::PlacefileManager::PlacefileUpdated, + self_, + [this](const std::string& name) + { + if (name == placefileName_) + { + dirty_ = true; + } + }); +} + +std::string PlacefileLayer::placefile_name() const +{ + return p->placefileName_; +} + +void PlacefileLayer::set_placefile_name(const std::string& placefileName) +{ + p->placefileName_ = placefileName; + p->dirty_ = true; +} + void PlacefileLayer::Initialize() { logger_->debug("Initialize()"); @@ -74,6 +115,11 @@ void PlacefileLayer::Impl::RenderIconDrawItem( const QMapLibreGL::CustomLayerRenderParameters& params, const std::shared_ptr& di) { + if (!dirty_) + { + return; + } + auto distance = (thresholded_) ? util::GeographicLib::GetDistance( @@ -162,9 +208,6 @@ void PlacefileLayer::Render( // Reset text ID per frame p->textId_ = 0; - // Reset graphics - p->placefileIcons_->Reset(); - // Update map screen coordinate and scale information p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( {params.latitude, params.longitude}); @@ -192,14 +235,21 @@ void PlacefileLayer::Render( std::shared_ptr placefileManager = manager::PlacefileManager::Instance(); - // Render text - for (auto& placefile : placefileManager->GetActivePlacefiles()) + auto placefile = placefileManager->placefile(p->placefileName_); + + // Render placefile + if (placefile != nullptr) { p->thresholded_ = placefileManager->placefile_thresholded(placefile->name()); - p->placefileIcons_->SetIconFiles(placefile->icon_files(), - placefile->name()); + if (p->dirty_) + { + // Reset Placefile Icons + p->placefileIcons_->Reset(); + p->placefileIcons_->SetIconFiles(placefile->icon_files(), + placefile->name()); + } for (auto& drawItem : placefile->GetDrawItems()) { diff --git a/scwx-qt/source/scwx/qt/map/placefile_layer.hpp b/scwx-qt/source/scwx/qt/map/placefile_layer.hpp index 9a293d38..2e07c5c9 100644 --- a/scwx-qt/source/scwx/qt/map/placefile_layer.hpp +++ b/scwx-qt/source/scwx/qt/map/placefile_layer.hpp @@ -2,6 +2,8 @@ #include +#include + namespace scwx { namespace qt @@ -12,9 +14,14 @@ namespace map class PlacefileLayer : public DrawLayer { public: - explicit PlacefileLayer(std::shared_ptr context); + explicit PlacefileLayer(std::shared_ptr context, + const std::string& placefileName); ~PlacefileLayer(); + std::string placefile_name() const; + + void set_placefile_name(const std::string& placefileName); + void Initialize() override final; void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; void Deinitialize() override final;