mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 07:20:04 +00:00 
			
		
		
		
	Add radar line and radar distance/altitude tooltip
This commit is contained in:
		
							parent
							
								
									d21a11963f
								
							
						
					
					
						commit
						33f92bcda5
					
				
					 2 changed files with 141 additions and 10 deletions
				
			
		|  | @ -1,6 +1,9 @@ | ||||||
| #include <scwx/qt/map/radar_product_layer.hpp> | #include <scwx/qt/map/radar_product_layer.hpp> | ||||||
| #include <scwx/qt/map/map_settings.hpp> | #include <scwx/qt/map/map_settings.hpp> | ||||||
| #include <scwx/qt/gl/shader_program.hpp> | #include <scwx/qt/gl/shader_program.hpp> | ||||||
|  | #include <scwx/qt/settings/unit_settings.hpp> | ||||||
|  | #include <scwx/qt/types/unit_types.hpp> | ||||||
|  | #include <scwx/qt/util/geographic_lib.hpp> | ||||||
| #include <scwx/qt/util/maplibre.hpp> | #include <scwx/qt/util/maplibre.hpp> | ||||||
| #include <scwx/qt/util/tooltip.hpp> | #include <scwx/qt/util/tooltip.hpp> | ||||||
| #include <scwx/qt/view/radar_product_view.hpp> | #include <scwx/qt/view/radar_product_view.hpp> | ||||||
|  | @ -353,11 +356,66 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|       std::shared_ptr<view::RadarProductView> radarProductView = |       std::shared_ptr<view::RadarProductView> radarProductView = | ||||||
|          context()->radar_product_view(); |          context()->radar_product_view(); | ||||||
| 
 | 
 | ||||||
