diff --git a/Gui/VtkVis/VtkRaster.cpp b/Gui/VtkVis/VtkRaster.cpp index 71e52752b39071bc982c83fe55b0bb5dce99f241..68d9a20d21b741a05e00939572f94eb9b47a4a00 100644 --- a/Gui/VtkVis/VtkRaster.cpp +++ b/Gui/VtkVis/VtkRaster.cpp @@ -20,6 +20,9 @@ #include "StringTools.h" +// GeoLib +#include "Raster.h" + #include <vtkFloatArray.h> #include <vtkPointData.h> @@ -40,19 +43,23 @@ vtkImageAlgorithm* VtkRaster::loadImage(const std::string &fileName, double& x0, double& y0, double& delta) { QFileInfo fileInfo(QString::fromStdString(fileName)); - unsigned width(0), height(0); - double* data; - double no_data(-9999); - if (fileInfo.suffix().toLower() == "asc") - { - data = loadDataFromASC(fileName, x0, y0, width, height, delta, no_data); - return loadImageFromArray(data, x0, y0, width, height, delta); + + GeoLib::Raster *raster(nullptr); + if (fileInfo.suffix().toLower() == "asc") { + raster = GeoLib::Raster::getRasterFromASCFile(fileName); } else if (fileInfo.suffix().toLower() == "grd") { - data = loadDataFromSurfer(fileName, x0, y0, width, height, delta, no_data); - return loadImageFromArray(data, x0, y0, width, height, delta); + raster = GeoLib::Raster::getRasterFromSurferFile(fileName); + } + if (raster) { + x0 = raster->getOrigin()[0]; + y0 = raster->getOrigin()[1]; + double const*const data (raster->begin()); + return VtkRaster::loadImageFromArray(data, x0, y0, + raster->getNCols(), raster->getNRows(), raster->getRasterPixelDistance(), + raster->getNoDataValue()); } #ifdef libgeotiff_FOUND else if ((fileInfo.suffix().toLower() == "tif") || (fileInfo.suffix().toLower() == "tiff")) @@ -62,7 +69,7 @@ vtkImageAlgorithm* VtkRaster::loadImage(const std::string &fileName, return loadImageFromFile(fileName); } -vtkImageImport* VtkRaster::loadImageFromArray(double* data_array, double &x0, double &y0, unsigned &width, unsigned &height, double &delta, double noData) +vtkImageImport* VtkRaster::loadImageFromArray(double const*const data_array, double x0, double y0, std::size_t width, std::size_t height, double delta, double noData) { const unsigned length = height*width; float* data = new float[length*2]; @@ -101,203 +108,7 @@ vtkImageImport* VtkRaster::loadImageFromArray(double* data_array, double &x0, do } -bool VtkRaster::readASCHeader(ascHeader &header, std::ifstream &in) -{ - std::string line, tag, value; - in >> tag; - if (tag.compare("ncols") == 0) - { - in >> value; - header.ncols = atoi(value.c_str()); - } - else - return false; - in >> tag; - if (tag.compare("nrows") == 0) - { - in >> value; - header.nrows = atoi(value.c_str()); - } - else - return false; - in >> tag; - if (tag.compare("xllcorner") == 0) - { - in >> value; - header.x = strtod(BaseLib::replaceString(",", ".", value).c_str(),0); - } - else - return false; - in >> tag; - if (tag.compare("yllcorner") == 0) - { - in >> value; - header.y = strtod(BaseLib::replaceString(",", ".", value).c_str(),0); - } - else - return false; - in >> tag; - if (tag.compare("cellsize") == 0) - { - in >> value; - header.cellsize = strtod(BaseLib::replaceString(",", ".", value).c_str(),0); - } - else - return false; - in >> tag; - if (tag.compare("NODATA_value") == 0) - { - in >> value; - header.noData = value.c_str(); - } - else - return false; - - // correct raster position by half a pixel for correct visualisation - // argh! wrong! correction has to happen in visualisation object, otherwise the actual data is wrong - //header.x = header.x + (header.cellsize / 2); - //header.y = header.y + (header.cellsize / 2); - - return true; -} - -double* VtkRaster::loadDataFromASC(const std::string &fileName, - double &x0, - double &y0, - unsigned &width, - unsigned &height, - double &delta, - double &no_data) -{ - std::ifstream in( fileName.c_str() ); - - if (!in.is_open()) - { - std::cout << "VtkRaster::loadImageFromASC() - Could not open file..." << std::endl; - return NULL; - } - - ascHeader header; - - if (readASCHeader(header, in)) - { - x0 = header.x; - y0 = header.y; - width = header.ncols; - height = header.nrows; - delta = header.cellsize; - - double* values = new double[header.ncols * header.nrows]; - - int col_index(0); - int noData = atoi(header.noData.c_str()); - std::string s(""); - // read the file into a double-array - for (int j = 0; j < header.nrows; ++j) - { - col_index = (header.nrows - j - 1) * header.ncols; - for (int i = 0; i < header.ncols; ++i) - { - in >> s; - unsigned index = col_index+i; - values[index] = strtod(BaseLib::replaceString(",", ".", s).c_str(),0); - } - } - - in.close(); - return values; - } - return NULL; -} - -bool VtkRaster::readSurferHeader(ascHeader &header, std::ifstream &in) -{ - std::string line, tag, value; - double min, max; - - in >> tag; - - if (tag.compare("DSAA") != 0) - { - std::cout << "Error in readSurferHeader() - No Surfer file..." << std::endl; - return false; - } - else - { - in >> header.ncols >> header.nrows; - in >> min >> max; - header.x = min; - header.cellsize = (max-min)/(double)header.ncols; - - in >> min >> max; - header.y = min; - - if (ceil((max-min)/(double)header.nrows) == ceil(header.cellsize)) - header.cellsize = ceil(header.cellsize); - else - { - std::cout << "Error in readSurferHeader() - Anisotropic cellsize detected..." << std::endl; - return 0; - } - in >> min >> max; // ignore min- and max-values - - header.noData = "1.70141E+038"; - } - - return true; -} - -double* VtkRaster::loadDataFromSurfer(const std::string &fileName, - double &x0, - double &y0, - unsigned &width, - unsigned &height, - double &delta, - double &no_data) -{ - std::ifstream in( fileName.c_str() ); - - if (!in.is_open()) - { - std::cout << "VtkRaster::loadImageFromSurfer() - Could not open file..." << std::endl; - return NULL; - } - - ascHeader header; - - if (readSurferHeader(header, in)) - { - x0 = header.x; - y0 = header.y; - width = header.ncols; - height = header.nrows; - delta = header.cellsize; - - double* values = new double[header.ncols * header.nrows]; - - int col_index(0); - int noData = -9999; - std::string s(""); - // read the file into a double-array - for (int j = 0; j < header.nrows; ++j) - { - col_index = j * header.ncols; - for (int i = 0; i < header.ncols; ++i) - { - in >> s; - if (s.compare(header.noData) == 0) - s = "-9999"; - unsigned index = col_index+i; - values[index] = strtod(BaseLib::replaceString(",", ".", s).c_str(),0); - } - } - - in.close(); - return values; - } - return NULL; -} #ifdef libgeotiff_FOUND vtkImageImport* VtkRaster::loadImageFromTIFF(const std::string &fileName, diff --git a/Gui/VtkVis/VtkRaster.h b/Gui/VtkVis/VtkRaster.h index 22572be524fd7b5a256ccd56d946d12d3cd3e2ca..a53b47df2239c75599766b77ca90f094feda66fd 100644 --- a/Gui/VtkVis/VtkRaster.h +++ b/Gui/VtkVis/VtkRaster.h @@ -25,18 +25,17 @@ class vtkImageReader2; */ class VtkRaster { - /// Data structure for the asc-file header. - struct ascHeader - { - int ncols; - int nrows; - double x; - double y; - double cellsize; - std::string noData; - }; - public: + /** + * \brief Returns a VtkImageAlgorithm from an array of pixel values and some image meta data. + */ + static vtkImageImport* loadImageFromArray(double const*const data_array, + double x0, + double y0, + std::size_t width, + std::size_t height, + double delta, + double no_data = -9999); /** * \brief Loads an image- or raster-file into an vtkImageAlgorithm-Object. * @@ -52,51 +51,6 @@ public: double& x0, double& y0, double& delta); - - /** - * \brief Loads an ASC file into a double array. - * The array alternates between pixel values and their respective alpha-values, i.e. - * result = { pixel0-value; pixel0-alpha, pixel1-value; pixel1-alpha; ... } - * - * \param fileName Filename of the file that should be loaded. - * \param x0 The x-coordinate of the origin. - * \param y0 The y-coordinate of the origin. - * \param width The width of the image. - * \param height The height of the image - * \param delta The size of each pixel in the image which is needed for correctly displaying the data. - * \return A float-array of pixel values incl. opacity (noData values are transparent) - */ - static double* loadDataFromASC(const std::string &fileName, - double &x0, - double &y0, - unsigned &width, - unsigned &height, - double &delta, - double &no_data); - - /** - * \brief Loads a Surfer file into a double array. - * Works exactly like loadDataFromASC(). - */ - static double* loadDataFromSurfer(const std::string &fileName, - double &x0, - double &y0, - unsigned &width, - unsigned &height, - double &delta, - double &no_data); - - /** - * \brief Returns a VtkImageAlgorithm from an array of pixel values and some image meta data. - */ - static vtkImageImport* loadImageFromArray(double* data_array, - double &x0, - double &y0, - unsigned &width, - unsigned &height, - double &delta, - double no_data = -9999); - private: /** * Loads ArcGIS asc-files to a QPixmap object and automatically does a contrast stretching to adjust values to 8 bit greyscale images. @@ -118,22 +72,6 @@ private: */ static vtkImageReader2* loadImageFromFile(const std::string &fileName); - /** - * Reads the header of an ArcGIS asc-file. - * \param header The ascHeader-object into which all the information will be written. - * \param in FileInputStream used for reading the data. - * \return True if the header could be read correctly, false otherwise. - */ - static bool readASCHeader(ascHeader &header, std::ifstream &in); - - /** - * Reads the header of a Surfer grd-file. - * \param header The ascHeader-object into which all the information will be written. - * \param in FileInputStream used for reading the data. - * \return True if the header could be read correctly, false otherwise. - */ - static bool readSurferHeader(ascHeader &header, std::ifstream &in); - /// Converts an uint32-number into a quadruple representing RGBA-colours for a pixel. static void uint32toRGBA(const unsigned int s, int* p); };