File vegetation.hpp
File List > lib > vegetation > vegetation.hpp
Go to the documentation of this file
#pragma once
#include <cstddef>
#include "config_input/config_input.hpp"
#include "grid/grid.hpp"
#include "las/las_point.hpp"
#include "utilities/coordinate.hpp"
#include "utilities/timer.hpp"
inline GeoGrid<std::optional<float>> get_blocked_proportion(
const GeoGrid<std::vector<LASPoint>>& grid, const GeoGrid<double>& ground,
const VegeHeightConfig& vege_config) {
TimeFunction timer("counting " + vege_config.name + " blocked proportion");
GeoGrid<std::optional<float>> blocked_proportion(grid.width(), grid.height(),
GeoTransform(grid.transform()),
GeoProjection(grid.projection()));
#pragma omp parallel for
for (size_t i = 0; i < grid.height(); i++) {
for (size_t j = 0; j < grid.width(); j++) {
size_t below_count = 0;
size_t in_count = 0;
for (const LASPoint& las_point : grid[{j, i}]) {
double ground_height = interpolate_value(ground, las_point);
double height = las_point.z() - ground_height;
if (height > -1 && height < vege_config.max_height) {
if (height < vege_config.min_height) {
below_count++;
} else {
in_count++;
}
}
}
blocked_proportion[{j, i}] =
(in_count + below_count) > 0
? std::make_optional<float>((double)in_count / (in_count + below_count))
: std::nullopt;
}
}
return blocked_proportion;
}
inline GeoGrid<float> low_pass(const GeoGrid<float>& grid, int delta = 8) {
TimeFunction timer("Low pass filter");
GeoGrid<float> low_pass(grid.width(), grid.height(), GeoTransform(grid.transform()),
GeoProjection(grid.projection()));
#pragma omp parallel for
for (size_t i = 0; i < grid.height(); i++) {
for (size_t j = 0; j < grid.width(); j++) {
float sum = 0;
float weight_sum = 0;
for (int x = -delta; x <= delta; x++) {
for (int y = -delta; y <= delta; y++) {
if (y + (int)i >= 0 && i + y < grid.height() && x + (int)j >= 0 &&
(unsigned int)j + x < grid.width()) {
if (sqrt(x * x + y * y) <= delta) {
float weight = 1 - (sqrt(x * x + y * y) / delta);
sum += grid[{j + x, i + y}] * weight;
weight_sum += weight;
}
}
}
}
low_pass[{j, i}] = sum / weight_sum;
}
}
return low_pass;
}
inline GeoGrid<float> low_pass(const GeoGrid<std::optional<float>>& grid, int delta = 8) {
TimeFunction timer("Low pass filter");
GeoGrid<float> low_pass(grid.width(), grid.height(), GeoTransform(grid.transform()),
GeoProjection(grid.projection()));
#pragma omp parallel for
for (size_t i = 0; i < grid.height(); i++) {
for (size_t j = 0; j < grid.width(); j++) {
float sum = 0;
float weight_sum = 0;
for (int x = -delta; x <= delta; x++) {
for (int y = -delta; y <= delta; y++) {
if (y + (int)i >= 0 && i + y < grid.height() && x + (int)j >= 0 &&
(unsigned int)j + x < grid.width()) {
if (sqrt(x * x + y * y) <= delta) {
float weight = 1 - (sqrt(x * x + y * y) / delta);
if (grid[{j + x, i + y}].has_value()) {
sum += *grid[{j + x, i + y}] * weight;
weight_sum += weight;
}
}
}
}
}
if (weight_sum == 0) {
low_pass[{j, i}] = 0;
continue;
}
low_pass[{j, i}] = sum / weight_sum;
}
}
return low_pass;
}