mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 15:20:05 +00:00 
			
		
		
		
	Merge pull request #97 from dpaulat/feature/radar-site-labels
Radar Site Labels
This commit is contained in:
		
						commit
						6e4501f0bc
					
				
					 9 changed files with 268 additions and 16 deletions
				
			
		|  | @ -102,7 +102,8 @@ set(HDR_MAP source/scwx/qt/map/alert_layer.hpp | ||||||
|             source/scwx/qt/map/overlay_layer.hpp |             source/scwx/qt/map/overlay_layer.hpp | ||||||
|             source/scwx/qt/map/placefile_layer.hpp |             source/scwx/qt/map/placefile_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 | ||||||
|  |             source/scwx/qt/map/radar_site_layer.hpp) | ||||||
| set(SRC_MAP source/scwx/qt/map/alert_layer.cpp | set(SRC_MAP source/scwx/qt/map/alert_layer.cpp | ||||||
|             source/scwx/qt/map/color_table_layer.cpp |             source/scwx/qt/map/color_table_layer.cpp | ||||||
|             source/scwx/qt/map/draw_layer.cpp |             source/scwx/qt/map/draw_layer.cpp | ||||||
|  | @ -114,7 +115,8 @@ set(SRC_MAP source/scwx/qt/map/alert_layer.cpp | ||||||
|             source/scwx/qt/map/overlay_layer.cpp |             source/scwx/qt/map/overlay_layer.cpp | ||||||
|             source/scwx/qt/map/placefile_layer.cpp |             source/scwx/qt/map/placefile_layer.cpp | ||||||
|             source/scwx/qt/map/radar_product_layer.cpp |             source/scwx/qt/map/radar_product_layer.cpp | ||||||
|             source/scwx/qt/map/radar_range_layer.cpp) |             source/scwx/qt/map/radar_range_layer.cpp | ||||||
|  |             source/scwx/qt/map/radar_site_layer.cpp) | ||||||
| set(HDR_MODEL source/scwx/qt/model/alert_model.hpp | set(HDR_MODEL source/scwx/qt/model/alert_model.hpp | ||||||
|               source/scwx/qt/model/alert_proxy_model.hpp |               source/scwx/qt/model/alert_proxy_model.hpp | ||||||
|               source/scwx/qt/model/imgui_context_model.hpp |               source/scwx/qt/model/imgui_context_model.hpp | ||||||
|  |  | ||||||
|  | @ -807,6 +807,18 @@ void MainWindowImpl::ConnectAnimationSignals() | ||||||
|               &map::MapWidget::WidgetPainted, |               &map::MapWidget::WidgetPainted, | ||||||
|               timelineManager_.get(), |               timelineManager_.get(), | ||||||
|               [=, this]() { timelineManager_->ReceiveMapWidgetPainted(i); }); |               [=, this]() { timelineManager_->ReceiveMapWidgetPainted(i); }); | ||||||
|  |       connect(maps_[i], | ||||||
|  |               &map::MapWidget::RadarSiteRequested, | ||||||
|  |               this, | ||||||
|  |               [this](const std::string& id) | ||||||
|  |               { | ||||||
|  |                  for (map::MapWidget* map : maps_) | ||||||
|  |                  { | ||||||
|  |                     map->SelectRadarSite(id); | ||||||
|  |                  } | ||||||
|  | 
 | ||||||
|  |                  UpdateRadarSite(); | ||||||
|  |               }); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include <scwx/qt/map/placefile_layer.hpp> | #include <scwx/qt/map/placefile_layer.hpp> | ||||||
| #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/map/radar_site_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/model/layer_model.hpp> | ||||||
| #include <scwx/qt/settings/general_settings.hpp> | #include <scwx/qt/settings/general_settings.hpp> | ||||||
|  | @ -164,6 +165,8 @@ public: | ||||||
|    std::shared_ptr<QMapLibreGL::Map> map_; |    std::shared_ptr<QMapLibreGL::Map> map_; | ||||||
|    std::list<std::string>            layerList_; |    std::list<std::string>            layerList_; | ||||||
| 
 | 
 | ||||||
|  |    std::vector<std::shared_ptr<GenericLayer>> genericLayers_ {}; | ||||||
|  | 
 | ||||||
|    QStringList        styleLayers_; |    QStringList        styleLayers_; | ||||||
|    types::LayerVector customLayers_; |    types::LayerVector customLayers_; | ||||||
| 
 | 
 | ||||||
|  | @ -186,6 +189,7 @@ public: | ||||||
|    std::shared_ptr<OverlayLayer>      overlayLayer_; |    std::shared_ptr<OverlayLayer>      overlayLayer_; | ||||||
|    std::shared_ptr<PlacefileLayer>    placefileLayer_; |    std::shared_ptr<PlacefileLayer>    placefileLayer_; | ||||||
|    std::shared_ptr<ColorTableLayer>   colorTableLayer_; |    std::shared_ptr<ColorTableLayer>   colorTableLayer_; | ||||||
|  |    std::shared_ptr<RadarSiteLayer>    radarSiteLayer_ {nullptr}; | ||||||
| 
 | 
 | ||||||
|    std::list<std::shared_ptr<PlacefileLayer>> placefileLayers_ {}; |    std::list<std::shared_ptr<PlacefileLayer>> placefileLayers_ {}; | ||||||
| 
 | 
 | ||||||
|  | @ -800,6 +804,7 @@ void MapWidgetImpl::AddLayers() | ||||||
|       map_->removeLayer(id.c_str()); |       map_->removeLayer(id.c_str()); | ||||||
|    } |    } | ||||||
|    layerList_.clear(); |    layerList_.clear(); | ||||||
|  |    genericLayers_.clear(); | ||||||
|    placefileLayers_.clear(); |    placefileLayers_.clear(); | ||||||
| 
 | 
 | ||||||
|    // Update custom layer list from model
 |    // Update custom layer list from model
 | ||||||
|  | @ -890,6 +895,16 @@ void MapWidgetImpl::AddLayer(types::LayerType        type, | ||||||
|          } |          } | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|  |       // Create the radar site layer
 | ||||||
|  |       case types::InformationLayer::RadarSite: | ||||||
|  |          radarSiteLayer_ = std::make_shared<RadarSiteLayer>(context_); | ||||||
|  |          AddLayer(layerName, radarSiteLayer_, before); | ||||||
|  |          connect(radarSiteLayer_.get(), | ||||||
|  |                  &RadarSiteLayer::RadarSiteSelected, | ||||||
|  |                  widget_, | ||||||
|  |                  &MapWidget::RadarSiteRequested); | ||||||
|  |          break; | ||||||
|  | 
 | ||||||
|       default: |       default: | ||||||
|          break; |          break; | ||||||
|       } |       } | ||||||
|  | @ -953,6 +968,7 @@ void MapWidgetImpl::AddLayer(const std::string&            id, | ||||||
|       map_->addCustomLayer(id.c_str(), std::move(pHost), before.c_str()); |       map_->addCustomLayer(id.c_str(), std::move(pHost), before.c_str()); | ||||||
| 
 | 
 | ||||||
|       layerList_.push_back(id); |       layerList_.push_back(id); | ||||||
|  |       genericLayers_.push_back(layer); | ||||||
|    } |    } | ||||||
|    catch (const std::exception&) |    catch (const std::exception&) | ||||||
|    { |    { | ||||||
|  | @ -1198,10 +1214,8 @@ void MapWidgetImpl::RunMousePicking() | ||||||
|       util::maplibre::LatLongToScreenCoordinate(coordinate); |       util::maplibre::LatLongToScreenCoordinate(coordinate); | ||||||
| 
 | 
 | ||||||
|    // For each layer in reverse
 |    // For each layer in reverse
 | ||||||
|    // TODO: All Generic Layers, not just Placefile Layers
 |  | ||||||
|    bool itemPicked = false; |    bool itemPicked = false; | ||||||
|    for (auto it = placefileLayers_.rbegin(); it != placefileLayers_.rend(); |    for (auto it = genericLayers_.rbegin(); it != genericLayers_.rend(); ++it) | ||||||
|         ++it) |  | ||||||
|    { |    { | ||||||
|       // Run mouse picking for each layer
 |       // Run mouse picking for each layer
 | ||||||
|       if ((*it)->RunMousePicking( |       if ((*it)->RunMousePicking( | ||||||
|  |  | ||||||
|  | @ -147,6 +147,7 @@ signals: | ||||||
|                              double bearing, |                              double bearing, | ||||||
|                              double pitch); |                              double pitch); | ||||||
|    void MapStyleChanged(const std::string& styleName); |    void MapStyleChanged(const std::string& styleName); | ||||||
|  |    void RadarSiteRequested(const std::string& id); | ||||||
|    void RadarSiteUpdated(std::shared_ptr<config::RadarSite> radarSite); |    void RadarSiteUpdated(std::shared_ptr<config::RadarSite> radarSite); | ||||||
|    void RadarSweepUpdated(); |    void RadarSweepUpdated(); | ||||||
|    void RadarSweepNotUpdated(types::NoUpdateReason reason); |    void RadarSweepNotUpdated(types::NoUpdateReason reason); | ||||||
|  |  | ||||||
							
								
								
									
										173
									
								
								scwx-qt/source/scwx/qt/map/radar_site_layer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								scwx-qt/source/scwx/qt/map/radar_site_layer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,173 @@ | ||||||
|  | #include <scwx/qt/map/radar_site_layer.hpp> | ||||||
|  | #include <scwx/qt/config/radar_site.hpp> | ||||||
|  | #include <scwx/qt/util/maplibre.hpp> | ||||||
|  | #include <scwx/qt/util/tooltip.hpp> | ||||||
|  | #include <scwx/common/geographic.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | // #include <GeographicLib/Geodesic.hpp>
 | ||||||
|  | #include <imgui.h> | ||||||
|  | #include <mbgl/util/constants.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace map | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::map::radar_site_layer"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | class RadarSiteLayer::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl(RadarSiteLayer* self) : self_ {self} {} | ||||||
|  |    ~Impl() = default; | ||||||
|  | 
 | ||||||
|  |    void RenderRadarSite(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|  |                         std::shared_ptr<config::RadarSite>& radarSite); | ||||||
|  | 
 | ||||||
|  |    RadarSiteLayer* self_; | ||||||
|  | 
 | ||||||
|  |    std::vector<std::shared_ptr<config::RadarSite>> radarSites_ {}; | ||||||
|  | 
 | ||||||
|  |    glm::vec2 mapScreenCoordLocation_ {}; | ||||||
|  |    float     mapScale_ {1.0f}; | ||||||
|  |    float     mapBearingCos_ {1.0f}; | ||||||
|  |    float     mapBearingSin_ {0.0f}; | ||||||
|  |    float     halfWidth_ {}; | ||||||
|  |    float     halfHeight_ {}; | ||||||
|  | 
 | ||||||
|  |    std::string hoverText_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | RadarSiteLayer::RadarSiteLayer(std::shared_ptr<MapContext> context) : | ||||||
|  |     DrawLayer(context), p(std::make_unique<Impl>(this)) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RadarSiteLayer::~RadarSiteLayer() = default; | ||||||
|  | 
 | ||||||
|  | void RadarSiteLayer::Initialize() | ||||||
|  | { | ||||||
|  |    logger_->debug("Initialize()"); | ||||||
|  | 
 | ||||||
|  |    p->radarSites_ = config::RadarSite::GetAll(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RadarSiteLayer::Render( | ||||||
|  |    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||||
|  | { | ||||||
|  |    gl::OpenGLFunctions& gl = context()->gl(); | ||||||
|  | 
 | ||||||
|  |    context()->set_render_parameters(params); | ||||||
|  | 
 | ||||||
|  |    // Update map screen coordinate and scale information
 | ||||||
|  |    p->mapScreenCoordLocation_ = util::maplibre::LatLongToScreenCoordinate( | ||||||
|  |       {params.latitude, params.longitude}); | ||||||
|  |    p->mapScale_ = std::pow(2.0, params.zoom) * mbgl::util::tileSize_D / | ||||||
|  |                   mbgl::util::DEGREES_MAX; | ||||||
|  |    p->mapBearingCos_ = cosf(params.bearing * common::kDegreesToRadians); | ||||||
|  |    p->mapBearingSin_ = sinf(params.bearing * common::kDegreesToRadians); | ||||||
|  |    p->halfWidth_     = params.width * 0.5f; | ||||||
|  |    p->halfHeight_    = params.height * 0.5f; | ||||||
|  | 
 | ||||||
|  |    p->hoverText_.clear(); | ||||||
|  | 
 | ||||||
|  |    // Radar site ImGui windows shouldn't have padding
 | ||||||
|  |    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2 {0.0f, 0.0f}); | ||||||
|  | 
 | ||||||
|  |    for (auto& radarSite : p->radarSites_) | ||||||
|  |    { | ||||||
|  |       p->RenderRadarSite(params, radarSite); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    ImGui::PopStyleVar(); | ||||||
|  | 
 | ||||||
|  |    SCWX_GL_CHECK_ERROR(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RadarSiteLayer::Impl::RenderRadarSite( | ||||||
|  |    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|  |    std::shared_ptr<config::RadarSite>&             radarSite) | ||||||
|  | { | ||||||
|  |    const std::string windowName = fmt::format("radar-site-{}", radarSite->id()); | ||||||
|  | 
 | ||||||
|  |    const auto screenCoordinates = | ||||||
|  |       (util::maplibre::LatLongToScreenCoordinate( | ||||||
|  |           {radarSite->latitude(), radarSite->longitude()}) - | ||||||
|  |        mapScreenCoordLocation_) * | ||||||
|  |       mapScale_; | ||||||
|  | 
 | ||||||
|  |    // Rotate text according to map rotation
 | ||||||
|  |    float rotatedX = screenCoordinates.x; | ||||||
|  |    float rotatedY = screenCoordinates.y; | ||||||
|  |    if (params.bearing != 0.0) | ||||||
|  |    { | ||||||
|  |       rotatedX = screenCoordinates.x * mapBearingCos_ - | ||||||
|  |                  screenCoordinates.y * mapBearingSin_; | ||||||
|  |       rotatedY = screenCoordinates.x * mapBearingSin_ + | ||||||
|  |                  screenCoordinates.y * mapBearingCos_; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Convert screen to ImGui coordinates
 | ||||||
|  |    float x = rotatedX + halfWidth_; | ||||||
|  |    float y = params.height - (rotatedY + halfHeight_); | ||||||
|  | 
 | ||||||
|  |    // Setup window to hold text
 | ||||||
|  |    ImGui::SetNextWindowPos( | ||||||
|  |       ImVec2 {x, y}, ImGuiCond_Always, ImVec2 {0.5f, 0.5f}); | ||||||
|  |    if (ImGui::Begin(windowName.c_str(), | ||||||
|  |                     nullptr, | ||||||
|  |                     ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | | ||||||
|  |                        ImGuiWindowFlags_AlwaysAutoResize)) | ||||||
|  |    { | ||||||
|  |       // Render text
 | ||||||
|  |       if (ImGui::Button(radarSite->id().c_str())) | ||||||
|  |       { | ||||||
|  |          Q_EMIT self_->RadarSiteSelected(radarSite->id()); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Store hover text for mouse picking pass
 | ||||||
|  |       if (ImGui::IsItemHovered()) | ||||||
|  |       { | ||||||
|  |          hoverText_ = | ||||||
|  |             fmt::format("{} ({})\n{}\n{}, {}", | ||||||
|  |                         radarSite->id(), | ||||||
|  |                         radarSite->type_name(), | ||||||
|  |                         radarSite->location_name(), | ||||||
|  |                         common::GetLatitudeString(radarSite->latitude()), | ||||||
|  |                         common::GetLongitudeString(radarSite->longitude())); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // End window
 | ||||||
|  |       ImGui::End(); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RadarSiteLayer::Deinitialize() | ||||||
|  | { | ||||||
|  |    logger_->debug("Deinitialize()"); | ||||||
|  | 
 | ||||||
|  |    p->radarSites_.clear(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RadarSiteLayer::RunMousePicking( | ||||||
|  |    const QMapLibreGL::CustomLayerRenderParameters& /* params */, | ||||||
|  |    const QPointF& /* mouseLocalPos */, | ||||||
|  |    const QPointF& mouseGlobalPos, | ||||||
|  |    const glm::vec2& /* mouseCoords */) | ||||||
|  | { | ||||||
|  |    if (!p->hoverText_.empty()) | ||||||
|  |    { | ||||||
|  |       util::tooltip::Show(p->hoverText_, mouseGlobalPos); | ||||||
|  |       return true; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace map
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										40
									
								
								scwx-qt/source/scwx/qt/map/radar_site_layer.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								scwx-qt/source/scwx/qt/map/radar_site_layer.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/qt/map/draw_layer.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace map | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class RadarSiteLayer : public DrawLayer | ||||||
|  | { | ||||||
|  |    Q_OBJECT | ||||||
|  |    Q_DISABLE_COPY_MOVE(RadarSiteLayer) | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |    explicit RadarSiteLayer(std::shared_ptr<MapContext> context); | ||||||
|  |    ~RadarSiteLayer(); | ||||||
|  | 
 | ||||||
|  |    void Initialize() override final; | ||||||
|  |    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||||
|  |    void Deinitialize() override final; | ||||||
|  | 
 | ||||||
|  |    bool RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||||
|  |                         const QPointF&   mouseLocalPos, | ||||||
|  |                         const QPointF&   mouseGlobalPos, | ||||||
|  |                         const glm::vec2& mouseCoords) override final; | ||||||
|  | 
 | ||||||
|  | signals: | ||||||
|  |    void RadarSiteSelected(const std::string& id); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace map
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
|  | @ -39,6 +39,10 @@ static const QString kMimeFormat {"application/x.scwx-layer-model"}; | ||||||
| static const std::vector<types::LayerInfo> kDefaultLayers_ { | static const std::vector<types::LayerInfo> kDefaultLayers_ { | ||||||
|    {types::LayerType::Information, types::InformationLayer::MapOverlay, false}, |    {types::LayerType::Information, types::InformationLayer::MapOverlay, false}, | ||||||
|    {types::LayerType::Information, types::InformationLayer::ColorTable, false}, |    {types::LayerType::Information, types::InformationLayer::ColorTable, false}, | ||||||
|  |    {types::LayerType::Information, | ||||||
|  |     types::InformationLayer::RadarSite, | ||||||
|  |     false, | ||||||
|  |     {false, false, false, false}}, | ||||||
|    {types::LayerType::Data, types::DataLayer::RadarRange, true}, |    {types::LayerType::Data, types::DataLayer::RadarRange, true}, | ||||||
|    {types::LayerType::Alert, awips::Phenomenon::Tornado, true}, |    {types::LayerType::Alert, awips::Phenomenon::Tornado, true}, | ||||||
|    {types::LayerType::Alert, awips::Phenomenon::SnowSquall, true}, |    {types::LayerType::Alert, awips::Phenomenon::SnowSquall, true}, | ||||||
|  | @ -53,6 +57,10 @@ static const std::vector<types::LayerInfo> kDefaultLayers_ { | ||||||
| static const std::vector<types::LayerInfo> kImmovableLayers_ { | static const std::vector<types::LayerInfo> kImmovableLayers_ { | ||||||
|    {types::LayerType::Information, types::InformationLayer::MapOverlay, false}, |    {types::LayerType::Information, types::InformationLayer::MapOverlay, false}, | ||||||
|    {types::LayerType::Information, types::InformationLayer::ColorTable, false}, |    {types::LayerType::Information, types::InformationLayer::ColorTable, false}, | ||||||
|  |    {types::LayerType::Information, | ||||||
|  |     types::InformationLayer::RadarSite, | ||||||
|  |     false, | ||||||
|  |     {false, false, false, false}}, | ||||||
|    {types::LayerType::Map, types::MapLayer::MapSymbology, false}, |    {types::LayerType::Map, types::MapLayer::MapSymbology, false}, | ||||||
|    {types::LayerType::Map, types::MapLayer::MapUnderlay, false}, |    {types::LayerType::Map, types::MapLayer::MapUnderlay, false}, | ||||||
| }; | }; | ||||||
|  | @ -235,13 +243,13 @@ void LayerModel::Impl::ValidateLayerSettings(types::LayerVector& layers) | ||||||
| 
 | 
 | ||||||
|    // Validate immovable layers
 |    // Validate immovable layers
 | ||||||
|    std::vector<types::LayerVector::iterator> immovableIterators {}; |    std::vector<types::LayerVector::iterator> immovableIterators {}; | ||||||
|    types::LayerVector::iterator              colorTableIterator {}; |    types::LayerVector::iterator              radarSiteIterator {}; | ||||||
|    types::LayerVector::iterator              mapSymbologyIterator {}; |    types::LayerVector::iterator              mapSymbologyIterator {}; | ||||||
|    types::LayerVector::iterator              mapUnderlayIterator {}; |    types::LayerVector::iterator              mapUnderlayIterator {}; | ||||||
|    for (auto& immovableLayer : kImmovableLayers_) |    for (auto& immovableLayer : kImmovableLayers_) | ||||||
|    { |    { | ||||||
|       // Set the default displayed state for a layer that is not found
 |       // Set the default displayed state for a layer that is not found
 | ||||||
|       std::array<bool, kMapCount_> displayed {true, true, true, true}; |       std::array<bool, kMapCount_> displayed = immovableLayer.displayed_; | ||||||
| 
 | 
 | ||||||
|       // Find the immovable layer
 |       // Find the immovable layer
 | ||||||
|       auto it = std::find_if(layers.begin(), |       auto it = std::find_if(layers.begin(), | ||||||
|  | @ -285,8 +293,8 @@ void LayerModel::Impl::ValidateLayerSettings(types::LayerVector& layers) | ||||||
|       { |       { | ||||||
|          switch (std::get<types::InformationLayer>(it->description_)) |          switch (std::get<types::InformationLayer>(it->description_)) | ||||||
|          { |          { | ||||||
|          case types::InformationLayer::ColorTable: |          case types::InformationLayer::RadarSite: | ||||||
|             colorTableIterator = it; |             radarSiteIterator = it; | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|          default: |          default: | ||||||
|  | @ -330,10 +338,10 @@ void LayerModel::Impl::ValidateLayerSettings(types::LayerVector& layers) | ||||||
| 
 | 
 | ||||||
|       if (it == layers.end()) |       if (it == layers.end()) | ||||||
|       { |       { | ||||||
|          // If this is the first data layer, insert after the color table layer,
 |          // If this is the first data layer, insert after the radar site layer,
 | ||||||
|          // otherwise, insert after the previous data layer
 |          // otherwise, insert after the previous data layer
 | ||||||
|          types::LayerVector::iterator insertPosition = |          types::LayerVector::iterator insertPosition = | ||||||
|             dataIterators.empty() ? colorTableIterator + 1 : |             dataIterators.empty() ? radarSiteIterator + 1 : | ||||||
|                                     dataIterators.back() + 1; |                                     dataIterators.back() + 1; | ||||||
|          it = |          it = | ||||||
|             layers.insert(insertPosition, {types::LayerType::Data, dataLayer}); |             layers.insert(insertPosition, {types::LayerType::Data, dataLayer}); | ||||||
|  | @ -398,7 +406,7 @@ void LayerModel::ResetLayers() | ||||||
|    types::LayerVector newLayers {}; |    types::LayerVector newLayers {}; | ||||||
|    newLayers.assign(kDefaultLayers_.cbegin(), kDefaultLayers_.cend()); |    newLayers.assign(kDefaultLayers_.cbegin(), kDefaultLayers_.cend()); | ||||||
| 
 | 
 | ||||||
|    auto colorTableIterator = std::find_if( |    auto radarSiteIterator = std::find_if( | ||||||
|       newLayers.begin(), |       newLayers.begin(), | ||||||
|       newLayers.end(), |       newLayers.end(), | ||||||
|       [](const types::LayerInfo& layerInfo) |       [](const types::LayerInfo& layerInfo) | ||||||
|  | @ -406,7 +414,7 @@ void LayerModel::ResetLayers() | ||||||
|          return std::holds_alternative<types::InformationLayer>( |          return std::holds_alternative<types::InformationLayer>( | ||||||
|                    layerInfo.description_) && |                    layerInfo.description_) && | ||||||
|                 std::get<types::InformationLayer>(layerInfo.description_) == |                 std::get<types::InformationLayer>(layerInfo.description_) == | ||||||
|                    types::InformationLayer::ColorTable; |                    types::InformationLayer::RadarSite; | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|    // Add all existing placefile layers
 |    // Add all existing placefile layers
 | ||||||
|  | @ -415,7 +423,7 @@ void LayerModel::ResetLayers() | ||||||
|       if (it->type_ == types::LayerType::Placefile) |       if (it->type_ == types::LayerType::Placefile) | ||||||
|       { |       { | ||||||
|          newLayers.insert( |          newLayers.insert( | ||||||
|             colorTableIterator + 1, |             radarSiteIterator + 1, | ||||||
|             {it->type_, it->description_, it->movable_, it->displayed_}); |             {it->type_, it->description_, it->movable_, it->displayed_}); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  | @ -1007,7 +1015,7 @@ void LayerModel::Impl::HandlePlacefileUpdate(const std::string& name, | ||||||
| 
 | 
 | ||||||
| void LayerModel::Impl::AddPlacefile(const std::string& name) | void LayerModel::Impl::AddPlacefile(const std::string& name) | ||||||
| { | { | ||||||
|    // Insert after color table
 |    // Insert after radar site
 | ||||||
|    auto insertPosition = std::find_if( |    auto insertPosition = std::find_if( | ||||||
|       layers_.begin(), |       layers_.begin(), | ||||||
|       layers_.end(), |       layers_.end(), | ||||||
|  | @ -1016,7 +1024,7 @@ void LayerModel::Impl::AddPlacefile(const std::string& name) | ||||||
|          return std::holds_alternative<types::InformationLayer>( |          return std::holds_alternative<types::InformationLayer>( | ||||||
|                    layerInfo.description_) && |                    layerInfo.description_) && | ||||||
|                 std::get<types::InformationLayer>(layerInfo.description_) == |                 std::get<types::InformationLayer>(layerInfo.description_) == | ||||||
|                    types::InformationLayer::ColorTable; |                    types::InformationLayer::RadarSite; | ||||||
|       }); |       }); | ||||||
|    if (insertPosition != layers_.end()) |    if (insertPosition != layers_.end()) | ||||||
|    { |    { | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ static const std::unordered_map<DataLayer, std::string> dataLayerName_ { | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<InformationLayer, std::string> | static const std::unordered_map<InformationLayer, std::string> | ||||||
|    informationLayerName_ {{InformationLayer::MapOverlay, "Map Overlay"}, |    informationLayerName_ {{InformationLayer::MapOverlay, "Map Overlay"}, | ||||||
|  |                           {InformationLayer::RadarSite, "Radar Sites"}, | ||||||
|                           {InformationLayer::ColorTable, "Color Table"}, |                           {InformationLayer::ColorTable, "Color Table"}, | ||||||
|                           {InformationLayer::Unknown, "?"}}; |                           {InformationLayer::Unknown, "?"}}; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -41,6 +41,7 @@ typedef scwx::util:: | ||||||
| enum class InformationLayer | enum class InformationLayer | ||||||
| { | { | ||||||
|    MapOverlay, |    MapOverlay, | ||||||
|  |    RadarSite, | ||||||
|    ColorTable, |    ColorTable, | ||||||
|    Unknown |    Unknown | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat