mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 10:00:05 +00:00 
			
		
		
		
	Dynamic range circle
This commit is contained in:
		
							parent
							
								
									77ba92ce7f
								
							
						
					
					
						commit
						87581892a7
					
				
					 9 changed files with 105 additions and 34 deletions
				
			
		|  | @ -115,7 +115,10 @@ void MapWidget::SelectRadarProduct(common::Level2Product product) | ||||||
|       p->radarProductView_.get(), |       p->radarProductView_.get(), | ||||||
|       &view::RadarProductView::SweepComputed, |       &view::RadarProductView::SweepComputed, | ||||||
|       this, |       this, | ||||||
|       [&]() { update(); }, |       [&]() { | ||||||
|  |          RadarRangeLayer::Update(p->map_, p->radarProductView_->range()); | ||||||
|  |          update(); | ||||||
|  |       }, | ||||||
|       Qt::QueuedConnection); |       Qt::QueuedConnection); | ||||||
| 
 | 
 | ||||||
|    if (p->map_ != nullptr) |    if (p->map_ != nullptr) | ||||||
|  | @ -148,14 +151,6 @@ void MapWidget::changeStyle() | ||||||
| void MapWidget::AddLayers() | void MapWidget::AddLayers() | ||||||
| { | { | ||||||
|    // TODO: Improve this
 |    // TODO: Improve this
 | ||||||
|    if (p->map_->layerExists("rangeCircleLayer")) |  | ||||||
|    { |  | ||||||
|       p->map_->removeLayer("rangeCircleLayer"); |  | ||||||
|    } |  | ||||||
|    if (p->map_->sourceExists("rangeCircleSource")) |  | ||||||
|    { |  | ||||||
|       p->map_->removeSource("rangeCircleSource"); |  | ||||||
|    } |  | ||||||
|    if (p->map_->layerExists("radar")) |    if (p->map_->layerExists("radar")) | ||||||
|    { |    { | ||||||
|       p->map_->removeLayer("radar"); |       p->map_->removeLayer("radar"); | ||||||
|  | @ -185,7 +180,7 @@ void MapWidget::AddLayers() | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    p->map_->addCustomLayer("radar", pHost, before); |    p->map_->addCustomLayer("radar", pHost, before); | ||||||
|    RadarRangeLayer::Add(p->map_, before); |    RadarRangeLayer::Add(p->map_, p->radarProductView_->range(), before); | ||||||
|    p->map_->addCustomLayer("overlay", pOverlayHost); |    p->map_->addCustomLayer("overlay", pOverlayHost); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,15 +13,49 @@ namespace map | ||||||
| 
 | 
 | ||||||
| static const std::string logPrefix_ = "[scwx::qt::map::radar_range_layer] "; | static const std::string logPrefix_ = "[scwx::qt::map::radar_range_layer] "; | ||||||
| 
 | 
 | ||||||
| void RadarRangeLayer::Add(std::shared_ptr<QMapboxGL> map, const QString& before) | static std::shared_ptr<QMapbox::Feature> GetRangeCircle(float range); | ||||||
|  | 
 | ||||||
|  | void RadarRangeLayer::Add(std::shared_ptr<QMapboxGL> map, | ||||||
|  |                           float                      range, | ||||||
|  |                           const QString&             before) | ||||||
| { | { | ||||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Add()"; |    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Add()"; | ||||||
| 
 | 
 | ||||||
|  |    if (map->layerExists("rangeCircleLayer")) | ||||||
|  |    { | ||||||
|  |       map->removeLayer("rangeCircleLayer"); | ||||||
|  |    } | ||||||
|  |    if (map->sourceExists("rangeCircleSource")) | ||||||
|  |    { | ||||||
|  |       map->removeSource("rangeCircleSource"); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    std::shared_ptr<QMapbox::Feature> rangeCircle = GetRangeCircle(range); | ||||||
|  | 
 | ||||||
|  |    map->addSource( | ||||||
|  |       "rangeCircleSource", | ||||||
|  |       {{"type", "geojson"}, {"data", QVariant::fromValue(*rangeCircle)}}); | ||||||
|  |    map->addLayer({{"id", "rangeCircleLayer"}, | ||||||
|  |                   {"type", "line"}, | ||||||
|  |                   {"source", "rangeCircleSource"}}, | ||||||
|  |                  before); | ||||||
|  |    map->setPaintProperty( | ||||||
|  |       "rangeCircleLayer", "line-color", "rgba(128, 128, 128, 128)"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RadarRangeLayer::Update(std::shared_ptr<QMapboxGL> map, float range) | ||||||
|  | { | ||||||
|  |    std::shared_ptr<QMapbox::Feature> rangeCircle = GetRangeCircle(range); | ||||||
|  | 
 | ||||||
|  |    map->updateSource("rangeCircleSource", | ||||||
|  |                      {{"data", QVariant::fromValue(*rangeCircle)}}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static std::shared_ptr<QMapbox::Feature> GetRangeCircle(float range) | ||||||
|  | { | ||||||
|    GeographicLib::Geodesic geodesic(GeographicLib::Constants::WGS84_a(), |    GeographicLib::Geodesic geodesic(GeographicLib::Constants::WGS84_a(), | ||||||
|                                     GeographicLib::Constants::WGS84_f()); |                                     GeographicLib::Constants::WGS84_f()); | ||||||
| 
 | 
 | ||||||
|    constexpr float range = 460.0f * 1000.0f; |  | ||||||
| 
 |  | ||||||
|    constexpr float angleDelta  = 0.5f; |    constexpr float angleDelta  = 0.5f; | ||||||
|    constexpr float angleDeltaH = angleDelta / 2.0f; |    constexpr float angleDeltaH = angleDelta / 2.0f; | ||||||
| 
 | 
 | ||||||
|  | @ -36,26 +70,25 @@ void RadarRangeLayer::Add(std::shared_ptr<QMapboxGL> map, const QString& before) | ||||||
|       double latitude; |       double latitude; | ||||||
|       double longitude; |       double longitude; | ||||||
| 
 | 
 | ||||||
|       geodesic.Direct( |       geodesic.Direct(radar.first, | ||||||
|          radar.first, radar.second, angle, range, latitude, longitude); |                       radar.second, | ||||||
|  |                       angle, | ||||||
|  |                       range * 1000.0f, | ||||||
|  |                       latitude, | ||||||
|  |                       longitude); | ||||||
| 
 | 
 | ||||||
|       geometry.append({latitude, longitude}); |       geometry.append({latitude, longitude}); | ||||||
| 
 | 
 | ||||||
|       angle += angleDelta; |       angle += angleDelta; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    QMapbox::Feature rangeCircle {QMapbox::Feature::LineStringType, |    std::shared_ptr<QMapbox::Feature> rangeCircle = | ||||||
|                                  {{geometry}}}; |       std::make_shared<QMapbox::Feature>( | ||||||
|  |          QMapbox::Feature::LineStringType, | ||||||
|  |          std::initializer_list<QMapbox::CoordinatesCollection> { | ||||||
|  |             std::initializer_list<QMapbox::Coordinates> {geometry}}); | ||||||
| 
 | 
 | ||||||
|    map->addSource( |    return rangeCircle; | ||||||
|       "rangeCircleSource", |  | ||||||
|       {{"type", "geojson"}, {"data", QVariant::fromValue(rangeCircle)}}); |  | ||||||
|    map->addLayer({{"id", "rangeCircleLayer"}, |  | ||||||
|                   {"type", "line"}, |  | ||||||
|                   {"source", "rangeCircleSource"}}, |  | ||||||
|                  before); |  | ||||||
|    map->setPaintProperty( |  | ||||||
|       "rangeCircleLayer", "line-color", "rgba(128, 128, 128, 128)"); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace map
 | } // namespace map
 | ||||||
|  |  | ||||||
|  | @ -8,12 +8,15 @@ namespace qt | ||||||
| { | { | ||||||
| namespace map | namespace map | ||||||
| { | { | ||||||
| 
 |  | ||||||
| namespace RadarRangeLayer | namespace RadarRangeLayer | ||||||
| { | { | ||||||
| void Add(std::shared_ptr<QMapboxGL> map, const QString& before = QString()); |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
|  | void Add(std::shared_ptr<QMapboxGL> map, | ||||||
|  |          float                      range, | ||||||
|  |          const QString&             before = QString()); | ||||||
|  | void Update(std::shared_ptr<QMapboxGL> map, float range); | ||||||
|  | 
 | ||||||
|  | } // namespace RadarRangeLayer
 | ||||||
| } // namespace map
 | } // namespace map
 | ||||||
| } // namespace qt
 | } // namespace qt
 | ||||||
| } // namespace scwx
 | } // namespace scwx
 | ||||||
|  |  | ||||||
|  | @ -46,6 +46,7 @@ public: | ||||||
|        radarProductManager_ {radarProductManager}, |        radarProductManager_ {radarProductManager}, | ||||||
|        latitude_ {}, |        latitude_ {}, | ||||||
|        longitude_ {}, |        longitude_ {}, | ||||||
|  |        range_ {}, | ||||||
|        sweepTime_ {}, |        sweepTime_ {}, | ||||||
|        colorTable_ {}, |        colorTable_ {}, | ||||||
|        colorTableLut_ {}, |        colorTableLut_ {}, | ||||||
|  | @ -80,6 +81,7 @@ public: | ||||||
| 
 | 
 | ||||||
|    float latitude_; |    float latitude_; | ||||||
|    float longitude_; |    float longitude_; | ||||||
|  |    float range_; | ||||||
| 
 | 
 | ||||||
|    std::chrono::system_clock::time_point sweepTime_; |    std::chrono::system_clock::time_point sweepTime_; | ||||||
| 
 | 
 | ||||||
|  | @ -120,6 +122,11 @@ Level2ProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const | ||||||
|    } |    } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | float Level2ProductView::range() const | ||||||
|  | { | ||||||
|  |    return p->range_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::chrono::system_clock::time_point Level2ProductView::sweep_time() const | std::chrono::system_clock::time_point Level2ProductView::sweep_time() const | ||||||
| { | { | ||||||
|    return p->sweepTime_; |    return p->sweepTime_; | ||||||
|  | @ -295,10 +302,16 @@ void Level2ProductView::ComputeSweep() | ||||||
|       return; |       return; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    const uint32_t gates = momentData0->number_of_data_moment_gates(); | ||||||
|  | 
 | ||||||
|  |    auto radialData0 = radarData0->radial_data_block(); | ||||||
|    auto volumeData0 = radarData0->volume_data_block(); |    auto volumeData0 = radarData0->volume_data_block(); | ||||||
|    p->latitude_     = volumeData0->latitude(); |    p->latitude_     = volumeData0->latitude(); | ||||||
|    p->longitude_    = volumeData0->longitude(); |    p->longitude_    = volumeData0->longitude(); | ||||||
|    p->sweepTime_    = util::TimePoint(radarData0->modified_julian_date(), |    p->range_ = | ||||||
|  |       momentData0->data_moment_range() + | ||||||
|  |       momentData0->data_moment_range_sample_interval() * (gates - 0.5f); | ||||||
|  |    p->sweepTime_ = util::TimePoint(radarData0->modified_julian_date(), | ||||||
|                                    radarData0->collection_time()); |                                    radarData0->collection_time()); | ||||||
| 
 | 
 | ||||||
|    // Calculate vertices
 |    // Calculate vertices
 | ||||||
|  | @ -306,7 +319,6 @@ void Level2ProductView::ComputeSweep() | ||||||
| 
 | 
 | ||||||
|    // Setup vertex vector
 |    // Setup vertex vector
 | ||||||
|    std::vector<float>& vertices = p->vertices_; |    std::vector<float>& vertices = p->vertices_; | ||||||
|    const uint32_t      gates    = momentData0->number_of_data_moment_gates(); |  | ||||||
|    size_t              vIndex   = 0; |    size_t              vIndex   = 0; | ||||||
|    vertices.clear(); |    vertices.clear(); | ||||||
|    vertices.resize(radials * gates * VERTICES_PER_BIN * VALUES_PER_VERTEX); |    vertices.resize(radials * gates * VERTICES_PER_BIN * VALUES_PER_VERTEX); | ||||||
|  |  | ||||||
|  | @ -29,7 +29,8 @@ public: | ||||||
|    ~Level2ProductView(); |    ~Level2ProductView(); | ||||||
| 
 | 
 | ||||||
|    const std::vector<boost::gil::rgba8_pixel_t>& |    const std::vector<boost::gil::rgba8_pixel_t>& | ||||||
|    color_table(uint16_t& minValue, uint16_t& maxValue) const override; |          color_table(uint16_t& minValue, uint16_t& maxValue) const override; | ||||||
|  |    float range() const override; | ||||||
|    std::chrono::system_clock::time_point sweep_time() const override; |    std::chrono::system_clock::time_point sweep_time() const override; | ||||||
|    const std::vector<float>&             vertices() const override; |    const std::vector<float>&             vertices() const override; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -40,6 +40,11 @@ RadarProductView::color_table(uint16_t& minValue, uint16_t& maxValue) const | ||||||
|    return DEFAULT_COLOR_TABLE; |    return DEFAULT_COLOR_TABLE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | float RadarProductView::range() const | ||||||
|  | { | ||||||
|  |    return 0.0f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::chrono::system_clock::time_point RadarProductView::sweep_time() const | std::chrono::system_clock::time_point RadarProductView::sweep_time() const | ||||||
| { | { | ||||||
|    return {}; |    return {}; | ||||||
|  |  | ||||||
|  | @ -26,7 +26,8 @@ public: | ||||||
|    ~RadarProductView(); |    ~RadarProductView(); | ||||||
| 
 | 
 | ||||||
|    virtual const std::vector<boost::gil::rgba8_pixel_t>& |    virtual const std::vector<boost::gil::rgba8_pixel_t>& | ||||||
|    color_table(uint16_t& minValue, uint16_t& maxValue) const; |                  color_table(uint16_t& minValue, uint16_t& maxValue) const; | ||||||
|  |    virtual float range() const; | ||||||
|    virtual std::chrono::system_clock::time_point sweep_time() const; |    virtual std::chrono::system_clock::time_point sweep_time() const; | ||||||
|    virtual const std::vector<float>&             vertices() const = 0; |    virtual const std::vector<float>&             vertices() const = 0; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -129,6 +129,8 @@ public: | ||||||
|    RadialDataBlock(RadialDataBlock&&) noexcept; |    RadialDataBlock(RadialDataBlock&&) noexcept; | ||||||
|    RadialDataBlock& operator=(RadialDataBlock&&) noexcept; |    RadialDataBlock& operator=(RadialDataBlock&&) noexcept; | ||||||
| 
 | 
 | ||||||
|  |    float unambiguous_range() const; | ||||||
|  | 
 | ||||||
|    static std::shared_ptr<RadialDataBlock> |    static std::shared_ptr<RadialDataBlock> | ||||||
|    Create(const std::string& dataBlockType, |    Create(const std::string& dataBlockType, | ||||||
|           const std::string& dataName, |           const std::string& dataName, | ||||||
|  | @ -195,7 +197,9 @@ public: | ||||||
|    uint8_t            azimuth_indexing_mode() const; |    uint8_t            azimuth_indexing_mode() const; | ||||||
|    uint16_t           data_block_count() const; |    uint16_t           data_block_count() const; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<VolumeDataBlock> volume_data_block() const; |    std::shared_ptr<ElevationDataBlock> elevation_data_block() const; | ||||||
|  |    std::shared_ptr<RadialDataBlock>    radial_data_block() const; | ||||||
|  |    std::shared_ptr<VolumeDataBlock>    volume_data_block() const; | ||||||
|    std::shared_ptr<MomentDataBlock> moment_data_block(DataBlockType type) const; |    std::shared_ptr<MomentDataBlock> moment_data_block(DataBlockType type) const; | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is); |    bool Parse(std::istream& is); | ||||||
|  |  | ||||||
|  | @ -434,6 +434,11 @@ RadialDataBlock::RadialDataBlock(RadialDataBlock&&) noexcept = default; | ||||||
| RadialDataBlock& | RadialDataBlock& | ||||||
| RadialDataBlock::operator=(RadialDataBlock&&) noexcept = default; | RadialDataBlock::operator=(RadialDataBlock&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
|  | float RadialDataBlock::unambiguous_range() const | ||||||
|  | { | ||||||
|  |    return p->unambigiousRange_ / 10.0f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<RadialDataBlock> | std::shared_ptr<RadialDataBlock> | ||||||
| RadialDataBlock::Create(const std::string& dataBlockType, | RadialDataBlock::Create(const std::string& dataBlockType, | ||||||
|                         const std::string& dataName, |                         const std::string& dataName, | ||||||
|  | @ -613,6 +618,18 @@ uint16_t DigitalRadarData::data_block_count() const | ||||||
| { | { | ||||||
|    return p->dataBlockCount_; |    return p->dataBlockCount_; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<ElevationDataBlock> | ||||||
|  | DigitalRadarData::elevation_data_block() const | ||||||
|  | { | ||||||
|  |    return p->elevationDataBlock_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<RadialDataBlock> DigitalRadarData::radial_data_block() const | ||||||
|  | { | ||||||
|  |    return p->radialDataBlock_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::shared_ptr<VolumeDataBlock> DigitalRadarData::volume_data_block() const | std::shared_ptr<VolumeDataBlock> DigitalRadarData::volume_data_block() const | ||||||
| { | { | ||||||
|    return p->volumeDataBlock_; |    return p->volumeDataBlock_; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat