OGS
GeoLib::IO::XmlStnInterface Class Referencefinal

Detailed Description

Reads and writes Observation Sites to and from XML files.

Definition at line 33 of file XmlStnInterface.h.

#include <XmlStnInterface.h>

Inheritance diagram for GeoLib::IO::XmlStnInterface:
[legend]
Collaboration diagram for GeoLib::IO::XmlStnInterface:
[legend]

Public Member Functions

 XmlStnInterface (GeoLib::GEOObjects &geo_objs)
 
int readFile (const QString &fileName) override
 Reads an xml-file containing station object definitions into the GEOObjects used in the constructor (requires Qt)
 
bool readFile (std::string const &fname) override
 
- Public Member Functions inherited from BaseLib::IO::Writer
 Writer ()
 
virtual ~Writer ()=default
 
std::string writeToString ()
 Writes the object to a string.
 
- Public Member Functions inherited from BaseLib::IO::XMLQtInterface
 XMLQtInterface (QString schemaFile="")
 
virtual ~XMLQtInterface ()=default
 

Protected Member Functions

bool write () override
 Writes the object to the internal stream. This method must be implemented by a subclass. The implementation should return true on success, else false.
 
- Protected Member Functions inherited from BaseLib::IO::XMLQtInterface
bool checkHash () const
 
QByteArray const & getContent () const
 

Private Member Functions

void readStations (const QDomNode &stationsRoot, std::vector< GeoLib::Point * > &stations, const std::string &station_file_name)
 Reads GeoLib::Station- or StationBorehole-objects from an xml-file.
 
void writeBoreholeData (QDomDocument &doc, QDomElement &boreholeTag, GeoLib::StationBorehole *borehole) const
 Writes borehole-specific data to a station-xml-file.
 
void readStratigraphy (const QDomNode &stratRoot, GeoLib::StationBorehole *borehole)
 Reads the stratigraphy of a borehole from an xml-file.
 

Private Attributes

GeoLib::GEOObjects_geo_objs
 

Additional Inherited Members

- Public Attributes inherited from BaseLib::IO::XMLInterface
std::string export_name = {}
 
- Protected Attributes inherited from BaseLib::IO::Writer
std::ostringstream out
 The stream to write to.
 

Constructor & Destructor Documentation

◆ XmlStnInterface()

GeoLib::IO::XmlStnInterface::XmlStnInterface ( GeoLib::GEOObjects & geo_objs)
explicit

Definition at line 32 of file XmlStnInterface.cpp.

33 : XMLQtInterface("OpenGeoSysSTN.xsd"), _geo_objs(geo_objs)
34{
35}
XMLQtInterface(QString schemaFile="")
GeoLib::GEOObjects & _geo_objs

Member Function Documentation

◆ readFile() [1/2]

int GeoLib::IO::XmlStnInterface::readFile ( const QString & fileName)
overridevirtual

Reads an xml-file containing station object definitions into the GEOObjects used in the constructor (requires Qt)

Reimplemented from BaseLib::IO::XMLQtInterface.

Definition at line 37 of file XmlStnInterface.cpp.

