Add partial handling for missing level 2 radials

- Need to handle additional cases (1999-05-03 @ KTLX is a good sample)
- Still crashes on getting bin level for hover text
This commit is contained in:
Dan Paulat 2024-10-01 06:31:02 -05:00
parent 50cf49568d
commit a548497767

View file

@ -536,7 +536,7 @@ void Level2ProductView::ComputeSweep()
return; return;
} }
const size_t radials = radarData->size(); const std::size_t radials = radarData->crbegin()->first;
p->ComputeCoordinates(radarData); p->ComputeCoordinates(radarData);
@ -829,7 +829,7 @@ void Level2ProductViewImpl::ComputeCoordinates(
auto momentData0 = radarData0->moment_data_block(dataBlockType_); auto momentData0 = radarData0->moment_data_block(dataBlockType_);
const std::uint16_t numRadials = const std::uint16_t numRadials =
static_cast<std::uint16_t>(radarData->size()); static_cast<std::uint16_t>(radarData->crbegin()->first + 1);
const std::uint16_t numRangeBins = const std::uint16_t numRangeBins =
std::max(momentData0->number_of_data_moment_gates() + 1u, std::max(momentData0->number_of_data_moment_gates() + 1u,
common::MAX_DATA_MOMENT_GATES); common::MAX_DATA_MOMENT_GATES);
@ -837,39 +837,83 @@ void Level2ProductViewImpl::ComputeCoordinates(
auto radials = boost::irange<std::uint32_t>(0u, numRadials); auto radials = boost::irange<std::uint32_t>(0u, numRadials);
auto gates = boost::irange<std::uint32_t>(0u, numRangeBins); auto gates = boost::irange<std::uint32_t>(0u, numRangeBins);
std::for_each(std::execution::par_unseq, std::for_each(
radials.begin(), std::execution::par_unseq,
radials.end(), radials.begin(),
[&](std::uint32_t radial) radials.end(),
{ [&](std::uint32_t radial)
const units::degrees<float> angle = {
(*radarData)[radial]->azimuth_angle(); units::degrees<float> angle {};
std::for_each(std::execution::par_unseq, auto radialData = radarData->find(radial);
gates.begin(), if (radialData != radarData->cend())
gates.end(), {
[&](std::uint32_t gate) angle = radialData->second->azimuth_angle();
{ }
const std::uint32_t radialGate = else
radial * common::MAX_DATA_MOMENT_GATES + {
gate; auto prevRadial1 = radarData->find(
const float range = (gate + 1) * gateSize; (radial >= 1) ? radial - 1 : numRadials - (1 - radial));
const std::size_t offset = radialGate * 2; auto prevRadial2 = radarData->find(
(radial >= 2) ? radial - 2 : numRadials - (2 - radial));
double latitude; if (prevRadial1 != radarData->cend() &&
double longitude; prevRadial2 != radarData->cend())
{
const units::degrees<float> prevAngle1 =
prevRadial1->second->azimuth_angle();
const units::degrees<float> prevAngle2 =
prevRadial2->second->azimuth_angle();
geodesic.Direct(radarLatitude, // No wrapping required since angle is only used for geodesic
radarLongitude, // calculation
angle.value(), const units::degrees<float> deltaAngle = prevAngle1 - prevAngle2;
range,
latitude,
longitude);
coordinates_[offset] = latitude; angle = prevAngle1 + deltaAngle;
coordinates_[offset + 1] = longitude; }
}); else if (prevRadial1 != radarData->cend())
}); {
const units::degrees<float> prevAngle1 =
prevRadial1->second->azimuth_angle();
// Assume a half degree delta if there aren't enough angles
// to determine a delta angle
constexpr units::degrees<float> deltaAngle =
units::degrees<float> {0.5};
angle = prevAngle1 + deltaAngle;
}
else
{
// Not enough angles present to determine an angle
return;
}
}
std::for_each(std::execution::par_unseq,
gates.begin(),
gates.end(),
[&](std::uint32_t gate)
{
const std::uint32_t radialGate =
radial * common::MAX_DATA_MOMENT_GATES + gate;
const float range = (gate + 1) * gateSize;
const std::size_t offset = radialGate * 2;
double latitude;
double longitude;
geodesic.Direct(radarLatitude,
radarLongitude,
angle.value(),
range,
latitude,
longitude);
coordinates_[offset] = latitude;
coordinates_[offset + 1] = longitude;
});
});
timer.stop(); timer.stop();
logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws")); logger_->debug("Coordinates calculated in {}", timer.format(6, "%ws"));
} }