|       if (radarProductView == nullptr) |       if (context()->radar_site() == nullptr) | ||||||
|       { |       { | ||||||
|          return itemPicked; |          return itemPicked; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|  |       // Get distance and altitude of point
 | ||||||
|  |       const double radarLatitude  = context()->radar_site()->latitude(); | ||||||
|  |       const double radarLongitude = context()->radar_site()->longitude(); | ||||||
|  | 
 | ||||||
|  |       const auto distanceMeters = util::GeographicLib::GetDistance( | ||||||
|  |             mouseGeoCoords.latitude_, | ||||||
|  |             mouseGeoCoords.longitude_, | ||||||
|  |             radarLatitude, | ||||||
|  |             radarLongitude); | ||||||
|  | 
 | ||||||
|  |       const std::string distanceUnitName = | ||||||
|  |          settings::UnitSettings::Instance().distance_units().GetValue(); | ||||||
|  |       const types::DistanceUnits distanceUnits = | ||||||
|  |          types::GetDistanceUnitsFromName(distanceUnitName); | ||||||
|  |       const double distanceScale = types::GetDistanceUnitsScale(distanceUnits); | ||||||
|  |       const std::string distanceAbbrev = | ||||||
|  |          types::GetDistanceUnitsAbbreviation(distanceUnits); | ||||||
|  | 
 | ||||||
|  |       const double distance = distanceMeters.value() * | ||||||
|  |                               scwx::common::kKilometersPerMeter * distanceScale; | ||||||
|  |       std::string distanceHeightStr = | ||||||
|  |          fmt::format("{:.2f} {}", distance, distanceAbbrev); | ||||||
|  | 
 | ||||||
|  |       if (radarProductView == nullptr) | ||||||
|  |       { | ||||||
|  |          util::tooltip::Show(distanceHeightStr, mouseGlobalPos); | ||||||
|  |          itemPicked = true; | ||||||
|  |          return itemPicked; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       std::optional<float> elevation = radarProductView->elevation(); | ||||||
|  |       if (elevation.has_value()) | ||||||
|  |       { | ||||||
|  |          const auto altitudeMeters = | ||||||
|  |             util::GeographicLib::GetRadarBeamAltititude( | ||||||
|  |                distanceMeters, | ||||||
|  |                units::angle::degrees<double>(*elevation), | ||||||
|  |                context()->radar_site()->altitude()); | ||||||
|  | 
 | ||||||
|  |          const std::string heightUnitName = | ||||||
|  |             settings::UnitSettings::Instance().echo_tops_units().GetValue(); | ||||||
|  |          const types::EchoTopsUnits heightUnits = | ||||||
|  |             types::GetEchoTopsUnitsFromName(heightUnitName); | ||||||
|  |          const double heightScale = types::GetEchoTopsUnitsScale(heightUnits); | ||||||
|  |          const std::string heightAbbrev = | ||||||
|  |             types::GetEchoTopsUnitsAbbreviation(heightUnits); | ||||||
|  | 
 | ||||||
|  |          const double altitude = altitudeMeters.value() * | ||||||
|  |                                  scwx::common::kKilometersPerMeter * | ||||||
|  |                                  heightScale; | ||||||
|  | 
 | ||||||
|  |          distanceHeightStr = fmt::format( | ||||||
|  |             "{}\n{:.2f} {}", distanceHeightStr, altitude, heightAbbrev); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       std::optional<std::uint16_t> binLevel = |       std::optional<std::uint16_t> binLevel = | ||||||
|          radarProductView->GetBinLevel(mouseGeoCoords); |          radarProductView->GetBinLevel(mouseGeoCoords); | ||||||
| 
 | 
 | ||||||
|  | @ -383,12 +441,13 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|             if (codeName != codeShortName && !codeShortName.empty()) |             if (codeName != codeShortName && !codeShortName.empty()) | ||||||
|             { |             { | ||||||
|                // There is a unique long and short name for the code
 |                // There is a unique long and short name for the code
 | ||||||
|                hoverText = fmt::format("{}: {}", codeShortName, codeName); |                hoverText = fmt::format( | ||||||
|  |                   "{}: {}\n{}", codeShortName, codeName, distanceHeightStr); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                // Otherwise, only use the long name (always present)
 |                // Otherwise, only use the long name (always present)
 | ||||||
|                hoverText = codeName; |                hoverText = fmt::format("{}\n{}", codeName, distanceHeightStr); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Show the tooltip
 |             // Show the tooltip
 | ||||||
|  | @ -439,17 +498,20 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|             { |             { | ||||||
|                // Don't display a units value that wasn't intended to be
 |                // Don't display a units value that wasn't intended to be
 | ||||||
|                // displayed
 |                // displayed
 | ||||||
|                hoverText = fmt::format("{}{}", f, suffix); |                hoverText = | ||||||
|  |                   fmt::format("{}{}\n{}", f, suffix, distanceHeightStr); | ||||||
|             } |             } | ||||||
|             else if (std::isalpha(static_cast<unsigned char>(units.at(0)))) |             else if (std::isalpha(static_cast<unsigned char>(units.at(0)))) | ||||||
|             { |             { | ||||||
|                // dBZ, Kts, etc.
 |                // dBZ, Kts, etc.
 | ||||||
|                hoverText = fmt::format("{} {}{}", f, units, suffix); |                hoverText = fmt::format( | ||||||
|  |                   "{} {}{}\n{}", f, units, suffix, distanceHeightStr); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                // %, etc.
 |                // %, etc.
 | ||||||
|                hoverText = fmt::format("{}{}{}", f, units, suffix); |                hoverText = fmt::format( | ||||||
|  |                   "{}{}{}\n{}", f, units, suffix, distanceHeightStr); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Show the tooltip
 |             // Show the tooltip
 | ||||||
|  | @ -458,6 +520,12 @@ bool RadarProductLayer::RunMousePicking( | ||||||
|             itemPicked = true; |             itemPicked = true; | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          // Always show tooltip for distance and altitude
 | ||||||
|  |          util::tooltip::Show(distanceHeightStr, mouseGlobalPos); | ||||||
|  |          itemPicked = true; | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return itemPicked; |    return itemPicked; | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include <scwx/qt/map/radar_site_layer.hpp> | #include <scwx/qt/map/radar_site_layer.hpp> | ||||||
| #include <scwx/qt/config/radar_site.hpp> | #include <scwx/qt/config/radar_site.hpp> | ||||||
|  | #include <scwx/qt/gl/draw/geo_lines.hpp> | ||||||
| #include <scwx/qt/settings/general_settings.hpp> | #include <scwx/qt/settings/general_settings.hpp> | ||||||
| #include <scwx/qt/settings/text_settings.hpp> | #include <scwx/qt/settings/text_settings.hpp> | ||||||
| #include <scwx/qt/util/maplibre.hpp> | #include <scwx/qt/util/maplibre.hpp> | ||||||
|  | @ -10,6 +11,8 @@ | ||||||
| #include <imgui.h> | #include <imgui.h> | ||||||
| #include <mbgl/util/constants.hpp> | #include <mbgl/util/constants.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <QGuiApplication> | ||||||
|  | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
| namespace qt | namespace qt | ||||||
|  | @ -23,11 +26,32 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
| class RadarSiteLayer::Impl | class RadarSiteLayer::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl(RadarSiteLayer* self) : self_ {self} {} |    explicit Impl(RadarSiteLayer* self, std::shared_ptr<MapContext>& context) : | ||||||
|  |        self_ {self}, | ||||||
|  |        geoLines_ {std::make_shared<gl::draw::GeoLines>(context)} | ||||||
|  |    { | ||||||
|  |       geoLines_->StartLines(); | ||||||
|  |       radarSiteLines_[0] = geoLines_->AddLine(); | ||||||
|  |       radarSiteLines_[1] = geoLines_->AddLine(); | ||||||
|  |       geoLines_->FinishLines(); | ||||||
|  | 
 | ||||||
|  |       static const boost::gil::rgba32f_pixel_t color0 {0.0f, 0.0f, 0.0f, 1.0f}; | ||||||
|  |       static const boost::gil::rgba32f_pixel_t color1 {1.0f, 1.0f, 1.0f, 1.0f}; | ||||||
|  |       static const float width = 1; | ||||||
|  |       geoLines_->SetLineModulate(radarSiteLines_[0], color0); | ||||||
|  |       geoLines_->SetLineWidth(radarSiteLines_[0], width + 2); | ||||||
|  | 
 | ||||||
|  |       geoLines_->SetLineModulate(radarSiteLines_[1], color1); | ||||||
|  |       geoLines_->SetLineWidth(radarSiteLines_[1], width); | ||||||
|  | 
 | ||||||
|  |       self_->AddDrawItem(geoLines_); | ||||||
|  |       geoLines_->set_thresholded(false); | ||||||
|  |    } | ||||||
|    ~Impl() = default; |    ~Impl() = default; | ||||||
| 
 | 
 | ||||||
|    void RenderRadarSite(const QMapLibre::CustomLayerRenderParameters& params, |    void RenderRadarSite(const QMapLibre::CustomLayerRenderParameters& params, | ||||||
|                         std::shared_ptr<config::RadarSite>& radarSite); |                         std::shared_ptr<config::RadarSite>& radarSite); | ||||||
|  |    void RenderRadarLine(); | ||||||
| 
 | 
 | ||||||
|    RadarSiteLayer* self_; |    RadarSiteLayer* self_; | ||||||
| 
 | 
 | ||||||
|  | @ -41,10 +65,13 @@ public: | ||||||
|    float     halfHeight_ {}; |    float     halfHeight_ {}; | ||||||
| 
 | 
 | ||||||
|    std::string hoverText_ {}; |    std::string hoverText_ {}; | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<gl::draw::GeoLines>                       geoLines_; | ||||||
|  |    std::array<std::shared_ptr<gl::draw::GeoLineDrawItem>, 2> radarSiteLines_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| RadarSiteLayer::RadarSiteLayer(std::shared_ptr<MapContext> context) : | RadarSiteLayer::RadarSiteLayer(std::shared_ptr<MapContext> context) : | ||||||
|     DrawLayer(context, "RadarSiteLayer"), p(std::make_unique<Impl>(this)) |     DrawLayer(context, "RadarSiteLayer"), p(std::make_unique<Impl>(this, context)) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -56,7 +83,7 @@ void RadarSiteLayer::Initialize() | ||||||
| 
 | 
 | ||||||
|    p->radarSites_ = config::RadarSite::GetAll(); |    p->radarSites_ = config::RadarSite::GetAll(); | ||||||
| 
 | 
 | ||||||
|    ImGuiInitialize(); |    DrawLayer::Initialize(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RadarSiteLayer::Render( | void RadarSiteLayer::Render( | ||||||
|  | @ -96,8 +123,12 @@ void RadarSiteLayer::Render( | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    ImGui::PopStyleVar(); |    ImGui::PopStyleVar(); | ||||||
|    ImGuiFrameEnd(); |  | ||||||
| 
 | 
 | ||||||
|  |    p->RenderRadarLine(); | ||||||
|  | 
 | ||||||
|  |    DrawLayer::RenderWithoutImGui(params); | ||||||
|  | 
 | ||||||
|  |    ImGuiFrameEnd(); | ||||||
|    SCWX_GL_CHECK_ERROR(); |    SCWX_GL_CHECK_ERROR(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -163,6 +194,38 @@ void RadarSiteLayer::Impl::RenderRadarSite( | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void RadarSiteLayer::Impl::RenderRadarLine() | ||||||
|  | { | ||||||
|  |    // TODO check if state is updated.
 | ||||||
|  |    if ((QGuiApplication::keyboardModifiers() & | ||||||
|  |         Qt::KeyboardModifier::ShiftModifier) && | ||||||
|  |        self_->context()->radar_site() != nullptr) | ||||||
|  |    { | ||||||
|  |       const auto&  mouseCoord     = self_->context()->mouse_coordinate(); | ||||||
|  |       const double radarLatitude  = self_->context()->radar_site()->latitude(); | ||||||
|  |       const double radarLongitude = self_->context()->radar_site()->longitude(); | ||||||
|  | 
 | ||||||
|  |       geoLines_->SetLineLocation(radarSiteLines_[0], | ||||||
|  |                                  static_cast<float>(mouseCoord.latitude_), | ||||||
|  |                                  static_cast<float>(mouseCoord.longitude_), | ||||||
|  |                                  static_cast<float>(radarLatitude), | ||||||
|  |                                  static_cast<float>(radarLongitude)); | ||||||
|  |       geoLines_->SetLineVisible(radarSiteLines_[0], true); | ||||||
|  | 
 | ||||||
|  |       geoLines_->SetLineLocation(radarSiteLines_[1], | ||||||
|  |                                  static_cast<float>(mouseCoord.latitude_), | ||||||
|  |                                  static_cast<float>(mouseCoord.longitude_), | ||||||
|  |                                  static_cast<float>(radarLatitude), | ||||||
|  |                                  static_cast<float>(radarLongitude)); | ||||||
|  |       geoLines_->SetLineVisible(radarSiteLines_[1], true); | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       geoLines_->SetLineVisible(radarSiteLines_[0], false); | ||||||
|  |       geoLines_->SetLineVisible(radarSiteLines_[1], false); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void RadarSiteLayer::Deinitialize() | void RadarSiteLayer::Deinitialize() | ||||||
| { | { | ||||||
|    logger_->debug("Deinitialize()"); |    logger_->debug("Deinitialize()"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 AdenKoperczak
						AdenKoperczak