38{
39 if (XMLQtInterface::readFile(fileName) == 0)
40 {
41 return 0;
42 }
43
44 QDomDocument doc("OGS-STN-DOM");
45 doc.setContent(getContent());
46 QDomElement docElement =
47 doc.documentElement(); // root element, used for identifying file-type
48 if (docElement.nodeName().compare("OpenGeoSysSTN"))
49 {
50 ERR("XmlStnInterface::readFile(): Unexpected XML root.");
51 return 0;
52 }
53
54 QDomNodeList lists = docElement.childNodes();
55 for (int i = 0; i < lists.count(); i++)
56 {
57 // read all the station lists
58 QDomNodeList stationList = lists.at(i).childNodes();
59 std::vector<GeoLib::Point*> stations;
60 std::string stnName("[NN]");
61
62 for (int j = 0; j < stationList.count(); j++)
63 {
64 const QDomNode station_node(stationList.at(j));
65 const QString station_type(station_node.nodeName());
66 if (station_type.compare("name") == 0)
67 {
68 stnName = station_node.toElement().text().toStdString();
69 }
70 else if (station_type.compare("stations") == 0)
71 {
72 readStations(station_node, stations, fileName.toStdString());
73 }
74 else if (station_type.compare("boreholes") == 0)
75 {
76 readStations(station_node, stations, fileName.toStdString());
77 }
78 }
79
80 if (!stations.empty())
81 {
82 _geo_objs.addStationVec(std::move(stations), stnName);
83 }
84 }
85
86 return 1;
87}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
QByteArray const & getContent() const
void addStationVec(std::vector< Point * > &&stations, std::string &name)
Adds a vector of stations with the given name and colour to GEOObjects.
void readStations(const QDomNode &stationsRoot, std::vector< GeoLib::Point * > &stations, const std::string &station_file_name)
Reads GeoLib::Station- or StationBorehole-objects from an xml-file.

References _geo_objs, GeoLib::GEOObjects::addStationVec(), ERR(), BaseLib::IO::XMLQtInterface::getContent(), and readStations().

Referenced by MainWindow::loadFile(), FileIO::XmlPrjInterface::readFile(), and readFile().

◆ readFile() [2/2]

bool GeoLib::IO::XmlStnInterface::readFile ( std::string const & fname)
inlineoverridevirtual

Implements BaseLib::IO::XMLInterface.

Definition at line 42 of file XmlStnInterface.h.

43 {
44 return readFile(QString(fname.c_str())) != 0;
45 }
int readFile(const QString &fileName) override
Reads an xml-file containing station object definitions into the GEOObjects used in the constructor (...

References readFile().

◆ readStations()

void GeoLib::IO::XmlStnInterface::readStations ( const QDomNode & stationsRoot,
std::vector< GeoLib::Point * > & stations,
const std::string & station_file_name )
private

Reads GeoLib::Station- or StationBorehole-objects from an xml-file.

Definition at line 89 of file XmlStnInterface.cpp.

92{
93 QDomElement station = stationsRoot.firstChildElement();
94 while (!station.isNull())
95 {
96 if (station.hasAttribute("id") && station.hasAttribute("x") &&
97 station.hasAttribute("y"))
98 {
99 std::string stationName("[NN]");
100 std::string sensor_data_file_name;
101 std::string boreholeDate("0000-00-00");
102 double boreholeDepth(0.0);
103 double stationValue(0.0);
104
105 QDomNodeList stationFeatures = station.childNodes();
106 for (int i = 0; i < stationFeatures.count(); i++)
107 {
108 // check for general station features
109 const QDomNode feature_node(stationFeatures.at(i));
110 const QString feature_name(feature_node.nodeName());
111 const QString element_text(feature_node.toElement().text());
112 if (feature_name.compare("name") == 0)
113 {
114 stationName = element_text.toStdString();
115 }
116 if (feature_name.compare("sensordata") == 0)
117 {
118 sensor_data_file_name = element_text.toStdString();
119 /* add other station features here */
120
121 // check for general borehole features
122 }
123 else if (feature_name.compare("value") == 0)
124 {
125 stationValue = element_text.toDouble();
126 }
127 else if (feature_name.compare("bdepth") == 0)
128 {
129 boreholeDepth = element_text.toDouble();
130 }
131 else if (feature_name.compare("bdate") == 0)
132 {
133 boreholeDate = element_text.toStdString();
134 }
135 /* add other borehole features here */
136 }
137
138 double zVal = (station.hasAttribute("z"))
139 ? station.attribute("z").toDouble()
140 : 0.0;
141
142 if (station.nodeName().compare("station") == 0)
143 {
144 GeoLib::Station* s =
145 new GeoLib::Station(station.attribute("x").toDouble(),
146 station.attribute("y").toDouble(),
147 zVal,
148 stationName);
149 s->setStationValue(stationValue);
150 if (!sensor_data_file_name.empty())
151 {
153 sensor_data_file_name, station_file_name));
154 }
155 stations.push_back(s);
156 }
157 else if (station.nodeName().compare("borehole") == 0)
158 {
161 stationName,
162 station.attribute("x").toDouble(),
163 station.attribute("y").toDouble(),
164 zVal,
165 boreholeDepth,
166 boreholeDate);
167 s->setStationValue(stationValue);
168 /* add stratigraphy to the borehole */
169 for (int j = 0; j < stationFeatures.count(); j++)
170 {
171 if (stationFeatures.at(j).nodeName().compare("strat") == 0)
172 {
173 this->readStratigraphy(stationFeatures.at(j), s);
174 }
175 }
176
177 stations.push_back(s);
178 }
179 }
180 else
181 {
182 WARN(
183 "XmlStnInterface::readStations(): Attribute missing in "
184 "<station> tag.");
185 }
186 station = station.nextSiblingElement();
187 }
188}
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void readStratigraphy(const QDomNode &stratRoot, GeoLib::StationBorehole *borehole)
Reads the stratigraphy of a borehole from an xml-file.
A borehole as a geometric object.
static StationBorehole * createStation(const std::string &name, double x, double y, double z, double depth, const std::string &date="")
Creates a new borehole object based on the given parameters.
A Station (observation site) is basically a Point with some additional information.
Definition Station.h:37
void addSensorDataFromCSV(const std::string &file_name)
Allows to add sensor data from a CSV file to the observation site.
Definition Station.h:83
void setStationValue(double station_value)
Definition Station.h:77
std::string copyPathToFileName(const std::string &file_name, const std::string &source)

References GeoLib::Station::addSensorDataFromCSV(), BaseLib::copyPathToFileName(), GeoLib::StationBorehole::createStation(), readStratigraphy(), GeoLib::Station::setStationValue(), and WARN().

Referenced by readFile().

◆ readStratigraphy()

void GeoLib::IO::XmlStnInterface::readStratigraphy ( const QDomNode & stratRoot,
GeoLib::StationBorehole * borehole )
private

Reads the stratigraphy of a borehole from an xml-file.

Definition at line 190 of file XmlStnInterface.cpp.

192{
193 // borehole->addSoilLayer((*borehole)[0], (*borehole)[1], (*borehole)[2],
194 // "");
195 double depth_check((*borehole)[2]);
196 QDomElement horizon = stratRoot.firstChildElement();
197 while (!horizon.isNull())
198 {
199 if (horizon.hasAttribute("id") && horizon.hasAttribute("x") &&
200 horizon.hasAttribute("y") && horizon.hasAttribute("z"))
201 {
202 std::string horizonName("[NN]");
203
204 QDomNodeList horizonFeatures = horizon.childNodes();
205 for (int i = 0; i < horizonFeatures.count(); i++)
206 {
207 if (horizonFeatures.at(i).nodeName().compare("name") == 0)
208 {
209 horizonName =
210 horizonFeatures.at(i).toElement().text().toStdString();
211 }
212 }
213 /* add other horizon features here */
214
215 double depth(horizon.attribute("z").toDouble());
216 if (std::abs(depth - depth_check) >
217 std::numeric_limits<double>::
218 epsilon()) // skip soil-layer if its thickness is zero
219 {
220 borehole->addSoilLayer(horizon.attribute("x").toDouble(),
221 horizon.attribute("y").toDouble(),
222 depth,
223 horizonName);
224 depth_check = depth;
225 }
226 else
227 {
228 WARN(
229 "XmlStnInterface::readStratigraphy(): Skipped layer '{:s}' "
230 "in borehole '{:s}' because of thickness 0.0.",
231 horizonName, borehole->getName());
232 }
233 }
234 else
235 {
236 WARN(
237 "XmlStnInterface::readStratigraphy(): Attribute missing in "
238 "<horizon> tag.");
239 }
240 horizon = horizon.nextSiblingElement();
241 }
242}
void addSoilLayer(double thickness, const std::string &soil_name)
Add a soil layer to the boreholes stratigraphy.
std::string const & getName() const
Returns the name of the station.
Definition Station.h:60

References GeoLib::StationBorehole::addSoilLayer(), GeoLib::Station::getName(), and WARN().

Referenced by readStations().

◆ write()

bool GeoLib::IO::XmlStnInterface::write ( )
overrideprotectedvirtual

Writes the object to the internal stream. This method must be implemented by a subclass. The implementation should return true on success, else false.

Implements BaseLib::IO::Writer.

Definition at line 244 of file XmlStnInterface.cpp.

245{
246 if (export_name.empty())
247 {
248 ERR("XmlStnInterface::write(): No station list specified.");
249 return false;
250 }
251
252 out << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml
253 // definition
254 out << "<?xml-stylesheet type=\"text/xsl\" "
255 "href=\"OpenGeoSysSTN.xsl\"?>\n\n"; // stylefile definition
256
257 QDomDocument doc("OGS-STN-DOM");
258 QDomElement root = doc.createElement("OpenGeoSysSTN");
259 root.setAttribute("xmlns:ogs", "http://www.opengeosys.org");
260 root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
261
262 const std::vector<GeoLib::Point*>* stations(
264 bool const is_borehole =
265 dynamic_cast<GeoLib::StationBorehole*>((*stations)[0]);
266
267 doc.appendChild(root);
268 QDomElement stationListTag = doc.createElement("stationlist");
269 root.appendChild(stationListTag);
270
271 QDomElement listNameTag = doc.createElement("name");
272 stationListTag.appendChild(listNameTag);
273 QDomText stationListNameText =
274 doc.createTextNode(QString::fromStdString(export_name));
275 listNameTag.appendChild(stationListNameText);
276 QString listType = is_borehole ? "boreholes" : "stations";
277 QDomElement stationsTag = doc.createElement(listType);
278 stationListTag.appendChild(stationsTag);
279
280 bool useStationValue(false);
281 double sValue =
282 static_cast<GeoLib::Station*>((*stations)[0])->getStationValue();
283 std::size_t nStations(stations->size());
284 for (std::size_t i = 1; i < nStations; i++)
285 {
286 if ((static_cast<GeoLib::Station*>((*stations)[i])->getStationValue() -
287 sValue) < std::numeric_limits<double>::epsilon())
288 {
289 useStationValue = true;
290 break;
291 }
292 }
293
294 for (std::size_t i = 0; i < nStations; i++)
295 {
296 QString stationType = is_borehole ? "borehole" : "station";
297 QDomElement stationTag = doc.createElement(stationType);
298 stationTag.setAttribute("id", QString::number(i));
299 stationTag.setAttribute(
300 "x", QString::number((*(*stations)[i])[0], 'f',
301 std::numeric_limits<double>::digits10));
302 stationTag.setAttribute(
303 "y", QString::number((*(*stations)[i])[1], 'f',
304 std::numeric_limits<double>::digits10));
305 stationTag.setAttribute(
306 "z", QString::number((*(*stations)[i])[2], 'f',
307 std::numeric_limits<double>::digits10));
308 stationsTag.appendChild(stationTag);
309
310 QDomElement stationNameTag = doc.createElement("name");
311 stationTag.appendChild(stationNameTag);
312 QDomText stationNameText = doc.createTextNode(QString::fromStdString(
313 static_cast<GeoLib::Station*>((*stations)[i])->getName()));
314 stationNameTag.appendChild(stationNameText);
315
316 if (useStationValue)
317 {
318 QDomElement stationValueTag = doc.createElement("value");
319 stationTag.appendChild(stationValueTag);
320 QDomText stationValueText = doc.createTextNode(
321 QString::number(static_cast<GeoLib::Station*>((*stations)[i])
322 ->getStationValue()));
323 stationValueTag.appendChild(stationValueText);
324 }
325
326 if (is_borehole)
327 {
329 doc, stationTag,
330 static_cast<GeoLib::StationBorehole*>((*stations)[i]));
331 }
332 }
333
334 std::string xml = doc.toString().toStdString();
335 out << xml;
336 return true;
337}
std::string getName(std::string const &line)
Returns the name/title from the "Zone"-description.
std::ostringstream out
The stream to write to.
Definition Writer.h:47
const std::vector< GeoLib::Point * > * getStationVec(const std::string &name) const
Returns the station vector with the given name.
void writeBoreholeData(QDomDocument &doc, QDomElement &boreholeTag, GeoLib::StationBorehole *borehole) const
Writes borehole-specific data to a station-xml-file.

References _geo_objs, ERR(), BaseLib::IO::XMLInterface::export_name, getName(), GeoLib::GEOObjects::getStationVec(), BaseLib::IO::Writer::out, and writeBoreholeData().

◆ writeBoreholeData()

void GeoLib::IO::XmlStnInterface::writeBoreholeData ( QDomDocument & doc,
QDomElement & boreholeTag,
GeoLib::StationBorehole * borehole ) const
private

Writes borehole-specific data to a station-xml-file.

the first entry in the profile vector is just the position of the borehole

Definition at line 339 of file XmlStnInterface.cpp.

342{
343 QDomElement stationDepthTag = doc.createElement("bdepth");
344 boreholeTag.appendChild(stationDepthTag);
345 QDomText stationDepthText =
346 doc.createTextNode(QString::number(borehole->getDepth(), 'f'));
347 stationDepthTag.appendChild(stationDepthText);
348 if (std::abs(borehole->getDate()) > 0)
349 {
350 QDomElement stationDateTag = doc.createElement("bdate");
351 boreholeTag.appendChild(stationDateTag);
352 QDomText stationDateText = doc.createTextNode(
353 QString::fromStdString(BaseLib::date2string(borehole->getDate())));
354 stationDateTag.appendChild(stationDateText);
355 }
356
357 std::vector<GeoLib::Point*> profile = borehole->getProfile();
358 std::vector<std::string> soilNames = borehole->getSoilNames();
359 std::size_t nHorizons(profile.size());
360
361 if (nHorizons > 1)
362 {
363 QDomElement stratTag = doc.createElement("strat");
364 boreholeTag.appendChild(stratTag);
365
366 for (std::size_t j = 1; j < nHorizons;
367 j++)
369 {
370 QDomElement horizonTag = doc.createElement("horizon");
371 horizonTag.setAttribute("id", QString::number(j));
372 horizonTag.setAttribute("x",
373 QString::number((*profile[j])[0], 'f'));
374 horizonTag.setAttribute("y",
375 QString::number((*profile[j])[1], 'f'));
376 horizonTag.setAttribute("z",
377 QString::number((*profile[j])[2], 'f'));
378 stratTag.appendChild(horizonTag);
379 QDomElement horizonNameTag = doc.createElement("name");
380 horizonTag.appendChild(horizonNameTag);
381 QDomText horizonNameText =
382 doc.createTextNode(QString::fromStdString(soilNames[j]));
383 horizonNameTag.appendChild(horizonNameText);
384 }
385 }
386}
const std::vector< std::string > & getSoilNames() const
double getDate() const
Returns the date entry for the borehole.
const std::vector< Point * > & getProfile() const
std::string date2string(double ddate)
Definition DateTools.cpp:65

References BaseLib::date2string(), GeoLib::StationBorehole::getDate(), GeoLib::StationBorehole::getDepth(), GeoLib::StationBorehole::getProfile(), and GeoLib::StationBorehole::getSoilNames().

Referenced by write().

Member Data Documentation

◆ _geo_objs

GeoLib::GEOObjects& GeoLib::IO::XmlStnInterface::_geo_objs
private

Definition at line 64 of file XmlStnInterface.h.

Referenced by readFile(), and write().


The documentation for this class was generated from the following files: