mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 18:00:06 +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/map_settings.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/tooltip.hpp> | ||||
| #include <scwx/qt/view/radar_product_view.hpp> | ||||
|  | @ -353,11 +356,66 @@ bool RadarProductLayer::RunMousePicking( | |||
|       std::shared_ptr<view::RadarProductView> radarProductView = | ||||
|          context()->radar_product_view(); | ||||
| 
 | ||||
|       if (radarProductView == nullptr) | ||||
|       if (context()->radar_site() == nullptr) | ||||
|       { | ||||
|          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 = | ||||
|          radarProductView->GetBinLevel(mouseGeoCoords); | ||||
| 
 | ||||
|  | @ -383,12 +441,13 @@ bool RadarProductLayer::RunMousePicking( | |||
|             if (codeName != codeShortName && !codeShortName.empty()) | ||||
|             { | ||||
|                // There is a unique long and short name for the code
 | ||||
|                hoverText = fmt::format("{}: {}", codeShortName, codeName); | ||||
|                hoverText = fmt::format( | ||||
|                   "{}: {}\n{}", codeShortName, codeName, distanceHeightStr); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                // Otherwise, only use the long name (always present)
 | ||||
|                hoverText = codeName; | ||||
|                hoverText = fmt::format("{}\n{}", codeName, distanceHeightStr); | ||||
|             } | ||||
| 
 | ||||
|             // Show the tooltip
 | ||||
|  | @ -439,17 +498,20 @@ bool RadarProductLayer::RunMousePicking( | |||
|             { | ||||
|                // Don't display a units value that wasn't intended to be
 | ||||
|                // displayed
 | ||||
|                hoverText = fmt::format("{}{}", f, suffix); | ||||
|                hoverText = | ||||
|                   fmt::format("{}{}\n{}", f, suffix, distanceHeightStr); | ||||
|             } | ||||
|             else if (std::isalpha(static_cast<unsigned char>(units.at(0)))) | ||||
|             { | ||||
|                // dBZ, Kts, etc.
 | ||||
|                hoverText = fmt::format("{} {}{}", f, units, suffix); | ||||
|                hoverText = fmt::format( | ||||
|                   "{} {}{}\n{}", f, units, suffix, distanceHeightStr); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                // %, etc.
 | ||||
|                hoverText = fmt::format("{}{}{}", f, units, suffix); | ||||
|                hoverText = fmt::format( | ||||
|                   "{}{}{}\n{}", f, units, suffix, distanceHeightStr); | ||||
|             } | ||||
| 
 | ||||
|             // Show the tooltip
 | ||||
|  | @ -458,6 +520,12 @@ bool RadarProductLayer::RunMousePicking( | |||
|             itemPicked = true; | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // Always show tooltip for distance and altitude
 | ||||
|          util::tooltip::Show(distanceHeightStr, mouseGlobalPos); | ||||
|          itemPicked = true; | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    return itemPicked; | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include <scwx/qt/map/radar_site_layer.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/text_settings.hpp> | ||||
| #include <scwx/qt/util/maplibre.hpp> | ||||
|  | @ -10,6 +11,8 @@ | |||
| #include <imgui.h> | ||||
| #include <mbgl/util/constants.hpp> | ||||
| 
 | ||||
| #include <QGuiApplication> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
|  | @ -23,11 +26,32 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | |||
| class RadarSiteLayer::Impl | ||||
| { | ||||
| 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; | ||||
| 
 | ||||
|    void RenderRadarSite(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                         std::shared_ptr<config::RadarSite>& radarSite); | ||||
|    void RenderRadarLine(); | ||||
| 
 | ||||
|    RadarSiteLayer* self_; | ||||
| 
 | ||||
|  | @ -41,10 +65,13 @@ public: | |||
|    float     halfHeight_ {}; | ||||
| 
 | ||||
|    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) : | ||||
|     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(); | ||||
| 
 | ||||
|    ImGuiInitialize(); | ||||
|    DrawLayer::Initialize(); | ||||
| } | ||||
| 
 | ||||
| void RadarSiteLayer::Render( | ||||
|  | @ -96,8 +123,12 @@ void RadarSiteLayer::Render( | |||
|    } | ||||
| 
 | ||||
|    ImGui::PopStyleVar(); | ||||
|    ImGuiFrameEnd(); | ||||
| 
 | ||||
|    p->RenderRadarLine(); | ||||
| 
 | ||||
|    DrawLayer::RenderWithoutImGui(params); | ||||
| 
 | ||||
|    ImGuiFrameEnd(); | ||||
|    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() | ||||
| { | ||||
|    logger_->debug("Deinitialize()"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 AdenKoperczak
						AdenKoperczak