MeteoIODoc 20261004.b9219c1f
Environmental timeseries pre-processing
Loading...
Searching...
No Matches
iCSVHelper.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-3.0-or-later
2/***********************************************************************************/
3/* Copyright 2009 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
4/***********************************************************************************/
5/* This file is part of MeteoIO.
6 MeteoIO is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 MeteoIO is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with MeteoIO. If not, see <http://www.gnu.org/licenses/>.
18*/
19#ifndef iCSVHELP_H
20#define iCSVHELP_H
21
23#include <meteoio/IOUtils.h>
24
25#include <map>
26#include <sstream>
27#include <string>
28#include <vector>
29#include <algorithm>
30
31static const double default_nodata = M_PI;
32namespace mio {
33namespace iCSV {
34
35
36// ----------------- Datat structures -----------------
41 double x = default_nodata;
42 double y = default_nodata;
43 double z = default_nodata;
51 bool isEmpty() const { return x == default_nodata && y == default_nodata && z == default_nodata; }
52
57 std::string toString() const {
58 std::stringstream ss;
59 ss << "x: " << x << " y: " << y << " z: " << z
60 << (slope_angle != default_nodata ? " slope_angle: " + std::to_string(slope_angle) : "")
61 << (slope_azi != default_nodata ? " slope_azi: " + std::to_string(slope_azi) : "");
62 return ss.str();
63 }
64
66 if (x == default_nodata) {
68 }
69 if (y == default_nodata) {
71 }
72 if (z == default_nodata) {
74 }
77 }
80 }
81 }
82
83 Coords toCoords(const int& epsg) const {
84 Coords loc;
85 loc.setPoint(x, y, z, epsg);
86 return loc;
87 }
88
90 geoLocation(const geoLocation& rhs);
91 geoLocation() = default;
92 geoLocation(const double& in_x, const double& in_y, const double& in_z, const double& in_slope_angle=default_nodata, const double& in_slope_azi=default_nodata);
93
94};
95
96bool operator==(const geoLocation& lhs, const geoLocation& rhs);
97bool operator!=(const geoLocation& lhs, const geoLocation& rhs);
98
103 std::string field_delimiter = "0";
104 std::string geometry = "";
105 std::string srid = "";
106 std::string station_id = "";
107 std::string timestamp_meaning = "";
108 std::string doi = "";
111 int epsg = -1;
112
113 std::map<std::string, std::string> optional_metadata = {};
114
115 const std::vector<std::string> valid_delimiters = {",", "/", "\\", "|", ":", ";"};
116
117 std::string toString() const {
118 std::stringstream ss;
119 ss << "<metadata '" << station_id << "' (" << geometry << " epsg:" << epsg << " srid=" << srid << ")" << " doi='" << doi << "' />";
120 return ss.str();
121 }
122
127 void setEPSG(const int &in_epsg) {
128 epsg = in_epsg;
129 srid = "EPSG:" + std::to_string(in_epsg);
130 }
131
138 std::string getOptionalMetaData(const std::string &key) const {
139 const auto it = optional_metadata.find(key);
140 if (it != optional_metadata.end()) {
141 return it->second;
142 }
143 return "";
144 }
145
151 std::map<std::string, std::string> toMetaMap() const {
152 std::map<std::string, std::string> dict;
153 if (!doi.empty()) {
154 dict["doi"] = doi;
155 }
156
157 // Append optional_metadata to dict
158 dict.insert(optional_metadata.begin(), optional_metadata.end());
159
160 return dict;
161 }
162
168 std::map<std::string, std::string> toOutputMap() const {
169 std::map<std::string, std::string> dict;
170 dict["field_delimiter"] = field_delimiter;
171 dict["geometry"] = geometry;
172 dict["srid"] = srid;
173 if (!station_id.empty()) {
174 dict["station_id"] = station_id;
175 }
176 if (!timestamp_meaning.empty()) {
177 dict["timestamp_meaning"] = timestamp_meaning;
178 }
179 if (nodata != default_nodata) {
180 dict["nodata"] = std::to_string(nodata);
181 }
182 if (timezone != default_nodata) {
183 dict["timezone"] = std::to_string(timezone);
184 }
185 if (!doi.empty()) {
186 dict["doi"] = doi;
187 }
188
189 dict.insert(optional_metadata.begin(), optional_metadata.end());
190 return dict;
191 }
192};
193
194bool operator==(const MetaDataSection &lhs, const MetaDataSection &rhs);
195
203bool roughlyEqual(const MetaDataSection &lhs, const MetaDataSection &rhs);
204
206
212 std::vector<std::string> fields = {};
213 std::vector<double> units_multipliers = {};
214 std::vector<double> units_offsets = {};
215 std::vector<std::string> units = {};
216 std::vector<std::string> long_name = {};
217 std::vector<std::string> standard_name = {};
218
219 std::map<std::string, std::vector<std::string>> other_fields = {};
220
221 size_t getFieldIndex(const std::string &fieldname) const {
222 for (size_t id = 0; id < fields.size(); id++) {
223 if (fieldname == fields[id])
224 return id;
225 }
226 return IOUtils::npos;
227 }
228
229 std::vector<std::string> getOtherFields(const std::string &key) {
230 auto it = other_fields.find(key);
231 if (it != other_fields.end()) {
232 return it->second;
233 }
234 return {};
235 }
236 std::map<std::string, std::vector<std::string>> toMap() const {
237 std::map<std::string, std::vector<std::string>> dict;
238 dict["fields"] = fields;
239
240 if (!units.empty()) {
241 dict["units"] = units;
242 }
243 if (!long_name.empty()) {
244 dict["long_name"] = long_name;
245 }
246 if (!standard_name.empty()) {
247 dict["standard_name"] = standard_name;
248 }
249
250 // Convert vector<double> to vector<string>
251 if (!units_multipliers.empty()) {
252 std::vector<std::string> str_units_multipliers(units_multipliers.size());
253 std::transform(units_multipliers.begin(), units_multipliers.end(), str_units_multipliers.begin(),
254 [](double d) { return std::to_string(d); });
255 dict["units_multipliers"] = str_units_multipliers;
256 }
257
258 if (!units_offsets.empty()) {
259 std::vector<std::string> str_units_offsets(units_offsets.size());
260 std::transform(units_offsets.begin(), units_offsets.end(), str_units_offsets.begin(),
261 [](double d) { return std::to_string(d); });
262 dict["units_offsets"] = str_units_offsets;
263 }
264
265 // Append other_fields to dict
266 if (!other_fields.empty()) {
267 dict.insert(other_fields.begin(), other_fields.end());
268 }
269 return dict;
270 }
271};
272
273bool operator==(const fieldsSection &lhs, const fieldsSection &rhs);
274
282bool roughlyEqual(const fieldsSection &lhs, const fieldsSection &rhs);
284
285// ----------------- Helper functions -----------------
286std::vector<double> convertVector(const std::vector<std::string> &vec);
287std::vector<Coords> convertVector(const std::vector<geoLocation> &vec, const int& epsg);
288geoLocation extractCoordinates(const std::string &geometry);
289geoLocation toiCSVLocation(Coords coords, const int& epsg);
290
291
292
293// ----------------- iCSVFile class -----------------
294
310class iCSVFile {
311 public:
312 // Essential information
314 std::string filename;
315 std::string firstline;
317
320
321 // helper flags
323 bool timezone_in_data = false;
324 bool timestamp_present = false;
325 bool julian_present = false;
328
329 private:
330 // File data
331 std::vector<Date> dates_in_file;
332 std::vector<std::vector<double>> row_data;
333 std::vector<geoLocation> locations_in_data;
334
335
336 public:
337 // Constructors
338 iCSVFile();
339 iCSVFile(const iCSVFile &);
340 iCSVFile(const std::string &infile, const bool& read_sequential);
341
342 // Main methods
343 void readFile(const std::string &infile, const bool& sequentially, const bool& is_gzipped = false);
344 bool checkFormatValidity();
345 bool checkMeteoIOCompatibility() const;
346 void parseGeometry();
347
348 // Getters
349 double getNoData() const {
351 }
353 const std::vector<std::vector<double>>& getRowData() const { return row_data; }
354 const std::vector<Date>& getAllDatesInFile() const { return dates_in_file; }
355 const std::vector<geoLocation>& getAllLocationsInData() const { return locations_in_data; }
356 geoLocation getLocationAt(size_t index) const {
357 if (index >= locations_in_data.size()) {
358 throw std::out_of_range("Index out of range for locations");
359 }
360 return locations_in_data[index];
361 }
362 std::vector<Date> getDatesInFile(const Date &start_date, const Date &end_date) const {
363 std::vector<Date> dates;
364 for (const Date &date : dates_in_file) {
365 if (date >= start_date && date <= end_date) {
366 dates.push_back(date);
367 }
368 }
369 return dates;
370 }
371 std::vector<geoLocation> getLocationsInData(const Date &start_date, const Date &end_date) const {
373 return std::vector<geoLocation>();
374
375 std::vector<geoLocation> locations;
376 for (size_t i = 0; i < dates_in_file.size(); i++) {
377 if (dates_in_file[i] >= start_date && dates_in_file[i] <= end_date) {
378 locations.push_back(locations_in_data[i]);
379 }
380 }
381 return locations;
382 }
383 // reading helpers
384 bool processLine(const std::string& line, std::string& section, const bool& sequentially);
385 void parseLineContent(const std::string& content, const std::string& section);
386 void processData(const std::string& content);
387
388 // Format helpers
389 bool isValidLocation(const geoLocation& location);
390 bool isColumnName(const std::string &geometry);
391 void findTime();
392 void findLocation();
393 std::vector<std::string> columnsToAppend(const std::vector<MeteoData> &vecMeteo) const;
394
395 // Data methods
396 double readData(const Date &r_date, const std::string &fieldname);
397 void aggregateData(const std::vector<MeteoData> &vecMeteo, const bool& optimize_precision = false);
398 void parseMetaData(const std::string &key, const std::string &value);
399 void parseFields(const std::string &key, const std::string &value);
400};
401
402} // namespace iCSV
403} // namespace mio
404#endif // iCSVHELP_H
A class to handle geographic coordinate systems. This class offers an easy way to transparently conve...
Definition Coords.h:83
void setPoint(const double in_x_or_lat, const double in_y_or_lon, const double in_altitude)
Set coordinates based on the previously defined EPSG code If the EPSG code is 4326 (which represents ...
Definition Coords.cc:592
A class to handle timestamps. This class handles conversion between different time display formats (I...
Definition Date.h:86
This class is responsible for handling and storing iCSV files.
Definition iCSVHelper.h:310
std::vector< std::string > columnsToAppend(const std::vector< MeteoData > &vecMeteo) const
Definition iCSVHelper.cc:592
const std::vector< Date > & getAllDatesInFile() const
Definition iCSVHelper.h:354
void parseMetaData(const std::string &key, const std::string &value)
Definition iCSVHelper.cc:374
bool timezone_in_data
Definition iCSVHelper.h:323
std::string firstline
Definition iCSVHelper.h:315
geoLocation station_location
Definition iCSVHelper.h:316
std::vector< geoLocation > getLocationsInData(const Date &start_date, const Date &end_date) const
Definition iCSVHelper.h:371
double getNoData() const
Definition iCSVHelper.h:349
size_t time_id
Definition iCSVHelper.h:326
iCSVFile()
Definition iCSVHelper.cc:206
double getTimeZone() const
Definition iCSVHelper.h:352
fieldsSection FIELDS
Definition iCSVHelper.h:319
size_t skip_lines_to_data
Definition iCSVHelper.h:313
void parseFields(const std::string &key, const std::string &value)
Definition iCSVHelper.cc:403
bool checkFormatValidity()
Checks the validity of the format for the iCSVFile.
Definition iCSVHelper.cc:502
bool isValidLocation(const geoLocation &location)
Definition iCSVHelper.cc:579
void findTime()
Definition iCSVHelper.cc:656
bool location_in_header
Definition iCSVHelper.h:322
bool timestamp_present
Definition iCSVHelper.h:324
void findLocation()
Definition iCSVHelper.cc:674
bool isColumnName(const std::string &geometry)
Definition iCSVHelper.cc:581
std::vector< Date > getDatesInFile(const Date &start_date, const Date &end_date) const
Definition iCSVHelper.h:362
bool checkMeteoIOCompatibility() const
Definition iCSVHelper.cc:566
void readFile(const std::string &infile, const bool &sequentially, const bool &is_gzipped=false)
Definition iCSVHelper.cc:253
std::string filename
Definition iCSVHelper.h:314
geoLocation getLocationAt(size_t index) const
Definition iCSVHelper.h:356
void aggregateData(const std::vector< MeteoData > &vecMeteo, const bool &optimize_precision=false)
Definition iCSVHelper.cc:454
const std::vector< geoLocation > & getAllLocationsInData() const
Definition iCSVHelper.h:355
size_t location_id
Definition iCSVHelper.h:327
void processData(const std::string &content)
Definition iCSVHelper.cc:352
void parseGeometry()
Parses the geometry information of the iCSV file.
Definition iCSVHelper.cc:627
MetaDataSection METADATA
Definition iCSVHelper.h:318
void parseLineContent(const std::string &content, const std::string &section)
Definition iCSVHelper.cc:330
const std::vector< std::vector< double > > & getRowData() const
Definition iCSVHelper.h:353
bool processLine(const std::string &line, std::string &section, const bool &sequentially)
Definition iCSVHelper.cc:293
double readData(const Date &r_date, const std::string &fieldname)
Definition iCSVHelper.cc:431
bool julian_present
Definition iCSVHelper.h:325
static const double default_nodata
Definition iCSVHelper.h:31
constexpr double nodata
This is the internal nodata value.
Definition IOUtils.h:76
const size_t npos
npos is the out-of-range value
Definition IOUtils.h:82
std::vector< double > convertVector(const std::vector< std::string > &vec)
Definition iCSVHelper.cc:140
bool roughlyEqual(const MetaDataSection &lhs, const MetaDataSection &rhs)
Checks if two MetaDataSection objects are roughly equal.
Definition iCSVHelper.cc:744
MetaDataSection & operator+=(MetaDataSection &lhs, const MetaDataSection &rhs)
Definition iCSVHelper.cc:784
bool operator!=(const geoLocation &lhs, const geoLocation &rhs)
Definition iCSVHelper.cc:687
bool operator==(const geoLocation &lhs, const geoLocation &rhs)
Definition iCSVHelper.cc:686
geoLocation toiCSVLocation(Coords loc, const int &epsg)
Definition iCSVHelper.cc:171
geoLocation extractCoordinates(const std::string &geometry)
Extracts a geoLocation object from a WKT geometry string.
Definition iCSVHelper.cc:188
Definition Config.cc:34
Stores information on the METADATA section of a iCSV file.
Definition iCSVHelper.h:102
std::string toString() const
Definition iCSVHelper.h:117
std::map< std::string, std::string > toOutputMap() const
Convert the metadata section to an output map.
Definition iCSVHelper.h:168
const std::vector< std::string > valid_delimiters
The valid delimiters.
Definition iCSVHelper.h:115
int epsg
The EPSG code.
Definition iCSVHelper.h:111
void setEPSG(const int &in_epsg)
Set the EPSG code and update the SRID.
Definition iCSVHelper.h:127
std::map< std::string, std::string > toMetaMap() const
Convert the metadata section to a map.
Definition iCSVHelper.h:151
std::string geometry
The geometry information.
Definition iCSVHelper.h:104
std::string field_delimiter
The field delimiter character (must be as string for libz).
Definition iCSVHelper.h:103
double nodata
The nodata value.
Definition iCSVHelper.h:109
std::string timestamp_meaning
The meaning of the timestamp.
Definition iCSVHelper.h:107
std::string station_id
The station identifier.
Definition iCSVHelper.h:106
double timezone
The timezone value.
Definition iCSVHelper.h:110
std::map< std::string, std::string > optional_metadata
The optional metadata.
Definition iCSVHelper.h:113
std::string getOptionalMetaData(const std::string &key) const
Get the value of an optional metadata field.
Definition iCSVHelper.h:138
std::string doi
The Digital Object Identifier.
Definition iCSVHelper.h:108
std::string srid
The spatial reference system identifier.
Definition iCSVHelper.h:105
Stores Information on the FIELDS section of a iCSV file.
Definition iCSVHelper.h:211
size_t getFieldIndex(const std::string &fieldname) const
Definition iCSVHelper.h:221
std::vector< double > units_offsets
Definition iCSVHelper.h:214
std::map< std::string, std::vector< std::string > > other_fields
Definition iCSVHelper.h:219
std::vector< std::string > units
Definition iCSVHelper.h:215
std::vector< double > units_multipliers
Definition iCSVHelper.h:213
std::vector< std::string > long_name
Definition iCSVHelper.h:216
std::vector< std::string > fields
Definition iCSVHelper.h:212
std::map< std::string, std::vector< std::string > > toMap() const
Definition iCSVHelper.h:236
std::vector< std::string > standard_name
Definition iCSVHelper.h:217
std::vector< std::string > getOtherFields(const std::string &key)
Definition iCSVHelper.h:229
Represents a geographic location extracted from iCSV files. (POINT(X Y)...)
Definition iCSVHelper.h:40
bool isEmpty() const
Checks if the geoLocation is empty.
Definition iCSVHelper.h:51
geoLocation & operator=(const geoLocation &rhs)
Definition iCSVHelper.cc:689
void standardizeNodata()
Definition iCSVHelper.h:65
double x
Definition iCSVHelper.h:41
std::string toString() const
Converts the geoLocation to a string representation.
Definition iCSVHelper.h:57
Coords toCoords(const int &epsg) const
Definition iCSVHelper.h:83
double slope_angle
Definition iCSVHelper.h:44
double slope_azi
Definition iCSVHelper.h:45
double z
Definition iCSVHelper.h:43
double y
Definition iCSVHelper.h:42