mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 17:20:06 +00:00 
			
		
		
		
	Merge pull request #436 from AdenKoperczak/radar_site_line
Radar site line and radar distance and altitude tootlip
This commit is contained in:
		
						commit
						6ecb3f6ffb
					
				
					 9 changed files with 224 additions and 40 deletions
				
			
		|  | @ -51,6 +51,7 @@ public: | ||||||
|    std::string state_ {}; |    std::string state_ {}; | ||||||
|    std::string place_ {}; |    std::string place_ {}; | ||||||
|    std::string tzName_ {}; |    std::string tzName_ {}; | ||||||
|  |    double      altitude_ {0.0}; | ||||||
| 
 | 
 | ||||||
|    const scwx::util::time_zone* timeZone_ {nullptr}; |    const scwx::util::time_zone* timeZone_ {nullptr}; | ||||||
| }; | }; | ||||||
|  | @ -142,6 +143,11 @@ const scwx::util::time_zone* RadarSite::time_zone() const | ||||||
|    return p->timeZone_; |    return p->timeZone_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | units::length::feet<double> RadarSite::altitude() const | ||||||
|  | { | ||||||
|  |    return units::length::feet<double>(p->altitude_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<RadarSite> RadarSite::Get(const std::string& id) | std::shared_ptr<RadarSite> RadarSite::Get(const std::string& id) | ||||||
| { | { | ||||||
|    std::shared_lock           lock(siteMutex_); |    std::shared_lock           lock(siteMutex_); | ||||||
|  | @ -268,6 +274,8 @@ size_t RadarSite::ReadConfig(const std::string& path) | ||||||
|             site->p->state_ = boost::json::value_to<std::string>(o.at("state")); |             site->p->state_ = boost::json::value_to<std::string>(o.at("state")); | ||||||
|             site->p->place_ = boost::json::value_to<std::string>(o.at("place")); |             site->p->place_ = boost::json::value_to<std::string>(o.at("place")); | ||||||
|             site->p->tzName_ = boost::json::value_to<std::string>(o.at("tz")); |             site->p->tzName_ = boost::json::value_to<std::string>(o.at("tz")); | ||||||
|  |             site->p->altitude_ = | ||||||
|  |                boost::json::value_to<double>(o.at("elevation")); | ||||||
| 
 | 
 | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -6,12 +6,9 @@ | ||||||
| #include <optional> | #include <optional> | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <units/length.h> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::qt::config | ||||||
| { |  | ||||||
| namespace qt |  | ||||||
| { |  | ||||||
| namespace config |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class RadarSiteImpl; | class RadarSiteImpl; | ||||||
|  | @ -28,18 +25,19 @@ public: | ||||||
|    RadarSite(RadarSite&&) noexcept; |    RadarSite(RadarSite&&) noexcept; | ||||||
|    RadarSite& operator=(RadarSite&&) noexcept; |    RadarSite& operator=(RadarSite&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    std::string type() const; |    [[nodiscard]] std::string                 type() const; | ||||||
|    std::string type_name() const; |    [[nodiscard]] std::string                 type_name() const; | ||||||
|    std::string id() const; |    [[nodiscard]] std::string                 id() const; | ||||||
|    double      latitude() const; |    [[nodiscard]] double                      latitude() const; | ||||||
|    double      longitude() const; |    [[nodiscard]] double                      longitude() const; | ||||||
|    std::string country() const; |    [[nodiscard]] std::string                 country() const; | ||||||
|    std::string state() const; |    [[nodiscard]] std::string                 state() const; | ||||||
|    std::string place() const; |    [[nodiscard]] std::string                 place() const; | ||||||
|    std::string location_name() const; |    [[nodiscard]] std::string                 location_name() const; | ||||||
|    std::string tz_name() const; |    [[nodiscard]] std::string                 tz_name() const; | ||||||
|  |    [[nodiscard]] units::length::feet<double> altitude() const; | ||||||
| 
 | 
 | ||||||
|    const scwx::util::time_zone* time_zone() const; |    [[nodiscard]] const scwx::util::time_zone* time_zone() const; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<RadarSite>              Get(const std::string& id); |    static std::shared_ptr<RadarSite>              Get(const std::string& id); | ||||||
|    static std::vector<std::shared_ptr<RadarSite>> GetAll(); |    static std::vector<std::shared_ptr<RadarSite>> GetAll(); | ||||||
|  | @ -67,6 +65,4 @@ private: | ||||||
| 
 | 
 | ||||||
| std::string GetRadarIdFromSiteId(const std::string& siteId); | std::string GetRadarIdFromSiteId(const std::string& siteId); | ||||||
| 
 | 
 | ||||||
| } // namespace config
 | } // namespace scwx::qt::config
 | ||||||
| } // namespace qt
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ public: | ||||||
|       common::RadarProductGroup::Unknown}; |       common::RadarProductGroup::Unknown}; | ||||||
|    std::string                            radarProduct_ {"???"}; |    std::string                            radarProduct_ {"???"}; | ||||||
|    int16_t                                radarProductCode_ {0}; |    int16_t                                radarProductCode_ {0}; | ||||||
|  |    std::shared_ptr<config::RadarSite>     radarSite_ {nullptr}; | ||||||
| 
 | 
 | ||||||
|    MapProvider mapProvider_ {MapProvider::Unknown}; |    MapProvider mapProvider_ {MapProvider::Unknown}; | ||||||
|    std::string mapCopyrights_ {}; |    std::string mapCopyrights_ {}; | ||||||
|  | @ -106,6 +107,11 @@ std::string MapContext::radar_product() const | ||||||
|    return p->radarProduct_; |    return p->radarProduct_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::shared_ptr<config::RadarSite> MapContext::radar_site() const | ||||||
|  | { | ||||||
|  |    return p->radarSite_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int16_t MapContext::radar_product_code() const | int16_t MapContext::radar_product_code() const | ||||||
| { | { | ||||||
|    return p->radarProductCode_; |    return p->radarProductCode_; | ||||||
|  | @ -174,6 +180,11 @@ void MapContext::set_radar_product_code(int16_t radarProductCode) | ||||||
|    p->radarProductCode_ = radarProductCode; |    p->radarProductCode_ = radarProductCode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void MapContext::set_radar_site(const std::shared_ptr<config::RadarSite>& site) | ||||||
|  | { | ||||||
|  |    p->radarSite_ = site; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void MapContext::set_widget(QWidget* widget) | void MapContext::set_widget(QWidget* widget) | ||||||
| { | { | ||||||
|    p->widget_ = widget; |    p->widget_ = widget; | ||||||
|  |  | ||||||
|  | @ -4,13 +4,12 @@ | ||||||
| #include <scwx/qt/map/map_provider.hpp> | #include <scwx/qt/map/map_provider.hpp> | ||||||
| #include <scwx/common/geographic.hpp> | #include <scwx/common/geographic.hpp> | ||||||
| #include <scwx/common/products.hpp> | #include <scwx/common/products.hpp> | ||||||
|  | #include <scwx/qt/config/radar_site.hpp> | ||||||
| 
 | 
 | ||||||
| #include <qmaplibre.hpp> | #include <qmaplibre.hpp> | ||||||
| #include <QMargins> | #include <QMargins> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::qt | ||||||
| { |  | ||||||
| namespace qt |  | ||||||
| { | { | ||||||
| namespace view | namespace view | ||||||
| { | { | ||||||
|  | @ -30,7 +29,7 @@ class MapContext : public gl::GlContext | ||||||
| public: | public: | ||||||
|    explicit MapContext( |    explicit MapContext( | ||||||
|       std::shared_ptr<view::RadarProductView> radarProductView = nullptr); |       std::shared_ptr<view::RadarProductView> radarProductView = nullptr); | ||||||
|    ~MapContext(); |    ~MapContext() override; | ||||||
| 
 | 
 | ||||||
|    MapContext(const MapContext&)            = delete; |    MapContext(const MapContext&)            = delete; | ||||||
|    MapContext& operator=(const MapContext&) = delete; |    MapContext& operator=(const MapContext&) = delete; | ||||||
|  | @ -48,11 +47,12 @@ public: | ||||||
|    [[nodiscard]] std::shared_ptr<view::OverlayProductView> |    [[nodiscard]] std::shared_ptr<view::OverlayProductView> | ||||||
|    overlay_product_view() const; |    overlay_product_view() const; | ||||||
|    [[nodiscard]] std::shared_ptr<view::RadarProductView> |    [[nodiscard]] std::shared_ptr<view::RadarProductView> | ||||||
|                                            radar_product_view() const; |                                                     radar_product_view() const; | ||||||
|    [[nodiscard]] common::RadarProductGroup radar_product_group() const; |    [[nodiscard]] common::RadarProductGroup          radar_product_group() const; | ||||||
|    [[nodiscard]] std::string               radar_product() const; |    [[nodiscard]] std::string                        radar_product() const; | ||||||
|    [[nodiscard]] int16_t                   radar_product_code() const; |    [[nodiscard]] int16_t                            radar_product_code() const; | ||||||
|    [[nodiscard]] QWidget*                  widget() const; |    [[nodiscard]] std::shared_ptr<config::RadarSite> radar_site() const; | ||||||
|  |    [[nodiscard]] QWidget*                           widget() const; | ||||||
| 
 | 
 | ||||||
|    void set_map(const std::shared_ptr<QMapLibre::Map>& map); |    void set_map(const std::shared_ptr<QMapLibre::Map>& map); | ||||||
|    void set_map_copyrights(const std::string& copyrights); |    void set_map_copyrights(const std::string& copyrights); | ||||||
|  | @ -67,6 +67,7 @@ public: | ||||||
|    void set_radar_product_group(common::RadarProductGroup radarProductGroup); |    void set_radar_product_group(common::RadarProductGroup radarProductGroup); | ||||||
|    void set_radar_product(const std::string& radarProduct); |    void set_radar_product(const std::string& radarProduct); | ||||||
|    void set_radar_product_code(int16_t radarProductCode); |    void set_radar_product_code(int16_t radarProductCode); | ||||||
|  |    void set_radar_site(const std::shared_ptr<config::RadarSite>& site); | ||||||
|    void set_widget(QWidget* widget); |    void set_widget(QWidget* widget); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | @ -76,5 +77,4 @@ private: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace map
 | } // namespace map
 | ||||||
| } // namespace qt
 | } // namespace scwx::qt
 | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -2008,6 +2008,9 @@ void MapWidgetImpl::SelectNearestRadarSite(double                     latitude, | ||||||
| void MapWidgetImpl::SetRadarSite(const std::string& radarSite, | void MapWidgetImpl::SetRadarSite(const std::string& radarSite, | ||||||
|                                  bool               checkProductAvailability) |                                  bool               checkProductAvailability) | ||||||
| { | { | ||||||
|  |    // Set the radar site in the context
 | ||||||
|  |    context_->set_radar_site(config::RadarSite::Get(radarSite)); | ||||||
|  | 
 | ||||||
|    // Check if radar site has changed
 |    // Check if radar site has changed
 | ||||||
|    if (radarProductManager_ == nullptr || |    if (radarProductManager_ == nullptr || | ||||||
|        radarSite != radarProductManager_->radar_site()->id()) |        radarSite != radarProductManager_->radar_site()->id()) | ||||||
|  |  | ||||||
|  | @ -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,15 @@ 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)} | ||||||
|  |    { | ||||||
|  |    } | ||||||
|    ~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 +48,15 @@ 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_ { | ||||||
|  |       nullptr, nullptr}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 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 +68,24 @@ void RadarSiteLayer::Initialize() | ||||||
| 
 | 
 | ||||||
|    p->radarSites_ = config::RadarSite::GetAll(); |    p->radarSites_ = config::RadarSite::GetAll(); | ||||||
| 
 | 
 | ||||||
|    ImGuiInitialize(); |    p->geoLines_->StartLines(); | ||||||
|  |    p->radarSiteLines_[0] = p->geoLines_->AddLine(); | ||||||
|  |    p->radarSiteLines_[1] = p->geoLines_->AddLine(); | ||||||
|  |    p->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; | ||||||
|  |    p->geoLines_->SetLineModulate(p->radarSiteLines_[0], color0); | ||||||
|  |    p->geoLines_->SetLineWidth(p->radarSiteLines_[0], width + 2); | ||||||
|  | 
 | ||||||
|  |    p->geoLines_->SetLineModulate(p->radarSiteLines_[1], color1); | ||||||
|  |    p->geoLines_->SetLineWidth(p->radarSiteLines_[1], width); | ||||||
|  | 
 | ||||||
|  |    AddDrawItem(p->geoLines_); | ||||||
|  |    p->geoLines_->set_thresholded(false); | ||||||
|  | 
 | ||||||
|  |    DrawLayer::Initialize(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RadarSiteLayer::Render( | void RadarSiteLayer::Render( | ||||||
|  | @ -96,8 +125,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 +196,37 @@ void RadarSiteLayer::Impl::RenderRadarSite( | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void RadarSiteLayer::Impl::RenderRadarLine() | ||||||
|  | { | ||||||
|  |    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()"); | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
| #include <numbers> | #include <numbers> | ||||||
|  | #include <cmath> | ||||||
| 
 | 
 | ||||||
| #include <GeographicLib/Gnomonic.hpp> | #include <GeographicLib/Gnomonic.hpp> | ||||||
| #include <geos/algorithm/PointLocation.h> | #include <geos/algorithm/PointLocation.h> | ||||||
|  | @ -289,6 +290,25 @@ bool AreaInRangeOfPoint(const std::vector<common::Coordinate>& area, | ||||||
|     return GetDistanceAreaPoint(area, point) <= distance; |     return GetDistanceAreaPoint(area, point) <= distance; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | units::length::meters<double> | ||||||
|  | GetRadarBeamAltititude(units::length::meters<double> range, | ||||||
|  |                        units::angle::degrees<double> elevation, | ||||||
|  |                        units::length::meters<double> height) | ||||||
|  | { | ||||||
|  |    static const units::length::meters<double> earthRadius {6367444 * 4 / 3}; | ||||||
|  | 
 | ||||||
|  |    height += earthRadius; | ||||||
|  | 
 | ||||||
|  |    const double elevationRadians = | ||||||
|  |       units::angle::radians<double>(elevation).value(); | ||||||
|  |    const auto altitudeSquared = | ||||||
|  |       (range * range + height * height + | ||||||
|  |        2 * range * height * std::sin(elevationRadians)); | ||||||
|  | 
 | ||||||
|  |    return units::length::meters<double>(std::sqrt(altitudeSquared.value())) - | ||||||
|  |           earthRadius; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace GeographicLib
 | } // namespace GeographicLib
 | ||||||
| } // namespace util
 | } // namespace util
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
|  |  | ||||||
|  | @ -121,6 +121,20 @@ bool AreaInRangeOfPoint(const std::vector<common::Coordinate>& area, | ||||||
|                         const common::Coordinate&              point, |                         const common::Coordinate&              point, | ||||||
|                         const units::length::meters<double>    distance); |                         const units::length::meters<double>    distance); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Get the altitude of the radar beam at a given distance, elevation and height | ||||||
|  |  * | ||||||
|  |  * @param [in] range The range to the radar site | ||||||
|  |  * @param [in] elevation The elevation of the radar site | ||||||
|  |  * @param [in] height The height of the radar site | ||||||
|  |  * | ||||||
|  |  * @return The altitude of the radar at that range | ||||||
|  |  */ | ||||||
|  | units::length::meters<double> | ||||||
|  | GetRadarBeamAltititude(units::length::meters<double> range, | ||||||
|  |                        units::angle::degrees<double> elevation, | ||||||
|  |                        units::length::meters<double> height); | ||||||
|  | 
 | ||||||
| } // namespace GeographicLib
 | } // namespace GeographicLib
 | ||||||
| } // namespace util
 | } // namespace util
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat