File test_config_lookup.cpp
File List > config_input > tests > test_config_lookup.cpp
Go to the documentation of this file
#include <gtest/gtest.h>
#include "config_input/config_input.hpp"
#include "testing/output_dir.hpp"
// =============================================================================
// ContourConfigs tests
// =============================================================================
TEST(ContourConfigs, MinInterval) {
ContourConfigs configs({{"normal", ContourConfig{2.5, 3, RGBColor(0, 0, 0), 0.14}},
{"index", ContourConfig{10.0, 5, RGBColor(0, 0, 0), 0.25}}});
EXPECT_DOUBLE_EQ(configs.min_interval, 2.5);
}
TEST(ContourConfigs, PickFromHeight) {
ContourConfigs configs({{"normal", ContourConfig{2.5, 3, RGBColor(100, 0, 0), 0.14}},
{"index", ContourConfig{10.0, 5, RGBColor(0, 100, 0), 0.25}}});
// Height 5.0 is multiple of 2.5 but not 10.0 -> should pick "normal"
const ContourConfig& c1 = configs.pick_from_height(5.0);
EXPECT_DOUBLE_EQ(c1.interval, 2.5);
// Height 10.0 is multiple of both 2.5 and 10.0 -> should pick "index" (larger interval)
const ContourConfig& c2 = configs.pick_from_height(10.0);
EXPECT_DOUBLE_EQ(c2.interval, 10.0);
// Height 20.0 is multiple of both -> should pick "index"
const ContourConfig& c3 = configs.pick_from_height(20.0);
EXPECT_DOUBLE_EQ(c3.interval, 10.0);
// Height 2.5 is multiple of 2.5 only -> should pick "normal"
const ContourConfig& c4 = configs.pick_from_height(2.5);
EXPECT_DOUBLE_EQ(c4.interval, 2.5);
}
TEST(ContourConfigs, LayerNameFromHeight) {
ContourConfigs configs({{"normal", ContourConfig{2.5, 3, RGBColor(0, 0, 0), 0.14}},
{"index", ContourConfig{10.0, 5, RGBColor(0, 0, 0), 0.25}},
{"form_line", ContourConfig{1.25, 2, RGBColor(0, 0, 0), 0.1}}});
// Height 10.0 matches index (largest interval)
EXPECT_EQ(configs.layer_name_from_height(10.0), "102_Index_Contour");
// Height 5.0 matches normal but not index
EXPECT_EQ(configs.layer_name_from_height(5.0), "101_Contour");
// Height 2.5 matches normal (interval 2.5) which is bigger than form_line (1.25)
EXPECT_EQ(configs.layer_name_from_height(2.5), "101_Contour");
// Height 1.25 matches form_line only
EXPECT_EQ(configs.layer_name_from_height(1.25), "103_Form_Line");
}
TEST(ContourConfigs, LayerNameFromHeightFormlineAlias) {
// Config JSON uses "formline" (no underscore), matching default_config.json.
ContourConfigs configs({{"normal", ContourConfig{5.0, 3, RGBColor(0, 0, 0), 0.14}},
{"formline", ContourConfig{2.5, 2, RGBColor(0, 0, 0), 0.1}}});
EXPECT_EQ(configs.layer_name_from_height(2.5), "103_Form_Line");
EXPECT_EQ(configs.layer_name_from_height(5.0), "101_Contour");
}
TEST(ContourConfigs, IndexOperator) {
ContourConfigs configs({{"normal", ContourConfig{2.5, 3, RGBColor(0, 0, 0), 0.14}}});
const ContourConfig& c = configs["normal"];
EXPECT_DOUBLE_EQ(c.interval, 2.5);
EXPECT_EQ(c.min_points, 3u);
}
TEST(ContourConfigs, DefaultConstruction) {
ContourConfigs configs;
EXPECT_DOUBLE_EQ(configs.min_interval, std::numeric_limits<double>::max());
}
// =============================================================================
// WaterConfigs tests
// =============================================================================
TEST(WaterConfigs, ConfigFromCatchment) {
WaterConfigs configs;
configs.configs["minor"] = WaterConfig{0.01, RGBColor(0, 0, 255), 0.1};
configs.configs["medium"] = WaterConfig{0.1, RGBColor(0, 0, 255), 0.2};
configs.configs["major"] = WaterConfig{1.0, RGBColor(0, 0, 255), 0.3};
// Catchment of 0.5 -> should pick "medium" (0.1 <= 0.5 but 1.0 > 0.5)
const WaterConfig& c1 = configs.config_from_catchment(0.5);
EXPECT_DOUBLE_EQ(c1.catchment, 0.1);
// Catchment of 2.0 -> should pick "major" (all qualify, "major" has largest catchment)
const WaterConfig& c2 = configs.config_from_catchment(2.0);
EXPECT_DOUBLE_EQ(c2.catchment, 1.0);
// Catchment of 0.05 -> should pick "minor" (only one qualifies)
const WaterConfig& c3 = configs.config_from_catchment(0.05);
EXPECT_DOUBLE_EQ(c3.catchment, 0.01);
}
TEST(WaterConfigs, MinimumCatchment) {
WaterConfigs configs;
configs.configs["minor"] = WaterConfig{0.01, RGBColor(0, 0, 255), 0.1};
configs.configs["medium"] = WaterConfig{0.1, RGBColor(0, 0, 255), 0.2};
configs.configs["major"] = WaterConfig{1.0, RGBColor(0, 0, 255), 0.3};
EXPECT_DOUBLE_EQ(configs.minimum_catchment(), 0.01);
}
// =============================================================================
// VegeHeightConfig tests
// =============================================================================
TEST(VegeHeightConfig, PickFromBlockedProportion) {
VegeHeightConfig vhc;
vhc.name = "test";
vhc.min_height = 2.0;
vhc.max_height = 100.0;
BlockingThresholdColorPair green;
green.blocking_threshold = 0.01;
green.color = RGBColor(0, 255, 0);
BlockingThresholdColorPair dark_green;
dark_green.blocking_threshold = 0.5;
dark_green.color = RGBColor(0, 128, 0);
vhc.colors.push_back(green);
vhc.colors.push_back(dark_green);
// Below all thresholds -> no color
auto c1 = vhc.pick_from_blocked_proportion(0.005);
EXPECT_FALSE(c1.has_value());
// Above first threshold but below second
auto c2 = vhc.pick_from_blocked_proportion(0.2);
ASSERT_TRUE(c2.has_value());
RGBColor rgb2 = to_rgb(*c2);
EXPECT_EQ(rgb2.getRed(), 0);
EXPECT_EQ(rgb2.getGreen(), 255);
EXPECT_EQ(rgb2.getBlue(), 0);
// Above both thresholds -> should pick last qualifying (dark_green)
auto c3 = vhc.pick_from_blocked_proportion(0.8);
ASSERT_TRUE(c3.has_value());
RGBColor rgb3 = to_rgb(*c3);
EXPECT_EQ(rgb3.getRed(), 0);
EXPECT_EQ(rgb3.getGreen(), 128);
EXPECT_EQ(rgb3.getBlue(), 0);
}
TEST(VegeHeightConfig, PickFromBlockedProportionEmpty) {
VegeHeightConfig vhc;
vhc.name = "empty";
vhc.min_height = 0.0;
vhc.max_height = 10.0;
// No colors configured
auto c = vhc.pick_from_blocked_proportion(0.5);
EXPECT_FALSE(c.has_value());
}
TEST(ConfigJson, VegeMinHoleAreaRoundTrip) {
Config config;
VegeHeightConfig canopy;
canopy.name = "canopy";
BlockingThresholdColorPair btc;
btc.blocking_threshold = 0.1;
btc.layer = "405_Forest";
btc.color = CMYKColor(0, 0, 0, 0);
btc.min_area_m2 = 30;
btc.min_hole_area_m2 = 100;
canopy.colors.push_back(btc);
config.vege.height_configs.push_back(std::move(canopy));
const fs::path path = blaze::test::unique_test_output_path("vege_min_hole", ".json");
config.write_to_file(path);
Config loaded = Config::FromFile(path);
ASSERT_EQ(loaded.vege.height_configs.size(), 1u);
ASSERT_EQ(loaded.vege.height_configs[0].colors.size(), 1u);
const BlockingThresholdColorPair& out = loaded.vege.height_configs[0].colors[0];
EXPECT_DOUBLE_EQ(out.min_area_m2, 30);
EXPECT_DOUBLE_EQ(out.min_hole_area_m2, 100);
}
TEST(ConfigJson, VegeSmoothRadiusRoundTrip) {
Config config;
VegeHeightConfig canopy;
canopy.name = "canopy";
canopy.smooth_radius = 8;
config.vege.height_configs.push_back(canopy);
VegeHeightConfig green;
green.name = "green";
green.smooth_radius = 3;
config.vege.height_configs.push_back(std::move(green));
const fs::path path = blaze::test::unique_test_output_path("vege_smooth_radius", ".json");
config.write_to_file(path);
Config loaded = Config::FromFile(path);
ASSERT_EQ(loaded.vege.height_configs.size(), 2u);
EXPECT_EQ(loaded.vege.height_configs[0].smooth_radius, 8);
EXPECT_EQ(loaded.vege.height_configs[1].smooth_radius, 3);
}
TEST(ConfigJson, GroundAndWaterOverlayRoundTrip) {
Config config;
config.ground.use_only_ground_class = false;
config.ground.outlier_threshold_m = 1.25;
config.water.classified_overlay_color = ColorVariant(RGBColor(0, 0, 255, 255));
const fs::path path = blaze::test::unique_test_output_path("ground_water_overlay", ".json");
config.write_to_file(path);
Config loaded = Config::FromFile(path);
EXPECT_FALSE(loaded.ground.use_only_ground_class);
EXPECT_DOUBLE_EQ(loaded.ground.outlier_threshold_m, 1.25);
EXPECT_EQ(to_rgb(loaded.water.classified_overlay_color).getBlue(), 255);
}