36 if (XMLQtInterface::readFile(fileName) == 0)
41 QDomDocument doc(
"OGS-GLI-DOM");
43 QDomElement docElement = doc.documentElement();
44 if (docElement.nodeName().compare(
"OpenGeoSysGLI"))
46 ERR(
"XmlGmlInterface::readFile() - Unexpected XML root.");
50 std::string gliName(
"[NN]");
52 std::vector<GeoLib::Point*> points;
53 std::vector<GeoLib::Polyline*> polylines;
54 std::vector<GeoLib::Surface*> surfaces;
60 QDomNodeList geoTypes = docElement.childNodes();
61 for (
int i = 0; i < geoTypes.count(); i++)
63 const QDomNode type_node(geoTypes.at(i));
64 const QString nodeName = type_node.nodeName();
65 if (nodeName.compare(
"name") == 0)
67 if (type_node.toElement().text().isEmpty())
69 ERR(
"XmlGmlInterface::readFile(): <name>-tag is empty.");
74 gliName = type_node.toElement().text().toStdString();
76 else if (nodeName.compare(
"points") == 0)
80 std::move(pnt_names));
82 else if (nodeName.compare(
"polylines") == 0)
90 catch (std::runtime_error
const&)
97 else if (nodeName.compare(
"surfaces") == 0)
105 catch (std::runtime_error
const&)
115 if (!polylines.empty())
118 std::move(ply_names));
121 if (!surfaces.empty())
124 std::move(sfc_names));
130 std::vector<GeoLib::Point*>& points,
131 std::map<std::string, std::size_t>* pnt_names)
134 QDomElement point = pointsRoot.firstChildElement();
135 while (!point.isNull())
137 _idx_map.insert(std::pair<std::size_t, std::size_t>(
138 strtol((point.attribute(
"id")).toStdString().c_str(), &pEnd, 10),
141 point.attribute(
"y").toDouble(),
142 point.attribute(
"z").toDouble(),
143 point.attribute(
"id").toInt());
144 if (point.hasAttribute(
"name"))
146 pnt_names->insert(std::pair<std::string, std::size_t>(
147 point.attribute(
"name").toStdString(), points.size()));
151 point = point.nextSiblingElement();
156 std::vector<GeoLib::Polyline*>& polylines,
157 std::vector<GeoLib::Point*>
const& points,
158 const std::vector<std::size_t>& pnt_id_map,
161 QDomElement polyline = polylinesRoot.firstChildElement();
162 while (!polyline.isNull())
164 std::size_t
const idx = polylines.size();
167 if (polyline.hasAttribute(
"name"))
169 std::string
const ply_name(
170 polyline.attribute(
"name").toStdString());
171 std::map<std::string, std::size_t>::const_iterator it(
172 ply_names.find(ply_name));
173 if (it == ply_names.end())
176 std::pair<std::string, std::size_t>(ply_name, idx));
181 "Polyline '{:s}' exists already. Polyline {:d} will be "
182 "inserted without a name.",
187 QDomElement point = polyline.firstChildElement();
188 auto accessOrError = [
this, &polyline](
auto pt_idx)
190 auto search =
_idx_map.find(pt_idx);
193 std::string polyline_name;
194 if (polyline.hasAttribute(
"name"))
196 polyline_name = polyline.attribute(
"name").toStdString();
199 "Polyline `{:s}' contains the point id `{:d}' which is not "
200 "in the point list.",
201 polyline_name, pt_idx);
203 return search->second;
206 while (!point.isNull())
208 polylines[idx]->addPoint(
209 pnt_id_map[accessOrError(point.text().toInt())]);
210 point = point.nextSiblingElement();
213 polyline = polyline.nextSiblingElement();
218 std::vector<GeoLib::Surface*>& surfaces,
219 std::vector<GeoLib::Point*>
const& points,
220 const std::vector<std::size_t>& pnt_id_map,
223 QDomElement surface = surfacesRoot.firstChildElement();
224 while (!surface.isNull())
228 if (surface.hasAttribute(
"name"))
230 sfc_names.insert(std::pair<std::string, std::size_t>(
231 surface.attribute(
"name").toStdString(), surfaces.size() - 1));
234 auto accessOrError = [
this, &surface](
auto pt_idx)
236 auto search =
_idx_map.find(pt_idx);
239 std::string surface_name;
240 if (surface.hasAttribute(
"name"))
242 surface_name = surface.attribute(
"name").toStdString();
245 "Surface `{:s}' contains the point id `{:d}', which is not "
246 "in the point list.",
247 surface_name, pt_idx);
249 return search->second;
252 QDomElement element = surface.firstChildElement();
253 while (!element.isNull())
256 pnt_id_map[accessOrError(element.attribute(
"p1").toInt())];
258 pnt_id_map[accessOrError(element.attribute(
"p2").toInt())];
260 pnt_id_map[accessOrError(element.attribute(
"p3").toInt())];
261 surfaces.back()->addTriangle(p1, p2, p3);
262 element = element.nextSiblingElement();
265 surface = surface.nextSiblingElement();
272 ERR(
"XmlGmlInterface::write(): No geometry specified.");
276 out <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
279 QDomDocument doc(
"OGS-GML-DOM");
280 QDomElement root = doc.createElement(
"OpenGeoSysGLI");
281 root.setAttribute(
"xmlns:ogs",
"http://www.opengeosys.org");
282 root.setAttribute(
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
284 doc.appendChild(root);
286 QDomElement geoNameTag = doc.createElement(
"name");
287 root.appendChild(geoNameTag);
288 QDomText geoNameText =
289 doc.createTextNode(QString::fromStdString(
export_name));
290 geoNameTag.appendChild(geoNameText);
293 QDomElement pointsListTag = doc.createElement(
"points");
294 root.appendChild(pointsListTag);
299 auto const& points(pnt_vec->
getVector());
303 auto const nPoints = points.size();
304 for (std::size_t i = 0; i < nPoints; i++)
306 QDomElement pointTag = doc.createElement(
"point");
307 pointTag.setAttribute(
"id", QString::number(i));
308 pointTag.setAttribute(
310 QString::number((*points[i])[0],
'f',
311 std::numeric_limits<double>::max_digits10));
312 pointTag.setAttribute(
314 QString::number((*points[i])[1],
'f',
315 std::numeric_limits<double>::max_digits10));
316 pointTag.setAttribute(
318 QString::number((*points[i])[2],
'f',
319 std::numeric_limits<double>::max_digits10));
322 if (!point_name.empty())
324 pointTag.setAttribute(
"name",
325 QString::fromStdString(point_name));
328 pointsListTag.appendChild(pointTag);
333 ERR(
"XmlGmlInterface::write(): Point vector is empty, abort "
334 "writing geometry.");
340 ERR(
"XmlGmlInterface::write(): No point vector found, abort writing "
350 auto const& polylines(ply_vec->
getVector());
352 if (!polylines.empty())
354 QDomElement plyListTag = doc.createElement(
"polylines");
355 root.appendChild(plyListTag);
356 auto const nPolylines = polylines.size();
357 for (std::size_t i = 0; i < nPolylines; i++)
359 QDomElement polylineTag = doc.createElement(
"polyline");
360 polylineTag.setAttribute(
"id", QString::number(i));
362 std::string ply_name;
365 polylineTag.setAttribute(
"name",
366 QString::fromStdString(ply_name));
370 ply_name = std::to_string(i);
371 polylineTag.setAttribute(
"name",
372 QString::fromStdString(ply_name));
375 plyListTag.appendChild(polylineTag);
377 auto const nPoints = polylines[i]->getNumberOfPoints();
378 for (std::size_t j = 0; j < nPoints; j++)
380 QDomElement plyPointTag = doc.createElement(
"pnt");
381 polylineTag.appendChild(plyPointTag);
382 QDomText plyPointText = doc.createTextNode(
383 QString::number((polylines[i])->getPointID(j)));
384 plyPointTag.appendChild(plyPointText);
392 "XmlGmlInterface::write(): Polyline vector is empty, no polylines "
400 auto const& surfaces(sfc_vec->
getVector());
402 if (!surfaces.empty())
404 QDomElement sfcListTag = doc.createElement(
"surfaces");
405 root.appendChild(sfcListTag);
406 auto const nSurfaces = surfaces.size();
407 for (std::size_t i = 0; i < nSurfaces; i++)
409 QDomElement surfaceTag = doc.createElement(
"surface");
410 surfaceTag.setAttribute(
"id", QString::number(i));
412 std::string sfc_name;
415 surfaceTag.setAttribute(
"name",
416 QString::fromStdString(sfc_name));
419 sfcListTag.appendChild(surfaceTag);
422 std::size_t nElements = (surfaces[i])->getNumberOfTriangles();
423 for (std::size_t j = 0; j < nElements; j++)
425 QDomElement elementTag = doc.createElement(
"element");
426 elementTag.setAttribute(
427 "p1", QString::number((*(*surfaces[i])[j])[0]));
428 elementTag.setAttribute(
429 "p2", QString::number((*(*surfaces[i])[j])[1]));
430 elementTag.setAttribute(
431 "p3", QString::number((*(*surfaces[i])[j])[2]));
432 surfaceTag.appendChild(elementTag);
439 "XmlGmlInterface::write(): Surface vector is empty, no "
440 "surfaces written to file.");
446 "XmlGmlInterface::write(): Surface vector is empty, no surfaces "
450 std::string xml = doc.toString().toStdString();
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.