18#include <QtXml/QDomDocument>
20#include <rapidxml.hpp>
33 : XMLQtInterface(
"OpenGeoSysSTN.xsd"), _geo_objs(geo_objs)
39 if (XMLQtInterface::readFile(fileName) == 0)
44 QDomDocument doc(
"OGS-STN-DOM");
46 QDomElement docElement =
47 doc.documentElement();
48 if (docElement.nodeName().compare(
"OpenGeoSysSTN"))
50 ERR(
"XmlStnInterface::readFile(): Unexpected XML root.");
54 QDomNodeList lists = docElement.childNodes();
55 for (
int i = 0; i < lists.count(); i++)
58 QDomNodeList stationList = lists.at(i).childNodes();
59 std::vector<GeoLib::Point*> stations;
60 std::string stnName(
"[NN]");
62 for (
int j = 0; j < stationList.count(); j++)
64 const QDomNode station_node(stationList.at(j));
65 const QString station_type(station_node.nodeName());
66 if (station_type.compare(
"name") == 0)
68 stnName = station_node.toElement().text().toStdString();
70 else if (station_type.compare(
"stations") == 0)
72 readStations(station_node, stations, fileName.toStdString());
74 else if (station_type.compare(
"boreholes") == 0)
76 readStations(station_node, stations, fileName.toStdString());
80 if (!stations.empty())
90 std::vector<GeoLib::Point*>& stations,
91 const std::string& station_file_name)
93 QDomElement station = stationsRoot.firstChildElement();
94 while (!station.isNull())
96 if (station.hasAttribute(
"id") && station.hasAttribute(
"x") &&
97 station.hasAttribute(
"y"))
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);
105 QDomNodeList stationFeatures = station.childNodes();
106 for (
int i = 0; i < stationFeatures.count(); i++)
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)
114 stationName = element_text.toStdString();
116 if (feature_name.compare(
"sensordata") == 0)
118 sensor_data_file_name = element_text.toStdString();
123 else if (feature_name.compare(
"value") == 0)
125 stationValue = element_text.toDouble();
127 else if (feature_name.compare(
"bdepth") == 0)
129 boreholeDepth = element_text.toDouble();
131 else if (feature_name.compare(
"bdate") == 0)
133 boreholeDate = element_text.toStdString();
138 double zVal = (station.hasAttribute(
"z"))
139 ? station.attribute(
"z").toDouble()
142 if (station.nodeName().compare(
"station") == 0)
146 station.attribute(
"y").toDouble(),
150 if (!sensor_data_file_name.empty())
153 station_file_name, sensor_data_file_name));
155 stations.push_back(s);
157 else if (station.nodeName().compare(
"borehole") == 0)
162 station.attribute(
"x").toDouble(),
163 station.attribute(
"y").toDouble(),
169 for (
int j = 0; j < stationFeatures.count(); j++)
171 if (stationFeatures.at(j).nodeName().compare(
"strat") == 0)
177 stations.push_back(s);
183 "XmlStnInterface::readStations(): Attribute missing in "
186 station = station.nextSiblingElement();
195 double depth_check((*borehole)[2]);
196 QDomElement horizon = stratRoot.firstChildElement();
197 while (!horizon.isNull())
199 if (horizon.hasAttribute(
"id") && horizon.hasAttribute(
"x") &&
200 horizon.hasAttribute(
"y") && horizon.hasAttribute(
"z"))
202 std::string horizonName(
"[NN]");
204 QDomNodeList horizonFeatures = horizon.childNodes();
205 for (
int i = 0; i < horizonFeatures.count(); i++)
207 if (horizonFeatures.at(i).nodeName().compare(
"name") == 0)
210 horizonFeatures.at(i).toElement().text().toStdString();
215 double depth(horizon.attribute(
"z").toDouble());
216 if (std::abs(depth - depth_check) >
217 std::numeric_limits<double>::
220 borehole->
addSoilLayer(horizon.attribute(
"x").toDouble(),
221 horizon.attribute(
"y").toDouble(),
229 "XmlStnInterface::readStratigraphy(): Skipped layer '{:s}' "
230 "in borehole '{:s}' because of thickness 0.0.",
231 horizonName, borehole->
getName());
237 "XmlStnInterface::readStratigraphy(): Attribute missing in "
240 horizon = horizon.nextSiblingElement();
248 ERR(
"XmlStnInterface::write(): No station list specified.");
252 out <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
254 out <<
"<?xml-stylesheet type=\"text/xsl\" "
255 "href=\"OpenGeoSysSTN.xsl\"?>\n\n";
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");
262 const std::vector<GeoLib::Point*>* stations(
264 bool const is_borehole =
267 doc.appendChild(root);
268 QDomElement stationListTag = doc.createElement(
"stationlist");
269 root.appendChild(stationListTag);
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);
280 bool useStationValue(
false);
283 std::size_t nStations(stations->size());
284 for (std::size_t i = 1; i < nStations; i++)
286 if ((
static_cast<GeoLib::Station*
>((*stations)[i])->getStationValue() -
287 sValue) < std::numeric_limits<double>::epsilon())
289 useStationValue =
true;
294 for (std::size_t i = 0; i < nStations; i++)
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>::max_digits10));
302 stationTag.setAttribute(
303 "y", QString::number((*(*stations)[i])[1],
'f',
304 std::numeric_limits<double>::max_digits10));
305 stationTag.setAttribute(
306 "z", QString::number((*(*stations)[i])[2],
'f',
307 std::numeric_limits<double>::max_digits10));
308 stationsTag.appendChild(stationTag);
310 QDomElement stationNameTag = doc.createElement(
"name");
311 stationTag.appendChild(stationNameTag);
312 QDomText stationNameText = doc.createTextNode(QString::fromStdString(
314 stationNameTag.appendChild(stationNameText);
318 QDomElement stationValueTag = doc.createElement(
"value");
319 stationTag.appendChild(stationValueTag);
320 QDomText stationValueText = doc.createTextNode(
322 ->getStationValue()));
323 stationValueTag.appendChild(stationValueText);
334 std::string xml = doc.toString().toStdString();
340 QDomElement& boreholeTag,
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)
350 QDomElement stationDateTag = doc.createElement(
"bdate");
351 boreholeTag.appendChild(stationDateTag);
352 QDomText stationDateText = doc.createTextNode(
354 stationDateTag.appendChild(stationDateText);
357 std::vector<GeoLib::Point*> profile = borehole->
getProfile();
358 std::vector<std::string> soilNames = borehole->
getSoilNames();
359 std::size_t nHorizons(profile.size());
363 QDomElement stratTag = doc.createElement(
"strat");
364 boreholeTag.appendChild(stratTag);
366 for (std::size_t j = 1; j < nHorizons;
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);
Definition of the GEOObjects class.
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition of the StationBorehole class.
Definition of the XmlStnInterface class.
std::ostringstream out
The stream to write to.
QByteArray const & getContent() const
Container class for geometric objects.
void addStationVec(std::vector< Point * > &&stations, std::string &name)
Adds a vector of stations with the given name and colour to GEOObjects.
const std::vector< GeoLib::Point * > * getStationVec(const std::string &name) const
Returns the station vector with the given name.
void readStratigraphy(const QDomNode &stratRoot, GeoLib::StationBorehole *borehole)
Reads the stratigraphy of a borehole from an xml-file.
bool write() override
Writes the object to the internal stream. This method must be implemented by a subclass....
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.
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 (...
void writeBoreholeData(QDomDocument &doc, QDomElement &boreholeTag, GeoLib::StationBorehole *borehole) const
Writes borehole-specific data to a station-xml-file.
GeoLib::GEOObjects & _geo_objs
A borehole as a geometric object.
const std::vector< std::string > & getSoilNames() const
double getDate() const
Returns the date entry for the borehole.
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.
void addSoilLayer(double thickness, const std::string &soil_name)
Add a soil layer to the boreholes stratigraphy.
const std::vector< Point * > & getProfile() const
A Station (observation site) is basically a Point with some additional information.
void addSensorDataFromCSV(const std::string &file_name)
Allows to add sensor data from a CSV file to the observation site.
std::string const & getName() const
Returns the name of the station.
void setStationValue(double station_value)
std::string date2string(double ddate)
std::string joinPaths(std::string const &pathA, std::string const &pathB)