From 4c67ae418c622d78c3a77b19beadbfe3cc7d7a06 Mon Sep 17 00:00:00 2001 From: rinkk <karsten.rink@ufz.de> Date: Thu, 28 Jul 2016 11:35:34 +0200 Subject: [PATCH] added write functionality for csv --- Applications/FileIO/CsvInterface.cpp | 67 ++++++++++++++++++++++++++++ Applications/FileIO/CsvInterface.h | 45 ++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/Applications/FileIO/CsvInterface.cpp b/Applications/FileIO/CsvInterface.cpp index ce2878960cf..6163f99796f 100644 --- a/Applications/FileIO/CsvInterface.cpp +++ b/Applications/FileIO/CsvInterface.cpp @@ -14,6 +14,8 @@ #include "CsvInterface.h" #include <algorithm> +#include <iostream> +#include <numeric> #include <stdexcept> #include "GeoLib/Point.h" @@ -181,4 +183,69 @@ std::size_t CsvInterface::findColumn(std::string const& line, char delim, std::s return count; } +void CsvInterface::addIndexVectorForWriting(std::size_t s) +{ + std::vector<int> idx_vec(s); + std::iota(idx_vec.begin(), idx_vec.end(), 0); + addVectorForWriting("Index", idx_vec); +} + +bool CsvInterface::write() +{ + if (_data.empty()) + { + ERR ("CsvInterface::write() - No data to write."); + return false; + } + + std::size_t const vec_size (getVectorSize(0)); + std::size_t const n_vecs (_data.size()); + for (std::size_t i=1; i<n_vecs; ++i) + { + if (getVectorSize(i) != vec_size) + { + ERR ("CsvInterface::write() - Data vectors are not equally long."); + return false; + } + } + + _out << _vec_names[0]; + for (std::size_t i=1; i<n_vecs; ++i) + _out << "\t " << _vec_names[i]; + _out << std::endl; + + for (std::size_t j=1; j<vec_size; ++j) + { + writeValue(0,j); + for (std::size_t i=1; i<n_vecs; ++i) + { + _out << "\t "; + writeValue(i,j); + } + _out << std::endl; + } + return true; +} + +std::size_t CsvInterface::getVectorSize(std::size_t idx) const +{ + if (_data[idx].type() == typeid(std::vector<std::string>)) + return boost::any_cast<std::vector<std::string>>(_data[idx]).size(); + else if (_data[idx].type() == typeid(std::vector<double>)) + return boost::any_cast<std::vector<double>>(_data[idx]).size(); + else if (_data[idx].type() == typeid(std::vector<int>)) + return boost::any_cast<std::vector<int>>(_data[idx]).size(); + return 0; +} + +void CsvInterface::writeValue(std::size_t vec_idx, std::size_t in_vec_idx) +{ + if (_data[vec_idx].type() == typeid(std::vector<std::string>)) + _out << boost::any_cast<std::vector<std::string>>(_data[vec_idx])[in_vec_idx]; + else if (_data[vec_idx].type() == typeid(std::vector<double>)) + _out << boost::any_cast<std::vector<double>>(_data[vec_idx])[in_vec_idx]; + else if (_data[vec_idx].type() == typeid(std::vector<int>)) + _out << boost::any_cast<std::vector<int>>(_data[vec_idx])[in_vec_idx]; +} + } // end namespace FileIO diff --git a/Applications/FileIO/CsvInterface.h b/Applications/FileIO/CsvInterface.h index e78597c96e5..a6653f888d3 100644 --- a/Applications/FileIO/CsvInterface.h +++ b/Applications/FileIO/CsvInterface.h @@ -15,6 +15,7 @@ #define CSVINTERFACE_H_ #include <logog/include/logog.hpp> +#include <boost/any.hpp> #include <array> #include <fstream> @@ -22,10 +23,12 @@ #include <limits> #include <list> #include <string> +#include <typeinfo> #include <vector> #include "BaseLib/StringTools.h" +#include "BaseLib/IO/Writer.h" namespace GeoLib { class Point; @@ -36,9 +39,36 @@ namespace FileIO { /** * Interface for reading CSV file formats. */ -class CsvInterface { +class CsvInterface : public BaseLib::IO::Writer +{ public: + /// Contructor (only needed for writing files) + CsvInterface() {}; + + /// Adds an index vector of size s to the CSV file + void addIndexVectorForWriting(std::size_t s); + + /// Adds a data vector to the CSV file. All data vectors have to have the same size. + /// Vectors will be written in the same sequence they have been added to the interfaceW. + template<typename T> + bool addVectorForWriting(std::string const& vec_name, std::vector<T> const& vec) + { + if (typeid(vec) == typeid(std::vector<std::string>) || + typeid(vec) == typeid(std::vector<double>) || + typeid(vec) == typeid(std::vector<int>)) + { + _vec_names.push_back(vec_name); + _data.push_back(vec); + return true; + } + ERR ("Vector type currently not supported."); + return false; + } + + /// Writes the CSV file. + bool write(); + /** * Reads 3D points from a CSV file. It is assumed that the file has a header * specifying a name for each of the columns. The first three columns will be @@ -178,6 +208,19 @@ private: /// Returns the number of the column with column_name (or std::numeric_limits::max() if no such column has been found). static std::size_t findColumn(std::string const& line, char delim, std::string const& column_name); + + /// Returns the size of the vector with the given index + std::size_t getVectorSize(std::size_t idx) const; + + /** + * Writes a value from a vector to the file. + * \param vec_idx Index of the vector + * \param in_vec_idx Entry in the selected vector + */ + void writeValue(std::size_t vec_idx, std::size_t in_vec_idx); + + std::vector<std::string> _vec_names; + std::vector< boost::any > _data; }; } // FileIO -- GitLab