17 #include <boost/property_tree/xml_parser.hpp>
34 : _geo_objects(geo_objs)
44 doc->ignoreConfigAttribute(
"xmlns:xsi");
45 doc->ignoreConfigAttribute(
"xsi:noNamespaceSchemaLocation");
46 doc->ignoreConfigAttribute(
"xmlns:ogs");
48 auto polylines = std::make_unique<std::vector<GeoLib::Polyline*>>();
49 auto surfaces = std::make_unique<std::vector<GeoLib::Surface*>>();
51 using MapNameId = std::map<std::string, std::size_t>;
52 auto ply_names = std::make_unique<MapNameId>();
53 auto sfc_names = std::make_unique<MapNameId>();
56 auto geo_name = doc->getConfigParameter<std::string>(
"name");
59 OGS_FATAL(
"BoostXmlGmlInterface::readFile(): <name> tag is empty.");
63 for (
auto st : doc->getConfigSubtreeList(
"points"))
65 auto points = std::make_unique<std::vector<GeoLib::Point*>>();
66 auto pnt_names = std::make_unique<MapNameId>();
69 std::move(pnt_names));
73 for (
auto st : doc->getConfigSubtreeList(
"polylines"))
83 for (
auto st : doc->getConfigSubtreeList(
"surfaces"))
92 if (!polylines->empty())
95 std::move(ply_names));
98 if (!surfaces->empty())
101 std::move(sfc_names));
109 std::vector<GeoLib::Point*>& points,
110 std::map<std::string, std::size_t>& pnt_names)
116 auto const p_id = pt.getConfigAttribute<std::size_t>(
"id");
118 auto const p_x = pt.getConfigAttribute<
double>(
"x");
120 auto const p_y = pt.getConfigAttribute<
double>(
"y");
122 auto const p_z = pt.getConfigAttribute<
double>(
"z");
124 auto const p_size = points.size();
126 "The point id is not unique.");
129 if (
auto const p_name =
131 pt.getConfigAttributeOptional<std::string>(
"name"))
135 OGS_FATAL(
"Empty point name found in geometry file.");
139 pnt_names, *p_name, p_size,
"The point name is not unique.");
146 std::vector<GeoLib::Polyline*>& polylines,
147 std::vector<GeoLib::Point*>
const& points,
148 std::vector<std::size_t>
const& pnt_id_map,
149 std::map<std::string, std::size_t>& ply_names)
155 auto const id = pl.getConfigAttribute<std::size_t>(
"id");
162 if (
auto const p_name =
164 pl.getConfigAttributeOptional<std::string>(
"name"))
168 OGS_FATAL(
"Empty polyline name found in geometry file.");
172 ply_names, *p_name, polylines.size() - 1,
173 "The polyline name is not unique.");
175 auto accessOrError = [
this, &p_name](
auto pt_idx)
177 auto search =
_idx_map.find(pt_idx);
181 "Polyline `{:s}' contains the point id `{:d}', but the "
182 "id is not in the point list.",
183 p_name->c_str(), pt_idx);
185 return search->second;
189 for (
auto const pt : pl.getConfigParameterList<std::size_t>(
"pnt"))
191 polylines.back()->addPoint(pnt_id_map[accessOrError(pt)]);
197 pl.ignoreConfigParameterAll(
"pnt");
199 "Polyline name is required! Polylines without a name are "
207 std::vector<GeoLib::Surface*>& surfaces,
208 std::vector<GeoLib::Point*>
const& points,
209 const std::vector<std::size_t>& pnt_id_map,
210 std::map<std::string, std::size_t>& sfc_names)
216 auto const id = sfc.getConfigAttribute<std::size_t>(
"id");
222 if (
auto const s_name =
224 sfc.getConfigAttributeOptional<std::string>(
"name"))
228 OGS_FATAL(
"Empty surface name found in geometry file.");
232 sfc_names, *s_name, surfaces.size() - 1,
233 "The surface name is not unique.");
236 for (
auto const& element : sfc.getConfigParameterList(
"element"))
240 element.getConfigAttribute<std::size_t>(
"p1");
243 element.getConfigAttribute<std::size_t>(
"p2");
246 element.getConfigAttribute<std::size_t>(
"p3");
248 auto accessOrError = [
this, &s_name](std::size_t pt_idx)
250 auto search =
_idx_map.find(pt_idx);
254 "The element list of the surface `{:s}' contains "
255 "the invalid point id `{:d}'.",
256 s_name->c_str(), pt_idx);
258 return search->second;
261 auto const p1 = pnt_id_map[accessOrError(p1_attr)];
262 auto const p2 = pnt_id_map[accessOrError(p2_attr)];
263 auto const p3 = pnt_id_map[accessOrError(p3_attr)];
264 surfaces.back()->addTriangle(p1, p2, p3);
270 sfc.ignoreConfigParameterAll(
"element");
279 ERR(
"BoostXmlGmlInterface::write(): No geometry specified.");
287 ERR(
"BoostXmlGmlInterface::write(): No PointVec within the geometry "
293 std::vector<GeoLib::Point*>
const*
const pnts(pnt_vec->
getVector());
296 ERR(
"BoostXmlGmlInterface::write(): No vector of points within the "
303 ERR(
"BoostXmlGmlInterface::write(): No points within the geometry "
310 boost::property_tree::ptree pt;
313 pt.put(
"<xmlattr>.xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
314 pt.put(
"<xmlattr>.xmlns:ogs",
"https://www.opengeosys.org");
315 auto& geometry_set = pt.add(
"OpenGeoSysGLI",
"");
318 auto& pnts_tag = geometry_set.add(
"points",
"");
319 for (std::size_t k(0); k < pnts->size(); k++)
321 auto& pnt_tag = pnts_tag.add(
"point",
"");
322 pnt_tag.put(
"<xmlattr>.id", k);
323 pnt_tag.put(
"<xmlattr>.x", (*((*pnts)[k]))[0]);
324 pnt_tag.put(
"<xmlattr>.y", (*((*pnts)[k]))[1]);
325 pnt_tag.put(
"<xmlattr>.z", (*((*pnts)[k]))[2]);
327 if (!point_name.empty())
329 pnt_tag.put(
"<xmlattr>.name", point_name);
336 boost::property_tree::xml_writer_settings<std::string> settings(
'\t', 1);
337 write_xml(
out, pt, settings);
342 boost::property_tree::ptree& geometry_set)
349 "BoostXmlGmlInterface::addSurfacesToPropertyTree(): No surfaces "
350 "within the geometry '{:s}'.",
355 std::vector<GeoLib::Surface*>
const*
const surfaces(sfc_vec->
getVector());
356 if (!surfaces || surfaces->empty())
359 "BoostXmlGmlInterface::addSurfacesToPropertyTree(): No surfaces "
360 "within the geometry '{:s}'.",
365 auto& surfaces_tag = geometry_set.add(
"surfaces",
"");
366 for (std::size_t i = 0; i < surfaces->size(); ++i)
369 std::string sfc_name;
371 auto& surface_tag = surfaces_tag.add(
"surface",
"");
372 surface_tag.put(
"<xmlattr>.id", i);
373 if (!sfc_name.empty())
375 surface_tag.put(
"<xmlattr>.name", sfc_name);
379 auto& element_tag = surface_tag.add(
"element",
"");
380 element_tag.put(
"<xmlattr>.p1", (*(*surface)[j])[0]);
381 element_tag.put(
"<xmlattr>.p2", (*(*surface)[j])[1]);
382 element_tag.put(
"<xmlattr>.p3", (*(*surface)[j])[2]);
388 boost::property_tree::ptree& geometry_set)
395 "BoostXmlGmlInterface::addPolylinesToPropertyTree(): No polylines "
396 "within the geometry '{:s}'.",
401 std::vector<GeoLib::Polyline*>
const*
const polylines(vec->
getVector());
402 if (!polylines || polylines->empty())
405 "BoostXmlGmlInterface::addPolylinesToPropertyTree(): No polylines "
406 "within the geometry '{:s}'.",
411 auto& polylines_tag = geometry_set.add(
"polylines",
"");
412 for (std::size_t i = 0; i < polylines->size(); ++i)
415 std::string ply_name;
417 auto& polyline_tag = polylines_tag.add(
"polyline",
"");
418 polyline_tag.put(
"<xmlattr>.id", i);
419 if (!ply_name.empty())
421 polyline_tag.put(
"<xmlattr>.name", ply_name);
425 polyline_tag.add(
"pnt", polyline->
getPointID(j));
Definition of the BoostXmlGmlInterface class.
Definition of the GEOObjects class.
Definition of the Point class.
void INFO(char const *fmt, Args const &... args)
void ERR(char const *fmt, Args const &... args)
void WARN(char const *fmt, Args const &... args)
Definition of the PointVec class.
Definition of the PolyLine class.
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
Range< ValueIterator< T > > getConfigParameterList(std::string const ¶m) const
std::ostringstream out
The stream to write to.
Container class for geometric objects.
void addSurfaceVec(std::unique_ptr< std::vector< Surface * >> sfc, const std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> sfc_names=nullptr)
const std::vector< Point * > * getPointVec(const std::string &name) const
const PointVec * getPointVecObj(const std::string &name) const
void addPointVec(std::unique_ptr< std::vector< Point * >> points, std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> pnt_id_name_map=nullptr, double eps=std::sqrt(std::numeric_limits< double >::epsilon()))
SurfaceVec * getSurfaceVecObj(const std::string &name)
Returns the surface vector with the given name.
const PolylineVec * getPolylineVecObj(const std::string &name) const
void addPolylineVec(std::unique_ptr< std::vector< Polyline * >> lines, const std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> ply_names=nullptr)
bool write() override
Required method for writing geometry. This is not implemented here, use the Qt class for writing.
GeoLib::GEOObjects & _geo_objects
void readPolylines(BaseLib::ConfigTree const &polylinesRoot, std::vector< GeoLib::Polyline * > &polylines, std::vector< GeoLib::Point * > const &points, const std::vector< std::size_t > &pnt_id_map, std::map< std::string, std::size_t > &ply_names)
Reads GeoLib::Polyline-objects from an xml-file.
void addPolylinesToPropertyTree(BaseLib::ConfigTree::PTree &geometry_set)
void readPoints(BaseLib::ConfigTree const &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(BaseLib::ConfigTree const &surfacesRoot, std::vector< GeoLib::Surface * > &surfaces, std::vector< GeoLib::Point * > const &points, const std::vector< std::size_t > &pnt_id_map, std::map< std::string, std::size_t > &sfc_names)
Reads GeoLib::Surface-objects from an xml-file.
void addSurfacesToPropertyTree(BaseLib::ConfigTree::PTree &geometry_set)
bool readFile(const std::string &fname) override
Reads an xml-file containing OGS geometry.
std::map< std::size_t, std::size_t > _idx_map
BoostXmlGmlInterface(GeoLib::GEOObjects &geo_objs)
This class manages pointers to Points in a std::vector along with a name. It also handles the deletin...
const std::vector< std::size_t > & getIDMap() const
std::string const & getItemNameByID(std::size_t id) const
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
std::size_t getPointID(std::size_t i) const
std::size_t getNumberOfPoints() const
A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points...
std::size_t getNumberOfTriangles() const
The class TemplateVec takes a unique name and manages a std::vector of pointers to data elements of t...
const std::vector< T * > * getVector() const
bool getNameOfElement(const T *data, std::string &name) const
void insertIfKeyUniqueElseError(Map &map, Key const &key, Value &&value, std::string const &error_message)
ConfigTreeTopLevel makeConfigTree(const std::string &filepath, const bool be_ruthless, const std::string &toplevel_tag, const std::vector< std::string > &patch_files)