Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpXmlParserRectOriented.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * XML parser to load and save oriented rectangle in a XML file
32  */
33 
39 #include <visp3/core/vpXmlParserRectOriented.h>
40 
41 #include <map>
42 
43 #if defined(VISP_HAVE_PUGIXML)
44 #include <pugixml.hpp>
45 
46 #include <visp3/core/vpIoTools.h>
47 
49 #ifndef DOXYGEN_SHOULD_SKIP_THIS
50 class vpXmlParserRectOriented::Impl
51 {
52 private:
53  enum vpXmlCodeType
54  {
55  CODE_XML_BAD = -1,
56  CODE_XML_OTHER,
57  CODE_XML_CENTER_I,
58  CODE_XML_CENTER_J,
59  CODE_XML_HEIGHT,
60  CODE_XML_WIDTH,
61  CODE_XML_THETA
62  };
63 
64 public:
65  Impl() : m_rectangle(), m_center(), m_height(), m_width(), m_theta(), m_nodeMap()
66  {
67  m_nodeMap["center_i"] = CODE_XML_CENTER_I;
68  m_nodeMap["center_j"] = CODE_XML_CENTER_J;
69  m_nodeMap["height"] = CODE_XML_HEIGHT;
70  m_nodeMap["width"] = CODE_XML_WIDTH;
71  m_nodeMap["theta"] = CODE_XML_THETA;
72  }
73 
74  void parse(const std::string &filename)
75  {
76  pugi::xml_document doc;
77  if (!doc.load_file(filename.c_str())) {
78  throw vpException(vpException::ioError, "cannot open file: %s", filename.c_str());
79  }
80 
81  pugi::xml_node root_node = doc.document_element();
82  if (!root_node) {
83  throw vpException(vpException::ioError, "cannot get root element");
84  }
85 
86  readMainClass(root_node);
87  }
88 
89  void readMainClass(const pugi::xml_node &node_)
90  {
91  for (pugi::xml_node dataNode = node_.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
92  if (dataNode.type() == pugi::node_element) {
93  std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
94  if (iter_data != m_nodeMap.end()) {
95  switch (iter_data->second) {
96  case CODE_XML_CENTER_I:
97  this->m_center.set_i(dataNode.text().as_double());
98  break;
99  case CODE_XML_CENTER_J:
100  this->m_center.set_j(dataNode.text().as_double());
101  break;
102  case CODE_XML_HEIGHT:
103  this->m_height = dataNode.text().as_double();
104  break;
105  case CODE_XML_WIDTH:
106  this->m_width = dataNode.text().as_double();
107  break;
108  case CODE_XML_THETA:
109  this->m_theta = dataNode.text().as_double();
110  break;
111  default:
112  break;
113  }
114  }
115  }
116  }
117 
118  m_rectangle = vpRectOriented(m_center, m_width, m_height, m_theta);
119  }
120 
121  void save(const std::string &filename, bool append)
122  {
123  pugi::xml_document doc;
124  pugi::xml_node root_node;
125 
126  if (!doc.load_file(filename.c_str(), pugi::parse_default | pugi::parse_comments)) {
127  root_node = doc.append_child(pugi::node_declaration);
128  root_node.append_attribute("version") = "1.0";
129  root_node = doc.append_child("config");
130  }
131  else if (!append) {
132  if (!vpIoTools::remove(filename)) {
133  throw vpException(vpException::ioError, "Cannot remove existing xml file");
134  }
135 
136  root_node = doc.append_child(pugi::node_declaration);
137  root_node.append_attribute("version") = "1.0";
138  root_node = doc.append_child("config");
139  }
140 
141  root_node = doc.document_element();
142  if (!root_node) {
143  throw vpException(vpException::ioError, "problem to get the root node");
144  }
145 
146  writeMainClass(root_node);
147 
148  doc.save_file(filename.c_str(), PUGIXML_TEXT(" "));
149  }
150 
151  void writeMainClass(pugi::xml_node &node)
152  {
153  node.append_child("center_i").append_child(pugi::node_pcdata).text() = m_rectangle.getCenter().get_i();
154  node.append_child("center_j").append_child(pugi::node_pcdata).text() = m_rectangle.getCenter().get_j();
155  node.append_child("height").append_child(pugi::node_pcdata).text() = m_rectangle.getHeight();
156  node.append_child("width").append_child(pugi::node_pcdata).text() = m_rectangle.getWidth();
157  node.append_child("theta").append_child(pugi::node_pcdata).text() = m_rectangle.getOrientation();
158  }
159 
160  vpRectOriented getRectangle() const { return m_rectangle; }
161  void setRectangle(const vpRectOriented &rectangle) { m_rectangle = rectangle; }
162 
163 private:
164  vpRectOriented m_rectangle;
165  vpImagePoint m_center;
166  double m_height;
167  double m_width;
168  double m_theta;
169  std::map<std::string, int> m_nodeMap;
170 };
171 #endif // DOXYGEN_SHOULD_SKIP_THIS
172 
174 
176 
185 void vpXmlParserRectOriented::parse(const std::string &filename) { m_impl->parse(filename); }
186 
197 void vpXmlParserRectOriented::save(const std::string &filename, bool append) { m_impl->save(filename, append); }
198 
199 vpRectOriented vpXmlParserRectOriented::getRectangle() const { return m_impl->getRectangle(); }
200 
201 void vpXmlParserRectOriented::setRectangle(const vpRectOriented &rectangle) { m_impl->setRectangle(rectangle); }
202 END_VISP_NAMESPACE
203 #elif !defined(VISP_BUILD_SHARED_LIBS)
204 // Work around to avoid warning: libvisp_core.a(vpXmlParserRectOriented.cpp.o) has no symbols
205 void dummy_vpXmlParserRectOriented() { };
206 
207 #endif
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ ioError
I/O error.
Definition: vpException.h:67
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:921
Defines an oriented rectangle in the plane.
vpRectOriented getRectangle() const
void setRectangle(const vpRectOriented &rectangle)
void save(const std::string &filename, bool append=false)
void parse(const std::string &filename)