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