raster/grid.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Raster grids without values, and resampled grids and spacings derived from them. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/raster/geo_transform.h" | ||
| 6 | #include "terraingen/raster/raster.h" | ||
| 7 | #include "terraingen/util/geometry.h" | ||
| 8 | #include "terraingen/util/surface.h" | ||
| 9 | |||
| 10 | #include <cstddef> | ||
| 11 | |||
| 12 | namespace terraingen { | ||
| 13 | |||
| 14 | /// A grid of cells without values: its size and pixel-to-world transform. | ||
| 15 | /// | ||
| 16 | /// Terrains are evaluated over grids, so a tile of a larger grid is a grid on the same lattice. | ||
| 17 | struct RasterGrid { | ||
| 18 | 242 | std::size_t width = 0; ///< Columns. | |
| 19 | 231 | std::size_t height = 0; ///< Rows. | |
| 20 | 231 | GeoTransform transform{}; ///< Pixel-to-world transform. | |
| 21 | |||
| 22 | /// The size and transform of a raster. | ||
| 23 | 152634 | static RasterGrid FromRaster(const Raster<float>& raster) { | |
| 24 | 152634 | return {raster.Width(), raster.Height(), raster.Transform()}; | |
| 25 | } | ||
| 26 | |||
| 27 | /// The axis-aligned box the grid covers, in world coordinates. | ||
| 28 | Bounds2d Bounds() const; | ||
| 29 | |||
| 30 | /// The grid's area in square world units. | ||
| 31 | double Area() const; | ||
| 32 | |||
| 33 | /// The side of a cell in world units: the square root of a cell's area. | ||
| 34 | double PixelSize() const; | ||
| 35 | |||
| 36 | /// The area in m^2 the grid covers on a surface: `Area` on a plane. | ||
| 37 | /// | ||
| 38 | /// On a sphere of radius R this is R^2 (lon2 - lon1) (sin lat2 - sin lat1) over the grid's | ||
| 39 | /// longitude-latitude box, with latitudes clamped to [-90, 90] and at most a full turn; on an | ||
| 40 | /// ellipsoid the area element is integrated over the same box. | ||
| 41 | double SurfaceArea(const Surface& surface) const; | ||
| 42 | |||
| 43 | /// The grid's sample spacing in metres on a surface: `PixelSize` on a plane, on a sphere the | ||
| 44 | /// latitude step of a cell (its largest side). | ||
| 45 | double Spacing(const Surface& surface) const; | ||
| 46 | |||
| 47 | /// A raster with this grid's size and transform, every cell `fill`, and no no-data value. | ||
| 48 | Raster<float> MakeRaster(float fill = 0.0f) const; | ||
| 49 | |||
| 50 | 242 | bool operator==(const RasterGrid&) const = default; | |
| 51 | }; | ||
| 52 | |||
| 53 | /// A grid with square cells over the same extent, origin and axis directions as an unrotated | ||
| 54 | /// `grid`: round(width * |pixelWidth| / `pixelSize`) x round(height * |pixelHeight| / | ||
| 55 | /// `pixelSize`) cells, at least one each. | ||
| 56 | /// @param pixelSize The new cell side in world units; positive and finite. | ||
| 57 | /// @throws std::invalid_argument for a rotated grid, a `pixelSize` that is not positive and finite, | ||
| 58 | /// or a result wider or taller than 2^31 cells. | ||
| 59 | RasterGrid ResampledGrid(const RasterGrid& grid, double pixelSize); | ||
| 60 | |||
| 61 | /// The spacing a raster is sampled at: the larger of `spacing` and the raster's own spacing on | ||
| 62 | /// `surface` (`RasterGrid::Spacing`). | ||
| 63 | /// @param spacing The requested spacing in metres; 0 for the raster's own. | ||
| 64 | /// @throws std::domain_error if the raster's transform is not invertible. | ||
| 65 | double ResolvedSpacing(const Raster<float>& raster, double spacing, const Surface& surface); | ||
| 66 | |||
| 67 | } // namespace terraingen | ||
| 68 |