29 std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
56static std::optional<GeoLib::RasterHeader>
readASCHeader(std::ifstream& in)
67 header.
n_cols = atoi(value.c_str());
78 header.
n_rows = atoi(value.c_str());
88 if (tag ==
"xllcorner" || tag ==
"xllcenter")
98 if (tag ==
"yllcorner" || tag ==
"yllcenter")
109 if (tag ==
"cellsize")
119 if (tag ==
"NODATA_value" || tag ==
"nodata_value")
132 std::string
const& fname)
134 std::ifstream in(fname.c_str());
138 WARN(
"Raster::getRasterFromASCFile(): Could not open file {:s}.",
147 "Raster::getRasterFromASCFile(): Could not read header of file "
153 std::vector<double> values(header->n_cols * header->n_rows);
155 for (std::size_t j(0); j < header->n_rows; ++j)
157 const std::size_t idx((header->n_rows - j - 1) * header->n_cols);
158 for (std::size_t i(0); i < header->n_cols; ++i)
169static std::optional<std::tuple<GeoLib::RasterHeader, double, double>>
178 ERR(
"Error in readSurferHeader() - No Surfer file.");
193 if (ceil((max - min) /
static_cast<double>(header.
n_rows)) ==
200 ERR(
"Error in readSurferHeader() - Anisotropic cellsize detected.");
207 return {{header, min, max}};
211 std::string
const& fname)
213 std::ifstream in(fname.c_str());
217 ERR(
"Raster::getRasterFromSurferFile() - Could not open file {:s}",
223 if (!optional_header)
225 ERR(
"Raster::getRasterFromASCFile() - could not read header of file "
231 auto const [header, min, max] = *optional_header;
232 std::vector<double> values(header.n_cols * header.n_rows);
234 for (std::size_t j(0); j < header.n_rows; ++j)
236 const std::size_t idx(j * header.n_cols);
237 for (std::size_t i(0); i < header.n_cols; ++i)
240 values[idx + i] = (val > max || val < min) ? header.no_data : val;
249 std::string line(
"");
250 if (std::getline(in, line))
252 std::stringstream str_stream(line);
253 std::array<double, 3> coords;
254 str_stream >> coords[0] >> coords[1] >> coords[2];
255 return std::make_optional(coords);
261 std::string
const& fname)
263 std::ifstream in(fname.c_str());
266 ERR(
"Raster::getRasterFromXyzFile() - Could not open file {:s}", fname);
271 if (coords == std::nullopt)
276 std::vector<double> values;
277 values.push_back((*coords)[2]);
280 if (coords2 == std::nullopt)
284 values.push_back((*coords2)[2]);
286 0, 0, 1,
GeoLib::Point(*coords), (*coords2)[0] - (*coords)[0], -9999};
288 std::size_t n_cols = 2, n_rows = 1;
291 values.push_back((*coords)[2]);
292 if ((*coords)[0] > (*coords2)[0])
294 if ((*coords)[0] - (*coords2)[0] != header.cell_size)
296 ERR(
"Varying cell sizes or unordered pixel values found. "
304 if ((*coords)[1] - (*coords2)[1] != header.cell_size)
306 ERR(
"Varying cell sizes or unordered pixel values found. "
312 if (header.n_cols == 0)
314 header.n_cols = n_cols;
319 if (n_cols != header.n_cols)
321 ERR(
"Different number of pixels per line. Aborting!");
329 header.n_rows = n_rows;
330 if (header.n_cols == 0)
332 ERR(
"Could not determine raster size. Note that minimum allowed raster "
333 "size is 2 x 2 pixels.");
340 std::string
const& file_name)
344 unsigned const nCols(header.
n_cols);
345 unsigned const nRows(header.
n_rows);
348 std::ofstream out(file_name);
349 out <<
"ncols " << nCols <<
"\n";
350 out <<
"nrows " << nRows <<
"\n";
351 auto const default_precision = out.precision();
352 out.precision(std::numeric_limits<double>::digits10);
353 out <<
"xllcorner " << origin[0] <<
"\n";
354 out <<
"yllcorner " << origin[1] <<
"\n";
355 out <<
"cellsize " << header.
cell_size <<
"\n";
356 out.precision(default_precision);
357 out <<
"NODATA_value " << header.
no_data <<
"\n";
360 for (
unsigned row(0); row < nRows; ++row)
362 for (
unsigned col(0); col < nCols - 1; ++col)
364 out << raster.
data()[(nRows - row - 1) * nCols + col] <<
" ";
366 out << raster.
data()[(nRows - row) * nCols - 1] <<
"\n";
374 return std::all_of(raster_paths.begin(), raster_paths.end(),
375 [](std::string
const& raster_path)
377 if (BaseLib::IsFileExisting(raster_path))
381 ERR(
"Opening raster file {} failed.", raster_path);
386std::optional<std::vector<GeoLib::Raster const*>> readRasters(
387 std::vector<std::string>
const& raster_paths)
394 std::vector<GeoLib::Raster const*> rasters;
395 rasters.reserve(raster_paths.size());
396 std::transform(raster_paths.begin(), raster_paths.end(),
397 std::back_inserter(rasters),
399 { return FileIO::AsciiRasterInterface::readRaster(path); });
400 return std::make_optional(rasters);
Definition of the AsciiRasterInterface class.
Definition of the Point class.
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
static GeoLib::Raster * getRasterFromXyzFile(std::string const &fname)
Reads a XYZ raster file.
static GeoLib::Raster * getRasterFromSurferFile(std::string const &fname)
Reads a Surfer GRD raster file.
static void writeRasterAsASC(GeoLib::Raster const &raster, std::string const &file_name)
Writes an Esri asc-file.
static GeoLib::Raster * readRaster(std::string const &fname)
static GeoLib::Raster * getRasterFromASCFile(std::string const &fname)
Reads an ArcGis ASC raster file.
Class Raster is used for managing raster data.
double const * data() const
RasterHeader const & getHeader() const
Returns the complete header information.
std::string getFileExtension(const std::string &path)
std::string replaceString(const std::string &searchString, const std::string &replaceString, std::string stringToReplace)
static std::optional< GeoLib::RasterHeader > readASCHeader(std::ifstream &in)
static double readDoubleFromStream(std::istream &in)
Reads a double replacing comma by point.
std::optional< std::array< double, 3 > > readCoordinates(std::istream &in)
static std::optional< std::tuple< GeoLib::RasterHeader, double, double > > readSurferHeader(std::ifstream &in)
static bool allRastersExist(std::vector< std::string > const &raster_paths)
Checks if all raster files actually exist.