mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:40:04 +00:00
Load level 2 radar data for rendering
This commit is contained in:
parent
3a3843c280
commit
421c600ed0
5 changed files with 239 additions and 44 deletions
|
|
@ -63,60 +63,158 @@ void RadarView::Initialize()
|
|||
|
||||
boost::timer::cpu_timer timer;
|
||||
|
||||
// TODO: Pick this based on radar data
|
||||
const std::vector<float>& coordinates =
|
||||
p->radarManager_->coordinates(common::RadialSize::_0_5Degree);
|
||||
|
||||
std::shared_ptr<const wsr88d::Ar2vFile> level2Data =
|
||||
p->radarManager_->level2_data();
|
||||
if (level2Data == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Pick these based on view settings
|
||||
auto radarData = level2Data->radar_data()[0];
|
||||
wsr88d::rda::DataBlockType blockType = wsr88d::rda::DataBlockType::MomentRef;
|
||||
|
||||
// Calculate vertices
|
||||
timer.start();
|
||||
|
||||
auto momentData0 = radarData[0]->moment_data_block(blockType);
|
||||
|
||||
std::vector<float>& vertices = p->vertices_;
|
||||
const uint32_t radials = common::MAX_RADIALS;
|
||||
const uint32_t gates = common::MAX_DATA_MOMENT_GATES;
|
||||
const size_t radials = radarData.size();
|
||||
const uint32_t gates = momentData0->number_of_data_moment_gates();
|
||||
vertices.clear();
|
||||
vertices.resize(radials * gates * VERTICES_PER_BIN * VALUES_PER_VERTEX);
|
||||
size_t index = 0;
|
||||
|
||||
for (uint16_t radial = 0; radial < 720; ++radial)
|
||||
// Compute threshold at which to display an individual bin
|
||||
const float scale = momentData0->scale();
|
||||
const float offset = momentData0->offset();
|
||||
const uint16_t snrThreshold =
|
||||
std::lroundf(momentData0->snr_threshold_raw() * scale / 10 + offset);
|
||||
|
||||
// Azimuth resolution spacing:
|
||||
// 1 = 0.5 degrees
|
||||
// 2 = 1.0 degrees
|
||||
const float radialMultiplier =
|
||||
2.0f /
|
||||
std::clamp<int8_t>(radarData[0]->azimuth_resolution_spacing(), 1, 2);
|
||||
|
||||
const float startAngle = radarData[0]->azimuth_angle();
|
||||
const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier);
|
||||
|
||||
for (uint16_t radial = 0; radial < radials; ++radial)
|
||||
{
|
||||
const float dataMomentRange = 2.125f * 1000.0f;
|
||||
const float dataMomentInterval = 0.25f * 1000.0f;
|
||||
const float dataMomentIntervalH = dataMomentInterval * 0.5f;
|
||||
const float snrThreshold = 2.0f;
|
||||
auto radialData = radarData[radial];
|
||||
auto momentData = radarData[radial]->moment_data_block(blockType);
|
||||
|
||||
const uint16_t startGate = 7;
|
||||
const uint16_t numberOfDataMomentGates = 1832;
|
||||
// Compute gate interval
|
||||
const uint16_t dataMomentRange = momentData->data_moment_range_raw();
|
||||
const uint16_t dataMomentInterval =
|
||||
momentData->data_moment_range_sample_interval_raw();
|
||||
const uint16_t dataMomentIntervalH = dataMomentInterval / 2;
|
||||
|
||||
// Compute gate size (number of base 250m gates per bin)
|
||||
const uint16_t gateSize = std::max<uint16_t>(1, dataMomentInterval / 250);
|
||||
|
||||
// Compute gate range [startGate, endGate)
|
||||
const uint16_t startGate = (dataMomentRange - dataMomentIntervalH) / 250;
|
||||
const uint16_t numberOfDataMomentGates =
|
||||
std::min<uint16_t>(momentData->number_of_data_moment_gates(),
|
||||
static_cast<uint16_t>(gates));
|
||||
const uint16_t endGate =
|
||||
std::min<uint16_t>(numberOfDataMomentGates + startGate,
|
||||
common::MAX_DATA_MOMENT_GATES - 1);
|
||||
std::min<uint16_t>(startGate + numberOfDataMomentGates * gateSize,
|
||||
common::MAX_DATA_MOMENT_GATES);
|
||||
|
||||
for (uint16_t gate = startGate; gate < endGate; ++gate)
|
||||
const uint8_t* dataMoments8 = nullptr;
|
||||
const uint16_t* dataMoments16 = nullptr;
|
||||
|
||||
if (momentData->data_word_size() == 8)
|
||||
{
|
||||
size_t offset1 = (radial * common::MAX_DATA_MOMENT_GATES + gate) * 2;
|
||||
size_t offset2 = offset1 + 2;
|
||||
size_t offset3 = (((radial + 1) % common::MAX_RADIALS) *
|
||||
common::MAX_DATA_MOMENT_GATES +
|
||||
gate) *
|
||||
2;
|
||||
size_t offset4 = offset3 + 2;
|
||||
dataMoments8 =
|
||||
reinterpret_cast<const uint8_t*>(momentData->data_moments());
|
||||
}
|
||||
else
|
||||
{
|
||||
dataMoments16 =
|
||||
reinterpret_cast<const uint16_t*>(momentData->data_moments());
|
||||
}
|
||||
|
||||
vertices[index++] = coordinates[offset1];
|
||||
vertices[index++] = coordinates[offset1 + 1];
|
||||
for (uint16_t gate = startGate, i = 0; gate + gateSize <= endGate;
|
||||
gate += gateSize, ++i)
|
||||
{
|
||||
uint16_t dataValue =
|
||||
(dataMoments8 != nullptr) ? dataMoments8[i] : dataMoments16[i];
|
||||
|
||||
vertices[index++] = coordinates[offset2];
|
||||
vertices[index++] = coordinates[offset2 + 1];
|
||||
if (dataValue < snrThreshold)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vertices[index++] = coordinates[offset3];
|
||||
vertices[index++] = coordinates[offset3 + 1];
|
||||
if (gate > 0)
|
||||
{
|
||||
const uint16_t baseCoord = gate - 1;
|
||||
|
||||
vertices[index++] = coordinates[offset3];
|
||||
vertices[index++] = coordinates[offset3 + 1];
|
||||
size_t offset1 = ((startRadial + radial) % common::MAX_RADIALS *
|
||||
common::MAX_DATA_MOMENT_GATES +
|
||||
baseCoord) *
|
||||
2;
|
||||
size_t offset2 = offset1 + gateSize * 2;
|
||||
size_t offset3 =
|
||||
(((startRadial + radial + 1) % common::MAX_RADIALS) *
|
||||
common::MAX_DATA_MOMENT_GATES +
|
||||
baseCoord) *
|
||||
2;
|
||||
size_t offset4 = offset3 + gateSize * 2;
|
||||
|
||||
vertices[index++] = coordinates[offset4];
|
||||
vertices[index++] = coordinates[offset4 + 1];
|
||||
vertices[index++] = coordinates[offset1];
|
||||
vertices[index++] = coordinates[offset1 + 1];
|
||||
|
||||
vertices[index++] = coordinates[offset2];
|
||||
vertices[index++] = coordinates[offset2 + 1];
|
||||
vertices[index++] = coordinates[offset2];
|
||||
vertices[index++] = coordinates[offset2 + 1];
|
||||
|
||||
vertices[index++] = coordinates[offset3];
|
||||
vertices[index++] = coordinates[offset3 + 1];
|
||||
|
||||
vertices[index++] = coordinates[offset3];
|
||||
vertices[index++] = coordinates[offset3 + 1];
|
||||
|
||||
vertices[index++] = coordinates[offset4];
|
||||
vertices[index++] = coordinates[offset4 + 1];
|
||||
|
||||
vertices[index++] = coordinates[offset2];
|
||||
vertices[index++] = coordinates[offset2 + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint16_t baseCoord = gate;
|
||||
|
||||
size_t offset1 = ((startRadial + radial) % common::MAX_RADIALS *
|
||||
common::MAX_DATA_MOMENT_GATES +
|
||||
baseCoord) *
|
||||
2;
|
||||
size_t offset2 =
|
||||
(((startRadial + radial + 1) % common::MAX_RADIALS) *
|
||||
common::MAX_DATA_MOMENT_GATES +
|
||||
baseCoord) *
|
||||
2;
|
||||
|
||||
// TODO: Radar location
|
||||
vertices[index++] = 38.6986f;
|
||||
vertices[index++] = -90.6828f;
|
||||
|
||||
vertices[index++] = coordinates[offset1];
|
||||
vertices[index++] = coordinates[offset1 + 1];
|
||||
|
||||
vertices[index++] = coordinates[offset2];
|
||||
vertices[index++] = coordinates[offset2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
vertices.resize(index);
|
||||
timer.stop();
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< logPrefix_ << "Vertices calculated in " << timer.format(6, "%ws");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue