18 #include <QtXml/QDomDocument>
20 #include <rapidxml.hpp>
33 : XMLQtInterface(
"OpenGeoSysSTN.xsd"), _geo_objs(geo_objs)
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 auto stations = std::make_unique<std::vector<GeoLib::Point*>>();
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)
73 fileName.toStdString());
75 else if (station_type.compare(
"boreholes") == 0)
78 fileName.toStdString());
82 if (!stations->empty())
92 std::vector<GeoLib::Point*>* stations,
93 const std::string& station_file_name)
95 QDomElement station = stationsRoot.firstChildElement();
96 while (!station.isNull())
98 if (station.hasAttribute(
"id") && station.hasAttribute(
"x") &&
99 station.hasAttribute(
"y"))
101 std::string stationName(
"[NN]");
102 std::string sensor_data_file_name;
103 std::string boreholeDate(
"0000-00-00");
104 double boreholeDepth(0.0);
105 double stationValue(0.0);
107 QDomNodeList stationFeatures = station.childNodes();
108 for (
int i = 0; i < stationFeatures.count(); i++)
111 const QDomNode feature_node(stationFeatures.at(i));
112 const QString feature_name(feature_node.nodeName());
113 const QString element_text(feature_node.toElement().text());
114 if (feature_name.compare(
"name") == 0)
116 stationName = element_text.toStdString();
118 if (feature_name.compare(
"sensordata") == 0)
120 sensor_data_file_name = element_text.toStdString();
125 else if (feature_name.compare(
"value") == 0)
127 stationValue = element_text.toDouble();
129 else if (feature_name.compare(
"bdepth") == 0)
131 boreholeDepth = element_text.toDouble();
133 else if (feature_name.compare(
"bdate") == 0)
135 boreholeDate = element_text.toStdString();
140 double zVal = (station.hasAttribute(
"z"))
141 ? station.attribute(
"z").toDouble()
144 if (station.nodeName().compare(
"station") == 0)
148 station.attribute(
"y").toDouble(),
152 if (!sensor_data_file_name.empty())
155 sensor_data_file_name, station_file_name));
157 stations->push_back(s);
159 else if (station.nodeName().compare(
"borehole") == 0)
164 station.attribute(
"x").toDouble(),
165 station.attribute(
"y").toDouble(),
171 for (
int j = 0; j < stationFeatures.count(); j++)
173 if (stationFeatures.at(j).nodeName().compare(
"strat") == 0)
179 stations->push_back(s);
185 "XmlStnInterface::readStations(): Attribute missing in "
188 station = station.nextSiblingElement();
197 double depth_check((*borehole)[2]);
198 QDomElement horizon = stratRoot.firstChildElement();
199 while (!horizon.isNull())
201 if (horizon.hasAttribute(
"id") && horizon.hasAttribute(
"x") &&
202 horizon.hasAttribute(
"y") && horizon.hasAttribute(
"z"))
204 std::string horizonName(
"[NN]");
206 QDomNodeList horizonFeatures = horizon.childNodes();
207 for (
int i = 0; i < horizonFeatures.count(); i++)
209 if (horizonFeatures.at(i).nodeName().compare(
"name") == 0)
212 horizonFeatures.at(i).toElement().text().toStdString();
217 double depth(horizon.attribute(
"z").toDouble());
218 if (std::abs(depth - depth_check) >
219 std::numeric_limits<double>::
222 borehole->
addSoilLayer(horizon.attribute(
"x").toDouble(),
223 horizon.attribute(
"y").toDouble(),
231 "XmlStnInterface::readStratigraphy(): Skipped layer '{:s}' "
232 "in borehole '{:s}' because of thickness 0.0.",
233 horizonName, borehole->
getName());
239 "XmlStnInterface::readStratigraphy(): Attribute missing in "
242 horizon = horizon.nextSiblingElement();
250 ERR(
"XmlStnInterface::write(): No station list specified.");
254 out <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
256 out <<
"<?xml-stylesheet type=\"text/xsl\" "
257 "href=\"OpenGeoSysSTN.xsl\"?>\n\n";
259 QDomDocument doc(
"OGS-STN-DOM");
260 QDomElement root = doc.createElement(
"OpenGeoSysSTN");
261 root.setAttribute(
"xmlns:ogs",
"http://www.opengeosys.org");
262 root.setAttribute(
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
264 const std::vector<GeoLib::Point*>* stations(
266 bool const is_borehole =
269 doc.appendChild(root);
270 QDomElement stationListTag = doc.createElement(
"stationlist");
271 root.appendChild(stationListTag);
273 QDomElement listNameTag = doc.createElement(
"name");
274 stationListTag.appendChild(listNameTag);
275 QDomText stationListNameText =
276 doc.createTextNode(QString::fromStdString(
export_name));
277 listNameTag.appendChild(stationListNameText);
278 QString listType = is_borehole ?
"boreholes" :
"stations";
279 QDomElement stationsTag = doc.createElement(listType);
280 stationListTag.appendChild(stationsTag);
282 bool useStationValue(
false);
285 std::size_t nStations(stations->size());
286 for (std::size_t i = 1; i < nStations; i++)
288 if ((
static_cast<GeoLib::Station*
>((*stations)[i])->getStationValue() -
289 sValue) < std::numeric_limits<double>::epsilon())
291 useStationValue =
true;
296 for (std::size_t i = 0; i < nStations; i++)
298 QString stationType = is_borehole ?
"borehole" :
"station";
299 QDomElement stationTag = doc.createElement(stationType);
300 stationTag.setAttribute(
"id", QString::number(i));
301 stationTag.setAttribute(
302 "x", QString::number((*(*stations)[i])[0],
'f',
303 std::numeric_limits<double>::digits10));
304 stationTag.setAttribute(
305 "y", QString::number((*(*stations)[i])[1],
'f',
306 std::numeric_limits<double>::digits10));
307 stationTag.setAttribute(
308 "z", QString::number((*(*stations)[i])[2],
'f',
309 std::numeric_limits<double>::digits10));
310 stationsTag.appendChild(stationTag);
312 QDomElement stationNameTag = doc.createElement(
"name");
313 stationTag.appendChild(stationNameTag);
314 QDomText stationNameText = doc.createTextNode(QString::fromStdString(
316 stationNameTag.appendChild(stationNameText);
320 QDomElement stationValueTag = doc.createElement(
"value");
321 stationTag.appendChild(stationValueTag);
322 QDomText stationValueText = doc.createTextNode(
324 ->getStationValue()));
325 stationValueTag.appendChild(stationValueText);
336 std::string xml = doc.toString().toStdString();
342 QDomElement& boreholeTag,
345 QDomElement stationDepthTag = doc.createElement(
"bdepth");
346 boreholeTag.appendChild(stationDepthTag);
347 QDomText stationDepthText =
348 doc.createTextNode(QString::number(borehole->
getDepth(),
'f'));
349 stationDepthTag.appendChild(stationDepthText);
350 if (std::abs(borehole->
getDate()) > 0)
352 QDomElement stationDateTag = doc.createElement(
"bdate");
353 boreholeTag.appendChild(stationDateTag);
354 QDomText stationDateText = doc.createTextNode(
356 stationDateTag.appendChild(stationDateText);
359 std::vector<GeoLib::Point*> profile = borehole->
getProfile();
360 std::vector<std::string> soilNames = borehole->
getSoilNames();
361 std::size_t nHorizons(profile.size());
365 QDomElement stratTag = doc.createElement(
"strat");
366 boreholeTag.appendChild(stratTag);
368 for (std::size_t j = 1; j < nHorizons;
372 QDomElement horizonTag = doc.createElement(
"horizon");
373 horizonTag.setAttribute(
"id", QString::number(j));
374 horizonTag.setAttribute(
"x",
375 QString::number((*profile[j])[0],
'f'));
376 horizonTag.setAttribute(
"y",
377 QString::number((*profile[j])[1],
'f'));
378 horizonTag.setAttribute(
"z",
379 QString::number((*profile[j])[2],
'f'));
380 stratTag.appendChild(horizonTag);
381 QDomElement horizonNameTag = doc.createElement(
"name");
382 horizonTag.appendChild(horizonNameTag);
383 QDomText horizonNameText =
384 doc.createTextNode(QString::fromStdString(soilNames[j]));
385 horizonNameTag.appendChild(horizonNameText);
Definition of the GEOObjects class.
void ERR(char const *fmt, Args const &... args)
void WARN(char const *fmt, Args const &... 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::unique_ptr< 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....
XmlStnInterface(GeoLib::GEOObjects &geo_objs)
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.
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.
double getDate() const
Returns the date entry for the borehole.
const std::vector< std::string > & getSoilNames() const
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)
Allows to set a specific value for this station (e.g. for classification)
std::string date2string(double ddate)
std::string copyPathToFileName(const std::string &file_name, const std::string &source)
bool readFile(std::string const &file_name, std::vector< std::unique_ptr< MeshLib::Mesh >> &meshes, DataType const export_type)
Reads the specified file and writes data into internal mesh vector.