Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
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 #ifdef VISP_HAVE_PUGIXML
47 
48 #include <map>
49 #include <pugixml.hpp>
50 #include <visp3/core/vpIoTools.h>
51 
52 #ifndef DOXYGEN_SHOULD_SKIP_THIS
53 class vpXmlParserRectOriented::Impl
54 {
55 private:
56  enum vpXmlCodeType {
57  CODE_XML_BAD = -1,
58  CODE_XML_OTHER,
59  CODE_XML_CENTER_I,
60  CODE_XML_CENTER_J,
61  CODE_XML_HEIGHT,
62  CODE_XML_WIDTH,
63  CODE_XML_THETA
64  };
65 
66 public:
67  Impl() : m_rectangle(), m_center(), m_height(), m_width(), m_theta(), m_nodeMap()
68  {
69  m_nodeMap["center_i"] = CODE_XML_CENTER_I;
70  m_nodeMap["center_j"] = CODE_XML_CENTER_J;
71  m_nodeMap["height"] = CODE_XML_HEIGHT;
72  m_nodeMap["width"] = CODE_XML_WIDTH;
73  m_nodeMap["theta"] = CODE_XML_THETA;
74  }
75 
76  void parse(const std::string &filename)
77  {
78  pugi::xml_document doc;
79  if (!doc.load_file(filename.c_str())) {
80  throw vpException(vpException::ioError, "cannot open file: %s", filename.c_str());
81  }
82 
83  pugi::xml_node root_node = doc.document_element();
84  if (!root_node) {
85  throw vpException(vpException::ioError, "cannot get root element");
86  }
87 
88  readMainClass(root_node);
89  }
90 
91  void readMainClass(const pugi::xml_node &node_)
92  {
93  for (pugi::xml_node dataNode = node_.first_child(); dataNode; dataNode = dataNode.next_sibling()) {
94  if (dataNode.type() == pugi::node_element) {
95  std::map<std::string, int>::iterator iter_data = m_nodeMap.find(dataNode.name());
96  if (iter_data != m_nodeMap.end()) {
97  switch (iter_data->second) {
98  case CODE_XML_CENTER_I:
99  this->m_center.set_i(dataNode.text().as_double());
100  break;
101  case CODE_XML_CENTER_J:
102  this->m_center.set_j(dataNode.text().as_double());
103  break;
104  case CODE_XML_HEIGHT:
105  this->m_height = dataNode.text().as_double();
106  break;
107  case CODE_XML_WIDTH:
108  this->m_width = dataNode.text().as_double();
109  break;
110  case CODE_XML_THETA:
111  this->m_theta = dataNode.text().as_double();
112  break;
113  default:
114  break;
115  }
116  }
117  }
118  }
119 
120  m_rectangle = vpRectOriented(m_center, m_width, m_height, m_theta);
121  }
122 
123  void save(const std::string &filename, bool append)
124  {
125  pugi::xml_document doc;
126  pugi::xml_node root_node;
127 
128  if (!doc.load_file(filename.c_str(), pugi::parse_default | pugi::parse_comments)) {
129  root_node = doc.append_child(pugi::node_declaration);
130  root_node.append_attribute("version") = "1.0";
131  root_node = doc.append_child("config");
132  } else if (!append) {
133  if (!vpIoTools::remove(filename))
134  throw vpException(vpException::ioError, "Cannot remove existing xml file");
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 {
175 }
176 
178 {
179  delete m_impl;
180 }
181 
190 void vpXmlParserRectOriented::parse(const std::string &filename)
191 {
192  m_impl->parse(filename);
193 }
194 
205 void vpXmlParserRectOriented::save(const std::string &filename, bool append)
206 {
207  m_impl->save(filename, append);
208 }
209 
211 {
212  return m_impl->getRectangle();
213 }
214 
216 {
217  m_impl->setRectangle(rectangle);
218 }
219 
220 #elif !defined(VISP_BUILD_SHARED_LIBS)
221 // Work arround to avoid warning: libvisp_core.a(vpXmlParserRectOriented.cpp.o) has
222 // no symbols
223 void dummy_vpXmlParserRectOriented(){};
224 #endif //VISP_HAVE_PUGIXML
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:855
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:88
Defines an oriented rectangle in the plane.