mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 23:10:05 +00:00
Level 3 raster smoothing
This commit is contained in:
parent
b93c76ef1b
commit
44f91a3a86
3 changed files with 81 additions and 32 deletions
|
|
@ -131,7 +131,7 @@ public:
|
||||||
std::shared_ptr<wsr88d::rda::GenericRadarData::MomentDataBlock>
|
std::shared_ptr<wsr88d::rda::GenericRadarData::MomentDataBlock>
|
||||||
momentDataBlock0_;
|
momentDataBlock0_;
|
||||||
|
|
||||||
bool prevSmoothingEnabled_ {false};
|
bool lastSmoothingEnabled_ {false};
|
||||||
|
|
||||||
std::vector<float> coordinates_ {};
|
std::vector<float> coordinates_ {};
|
||||||
std::vector<float> vertices_ {};
|
std::vector<float> vertices_ {};
|
||||||
|
|
@ -528,13 +528,13 @@ void Level2ProductView::ComputeSweep()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (radarData == p->elevationScan_ &&
|
if (radarData == p->elevationScan_ &&
|
||||||
smoothingEnabled == p->prevSmoothingEnabled_)
|
smoothingEnabled == p->lastSmoothingEnabled_)
|
||||||
{
|
{
|
||||||
Q_EMIT SweepNotComputed(types::NoUpdateReason::NoChange);
|
Q_EMIT SweepNotComputed(types::NoUpdateReason::NoChange);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->prevSmoothingEnabled_ = smoothingEnabled;
|
p->lastSmoothingEnabled_ = smoothingEnabled;
|
||||||
|
|
||||||
logger_->debug("Computing Sweep");
|
logger_->debug("Computing Sweep");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,7 @@ public:
|
||||||
std::vector<std::uint8_t> dataMoments8_ {};
|
std::vector<std::uint8_t> dataMoments8_ {};
|
||||||
|
|
||||||
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> lastRadialData_ {};
|
std::shared_ptr<wsr88d::rpg::GenericRadialDataPacket> lastRadialData_ {};
|
||||||
|
bool lastSmoothingEnabled_ {false};
|
||||||
bool prevSmoothingEnabled_ {false};
|
|
||||||
|
|
||||||
float latitude_;
|
float latitude_;
|
||||||
float longitude_;
|
float longitude_;
|
||||||
|
|
@ -160,7 +159,7 @@ void Level3RadialView::ComputeSweep()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (gpm == graphic_product_message() &&
|
else if (gpm == graphic_product_message() &&
|
||||||
smoothingEnabled == p->prevSmoothingEnabled_)
|
smoothingEnabled == p->lastSmoothingEnabled_)
|
||||||
{
|
{
|
||||||
// Skip if this is the message we previously processed
|
// Skip if this is the message we previously processed
|
||||||
Q_EMIT SweepNotComputed(types::NoUpdateReason::NoChange);
|
Q_EMIT SweepNotComputed(types::NoUpdateReason::NoChange);
|
||||||
|
|
@ -168,7 +167,7 @@ void Level3RadialView::ComputeSweep()
|
||||||
}
|
}
|
||||||
set_graphic_product_message(gpm);
|
set_graphic_product_message(gpm);
|
||||||
|
|
||||||
p->prevSmoothingEnabled_ = smoothingEnabled;
|
p->lastSmoothingEnabled_ = smoothingEnabled;
|
||||||
|
|
||||||
// A message with radial data should have a Product Description Block and
|
// A message with radial data should have a Product Description Block and
|
||||||
// Product Symbology Block
|
// Product Symbology Block
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ public:
|
||||||
std::vector<uint8_t> dataMoments8_;
|
std::vector<uint8_t> dataMoments8_;
|
||||||
|
|
||||||
std::shared_ptr<wsr88d::rpg::RasterDataPacket> lastRasterData_ {};
|
std::shared_ptr<wsr88d::rpg::RasterDataPacket> lastRasterData_ {};
|
||||||
|
bool lastSmoothingEnabled_ {false};
|
||||||
|
|
||||||
float latitude_;
|
float latitude_;
|
||||||
float longitude_;
|
float longitude_;
|
||||||
|
|
@ -109,6 +110,7 @@ void Level3RasterView::ComputeSweep()
|
||||||
|
|
||||||
std::shared_ptr<manager::RadarProductManager> radarProductManager =
|
std::shared_ptr<manager::RadarProductManager> radarProductManager =
|
||||||
radar_product_manager();
|
radar_product_manager();
|
||||||
|
const bool smoothingEnabled = smoothing_enabled();
|
||||||
|
|
||||||
// Retrieve message from Radar Product Manager
|
// Retrieve message from Radar Product Manager
|
||||||
std::shared_ptr<wsr88d::rpg::Level3Message> message;
|
std::shared_ptr<wsr88d::rpg::Level3Message> message;
|
||||||
|
|
@ -139,7 +141,8 @@ void Level3RasterView::ComputeSweep()
|
||||||
Q_EMIT SweepNotComputed(types::NoUpdateReason::InvalidData);
|
Q_EMIT SweepNotComputed(types::NoUpdateReason::InvalidData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (gpm == graphic_product_message())
|
else if (gpm == graphic_product_message() &&
|
||||||
|
smoothingEnabled == p->lastSmoothingEnabled_)
|
||||||
{
|
{
|
||||||
// Skip if this is the message we previously processed
|
// Skip if this is the message we previously processed
|
||||||
Q_EMIT SweepNotComputed(types::NoUpdateReason::NoChange);
|
Q_EMIT SweepNotComputed(types::NoUpdateReason::NoChange);
|
||||||
|
|
@ -147,6 +150,8 @@ void Level3RasterView::ComputeSweep()
|
||||||
}
|
}
|
||||||
set_graphic_product_message(gpm);
|
set_graphic_product_message(gpm);
|
||||||
|
|
||||||
|
p->lastSmoothingEnabled_ = smoothingEnabled;
|
||||||
|
|
||||||
// A message with radial data should have a Product Description Block and
|
// A message with radial data should have a Product Description Block and
|
||||||
// Product Symbology Block
|
// Product Symbology Block
|
||||||
std::shared_ptr<wsr88d::rpg::ProductDescriptionBlock> descriptionBlock =
|
std::shared_ptr<wsr88d::rpg::ProductDescriptionBlock> descriptionBlock =
|
||||||
|
|
@ -231,16 +236,18 @@ void Level3RasterView::ComputeSweep()
|
||||||
const GeographicLib::Geodesic& geodesic =
|
const GeographicLib::Geodesic& geodesic =
|
||||||
util::GeographicLib::DefaultGeodesic();
|
util::GeographicLib::DefaultGeodesic();
|
||||||
|
|
||||||
const uint16_t xResolution = descriptionBlock->x_resolution_raw();
|
const std::uint16_t xResolution = descriptionBlock->x_resolution_raw();
|
||||||
const uint16_t yResolution = descriptionBlock->y_resolution_raw();
|
const std::uint16_t yResolution = descriptionBlock->y_resolution_raw();
|
||||||
double iCoordinate =
|
const double iCoordinate =
|
||||||
(-rasterData->i_coordinate_start() - 1.0 - p->range_) * 1000.0;
|
(-rasterData->i_coordinate_start() - 1.0 - p->range_) * 1000.0;
|
||||||
double jCoordinate =
|
const double jCoordinate =
|
||||||
(rasterData->j_coordinate_start() + 1.0 + p->range_) * 1000.0;
|
(rasterData->j_coordinate_start() + 1.0 + p->range_) * 1000.0;
|
||||||
|
const double xOffset = (smoothingEnabled) ? xResolution * 0.5 : 0.0;
|
||||||
|
const double yOffset = (smoothingEnabled) ? yResolution * 0.5 : 0.0;
|
||||||
|
|
||||||
size_t numCoordinates =
|
const std::size_t numCoordinates =
|
||||||
static_cast<size_t>(rows + 1) * static_cast<size_t>(maxColumns + 1);
|
static_cast<size_t>(rows + 1) * static_cast<size_t>(maxColumns + 1);
|
||||||
auto coordinateRange =
|
const auto coordinateRange =
|
||||||
boost::irange<uint32_t>(0, static_cast<uint32_t>(numCoordinates));
|
boost::irange<uint32_t>(0, static_cast<uint32_t>(numCoordinates));
|
||||||
|
|
||||||
std::vector<float> coordinates;
|
std::vector<float> coordinates;
|
||||||
|
|
@ -260,8 +267,8 @@ void Level3RasterView::ComputeSweep()
|
||||||
const uint32_t col = index % (rows + 1);
|
const uint32_t col = index % (rows + 1);
|
||||||
const uint32_t row = index / (rows + 1);
|
const uint32_t row = index / (rows + 1);
|
||||||
|
|
||||||
const double i = iCoordinate + xResolution * col;
|
const double i = iCoordinate + xResolution * col + xOffset;
|
||||||
const double j = jCoordinate - yResolution * row;
|
const double j = jCoordinate - yResolution * row - yOffset;
|
||||||
|
|
||||||
// Calculate polar coordinates based on i and j
|
// Calculate polar coordinates based on i and j
|
||||||
const double angle = std::atan2(i, j) * 180.0 / M_PI;
|
const double angle = std::atan2(i, j) * 180.0 / M_PI;
|
||||||
|
|
@ -299,25 +306,68 @@ void Level3RasterView::ComputeSweep()
|
||||||
// Compute threshold at which to display an individual bin
|
// Compute threshold at which to display an individual bin
|
||||||
const uint16_t snrThreshold = descriptionBlock->threshold();
|
const uint16_t snrThreshold = descriptionBlock->threshold();
|
||||||
|
|
||||||
for (size_t row = 0; row < rasterData->number_of_rows(); ++row)
|
const std::size_t rowCount = (smoothingEnabled) ?
|
||||||
|
rasterData->number_of_rows() - 1 :
|
||||||
|
rasterData->number_of_rows();
|
||||||
|
|
||||||
|
for (size_t row = 0; row < rowCount; ++row)
|
||||||
{
|
{
|
||||||
const auto dataMomentsArray8 =
|
const std::size_t nextRow =
|
||||||
|
(row == rasterData->number_of_rows() - 1) ? 0 : row + 1;
|
||||||
|
|
||||||
|
const auto& dataMomentsArray8 =
|
||||||
rasterData->level(static_cast<uint16_t>(row));
|
rasterData->level(static_cast<uint16_t>(row));
|
||||||
|
const auto& nextDataMomentsArray8 =
|
||||||
|
rasterData->level(static_cast<uint16_t>(nextRow));
|
||||||
|
|
||||||
for (size_t bin = 0; bin < dataMomentsArray8.size(); ++bin)
|
for (size_t bin = 0; bin < dataMomentsArray8.size(); ++bin)
|
||||||
{
|
{
|
||||||
constexpr size_t vertexCount = 6;
|
if (!smoothingEnabled)
|
||||||
|
|
||||||
// Store data moment value
|
|
||||||
uint8_t dataValue = dataMomentsArray8[bin];
|
|
||||||
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
|
||||||
{
|
{
|
||||||
continue;
|
constexpr size_t vertexCount = 6;
|
||||||
|
|
||||||
|
// Store data moment value
|
||||||
|
uint8_t dataValue = dataMomentsArray8[bin];
|
||||||
|
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t m = 0; m < vertexCount; m++)
|
||||||
|
{
|
||||||
|
dataMoments8[mIndex++] = dataValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
for (size_t m = 0; m < vertexCount; m++)
|
|
||||||
{
|
{
|
||||||
dataMoments8[mIndex++] = dataValue;
|
// Validate indices are all in range
|
||||||
|
if (bin + 1 >= dataMomentsArray8.size() ||
|
||||||
|
bin + 1 >= nextDataMomentsArray8.size())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::uint8_t& dm1 = dataMomentsArray8[bin];
|
||||||
|
const std::uint8_t& dm2 = dataMomentsArray8[bin + 1];
|
||||||
|
const std::uint8_t& dm3 = nextDataMomentsArray8[bin];
|
||||||
|
const std::uint8_t& dm4 = nextDataMomentsArray8[bin + 1];
|
||||||
|
|
||||||
|
if (dm1 < snrThreshold && dm1 != RANGE_FOLDED &&
|
||||||
|
dm2 < snrThreshold && dm2 != RANGE_FOLDED &&
|
||||||
|
dm3 < snrThreshold && dm3 != RANGE_FOLDED &&
|
||||||
|
dm4 < snrThreshold && dm4 != RANGE_FOLDED)
|
||||||
|
{
|
||||||
|
// Skip only if all data moments are hidden
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The order must match the store vertices section below
|
||||||
|
dataMoments8[mIndex++] = dm1;
|
||||||
|
dataMoments8[mIndex++] = dm2;
|
||||||
|
dataMoments8[mIndex++] = dm4;
|
||||||
|
dataMoments8[mIndex++] = dm1;
|
||||||
|
dataMoments8[mIndex++] = dm3;
|
||||||
|
dataMoments8[mIndex++] = dm4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store vertices
|
// Store vertices
|
||||||
|
|
@ -332,17 +382,17 @@ void Level3RasterView::ComputeSweep()
|
||||||
vertices[vIndex++] = coordinates[offset2];
|
vertices[vIndex++] = coordinates[offset2];
|
||||||
vertices[vIndex++] = coordinates[offset2 + 1];
|
vertices[vIndex++] = coordinates[offset2 + 1];
|
||||||
|
|
||||||
vertices[vIndex++] = coordinates[offset3];
|
vertices[vIndex++] = coordinates[offset4];
|
||||||
vertices[vIndex++] = coordinates[offset3 + 1];
|
vertices[vIndex++] = coordinates[offset4 + 1];
|
||||||
|
|
||||||
|
vertices[vIndex++] = coordinates[offset1];
|
||||||
|
vertices[vIndex++] = coordinates[offset1 + 1];
|
||||||
|
|
||||||
vertices[vIndex++] = coordinates[offset3];
|
vertices[vIndex++] = coordinates[offset3];
|
||||||
vertices[vIndex++] = coordinates[offset3 + 1];
|
vertices[vIndex++] = coordinates[offset3 + 1];
|
||||||
|
|
||||||
vertices[vIndex++] = coordinates[offset4];
|
vertices[vIndex++] = coordinates[offset4];
|
||||||
vertices[vIndex++] = coordinates[offset4 + 1];
|
vertices[vIndex++] = coordinates[offset4 + 1];
|
||||||
|
|
||||||
vertices[vIndex++] = coordinates[offset2];
|
|
||||||
vertices[vIndex++] = coordinates[offset2 + 1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vertices.resize(vIndex);
|
vertices.resize(vIndex);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue