From 9225103a92e454bad05834671a4441bd981740ff Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 6 Jan 2024 01:22:16 -0600 Subject: [PATCH] Get bin values at coordinates from level 3 raster data --- .../scwx/qt/view/level3_raster_view.cpp | 84 ++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp b/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp index d098cd3d..fefeb587 100644 --- a/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_raster_view.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace scwx { @@ -37,6 +38,8 @@ public: std::vector vertices_; std::vector dataMoments8_; + std::shared_ptr lastRasterData_ {}; + float latitude_; float longitude_; float range_; @@ -198,6 +201,8 @@ void Level3RasterView::ComputeSweep() return; } + p->lastRasterData_ = rasterData; + // Calculate raster grid size const uint16_t rows = rasterData->number_of_rows(); size_t maxColumns = 0; @@ -355,9 +360,82 @@ void Level3RasterView::ComputeSweep() std::optional Level3RasterView::GetBinLevel(const common::Coordinate& coordinate) const { - // TODO - Q_UNUSED(coordinate); - return std::nullopt; + auto gpm = graphic_product_message(); + if (gpm == nullptr) + { + return std::nullopt; + } + + std::shared_ptr descriptionBlock = + gpm->description_block(); + if (descriptionBlock == nullptr) + { + return std::nullopt; + } + + std::shared_ptr rasterData = + p->lastRasterData_; + if (rasterData == nullptr) + { + return std::nullopt; + } + + auto radarProductManager = radar_product_manager(); + auto radarSite = radarProductManager->radar_site(); + const double radarLatitude = radarSite->latitude(); + const double radarLongitude = radarSite->longitude(); + + // 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(radarLatitude, + radarLongitude, + coordinate.latitude_, + coordinate.longitude_, + s12, + azi1, + azi2); + + if (std::isnan(azi1)) + { + // If a problem occurred with the geodesic inverse calculation + return std::nullopt; + } + + units::angle::radians azi1Rads = units::angle::degrees(azi1); + + double j = -std::cos(azi1Rads.value()) * s12; + double i = std::sin(azi1Rads.value()) * s12; + + const uint32_t xResolution = descriptionBlock->x_resolution_raw(); + const uint32_t yResolution = descriptionBlock->y_resolution_raw(); + double iStart = + (-rasterData->i_coordinate_start() - 1.0 - p->range_) * 1000.0; + double jStart = + (rasterData->j_coordinate_start() + 1.0 + p->range_) * 1000.0; + + i -= iStart; + j += jStart; + + std::uint32_t col = static_cast(i / xResolution); + std::uint32_t row = static_cast(j / yResolution); + + if (row > rasterData->number_of_rows()) + { + // Coordinate is beyond radar range (latitude) + return std::nullopt; + } + + auto& momentData = rasterData->level(static_cast(row)); + + if (col > momentData.size()) + { + // Coordinate is beyond radar range (longitude) + return std::nullopt; + } + + return momentData[col]; } std::shared_ptr Level3RasterView::Create(