25 if (XMLQtInterface::readFile(fileName) == 0)
30 QDomDocument doc(
"OGS-GLI-DOM");
32 QDomElement docElement = doc.documentElement();
33 if (docElement.nodeName().compare(
"OpenGeoSysGLI"))
35 ERR(
"XmlGmlInterface::readFile() - Unexpected XML root.");
39 std::string gliName(
"[NN]");
41 std::vector<GeoLib::Point*> points;
42 std::vector<GeoLib::Polyline*> polylines;
43 std::vector<GeoLib::Surface*> surfaces;
49 QDomNodeList geoTypes = docElement.childNodes();
50 for (
int i = 0; i < geoTypes.count(); i++)
52 const QDomNode type_node(geoTypes.at(i));
53 const QString nodeName = type_node.nodeName();
54 if (nodeName.compare(
"name") == 0)
56 if (type_node.toElement().text().isEmpty())
58 ERR(
"XmlGmlInterface::readFile(): <name>-tag is empty.");
63 gliName = type_node.toElement().text().toStdString();
65 else if (nodeName.compare(
"points") == 0)
68 _geo_objs.addPointVec(std::move(points), gliName,
69 std::move(pnt_names));
71 else if (nodeName.compare(
"polylines") == 0)
76 type_node, polylines, *
_geo_objs.getPointVec(gliName),
77 _geo_objs.getPointVecObj(gliName)->getIDMap(), ply_names);
79 catch (std::runtime_error
const&)
86 else if (nodeName.compare(
"surfaces") == 0)
91 type_node, surfaces, *
_geo_objs.getPointVec(gliName),
92 _geo_objs.getPointVecObj(gliName)->getIDMap(), sfc_names);
94 catch (std::runtime_error
const&)
104 if (!polylines.empty())
106 _geo_objs.addPolylineVec(std::move(polylines), gliName,
107 std::move(ply_names));
110 if (!surfaces.empty())
112 _geo_objs.addSurfaceVec(std::move(surfaces), gliName,
113 std::move(sfc_names));
119 std::vector<GeoLib::Point*>& points,
120 std::map<std::string, std::size_t>* pnt_names)
123 QDomElement point = pointsRoot.firstChildElement();
124 while (!point.isNull())
126 _idx_map.insert(std::pair<std::size_t, std::size_t>(
127 strtol((point.attribute(
"id")).toStdString().c_str(), &pEnd, 10),
130 point.attribute(
"y").toDouble(),
131 point.attribute(
"z").toDouble(),
132 point.attribute(
"id").toInt());
133 if (point.hasAttribute(
"name"))
135 pnt_names->insert(std::pair<std::string, std::size_t>(
136 point.attribute(
"name").toStdString(), points.size()));
140 point = point.nextSiblingElement();
145 std::vector<GeoLib::Polyline*>& polylines,
146 std::vector<GeoLib::Point*>
const& points,
147 const std::vector<std::size_t>& pnt_id_map,
150 QDomElement polyline = polylinesRoot.firstChildElement();
151 while (!polyline.isNull())
153 std::size_t
const idx = polylines.size();
156 if (polyline.hasAttribute(
"name"))
158 std::string
const ply_name(
159 polyline.attribute(
"name").toStdString());
160 std::map<std::string, std::size_t>::const_iterator it(
161 ply_names.find(ply_name));
162 if (it == ply_names.end())
165 std::pair<std::string, std::size_t>(ply_name, idx));
170 "Polyline '{:s}' exists already. Polyline {:d} will be "
171 "inserted without a name.",
176 QDomElement point = polyline.firstChildElement();
177 auto accessOrError = [
this, &polyline](
auto pt_idx)
179 auto search =
_idx_map.find(pt_idx);
182 std::string polyline_name;
183 if (polyline.hasAttribute(
"name"))
185 polyline_name = polyline.attribute(
"name").toStdString();
188 "Polyline `{:s}' contains the point id `{:d}' which is not "
189 "in the point list.",
190 polyline_name, pt_idx);
192 return search->second;
195 while (!point.isNull())
197 polylines[idx]->addPoint(
198 pnt_id_map[accessOrError(point.text().toInt())]);
199 point = point.nextSiblingElement();
202 polyline = polyline.nextSiblingElement();
207 std::vector<GeoLib::Surface*>& surfaces,
208 std::vector<GeoLib::Point*>
const& points,
209 const std::vector<std::size_t>& pnt_id_map,
212 QDomElement surface = surfacesRoot.firstChildElement();
213 while (!surface.isNull())
217 if (surface.hasAttribute(
"name"))
219 sfc_names.insert(std::pair<std::string, std::size_t>(
220 surface.attribute(
"name").toStdString(), surfaces.size() - 1));
223 auto accessOrError = [
this, &surface](
auto pt_idx)
225 auto search =
_idx_map.find(pt_idx);
228 std::string surface_name;
229 if (surface.hasAttribute(
"name"))
231 surface_name = surface.attribute(
"name").toStdString();
234 "Surface `{:s}' contains the point id `{:d}', which is not "
235 "in the point list.",
236 surface_name, pt_idx);
238 return search->second;
241 QDomElement element = surface.firstChildElement();
242 while (!element.isNull())
245 pnt_id_map[accessOrError(element.attribute(
"p1").toInt())];
247 pnt_id_map[accessOrError(element.attribute(
"p2").toInt())];
249 pnt_id_map[accessOrError(element.attribute(
"p3").toInt())];
250 surfaces.back()->addTriangle(p1, p2, p3);
251 element = element.nextSiblingElement();
254 surface = surface.nextSiblingElement();
261 ERR(
"XmlGmlInterface::write(): No geometry specified.");
265 out <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
268 QDomDocument doc(
"OGS-GML-DOM");
269 QDomElement root = doc.createElement(
"OpenGeoSysGLI");
270 root.setAttribute(
"xmlns:ogs",
"http://www.opengeosys.org");
271 root.setAttribute(
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
273 doc.appendChild(root);
275 QDomElement geoNameTag = doc.createElement(
"name");
276 root.appendChild(geoNameTag);
277 QDomText geoNameText =
278 doc.createTextNode(QString::fromStdString(
export_name));
279 geoNameTag.appendChild(geoNameText);
282 QDomElement pointsListTag = doc.createElement(
"points");
283 root.appendChild(pointsListTag);
288 auto const& points(pnt_vec->
getVector());
292 auto const nPoints = points.size();
293 for (std::size_t i = 0; i < nPoints; i++)
295 QDomElement pointTag = doc.createElement(
"point");
296 pointTag.setAttribute(
"id", QString::number(i));
297 pointTag.setAttribute(
299 QString::number((*points[i])[0],
'f',
300 std::numeric_limits<double>::max_digits10));
301 pointTag.setAttribute(
303 QString::number((*points[i])[1],
'f',
304 std::numeric_limits<double>::max_digits10));
305 pointTag.setAttribute(
307 QString::number((*points[i])[2],
'f',
308 std::numeric_limits<double>::max_digits10));
311 if (!point_name.empty())
313 pointTag.setAttribute(
"name",
314 QString::fromStdString(point_name));
317 pointsListTag.appendChild(pointTag);
322 ERR(
"XmlGmlInterface::write(): Point vector is empty, abort "
323 "writing geometry.");
329 ERR(
"XmlGmlInterface::write(): No point vector found, abort writing "
339 auto const& polylines(ply_vec->
getVector());
341 if (!polylines.empty())
343 QDomElement plyListTag = doc.createElement(
"polylines");
344 root.appendChild(plyListTag);
345 auto const nPolylines = polylines.size();
346 for (std::size_t i = 0; i < nPolylines; i++)
348 QDomElement polylineTag = doc.createElement(
"polyline");
349 polylineTag.setAttribute(
"id", QString::number(i));
351 std::string ply_name;
354 polylineTag.setAttribute(
"name",
355 QString::fromStdString(ply_name));
359 ply_name = std::to_string(i);
360 polylineTag.setAttribute(
"name",
361 QString::fromStdString(ply_name));
364 plyListTag.appendChild(polylineTag);
366 auto const nPoints = polylines[i]->getNumberOfPoints();
367 for (std::size_t j = 0; j < nPoints; j++)
369 QDomElement plyPointTag = doc.createElement(
"pnt");
370 polylineTag.appendChild(plyPointTag);
371 QDomText plyPointText = doc.createTextNode(
372 QString::number((polylines[i])->getPointID(j)));
373 plyPointTag.appendChild(plyPointText);
381 "XmlGmlInterface::write(): Polyline vector is empty, no polylines "
389 auto const& surfaces(sfc_vec->
getVector());
391 if (!surfaces.empty())
393 QDomElement sfcListTag = doc.createElement(
"surfaces");
394 root.appendChild(sfcListTag);
395 auto const nSurfaces = surfaces.size();
396 for (std::size_t i = 0; i < nSurfaces; i++)
398 QDomElement surfaceTag = doc.createElement(
"surface");
399 surfaceTag.setAttribute(
"id", QString::number(i));
401 std::string sfc_name;
404 surfaceTag.setAttribute(
"name",
405 QString::fromStdString(sfc_name));
408 sfcListTag.appendChild(surfaceTag);
411 std::size_t nElements = (surfaces[i])->getNumberOfTriangles();
412 for (std::size_t j = 0; j < nElements; j++)
414 QDomElement elementTag = doc.createElement(
"element");
415 elementTag.setAttribute(
416 "p1", QString::number((*(*surfaces[i])[j])[0]));
417 elementTag.setAttribute(
418 "p2", QString::number((*(*surfaces[i])[j])[1]));
419 elementTag.setAttribute(
420 "p3", QString::number((*(*surfaces[i])[j])[2]));
421 surfaceTag.appendChild(elementTag);
428 "XmlGmlInterface::write(): Surface vector is empty, no "
429 "surfaces written to file.");
435 "XmlGmlInterface::write(): Surface vector is empty, no surfaces "
439 std::string xml = doc.toString().toStdString();