OGS
GeoLib::IO::XmlGmlInterface Class Referencefinal

Detailed Description

Reads and writes GeoObjects to and from XML files.

Definition at line 32 of file XmlGmlInterface.h.

#include <XmlGmlInterface.h>

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

Public Member Functions

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

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. More...
 
virtual bool write ()=0
 Writes the object to the internal stream. This method must be implemented by a subclass. The implementation should return true on success, else false. More...
 
- Protected Member Functions inherited from BaseLib::IO::XMLQtInterface
bool checkHash () const
 
QByteArray const & getContent () const
 

Private Member Functions

void readPoints (const QDomNode &pointsRoot, std::vector< GeoLib::Point * > &points, std::map< std::string, std::size_t > *pnt_names)
 Reads GeoLib::Point-objects from an xml-file. More...
 
void readPolylines (const QDomNode &polylinesRoot, std::vector< GeoLib::Polyline * > &polylines, std::vector< GeoLib::Point * > const &points, const std::vector< std::size_t > &pnt_id_map, GeoLib::PolylineVec::NameIdMap &ply_names)
 Reads GeoLib::Polyline-objects from an xml-file. More...
 
void readSurfaces (const QDomNode &surfacesRoot, std::vector< GeoLib::Surface * > &surfaces, std::vector< GeoLib::Point * > const &points, const std::vector< std::size_t > &pnt_id_map, GeoLib::SurfaceVec::NameIdMap &sfc_names)
 Reads GeoLib::Surface-objects from an xml-file. More...
 

Private Attributes

GeoLib::GEOObjects_geo_objs
 
std::map< std::size_t, std::size_t > _idx_map
 

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. More...
 

Constructor & Destructor Documentation

◆ XmlGmlInterface()

GeoLib::IO::XmlGmlInterface::XmlGmlInterface ( GeoLib::GEOObjects geo_objs)
explicit

Definition at line 28 of file XmlGmlInterface.cpp.

29 : XMLQtInterface("OpenGeoSysGLI.xsd"), _geo_objs(geo_objs)
30{
31}
XMLQtInterface(QString schemaFile="")
GeoLib::GEOObjects & _geo_objs

Member Function Documentation

◆ readFile() [1/2]

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

Reads an xml-file containing geometric object definitions into the GEOObjects used in the constructor.

Reimplemented from BaseLib::IO::XMLQtInterface.

Definition at line 33 of file XmlGmlInterface.cpp.

34{
35 if (XMLQtInterface::readFile(fileName) == 0)
36 {
37 return 0;
38 }
39
40 QDomDocument doc("OGS-GLI-DOM");
41 doc.setContent(getContent());
42 QDomElement docElement = doc.documentElement(); // OpenGeoSysGLI
43 if (docElement.nodeName().compare("OpenGeoSysGLI"))
44 {
45 ERR("XmlGmlInterface::readFile() - Unexpected XML root.");
46 return 0;
47 }
48
49 std::string gliName("[NN]");
50
51 std::vector<GeoLib::Point*> points;
52 std::vector<GeoLib::Polyline*> polylines;
53 std::vector<GeoLib::Surface*> surfaces;
54
58
59 QDomNodeList geoTypes = docElement.childNodes();
60 for (int i = 0; i < geoTypes.count(); i++)
61 {
62 const QDomNode type_node(geoTypes.at(i));
63 const QString nodeName = type_node.nodeName();
64 if (nodeName.compare("name") == 0)
65 {
66 if (type_node.toElement().text().isEmpty())
67 {
68 ERR("XmlGmlInterface::readFile(): <name>-tag is empty.");
69 BaseLib::cleanupVectorElements(surfaces, polylines, points);
70 return 0;
71 }
72
73 gliName = type_node.toElement().text().toStdString();
74 }
75 else if (nodeName.compare("points") == 0)
76 {
77 readPoints(type_node, points, &pnt_names);
78 _geo_objs.addPointVec(std::move(points), gliName,
79 std::move(pnt_names));
80 }
81 else if (nodeName.compare("polylines") == 0)
82 {
83 try
84 {
86 type_node, polylines, *_geo_objs.getPointVec(gliName),
87 _geo_objs.getPointVecObj(gliName)->getIDMap(), ply_names);
88 }
89 catch (std::runtime_error const&)
90 {
91 // further reading is aborted and it is necessary to clean up
93 throw;
94 }
95 }
96 else if (nodeName.compare("surfaces") == 0)
97 {
98 try
99 {
101 type_node, surfaces, *_geo_objs.getPointVec(gliName),
102 _geo_objs.getPointVecObj(gliName)->getIDMap(), sfc_names);
103 }
104 catch (std::runtime_error const&)
105 {
106 // further reading is aborted and it is necessary to clean up
107 _geo_objs.removePointVec(gliName);
109 throw;
110 }
111 }
112 }
113
114 if (!polylines.empty())
115 {
116 _geo_objs.addPolylineVec(std::move(polylines), gliName,
117 std::move(ply_names));
118 }
119
120 if (!surfaces.empty())
121 {
122 _geo_objs.addSurfaceVec(std::move(surfaces), gliName,
123 std::move(sfc_names));
124 }
125 return 1;
126}
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:44
QByteArray const & getContent() const
void addPolylineVec(std::vector< Polyline * > &&lines, std::string const &name, PolylineVec::NameIdMap &&ply_names)
Definition: GEOObjects.cpp:152
const std::vector< Point * > * getPointVec(const std::string &name) const
Definition: GEOObjects.cpp:72
void addPointVec(std::vector< Point * > &&points, std::string &name, PointVec::NameIdMap &&pnt_id_name_map, double const eps=std::sqrt(std::numeric_limits< double >::epsilon()))
Definition: GEOObjects.cpp:47
const PointVec * getPointVecObj(const std::string &name) const
Definition: GEOObjects.cpp:85
bool removePointVec(const std::string &name)
Definition: GEOObjects.cpp:98
void addSurfaceVec(std::vector< Surface * > &&sfc, const std::string &name, SurfaceVec::NameIdMap &&sfc_names)
Definition: GEOObjects.cpp:240
bool removePolylineVec(const std::string &name)
Definition: GEOObjects.cpp:222
void readPoints(const QDomNode &pointsRoot, std::vector< GeoLib::Point * > &points, std::map< std::string, std::size_t > *pnt_names)
Reads GeoLib::Point-objects from an xml-file.
void readSurfaces(const QDomNode &surfacesRoot, std::vector< GeoLib::Surface * > &surfaces, std::vector< GeoLib::Point * > const &points, const std::vector< std::size_t > &pnt_id_map, GeoLib::SurfaceVec::NameIdMap &sfc_names)
Reads GeoLib::Surface-objects from an xml-file.
void readPolylines(const QDomNode &polylinesRoot, std::vector< GeoLib::Polyline * > &polylines, std::vector< GeoLib::Point * > const &points, const std::vector< std::size_t > &pnt_id_map, GeoLib::PolylineVec::NameIdMap &ply_names)
Reads GeoLib::Polyline-objects from an xml-file.
const std::vector< std::size_t > & getIDMap() const
Definition: PointVec.h:96
std::map< std::string, std::size_t > NameIdMap
Definition: TemplateVec.h:44
void cleanupVectorElements(std::vector< T * > &items)
Definition: Algorithm.h:300
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.

References _geo_objs, GeoLib::GEOObjects::addPointVec(), GeoLib::GEOObjects::addPolylineVec(), GeoLib::GEOObjects::addSurfaceVec(), BaseLib::cleanupVectorElements(), ERR(), BaseLib::IO::XMLQtInterface::getContent(), GeoLib::PointVec::getIDMap(), GeoLib::GEOObjects::getPointVec(), GeoLib::GEOObjects::getPointVecObj(), FileIO::Gocad::GocadAsciiReader::readFile(), readPoints(), readPolylines(), readSurfaces(), GeoLib::GEOObjects::removePointVec(), and GeoLib::GEOObjects::removePolylineVec().

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

◆ readFile() [2/2]

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

Implements BaseLib::IO::XMLInterface.

Definition at line 41 of file XmlGmlInterface.h.

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

References readFile().

◆ readPoints()

void GeoLib::IO::XmlGmlInterface::readPoints ( const QDomNode &  pointsRoot,
std::vector< GeoLib::Point * > &  points,
std::map< std::string, std::size_t > *  pnt_names 
)
private

Reads GeoLib::Point-objects from an xml-file.

Definition at line 128 of file XmlGmlInterface.cpp.

131{
132 char* pEnd;
133 QDomElement point = pointsRoot.firstChildElement();
134 while (!point.isNull())
135 {
136 _idx_map.insert(std::pair<std::size_t, std::size_t>(
137 strtol((point.attribute("id")).toStdString().c_str(), &pEnd, 10),
138 points.size()));
139 GeoLib::Point* p = new GeoLib::Point(point.attribute("x").toDouble(),
140 point.attribute("y").toDouble(),
141 point.attribute("z").toDouble(),
142 point.attribute("id").toInt());
143 if (point.hasAttribute("name"))
144 {
145 pnt_names->insert(std::pair<std::string, std::size_t>(
146 point.attribute("name").toStdString(), points.size()));
147 }
148
149 points.push_back(p);
150 point = point.nextSiblingElement();
151 }
152}
std::map< std::size_t, std::size_t > _idx_map
TemplateElement< PointRule1 > Point
Definition: Point.h:20

References _idx_map.

Referenced by readFile().

◆ readPolylines()

void GeoLib::IO::XmlGmlInterface::readPolylines ( const QDomNode &  polylinesRoot,
std::vector< GeoLib::Polyline * > &  polylines,
std::vector< GeoLib::Point * > const &  points,
const std::vector< std::size_t > &  pnt_id_map,
GeoLib::PolylineVec::NameIdMap ply_names 
)
private

Reads GeoLib::Polyline-objects from an xml-file.

Definition at line 154 of file XmlGmlInterface.cpp.

159{
160 QDomElement polyline = polylinesRoot.firstChildElement();
161 while (!polyline.isNull())
162 {
163 std::size_t const idx = polylines.size();
164 polylines.push_back(new GeoLib::Polyline(points));
165
166 if (polyline.hasAttribute("name"))
167 {
168 std::string const ply_name(
169 polyline.attribute("name").toStdString());
170 std::map<std::string, std::size_t>::const_iterator it(
171 ply_names.find(ply_name));
172 if (it == ply_names.end())
173 {
174 ply_names.insert(
175 std::pair<std::string, std::size_t>(ply_name, idx));
176 }
177 else
178 {
179 WARN(
180 "Polyline '{:s}' exists already. Polyline {:d} will be "
181 "inserted without a name.",
182 ply_name, idx);
183 }
184 }
185
186 QDomElement point = polyline.firstChildElement();
187 auto accessOrError = [this, &polyline](auto pt_idx)
188 {
189 auto search = _idx_map.find(pt_idx);
190 if (search == _idx_map.end())
191 {
192 std::string polyline_name;
193 if (polyline.hasAttribute("name"))
194 {
195 polyline_name = polyline.attribute("name").toStdString();
196 }
197 OGS_FATAL(
198 "Polyline `{:s}' contains the point id `{:d}' which is not "
199 "in the point list.",
200 polyline_name, pt_idx);
201 }
202 return search->second;
203 };
204
205 while (!point.isNull())
206 {
207 polylines[idx]->addPoint(
208 pnt_id_map[accessOrError(point.text().toInt())]);
209 point = point.nextSiblingElement();
210 }
211
212 polyline = polyline.nextSiblingElement();
213 }
214}
#define OGS_FATAL(...)
Definition: Error.h:26
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:39
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition: Polyline.h:42

References _idx_map, OGS_FATAL, and WARN().

Referenced by readFile().

◆ readSurfaces()

void GeoLib::IO::XmlGmlInterface::readSurfaces ( const QDomNode &  surfacesRoot,
std::vector< GeoLib::Surface * > &  surfaces,
std::vector< GeoLib::Point * > const &  points,
const std::vector< std::size_t > &  pnt_id_map,
GeoLib::SurfaceVec::NameIdMap sfc_names 
)
private

Reads GeoLib::Surface-objects from an xml-file.

Definition at line 216 of file XmlGmlInterface.cpp.

221{
222 QDomElement surface = surfacesRoot.firstChildElement();
223 while (!surface.isNull())
224 {
225 surfaces.push_back(new GeoLib::Surface(points));
226
227 if (surface.hasAttribute("name"))
228 {
229 sfc_names.insert(std::pair<std::string, std::size_t>(
230 surface.attribute("name").toStdString(), surfaces.size() - 1));
231 }
232
233 auto accessOrError = [this, &surface](auto pt_idx)
234 {
235 auto search = _idx_map.find(pt_idx);
236 if (search == _idx_map.end())
237 {
238 std::string surface_name;
239 if (surface.hasAttribute("name"))
240 {
241 surface_name = surface.attribute("name").toStdString();
242 }
243 OGS_FATAL(
244 "Surface `{:s}' contains the point id `{:d}', which is not "
245 "in the point list.",
246 surface_name, pt_idx);
247 }
248 return search->second;
249 };
250
251 QDomElement element = surface.firstChildElement();
252 while (!element.isNull())
253 {
254 std::size_t p1 =
255 pnt_id_map[accessOrError(element.attribute("p1").toInt())];
256 std::size_t p2 =
257 pnt_id_map[accessOrError(element.attribute("p2").toInt())];
258 std::size_t p3 =
259 pnt_id_map[accessOrError(element.attribute("p3").toInt())];
260 surfaces.back()->addTriangle(p1, p2, p3);
261 element = element.nextSiblingElement();
262 }
263
264 surface = surface.nextSiblingElement();
265 }
266}
A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points...
Definition: Surface.h:34

References _idx_map, and OGS_FATAL.

Referenced by readFile().

◆ write()

bool GeoLib::IO::XmlGmlInterface::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 267 of file XmlGmlInterface.cpp.

268{
269 if (export_name.empty())
270 {
271 ERR("XmlGmlInterface::write(): No geometry specified.");
272 return false;
273 }
274
275 out << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml
276 // definition
277
278 QDomDocument doc("OGS-GML-DOM");
279 QDomElement root = doc.createElement("OpenGeoSysGLI");
280 root.setAttribute("xmlns:ogs", "http://www.opengeosys.org");
281 root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
282
283 doc.appendChild(root);
284
285 QDomElement geoNameTag = doc.createElement("name");
286 root.appendChild(geoNameTag);
287 QDomText geoNameText =
288 doc.createTextNode(QString::fromStdString(export_name));
289 geoNameTag.appendChild(geoNameText);
290
291 // POINTS
292 QDomElement pointsListTag = doc.createElement("points");
293 root.appendChild(pointsListTag);
294
296 if (pnt_vec)
297 {
298 auto const& points(pnt_vec->getVector());
299
300 if (!points.empty())
301 {
302 auto const nPoints = points.size();
303 for (std::size_t i = 0; i < nPoints; i++)
304 {
305 QDomElement pointTag = doc.createElement("point");
306 pointTag.setAttribute("id", QString::number(i));
307 pointTag.setAttribute(
308 "x",
309 QString::number((*points[i])[0], 'f',
310 std::numeric_limits<double>::digits10));
311 pointTag.setAttribute(
312 "y",
313 QString::number((*points[i])[1], 'f',
314 std::numeric_limits<double>::digits10));
315 pointTag.setAttribute(
316 "z",
317 QString::number((*points[i])[2], 'f',
318 std::numeric_limits<double>::digits10));
319
320 std::string const& point_name(pnt_vec->getItemNameByID(i));
321 if (!point_name.empty())
322 {
323 pointTag.setAttribute("name",
324 QString::fromStdString(point_name));
325 }
326
327 pointsListTag.appendChild(pointTag);
328 }
329 }
330 else
331 {
332 ERR("XmlGmlInterface::write(): Point vector is empty, abort "
333 "writing geometry.");
334 return false;
335 }
336 }
337 else
338 {
339 ERR("XmlGmlInterface::write(): No point vector found, abort writing "
340 "geometry.");
341 return false;
342 }
343
344 // POLYLINES
345 const GeoLib::PolylineVec* ply_vec(
347 if (ply_vec)
348 {
349 auto const& polylines(ply_vec->getVector());
350
351 if (!polylines.empty())
352 {
353 QDomElement plyListTag = doc.createElement("polylines");
354 root.appendChild(plyListTag);
355 auto const nPolylines = polylines.size();
356 for (std::size_t i = 0; i < nPolylines; i++)
357 {
358 QDomElement polylineTag = doc.createElement("polyline");
359 polylineTag.setAttribute("id", QString::number(i));
360
361 std::string ply_name;
362 if (ply_vec->getNameOfElementByID(i, ply_name))
363 {
364 polylineTag.setAttribute("name",
365 QString::fromStdString(ply_name));
366 }
367 else
368 {
369 ply_name = std::to_string(i);
370 polylineTag.setAttribute("name",
371 QString::fromStdString(ply_name));
372 }
373
374 plyListTag.appendChild(polylineTag);
375
376 auto const nPoints = polylines[i]->getNumberOfPoints();
377 for (std::size_t j = 0; j < nPoints; j++)
378 {
379 QDomElement plyPointTag = doc.createElement("pnt");
380 polylineTag.appendChild(plyPointTag);
381 QDomText plyPointText = doc.createTextNode(
382 QString::number((polylines[i])->getPointID(j)));
383 plyPointTag.appendChild(plyPointText);
384 }
385 }
386 }
387 }
388 else
389 {
390 INFO(
391 "XmlGmlInterface::write(): Polyline vector is empty, no polylines "
392 "written to file.");
393 }
394
395 // SURFACES
397 if (sfc_vec)
398 {
399 auto const& surfaces(sfc_vec->getVector());
400
401 if (!surfaces.empty())
402 {
403 QDomElement sfcListTag = doc.createElement("surfaces");
404 root.appendChild(sfcListTag);
405 auto const nSurfaces = surfaces.size();
406 for (std::size_t i = 0; i < nSurfaces; i++)
407 {
408 QDomElement surfaceTag = doc.createElement("surface");
409 surfaceTag.setAttribute("id", QString::number(i));
410
411 std::string sfc_name;
412 if (sfc_vec->getNameOfElementByID(i, sfc_name))
413 {
414 surfaceTag.setAttribute("name",
415 QString::fromStdString(sfc_name));
416 }
417
418 sfcListTag.appendChild(surfaceTag);
419
420 // writing the elements compromising the surface
421 std::size_t nElements = (surfaces[i])->getNumberOfTriangles();
422 for (std::size_t j = 0; j < nElements; j++)
423 {
424 QDomElement elementTag = doc.createElement("element");
425 elementTag.setAttribute(
426 "p1", QString::number((*(*surfaces[i])[j])[0]));
427 elementTag.setAttribute(
428 "p2", QString::number((*(*surfaces[i])[j])[1]));
429 elementTag.setAttribute(
430 "p3", QString::number((*(*surfaces[i])[j])[2]));
431 surfaceTag.appendChild(elementTag);
432 }
433 }
434 }
435 else
436 {
437 INFO(
438 "XmlGmlInterface::write(): Surface vector is empty, no "
439 "surfaces written to file.");
440 }
441 }
442 else
443 {
444 INFO(
445 "XmlGmlInterface::write(): Surface vector is empty, no surfaces "
446 "written to file.");
447 }
448
449 std::string xml = doc.toString().toStdString();
450 out << xml;
451
452 return true;
453}
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:34
std::ostringstream out
The stream to write to.
Definition: Writer.h:46
SurfaceVec * getSurfaceVecObj(const std::string &name)
Returns the surface vector with the given name.
Definition: GEOObjects.h:211
const PolylineVec * getPolylineVecObj(const std::string &name) const
Definition: GEOObjects.cpp:206
This class manages pointers to Points in a std::vector along with a name. It also handles the deletio...
Definition: PointVec.h:38
The class TemplateVec takes a unique name and manages a std::vector of pointers to data elements of t...
Definition: TemplateVec.h:41

References _geo_objs, ERR(), BaseLib::IO::XMLInterface::export_name, GeoLib::PointVec::getItemNameByID(), GeoLib::TemplateVec< T >::getNameOfElementByID(), GeoLib::GEOObjects::getPointVecObj(), GeoLib::GEOObjects::getPolylineVecObj(), GeoLib::GEOObjects::getSurfaceVecObj(), GeoLib::TemplateVec< T >::getVector(), INFO(), and BaseLib::IO::Writer::out.

Member Data Documentation

◆ _geo_objs

GeoLib::GEOObjects& GeoLib::IO::XmlGmlInterface::_geo_objs
private

Definition at line 69 of file XmlGmlInterface.h.

Referenced by readFile(), and write().

◆ _idx_map

std::map<std::size_t, std::size_t> GeoLib::IO::XmlGmlInterface::_idx_map
private

Definition at line 70 of file XmlGmlInterface.h.

Referenced by readPoints(), readPolylines(), and readSurfaces().


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