TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
44 / 44
100.0%
Branches:
39 / 42
92.9%
Functions:
4 / 4
100.0%

raster/resample.h
Line Branch Exec Source
1 /// @file
2 /// @brief Resampling and interpolation of rasters: nearest, bilinear and cubic.
3 #pragma once
4
5 #include "terraingen/raster/grid.h"
6 #include "terraingen/raster/raster.h"
7
8 #include <cmath>
9 #include <cstddef>
10 #include <limits>
11 #include <optional>
12
13 namespace terraingen {
14
15 /// How `Resample` interpolates between source cells.
16 enum class ResampleMethod {
17 Nearest, ///< The value of the nearest cell centre.
18 Bilinear, ///< Linear in each axis over the four surrounding cells.
19 Cubic, ///< Keys cubic convolution (a = -0.5) over the sixteen surrounding cells.
20 };
21
22 /// A raster resampled to square cells over the same extent, origin and axis directions, on the
23 /// `ResampledGrid`, keeping `raster`'s no-data value (NaN cells without one).
24 ///
25 /// Each output cell centre is interpolated in the source, with samples beyond the edge taken from
26 /// the nearest edge cell. An output cell is no-data where any contributing cell is.
27 /// @param raster The source raster; not empty and not rotated.
28 /// @param pixelSize The new cell side in world units; positive and finite.
29 /// @throws std::invalid_argument for an empty or rotated raster, a non-positive or non-finite
30 /// `pixelSize`, or a result wider or taller than 2^31 cells.
31 Raster<float> Resample(const Raster<float>& raster, double pixelSize, ResampleMethod method);
32
33 /// A raster interpolated at world position (`x`, `y`), as `Resample` interpolates; NaN outside
34 /// the raster's extent or where a contributing cell is no-data.
35 /// @param raster The raster; not empty and not rotated.
36 /// @throws std::invalid_argument for an empty or rotated raster.
37 /// @throws std::domain_error if the raster's transform is not invertible.
38 float SampleRaster(const Raster<float>& raster, double x, double y, ResampleMethod method);
39
40 /// A raster resampled onto a non-empty grid, each cell `SampleRaster` at its centre.
41 ///
42 /// Cells giving NaN hold `raster`'s no-data value, or NaN, which then becomes the no-data value
43 /// (`FilledNoData`).
44 /// @param raster The source raster; not empty and not rotated.
45 /// @throws std::invalid_argument for an empty or rotated raster, or an empty grid.
46 /// @throws std::domain_error if the raster's transform is not invertible.
47 Raster<float> ResampleTo(const Raster<float>& raster, const RasterGrid& grid,
48 ResampleMethod method);
49
50 /// The no-data value of a raster filled from a source with no-data value `noData`, whose
51 /// missing cells hold `noData` or, without one, NaN: `noData` if set; otherwise NaN if a cell
52 /// was `missing`, else none.
53 std::optional<float> FilledNoData(std::optional<float> noData, bool missing);
54
55 /// Sets each cell of `target` to `sample` at the cell's centre; cells where it gives NaN
56 /// hold `noData`, or NaN without one, and `target` gets `FilledNoData`.
57 /// @tparam Sample Callable as `float(double x, double y)` with world coordinates; returns NaN
58 /// where missing.
59 template <typename Sample>
60 7 void SampleAtCentres(Raster<float>& target, std::optional<float> noData, Sample&& sample) {
61 7 const float fill = noData.value_or(std::numeric_limits<float>::quiet_NaN());
62 7 bool missing = false;
63
8/8
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}&&):
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}&&):
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
void terraingen::SampleAtCentres<terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}&&):
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 3 times.
void terraingen::SampleAtCentres<terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}&&):
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
36 for (std::size_t row = 0; row < target.Height(); ++row) {
64
8/8
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}&&):
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}&&):
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
void terraingen::SampleAtCentres<terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}&&):
✓ Branch 1 taken 97 times.
✓ Branch 2 taken 15 times.
void terraingen::SampleAtCentres<terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}&&):
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 10 times.
190 for (std::size_t col = 0; col < target.Width(); ++col) {
65 161 const Vec2d centre = target.CellCenter(col, row);
66
2/2
void terraingen::SampleAtCentres<terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}&&):
✓ Branch 1 taken 97 times.
void terraingen::SampleAtCentres<terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}&&):
✓ Branch 1 taken 52 times.
161 const float value = sample(centre.x, centre.y);
67
14/16
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}&&):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 2 times.
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}&&):
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
void terraingen::SampleAtCentres<terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}&&):
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 24 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 72 times.
void terraingen::SampleAtCentres<terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}&&):
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 35 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 16 times.
161 missing = missing || std::isnan(value);
68
7/8
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#1}&&):
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
void terraingen::SampleAtCentres<SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}>(terraingen::Raster<float>&, std::optional<float>, SampleAtCentres_CallsTheSamplerAtEachCellCentre_Test::TestBody()::{lambda(double, double)#2}&&):
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
void terraingen::SampleAtCentres<terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::GeoTiffSource::FillBySampling(terraingen::Raster<float>&) const::{lambda(double, double)#1}&&):
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 88 times.
void terraingen::SampleAtCentres<terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}>(terraingen::Raster<float>&, std::optional<float>, terraingen::ResampleTo(terraingen::Raster<float> const&, terraingen::RasterGrid const&, terraingen::ResampleMethod)::{lambda(double, double)#1}&&):
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 32 times.
161 target(col, row) = std::isnan(value) ? fill : value;
69 }
70 }
71 7 target.SetNoData(FilledNoData(noData, missing));
72 7 }
73
74 } // namespace terraingen
75