mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 09:40:04 +00:00 
			
		
		
		
	Get bin values at coordinates from level 3 radial data, stubs for raster and level 2
This commit is contained in:
		
							parent
							
								
									c67b4cf536
								
							
						
					
					
						commit
						6e04e1fab3
					
				
					 9 changed files with 153 additions and 19 deletions
				
			
		|  | @ -774,6 +774,14 @@ void Level2ProductViewImpl::ComputeCoordinates( | ||||||
|    logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws")); |    logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::optional<std::uint16_t> | ||||||
|  | Level2ProductView::GetBinLevel(const common::Coordinate& coordinate) const | ||||||
|  | { | ||||||
|  |    // TODO
 | ||||||
|  |    Q_UNUSED(coordinate); | ||||||
|  |    return std::nullopt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<Level2ProductView> Level2ProductView::Create( | std::shared_ptr<Level2ProductView> Level2ProductView::Create( | ||||||
|    common::Level2Product                         product, |    common::Level2Product                         product, | ||||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) |    std::shared_ptr<manager::RadarProductManager> radarProductManager) | ||||||
|  |  | ||||||
|  | @ -47,6 +47,8 @@ public: | ||||||
|    GetMomentData() const override; |    GetMomentData() const override; | ||||||
|    std::tuple<const void*, std::size_t, std::size_t> |    std::tuple<const void*, std::size_t, std::size_t> | ||||||
|    GetCfpMomentData() const override; |    GetCfpMomentData() const override; | ||||||
|  |    std::optional<std::uint16_t> | ||||||
|  |    GetBinLevel(const common::Coordinate& coordinate) const override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<Level2ProductView> |    static std::shared_ptr<Level2ProductView> | ||||||
|    Create(common::Level2Product                         product, |    Create(common::Level2Product                         product, | ||||||
|  |  | ||||||
|  | @ -27,10 +27,10 @@ static const auto        logger_    = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| static constexpr uint16_t RANGE_FOLDED = 1u; | static constexpr uint16_t RANGE_FOLDED = 1u; | ||||||
| 
 | 
 | ||||||
| class Level3ProductViewImpl | class Level3ProductView::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Level3ProductViewImpl(const std::string& product) : |    explicit Impl(const std::string& product) : | ||||||
|        product_ {product}, |        product_ {product}, | ||||||
|        graphicMessage_ {nullptr}, |        graphicMessage_ {nullptr}, | ||||||
|        colorTable_ {}, |        colorTable_ {}, | ||||||
|  | @ -42,7 +42,7 @@ public: | ||||||
|        savedOffset_ {0.0f} |        savedOffset_ {0.0f} | ||||||
|    { |    { | ||||||
|    } |    } | ||||||
|    ~Level3ProductViewImpl() = default; |    ~Impl() = default; | ||||||
| 
 | 
 | ||||||
|    std::string product_; |    std::string product_; | ||||||
| 
 | 
 | ||||||
|  | @ -61,8 +61,7 @@ public: | ||||||
| Level3ProductView::Level3ProductView( | Level3ProductView::Level3ProductView( | ||||||
|    const std::string&                            product, |    const std::string&                            product, | ||||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) : |    std::shared_ptr<manager::RadarProductManager> radarProductManager) : | ||||||
|     RadarProductView(radarProductManager), |     RadarProductView(radarProductManager), p(std::make_unique<Impl>(product)) | ||||||
|     p(std::make_unique<Level3ProductViewImpl>(product)) |  | ||||||
| { | { | ||||||
|    ConnectRadarProductManager(); |    ConnectRadarProductManager(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,8 +15,6 @@ namespace qt | ||||||
| namespace view | namespace view | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class Level3ProductViewImpl; |  | ||||||
| 
 |  | ||||||
| class Level3ProductView : public RadarProductView | class Level3ProductView : public RadarProductView | ||||||
| { | { | ||||||
|    Q_OBJECT |    Q_OBJECT | ||||||
|  | @ -52,7 +50,8 @@ protected: | ||||||
|    void UpdateColorTable() override; |    void UpdateColorTable() override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<Level3ProductViewImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace view
 | } // namespace view
 | ||||||
|  |  | ||||||
|  | @ -28,10 +28,10 @@ static constexpr std::uint16_t RANGE_FOLDED      = 1u; | ||||||
| static constexpr std::uint32_t VERTICES_PER_BIN  = 6u; | static constexpr std::uint32_t VERTICES_PER_BIN  = 6u; | ||||||
| static constexpr std::uint32_t VALUES_PER_VERTEX = 2u; | static constexpr std::uint32_t VALUES_PER_VERTEX = 2u; | ||||||
| 
 | 
 | ||||||
| class Level3RadialViewImpl | class Level3RadialView::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Level3RadialViewImpl(Level3RadialView* self) : |    explicit Impl(Level3RadialView* self) : | ||||||
|        self_ {self}, |        self_ {self}, | ||||||
|        latitude_ {}, |        latitude_ {}, | ||||||
|        longitude_ {}, |        longitude_ {}, | ||||||
|  | @ -41,10 +41,10 @@ public: | ||||||
|    { |    { | ||||||
|       coordinates_.resize(kMaxCoordinates_); |       coordinates_.resize(kMaxCoordinates_); | ||||||
|    } |    } | ||||||
|    ~Level3RadialViewImpl() { threadPool_.join(); }; |    ~Impl() { threadPool_.join(); }; | ||||||
| 
 | 
 | ||||||
|    void ComputeCoordinates( |    void ComputeCoordinates( | ||||||
|       std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData); |       const std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket>& radialData); | ||||||
| 
 | 
 | ||||||
|    Level3RadialView* self_; |    Level3RadialView* self_; | ||||||
| 
 | 
 | ||||||
|  | @ -54,6 +54,8 @@ public: | ||||||
|    std::vector<float>        vertices_ {}; |    std::vector<float>        vertices_ {}; | ||||||
|    std::vector<std::uint8_t> dataMoments8_ {}; |    std::vector<std::uint8_t> dataMoments8_ {}; | ||||||
| 
 | 
 | ||||||
|  |    std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> lastRadialData_ {}; | ||||||
|  | 
 | ||||||
|    float         latitude_; |    float         latitude_; | ||||||
|    float         longitude_; |    float         longitude_; | ||||||
|    float         range_; |    float         range_; | ||||||
|  | @ -66,7 +68,7 @@ Level3RadialView::Level3RadialView( | ||||||
|    const std::string&                            product, |    const std::string&                            product, | ||||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) : |    std::shared_ptr<manager::RadarProductManager> radarProductManager) : | ||||||
|     Level3ProductView(product, radarProductManager), |     Level3ProductView(product, radarProductManager), | ||||||
|     p(std::make_unique<Level3RadialViewImpl>(this)) |     p(std::make_unique<Impl>(this)) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -235,6 +237,8 @@ void Level3RadialView::ComputeSweep() | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    p->lastRadialData_ = radialData; | ||||||
|  | 
 | ||||||
|    // Valid number of radials is 1-720
 |    // Valid number of radials is 1-720
 | ||||||
|    size_t radials = radialData->number_of_radials(); |    size_t radials = radialData->number_of_radials(); | ||||||
|    if (radials < 1 || radials > 720) |    if (radials < 1 || radials > 720) | ||||||
|  | @ -424,8 +428,8 @@ void Level3RadialView::ComputeSweep() | ||||||
|    Q_EMIT SweepComputed(); |    Q_EMIT SweepComputed(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Level3RadialViewImpl::ComputeCoordinates( | void Level3RadialView::Impl::ComputeCoordinates( | ||||||
|    std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData) |    const std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket>& radialData) | ||||||
| { | { | ||||||
|    logger_->debug("ComputeCoordinates()"); |    logger_->debug("ComputeCoordinates()"); | ||||||
| 
 | 
 | ||||||
|  | @ -485,6 +489,113 @@ void Level3RadialViewImpl::ComputeCoordinates( | ||||||
|    logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws")); |    logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::optional<std::uint16_t> | ||||||
|  | Level3RadialView::GetBinLevel(const common::Coordinate& coordinate) const | ||||||
|  | { | ||||||
|  |    auto gpm = graphic_product_message(); | ||||||
|  |    if (gpm == nullptr) | ||||||
|  |    { | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<wsr88d::rpg::ProductDescriptionBlock> descriptionBlock = | ||||||
|  |       gpm->description_block(); | ||||||
|  |    if (descriptionBlock == nullptr) | ||||||
|  |    { | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> radialData = | ||||||
|  |       p->lastRadialData_; | ||||||
|  |    if (radialData == nullptr) | ||||||
|  |    { | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Determine distance and azimuth of coordinate relative to radar location
 | ||||||
|  |    double s12;  // Distance (meters)
 | ||||||
|  |    double azi1; // Azimuth (degrees)
 | ||||||
|  |    double azi2; // Unused
 | ||||||
|  |    util::GeographicLib::DefaultGeodesic().Inverse( | ||||||
|  |       descriptionBlock->latitude_of_radar(), | ||||||
|  |       descriptionBlock->longitude_of_radar(), | ||||||
|  |       coordinate.latitude_, | ||||||
|  |       coordinate.longitude_, | ||||||
|  |       s12, | ||||||
|  |       azi1, | ||||||
|  |       azi2); | ||||||
|  | 
 | ||||||
|  |    if (std::isnan(azi1)) | ||||||
|  |    { | ||||||
|  |       // If a problem occurred with the geodesic inverse calculation
 | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Azimuth is returned as [-180, 180) from the geodesic inverse, we need a
 | ||||||
|  |    // range of [0, 360)
 | ||||||
|  |    while (azi1 < 0.0) | ||||||
|  |    { | ||||||
|  |       azi1 += 360.0; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Compute gate interval
 | ||||||
|  |    const std::uint16_t gates = radialData->number_of_range_bins(); | ||||||
|  |    const std::uint16_t dataMomentInterval = | ||||||
|  |       descriptionBlock->x_resolution_raw(); | ||||||
|  |    std::uint16_t gate = s12 / dataMomentInterval; | ||||||
|  | 
 | ||||||
|  |    if (gate >= gates) | ||||||
|  |    { | ||||||
|  |       // Coordinate is beyond radar range
 | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Find Radial
 | ||||||
|  |    const std::uint16_t numRadials = radialData->number_of_radials(); | ||||||
|  |    std::uint16_t       radial     = numRadials; | ||||||
|  |    float               nextAngle  = radialData->start_angle(0); | ||||||
|  |    for (std::uint16_t i = 0; i < numRadials; ++i) | ||||||
|  |    { | ||||||
|  |       float startAngle = nextAngle; | ||||||
|  |       nextAngle        = radialData->start_angle((i + 1) % numRadials); | ||||||
|  | 
 | ||||||
|  |       if (startAngle < nextAngle) | ||||||
|  |       { | ||||||
|  |          if (startAngle <= azi1 && azi1 < nextAngle) | ||||||
|  |          { | ||||||
|  |             radial = i; | ||||||
|  |             break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          // If the bin crosses 0/360 degrees, special handling is needed
 | ||||||
|  |          if (startAngle <= azi1 || azi1 < nextAngle) | ||||||
|  |          { | ||||||
|  |             radial = i; | ||||||
|  |             break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (radial == numRadials) | ||||||
|  |    { | ||||||
|  |       // No radial was found (not likely to happen without a gap in data)
 | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Compute threshold at which to display an individual bin
 | ||||||
|  |    const std::uint16_t snrThreshold = descriptionBlock->threshold(); | ||||||
|  |    const std::uint8_t  level        = radialData->level(radial).at(gate); | ||||||
|  | 
 | ||||||
|  |    if (level < snrThreshold && level != RANGE_FOLDED) | ||||||
|  |    { | ||||||
|  |       return std::nullopt; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return level; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<Level3RadialView> Level3RadialView::Create( | std::shared_ptr<Level3RadialView> Level3RadialView::Create( | ||||||
|    const std::string&                            product, |    const std::string&                            product, | ||||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) |    std::shared_ptr<manager::RadarProductManager> radarProductManager) | ||||||
|  |  | ||||||
|  | @ -13,8 +13,6 @@ namespace qt | ||||||
| namespace view | namespace view | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class Level3RadialViewImpl; |  | ||||||
| 
 |  | ||||||
| class Level3RadialView : public Level3ProductView | class Level3RadialView : public Level3ProductView | ||||||
| { | { | ||||||
|    Q_OBJECT |    Q_OBJECT | ||||||
|  | @ -32,6 +30,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    std::tuple<const void*, std::size_t, std::size_t> |    std::tuple<const void*, std::size_t, std::size_t> | ||||||
|    GetMomentData() const override; |    GetMomentData() const override; | ||||||
|  |    std::optional<std::uint16_t> | ||||||
|  |    GetBinLevel(const common::Coordinate& coordinate) const override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<Level3RadialView> |    static std::shared_ptr<Level3RadialView> | ||||||
|    Create(const std::string&                            product, |    Create(const std::string&                            product, | ||||||
|  | @ -44,7 +44,8 @@ protected slots: | ||||||
|    void ComputeSweep() override; |    void ComputeSweep() override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<Level3RadialViewImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace view
 | } // namespace view
 | ||||||
|  |  | ||||||
|  | @ -352,6 +352,14 @@ void Level3RasterView::ComputeSweep() | ||||||
|    Q_EMIT SweepComputed(); |    Q_EMIT SweepComputed(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::optional<std::uint16_t> | ||||||
|  | Level3RasterView::GetBinLevel(const common::Coordinate& coordinate) const | ||||||
|  | { | ||||||
|  |    // TODO
 | ||||||
|  |    Q_UNUSED(coordinate); | ||||||
|  |    return std::nullopt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<Level3RasterView> Level3RasterView::Create( | std::shared_ptr<Level3RasterView> Level3RasterView::Create( | ||||||
|    const std::string&                            product, |    const std::string&                            product, | ||||||
|    std::shared_ptr<manager::RadarProductManager> radarProductManager) |    std::shared_ptr<manager::RadarProductManager> radarProductManager) | ||||||
|  |  | ||||||
|  | @ -32,6 +32,8 @@ public: | ||||||
| 
 | 
 | ||||||
|    std::tuple<const void*, std::size_t, std::size_t> |    std::tuple<const void*, std::size_t, std::size_t> | ||||||
|    GetMomentData() const override; |    GetMomentData() const override; | ||||||
|  |    std::optional<std::uint16_t> | ||||||
|  |    GetBinLevel(const common::Coordinate& coordinate) const override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<Level3RasterView> |    static std::shared_ptr<Level3RasterView> | ||||||
|    Create(const std::string&                            product, |    Create(const std::string&                            product, | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <scwx/common/color_table.hpp> | #include <scwx/common/color_table.hpp> | ||||||
|  | #include <scwx/common/geographic.hpp> | ||||||
| #include <scwx/common/products.hpp> | #include <scwx/common/products.hpp> | ||||||
| #include <scwx/qt/manager/radar_product_manager.hpp> | #include <scwx/qt/manager/radar_product_manager.hpp> | ||||||
| #include <scwx/qt/types/map_types.hpp> | #include <scwx/qt/types/map_types.hpp> | ||||||
|  | @ -8,6 +9,7 @@ | ||||||
| #include <chrono> | #include <chrono> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <mutex> | #include <mutex> | ||||||
|  | #include <optional> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| #include <QObject> | #include <QObject> | ||||||
|  | @ -63,7 +65,9 @@ public: | ||||||
|    virtual std::tuple<const void*, std::size_t, std::size_t> |    virtual std::tuple<const void*, std::size_t, std::size_t> | ||||||
|    GetMomentData() const = 0; |    GetMomentData() const = 0; | ||||||
|    virtual std::tuple<const void*, std::size_t, std::size_t> |    virtual std::tuple<const void*, std::size_t, std::size_t> | ||||||
|                                          GetCfpMomentData() const; |    GetCfpMomentData() const; | ||||||
|  |    virtual std::optional<std::uint16_t> | ||||||
|  |    GetBinLevel(const common::Coordinate& coordinate) const = 0; | ||||||
|    std::chrono::system_clock::time_point GetSelectedTime() const; |    std::chrono::system_clock::time_point GetSelectedTime() const; | ||||||
| 
 | 
 | ||||||
|    virtual std::vector<std::pair<std::string, std::string>> |    virtual std::vector<std::pair<std::string, std::string>> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat