Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
vpXmlParserRectOriented.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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 http://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 #include <pugixml.hpp>
48 #include <visp3/core/vpIoTools.h>
49 
50 #ifndef DOXYGEN_SHOULD_SKIP_THIS
51 class vpXmlParserRectOriented::Impl
52 {
53 private:
54  enum vpXmlCodeType {
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  } else if (!append) {
131  if (!vpIoTools::remove(filename))
132  throw vpException(vpException::ioError, "Cannot remove existing xml file");
133 
134  root_node = doc.append_child(pugi::node_declaration);
135  root_node.append_attribute("version") = "1.0";
136  root_node = doc.append_child("config");
137  }
138 
139  root_node = doc.document_element();
140  if (!root_node) {
141  throw vpException(vpException::ioError, "problem to get the root node");
142  }
143 
144  writeMainClass(root_node);
145 
146  doc.save_file(filename.c_str(), PUGIXML_TEXT(" "));
147  }
148 
149  void writeMainClass(pugi::xml_node &node)
150  {
151  node.append_child("center_i").append_child(pugi::node_pcdata).text() = m_rectangle.getCenter().get_i();
152  node.append_child("center_j").append_child(pugi::node_pcdata).text() = m_rectangle.getCenter().get_j();
153  node.append_child("height").append_child(pugi::node_pcdata).text() = m_rectangle.getHeight();
154  node.append_child("width").append_child(pugi::node_pcdata).text() = m_rectangle.getWidth();
155  node.append_child("theta").append_child(pugi::node_pcdata).text() = m_rectangle.getOrientation();
156  }
157 
158  vpRectOriented getRectangle() const { return m_rectangle; }
159  void setRectangle(const vpRectOriented &rectangle) { m_rectangle = rectangle; }
160 
161 private:
162  vpRectOriented m_rectangle;
163  vpImagePoint m_center;
164  double m_height;
165  double m_width;
166  double m_theta;
167  std::map<std::string, int> m_nodeMap;
168 };
169 #endif //DOXYGEN_SHOULD_SKIP_THIS
170 
172 {
173 }
174 
176 {
177  delete m_impl;
178 }
179 
188 void vpXmlParserRectOriented::parse(const std::string &filename)
189 {
190  m_impl->parse(filename);
191 }
192 
203 void vpXmlParserRectOriented::save(const std::string &filename, bool append)
204 {
205  m_impl->save(filename, append);
206 }
207 
209 {
210  return m_impl->getRectangle();
211 }
212 
214 {
215  m_impl->setRectangle(rectangle);
216 }
void setRectangle(const vpRectOriented &rectangle)
error that can be emited by ViSP classes.
Definition: vpException.h:71
void save(const std::string &filename, bool append=false)
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:929
vpRectOriented getRectangle() const
void parse(const std::string &filename)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:87
Defines an oriented rectangle in the plane.