Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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
38
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
50class vpXmlParserRectOriented::Impl
51{
52private:
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
64public:
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
163private:
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
185void vpXmlParserRectOriented::parse(const std::string &filename) { m_impl->parse(filename); }
186
197void vpXmlParserRectOriented::save(const std::string &filename, bool append) { m_impl->save(filename, append); }
198
199vpRectOriented vpXmlParserRectOriented::getRectangle() const { return m_impl->getRectangle(); }
200
201void vpXmlParserRectOriented::setRectangle(const vpRectOriented &rectangle) { m_impl->setRectangle(rectangle); }
202END_VISP_NAMESPACE
203#elif !defined(VISP_BUILD_SHARED_LIBS)
204// Work around to avoid warning: libvisp_core.a(vpXmlParserRectOriented.cpp.o) has no symbols
205void dummy_vpXmlParserRectOriented() { }
206
207#endif
@ ioError
I/O error.
Definition vpException.h:67
static bool remove(const std::string &filename)
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)