OGS
Mesh2Raster.cpp File Reference
#include <tclap/CmdLine.h>
#include <filesystem>
#include <fstream>
#include <memory>
#include <string>
#include "BaseLib/Logging.h"
#include "BaseLib/MPI.h"
#include "BaseLib/TCLAPArguments.h"
#include "GeoLib/AABB.h"
#include "InfoLib/GitInfo.h"
#include "MeshLib/IO/readMeshFromFile.h"
#include "MeshLib/Mesh.h"
#include "MeshLib/MeshSearch/MeshElementGrid.h"
#include "MeshLib/Node.h"
#include "MeshToolsLib/MeshEditing/ProjectPointOnMesh.h"
Include dependency graph for Mesh2Raster.cpp:

Go to the source code of this file.

Functions

int main (int argc, char *argv[])

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 22 of file Mesh2Raster.cpp.

23{
24 TCLAP::CmdLine cmd(
25 "Mesh to raster converter.\n"
26 "Rasterises a 2D mesh, pixel values are set to the elevation of a "
27 "regular grid superimposed on the mesh. If no mesh element is located "
28 "beneath a pixel it is set to NODATA.\n\n"
29 "OpenGeoSys-6 software, version " +
31 ".\n"
32 "Copyright (c) 2012-2026, OpenGeoSys Community "
33 "(http://www.opengeosys.org)",
35 TCLAP::ValueArg<double> cell_arg(
36 "c", "cellsize", "edge length of raster cells in result. (min = 0)",
37 false, 1, "CELLSIZE");
38 cmd.add(cell_arg);
39 TCLAP::ValueArg<std::string> output_arg("o", "output-file",
40 "Output (.asc). Raster output file",
41 true, "", "OUTPUT_FILE");
42 cmd.add(output_arg);
43 TCLAP::ValueArg<std::string> input_arg(
44 "i", "input-file", "Input (.vtu | .msh). Mesh input file", true, "",
45 "string");
46 cmd.add(input_arg);
47 auto log_level_arg = BaseLib::makeLogLevelArg();
48 cmd.add(log_level_arg);
49 cmd.parse(argc, argv);
50
51 BaseLib::MPI::Setup mpi_setup(argc, argv);
52 BaseLib::initOGSLogger(log_level_arg.getValue());
53
54 INFO("Rasterising mesh...");
55 std::unique_ptr<MeshLib::Mesh> const mesh(
56 MeshLib::IO::readMeshFromFile(input_arg.getValue()));
57 if (mesh == nullptr)
58 {
59 ERR("Error reading mesh file.");
60 return 1;
61 }
62 if (mesh->getDimension() != 2)
63 {
64 ERR("The programme requires a mesh containing two-dimensional elements "
65 "(i.e. triangles or quadrilaterals.");
66 return 2;
67 }
68
69 auto const edgeLengths = minMaxEdgeLength(mesh->getElements());
70 double const cellsize =
71 (cell_arg.isSet()) ? cell_arg.getValue() : edgeLengths.first;
72 INFO("Cellsize set to {:f}", cellsize);
73
74 double const max_edge = edgeLengths.second + cellsize;
75
76 std::vector<MeshLib::Node*> const& nodes_vec(mesh->getNodes());
77 GeoLib::AABB const bounding_box(nodes_vec.begin(), nodes_vec.end());
78 auto const& [min, max] = bounding_box.getMinMaxPoints();
79 auto const n_cols =
80 static_cast<std::size_t>(std::ceil((max[0] - min[0]) / cellsize));
81 auto const n_rows =
82 static_cast<std::size_t>(std::ceil((max[1] - min[1]) / cellsize));
83 double const half_cell = cellsize / 2.0;
84
85 // raster header
86 std::string output_name = output_arg.getValue();
87 std::string const ext = ".asc";
88 if (std::filesystem::path(output_name).extension() != ext)
89 {
90 WARN("Adding extension '*.asc' to output file name '{:s}'.",
91 output_name);
92 output_name += ext;
93 }
94 std::ofstream out(output_name);
95 out << "ncols " << n_cols << "\n";
96 out << "nrows " << n_rows << "\n";
97 out << std::fixed << "xllcorner " << (min[0] - half_cell) << "\n";
98 out << std::fixed << "yllcorner " << (min[1] - half_cell) << "\n";
99 out << std::fixed << "cellsize " << cellsize << "\n";
100 out << "NODATA_value "
101 << "-9999\n";
102 INFO("Writing raster with {:d} x {:d} pixels.", n_cols, n_rows);
103
104 MeshLib::MeshElementGrid const grid(*mesh);
105
106 for (std::size_t row = 0; row < n_rows; ++row)
107 {
108 double const y = max[1] - row * cellsize;
109 for (std::size_t column = 0; column < n_cols; ++column)
110 {
111 // pixel values
112 double const x = min[0] + column * cellsize;
113 MeshLib::Node const node(x, y, 0);
114 MathLib::Point3d min_vol{{x - max_edge, y - max_edge,
115 -std::numeric_limits<double>::max()}};
116 MathLib::Point3d max_vol{{x + max_edge, y + max_edge,
117 std::numeric_limits<double>::max()}};
118 std::vector<const MeshLib::Element*> const& elems =
119 grid.getElementsInVolume(min_vol, max_vol);
120 auto const* element =
122 node);
123 // centre of the pixel is located within a mesh element
124 if (element != nullptr)
125 {
127 node)
128 << " ";
129 }
130 else
131 {
132 std::array<double, 4> const x_off{
133 {-half_cell, half_cell, -half_cell, half_cell}};
134 std::array<double, 4> const y_off{
135 {-half_cell, -half_cell, half_cell, half_cell}};
136 double sum(0);
137 std::size_t nonzero_count(0);
138 // test all of the pixel's corners if there are any within an
139 // element
140 for (std::size_t i = 0; i < 4; ++i)
141 {
142 MeshLib::Node const corner_node(x + x_off[i], y + y_off[i],
143 0);
144 auto const* corner_element =
146 elems, corner_node);
147 if (corner_element != nullptr)
148 {
150 *corner_element, node);
151 nonzero_count++;
152 }
153 }
154 if (nonzero_count > 0)
155 {
156 // calculate pixel value as average of corner values
157 out << sum / nonzero_count << " ";
158 }
159 else
160 {
161 // if none of the corners give a value, set pixel to NODATA
162 out << "-9999 ";
163 }
164 }
165 }
166 out << "\n";
167 }
168 out.close();
169 INFO("Result written to {:s}", output_name);
170 return 0;
171}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:56
GITINFOLIB_EXPORT const std::string ogs_version
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)
std::pair< double, double > minMaxEdgeLength(std::vector< Element * > const &elements)
Returns the minimum and maximum edge length for given elements.
Definition Mesh.cpp:179
double getElevation(MeshLib::Element const &element, MathLib::Point3d const &node)
MeshLib::Element const * getProjectedElement(std::vector< const MeshLib::Element * > const &elements, MathLib::Point3d const &node)

References ERR(), MeshLib::MeshElementGrid::getElementsInVolume(), MeshToolsLib::ProjectPointOnMesh::getElevation(), GeoLib::AABB::getMinMaxPoints(), MeshToolsLib::ProjectPointOnMesh::getProjectedElement(), INFO(), BaseLib::initOGSLogger(), BaseLib::makeLogLevelArg(), GitInfoLib::GitInfo::ogs_version, MeshLib::IO::readMeshFromFile(), and WARN().