Add layers in order defined by the layer manager

This commit is contained in:
Dan Paulat 2023-11-03 05:09:07 -05:00
parent 3392a9a402
commit cc0c82bbd2
3 changed files with 176 additions and 63 deletions

View file

@ -650,7 +650,7 @@ void MainWindowImpl::ConfigureMapLayout()
{ {
if (maps_.at(mapIndex) == nullptr) if (maps_.at(mapIndex) == nullptr)
{ {
maps_[mapIndex] = new map::MapWidget(settings_); maps_[mapIndex] = new map::MapWidget(mapIndex, settings_);
} }
hs->addWidget(maps_[mapIndex]); hs->addWidget(maps_[mapIndex]);

View file

@ -12,6 +12,7 @@
#include <scwx/qt/map/radar_product_layer.hpp> #include <scwx/qt/map/radar_product_layer.hpp>
#include <scwx/qt/map/radar_range_layer.hpp> #include <scwx/qt/map/radar_range_layer.hpp>
#include <scwx/qt/model/imgui_context_model.hpp> #include <scwx/qt/model/imgui_context_model.hpp>
#include <scwx/qt/model/layer_model.hpp>
#include <scwx/qt/settings/general_settings.hpp> #include <scwx/qt/settings/general_settings.hpp>
#include <scwx/qt/settings/palette_settings.hpp> #include <scwx/qt/settings/palette_settings.hpp>
#include <scwx/qt/util/file.hpp> #include <scwx/qt/util/file.hpp>
@ -56,7 +57,9 @@ class MapWidgetImpl : public QObject
public: public:
explicit MapWidgetImpl(MapWidget* widget, explicit MapWidgetImpl(MapWidget* widget,
std::size_t id,
const QMapLibreGL::Settings& settings) : const QMapLibreGL::Settings& settings) :
id_ {id},
uuid_ {boost::uuids::random_generator()()}, uuid_ {boost::uuids::random_generator()()},
context_ {std::make_shared<MapContext>()}, context_ {std::make_shared<MapContext>()},
widget_ {widget}, widget_ {widget},
@ -120,9 +123,15 @@ public:
threadPool_.join(); threadPool_.join();
} }
void AddLayer(types::LayerType type,
types::LayerDescription description,
const std::string& before = {});
void AddLayer(const std::string& id, void AddLayer(const std::string& id,
std::shared_ptr<GenericLayer> layer, std::shared_ptr<GenericLayer> layer,
const std::string& before = {}); const std::string& before = {});
void AddLayers();
void AddPlacefileLayer(const std::string& placefileName,
const std::string& before = "colorTable");
void ConnectSignals(); void ConnectSignals();
void ImGuiCheckFonts(); void ImGuiCheckFonts();
void InitializeNewRadarProductView(const std::string& colorPalette); void InitializeNewRadarProductView(const std::string& colorPalette);
@ -133,9 +142,12 @@ public:
void RemovePlacefileLayer(const std::string& placefileName); void RemovePlacefileLayer(const std::string& placefileName);
void RunMousePicking(); void RunMousePicking();
void SetRadarSite(const std::string& radarSite); void SetRadarSite(const std::string& radarSite);
void UpdateLoadedStyle();
void UpdatePlacefileLayers(); void UpdatePlacefileLayers();
bool UpdateStoredMapParameters(); bool UpdateStoredMapParameters();
std::string FindMapSymbologyLayer();
common::Level2Product common::Level2Product
GetLevel2ProductOrDefault(const std::string& productName) const; GetLevel2ProductOrDefault(const std::string& productName) const;
@ -143,6 +155,7 @@ public:
boost::asio::thread_pool threadPool_ {1u}; boost::asio::thread_pool threadPool_ {1u};
std::size_t id_;
boost::uuids::uuid uuid_; boost::uuids::uuid uuid_;
std::shared_ptr<MapContext> context_; std::shared_ptr<MapContext> context_;
@ -153,6 +166,9 @@ public:
std::shared_ptr<QMapLibreGL::Map> map_; std::shared_ptr<QMapLibreGL::Map> map_;
std::list<std::string> layerList_; std::list<std::string> layerList_;
QStringList styleLayers_;
types::LayerVector customLayers_;
ImGuiContext* imGuiContext_; ImGuiContext* imGuiContext_;
std::string imGuiContextName_; std::string imGuiContextName_;
bool imGuiRendererInitialized_; bool imGuiRendererInitialized_;
@ -198,8 +214,8 @@ public slots:
void Update(); void Update();
}; };
MapWidget::MapWidget(const QMapLibreGL::Settings& settings) : MapWidget::MapWidget(std::size_t id, const QMapLibreGL::Settings& settings) :
p(std::make_unique<MapWidgetImpl>(this, settings)) p(std::make_unique<MapWidgetImpl>(this, id, settings))
{ {
if (settings::GeneralSettings::Instance().anti_aliasing_enabled().GetValue()) if (settings::GeneralSettings::Instance().anti_aliasing_enabled().GetValue())
{ {
@ -590,7 +606,7 @@ void MapWidget::SelectRadarSite(std::shared_ptr<config::RadarSite> radarSite,
false); false);
} }
AddLayers(); p->AddLayers();
// TODO: Disable refresh from old site // TODO: Disable refresh from old site
@ -738,66 +754,154 @@ void MapWidget::changeStyle()
Q_EMIT MapStyleChanged(p->currentStyle_->name_); Q_EMIT MapStyleChanged(p->currentStyle_->name_);
} }
void MapWidget::AddLayers() std::string MapWidgetImpl::FindMapSymbologyLayer()
{ {
logger_->debug("AddLayers()");
// Clear custom layers
for (const std::string& id : p->layerList_)
{
p->map_->removeLayer(id.c_str());
}
p->layerList_.clear();
p->placefileLayers_.clear();
auto radarProductView = p->context_->radar_product_view();
if (radarProductView != nullptr)
{
p->radarProductLayer_ = std::make_shared<RadarProductLayer>(p->context_);
p->colorTableLayer_ = std::make_shared<ColorTableLayer>(p->context_);
std::shared_ptr<config::RadarSite> radarSite =
p->radarProductManager_->radar_site();
const auto& mapStyle = *p->currentStyle_;
std::string before = "ferry"; std::string before = "ferry";
for (const QString& qlayer : p->map_->layerIds()) for (const QString& qlayer : styleLayers_)
{ {
const std::string layer = qlayer.toStdString(); const std::string layer = qlayer.toStdString();
// Draw below layers defined in map style // Draw below layers defined in map style
auto it = std::find_if( auto it = std::find_if(
mapStyle.drawBelow_.cbegin(), currentStyle_->drawBelow_.cbegin(),
mapStyle.drawBelow_.cend(), currentStyle_->drawBelow_.cend(),
[&layer](const std::string& styleLayer) -> bool [&layer](const std::string& styleLayer) -> bool
{ {
std::regex re {styleLayer, std::regex_constants::icase}; std::regex re {styleLayer, std::regex_constants::icase};
return std::regex_match(layer, re); return std::regex_match(layer, re);
}); });
if (it != mapStyle.drawBelow_.cend()) if (it != currentStyle_->drawBelow_.cend())
{ {
before = layer; before = layer;
break; break;
} }
} }
p->AddLayer("radar", p->radarProductLayer_, before); return before;
RadarRangeLayer::Add(p->map_,
radarProductView->range(),
{radarSite->latitude(), radarSite->longitude()});
p->AddLayer("colorTable", p->colorTableLayer_);
} }
p->alertLayer_->AddLayers("colorTable"); void MapWidgetImpl::AddLayers()
{
logger_->debug("Add Layers");
p->UpdatePlacefileLayers(); // Clear custom layers
for (const std::string& id : layerList_)
{
map_->removeLayer(id.c_str());
}
layerList_.clear();
placefileLayers_.clear();
p->overlayLayer_ = std::make_shared<OverlayLayer>(p->context_); // Update custom layer list from model
p->AddLayer("overlay", p->overlayLayer_); customLayers_ = model::LayerModel::Instance()->GetLayers();
// Start by drawing layers before any style-defined layers
std::string before = styleLayers_.front().toStdString();
// Loop through each custom layer in reverse order
for (auto it = customLayers_.crbegin(); it != customLayers_.crend(); ++it)
{
if (it->type_ == types::LayerType::Map)
{
// Style-defined map layers
switch (std::get<types::MapLayer>(it->description_))
{
// Subsequent layers are drawn underneath the map symbology layer
case types::MapLayer::MapUnderlay:
before = FindMapSymbologyLayer();
break;
// Subsequent layers are drawn after all style-defined layers
case types::MapLayer::MapSymbology:
before = "";
break;
default:
break;
}
}
else if (it->displayed_[id_])
{
// If the layer is displayed for the current map, add it
AddLayer(it->type_, it->description_, before);
}
}
}
void MapWidgetImpl::AddLayer(types::LayerType type,
types::LayerDescription description,
const std::string& before)
{
std::string layerName = types::GetLayerName(type, description);
auto radarProductView = context_->radar_product_view();
if (type == types::LayerType::Radar)
{
// If there is a radar product view, create the radar product layer
if (radarProductView != nullptr)
{
radarProductLayer_ = std::make_shared<RadarProductLayer>(context_);
AddLayer(layerName, radarProductLayer_, before);
}
}
else if (type == types::LayerType::Alert)
{
// Add the alert layer for the phenomenon
alertLayer_->AddLayers(std::get<awips::Phenomenon>(description), before);
}
else if (type == types::LayerType::Placefile)
{
// Add the placefile layer
AddPlacefileLayer(std::get<std::string>(description), before);
}
else if (type == types::LayerType::Information)
{
switch (std::get<types::InformationLayer>(description))
{
// Create the map overlay layer
case types::InformationLayer::MapOverlay:
overlayLayer_ = std::make_shared<OverlayLayer>(context_);
AddLayer(layerName, overlayLayer_, before);
break;
// If there is a radar product view, create the color table layer
case types::InformationLayer::ColorTable:
if (radarProductView != nullptr)
{
colorTableLayer_ = std::make_shared<ColorTableLayer>(context_);
AddLayer(layerName, colorTableLayer_, before);
}
break;
default:
break;
}
}
else if (type == types::LayerType::Data)
{
switch (std::get<types::DataLayer>(description))
{
// If there is a radar product view, create the radar range layer
case types::DataLayer::RadarRange:
if (radarProductView != nullptr)
{
std::shared_ptr<config::RadarSite> radarSite =
radarProductManager_->radar_site();
RadarRangeLayer::Add(
map_,
radarProductView->range(),
{radarSite->latitude(), radarSite->longitude()},
QString::fromStdString(before));
}
break;
default:
break;
}
}
} }
void MapWidgetImpl::RemovePlacefileLayer(const std::string& placefileName) void MapWidgetImpl::RemovePlacefileLayer(const std::string& placefileName)
@ -840,12 +944,19 @@ void MapWidgetImpl::UpdatePlacefileLayers()
// If the layer doesn't exist, create it // If the layer doesn't exist, create it
if (it == placefileLayers_.end()) if (it == placefileLayers_.end())
{
AddPlacefileLayer(placefileName);
}
}
}
void MapWidgetImpl::AddPlacefileLayer(const std::string& placefileName,
const std::string& before)
{ {
std::shared_ptr<PlacefileLayer> placefileLayer = std::shared_ptr<PlacefileLayer> placefileLayer =
std::make_shared<PlacefileLayer>(context_, placefileName); std::make_shared<PlacefileLayer>(context_, placefileName);
placefileLayers_.push_back(placefileLayer); placefileLayers_.push_back(placefileLayer);
AddLayer( AddLayer(GetPlacefileLayerName(placefileName), placefileLayer, before);
GetPlacefileLayerName(placefileName), placefileLayer, "colorTable");
// When the layer updates, trigger a map widget update // When the layer updates, trigger a map widget update
connect(placefileLayer.get(), connect(placefileLayer.get(),
@ -853,8 +964,6 @@ void MapWidgetImpl::UpdatePlacefileLayers()
widget_, widget_,
[this]() { widget_->update(); }); [this]() { widget_->update(); });
} }
}
}
std::string std::string
MapWidgetImpl::GetPlacefileLayerName(const std::string& placefileName) MapWidgetImpl::GetPlacefileLayerName(const std::string& placefileName)
@ -1147,7 +1256,8 @@ void MapWidget::mapChanged(QMapLibreGL::Map::MapChange mapChange)
switch (mapChange) switch (mapChange)
{ {
case QMapLibreGL::Map::MapChangeDidFinishLoadingStyle: case QMapLibreGL::Map::MapChangeDidFinishLoadingStyle:
AddLayers(); p->UpdateLoadedStyle();
p->AddLayers();
break; break;
default: default:
@ -1155,6 +1265,11 @@ void MapWidget::mapChanged(QMapLibreGL::Map::MapChange mapChange)
} }
} }
void MapWidgetImpl::UpdateLoadedStyle()
{
styleLayers_ = map_->layerIds();
}
void MapWidgetImpl::RadarProductManagerConnect() void MapWidgetImpl::RadarProductManagerConnect()
{ {
if (radarProductManager_ != nullptr) if (radarProductManager_ != nullptr)
@ -1265,7 +1380,7 @@ void MapWidgetImpl::InitializeNewRadarProductView(
if (map_ != nullptr) if (map_ != nullptr)
{ {
widget_->AddLayers(); AddLayers();
} }
} }

View file

@ -32,7 +32,7 @@ class MapWidget : public QOpenGLWidget
Q_OBJECT Q_OBJECT
public: public:
explicit MapWidget(const QMapLibreGL::Settings&); explicit MapWidget(std::size_t id, const QMapLibreGL::Settings&);
~MapWidget(); ~MapWidget();
common::Level3ProductCategoryMap GetAvailableLevel3Categories(); common::Level3ProductCategoryMap GetAvailableLevel3Categories();
@ -130,8 +130,6 @@ private:
void initializeGL() override final; void initializeGL() override final;
void paintGL() override final; void paintGL() override final;
void AddLayers();
std::unique_ptr<MapWidgetImpl> p; std::unique_ptr<MapWidgetImpl> p;
friend class MapWidgetImpl; friend class MapWidgetImpl;