raster/raster_stats.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Minimum, maximum and mean of a raster's valid cells. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/raster/raster.h" | ||
| 6 | |||
| 7 | #include <cmath> | ||
| 8 | #include <cstddef> | ||
| 9 | #include <limits> | ||
| 10 | |||
| 11 | namespace terraingen { | ||
| 12 | |||
| 13 | /// Summary statistics of a raster's valid cells. | ||
| 14 | struct RasterStats { | ||
| 15 | double min = std::numeric_limits<double>::quiet_NaN(); ///< NaN if no cell is valid. | ||
| 16 | double max = std::numeric_limits<double>::quiet_NaN(); ///< NaN if no cell is valid. | ||
| 17 | double mean = std::numeric_limits<double>::quiet_NaN(); ///< NaN if no cell is valid. | ||
| 18 | std::size_t validCount = 0; ///< Cells that are finite and not the nodata value. | ||
| 19 | }; | ||
| 20 | |||
| 21 | /// Statistics over the cells that are finite and not the raster's no-data value; NaN with a | ||
| 22 | /// count of 0 when no cell is valid. | ||
| 23 | /// @tparam T Cell type, convertible to `double`. | ||
| 24 | 8 | template <typename T> RasterStats ComputeStats(const Raster<T>& raster) { | |
| 25 | 8 | RasterStats stats; | |
| 26 | 8 | double sum = 0.0; | |
| 27 | 27 | for (const T value : raster.Values()) { | |
| 28 | 19 | const auto v = static_cast<double>(value); | |
| 29 | 19 | if (!std::isfinite(v) || (raster.NoData() && value == *raster.NoData())) { | |
| 30 | 8 | continue; | |
| 31 | } | ||
| 32 | 11 | if (stats.validCount == 0) { | |
| 33 | 5 | stats.min = v; | |
| 34 | 5 | stats.max = v; | |
| 35 | } else { | ||
| 36 | 6 | stats.min = std::fmin(stats.min, v); | |
| 37 | 6 | stats.max = std::fmax(stats.max, v); | |
| 38 | } | ||
| 39 | 11 | sum += v; | |
| 40 | 11 | ++stats.validCount; | |
| 41 | } | ||
| 42 | 8 | if (stats.validCount > 0) { | |
| 43 | 5 | stats.mean = sum / static_cast<double>(stats.validCount); | |
| 44 | } | ||
| 45 | 8 | return stats; | |
| 46 | } | ||
| 47 | |||
| 48 | } // namespace terraingen | ||
| 49 |