File test_vegetation.cpp
File List > lib > vegetation > tests > test_vegetation.cpp
Go to the documentation of this file
#include <gtest/gtest.h>
#include <cmath>
#include "grid/grid.hpp"
#include "utilities/progress_tracker.hpp"
#include "vegetation/vegetation.hpp"
// =============================================================================
// low_pass filter tests (GeoGrid<float> overload)
// =============================================================================
TEST(Vegetation, LowPassUniformGrid) {
// A uniform grid should stay the same after low-pass filtering
std::vector<std::vector<float>> data(20, std::vector<float>(20, 5.0f));
GeoGrid<float> grid(data);
GeoGrid<float> result = low_pass(grid, 3, ProgressTracker());
// Center values should remain ~5.0
float center_val = result[{10, 10}];
EXPECT_NEAR(center_val, 5.0f, 0.01f);
}
TEST(Vegetation, LowPassSmoothing) {
// A grid with a high center value should be smoothed by low-pass
constexpr size_t N = 20;
std::vector<std::vector<float>> data(N, std::vector<float>(N, 0.0f));
data[10][10] = 100.0f; // single spike
GeoGrid<float> grid(data);
GeoGrid<float> result = low_pass(grid, 3, ProgressTracker());
// The spike should be reduced
float spike_val = result[{10, 10}];
EXPECT_LT(spike_val, 100.0f);
EXPECT_GT(spike_val, 0.0f);
// Neighbors should be elevated
float neighbor_val = result[{11, 10}];
EXPECT_GT(neighbor_val, 0.0f);
}
TEST(Vegetation, LowPassSmallDelta) {
// With delta=2, neighbors within radius 2 are weighted
constexpr size_t N = 5;
std::vector<std::vector<float>> data(N, std::vector<float>(N, 0.0f));
data[2][2] = 10.0f;
GeoGrid<float> grid(data);
GeoGrid<float> result = low_pass(grid, 2, ProgressTracker());
// Center should still be the largest but reduced (neighbors dilute it)
float center = result[{2, 2}];
EXPECT_LT(center, 10.0f);
EXPECT_GT(center, 0.0f);
// Corner values far from center should remain near 0
float corner = result[{0, 0}];
EXPECT_NEAR(corner, 0.0f, 0.01f);
}
// =============================================================================
// low_pass filter tests (GeoGrid<std::optional<float>> overload)
// =============================================================================
TEST(Vegetation, LowPassOptionalUniform) {
constexpr size_t N = 20;
std::vector<std::vector<std::optional<float>>> data(N,
std::vector<std::optional<float>>(N, 5.0f));
GeoGrid<std::optional<float>> grid(data);
GeoGrid<float> result = low_pass(grid, 3, ProgressTracker());
float center_val = result[{10, 10}];
EXPECT_NEAR(center_val, 5.0f, 0.01f);
}
TEST(Vegetation, LowPassOptionalWithNulls) {
// Grid with some null values - they should be skipped
constexpr size_t N = 10;
std::vector<std::vector<std::optional<float>>> data(N,
std::vector<std::optional<float>>(N, 5.0f));
// Set some values to null
data[5][5] = std::nullopt;
data[5][6] = std::nullopt;
data[6][5] = std::nullopt;
GeoGrid<std::optional<float>> grid(data);
GeoGrid<float> result = low_pass(grid, 3, ProgressTracker());
// Center should still be close to 5.0 since nulls are skipped
float val = result[{3, 3}];
EXPECT_NEAR(val, 5.0f, 0.1f);
}
TEST(Vegetation, LowPassOptionalAllNull) {
// All nulls should produce 0 values
constexpr size_t N = 5;
std::vector<std::vector<std::optional<float>>> data(
N, std::vector<std::optional<float>>(N, std::nullopt));
GeoGrid<std::optional<float>> grid(data);
GeoGrid<float> result = low_pass(grid, 2, ProgressTracker());
for (size_t i = 0; i < N; i++) {
for (size_t j = 0; j < N; j++) {
float val = result[{j, i}];
EXPECT_FLOAT_EQ(val, 0.0f);
}
}
}
TEST(Vegetation, LowPassPreservesGridDimensions) {
std::vector<std::vector<float>> data = {
{1.0f, 2.0f, 3.0f},
{4.0f, 5.0f, 6.0f},
{7.0f, 8.0f, 9.0f},
};
GeoGrid<float> grid(data);
GeoGrid<float> result = low_pass(grid, 2, ProgressTracker());
EXPECT_EQ(result.width(), 3u);
EXPECT_EQ(result.height(), 3u);
}