Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkContourModelWriter.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkContourModelWriter.h"
18 #include "mitkIOMimeTypes.h"
19 #include "mitkTimeGeometry.h"
20 #include <fstream>
21 #include <iostream>
22 #include <locale>
23 
24 /*
25  * The xml file will look like:
26  *
27  * <?xml version="1.0" encoding="utf-8"?>
28  * <contourModel>
29  * <head>
30  * <geometryInfo>
31  * </geometryInfo>
32  * </head>
33  * <data>
34  * <timestep n="0">
35  * <controlPoints>
36  * <point>
37  * <x></x>
38  * <y></y>
39  * <z></z>
40  * </point>
41  * </controlPoint>
42  * </timestep>
43  * </data>
44  * </contourModel>
45  */
46 
47 //
48 // Initialization of the xml tags.
49 //
50 
51 const char *mitk::ContourModelWriter::XML_CONTOURMODEL = "contourModel";
52 
53 const char *mitk::ContourModelWriter::XML_HEAD = "head";
54 
55 const char *mitk::ContourModelWriter::XML_GEOMETRY_INFO = "geometryInfo";
56 
57 const char *mitk::ContourModelWriter::XML_DATA = "data";
58 
59 const char *mitk::ContourModelWriter::XML_TIME_STEP = "timestep";
60 
61 const char *mitk::ContourModelWriter::XML_CONTROL_POINTS = "controlPoints";
62 
63 const char *mitk::ContourModelWriter::XML_POINT = "point";
64 
65 const char *mitk::ContourModelWriter::XML_X = "x";
66 
67 const char *mitk::ContourModelWriter::XML_Y = "y";
68 
69 const char *mitk::ContourModelWriter::XML_Z = "z";
70 
72  : AbstractFileWriter(ContourModel::GetStaticNameOfClass()), m_IndentDepth(0), m_Indent(2)
73 {
74  std::string category = "Contour File";
75  mitk::CustomMimeType customMimeType;
76  customMimeType.SetCategory(category);
77  customMimeType.AddExtension("cnt");
78 
79  this->SetDescription(category);
80  this->SetMimeType(customMimeType);
81 
83 }
84 
86  : AbstractFileWriter(other), m_IndentDepth(other.m_IndentDepth), m_Indent(other.m_Indent)
87 {
88 }
89 
91 {
92 }
93 
95 {
96  std::ostream *out;
97  std::ofstream outStream;
98 
99  if (this->GetOutputStream())
100  {
101  out = this->GetOutputStream();
102  }
103  else
104  {
105  outStream.open(this->GetOutputLocation().c_str());
106  out = &outStream;
107  }
108 
109  if (!out->good())
110  {
111  mitkThrow() << "Stream not good.";
112  }
113 
114  std::locale previousLocale(out->getloc());
115  std::locale I("C");
116  out->imbue(I);
117 
118  /*+++++++++++ Here the actual xml writing begins +++++++++*/
119 
120  /*++++ <?xml version="1.0" encoding="utf-8"?> ++++*/
121  WriteXMLHeader(*out);
122 
123  //
124  // for each input object write its xml representation to
125  // the stream
126  //
127  mitk::ContourModel::ConstPointer contourModel = dynamic_cast<const mitk::ContourModel *>(this->GetInput());
128  assert(contourModel.IsNotNull());
129  WriteXML(contourModel.GetPointer(), *out);
130 
131  out->imbue(previousLocale);
132 
133  if (!out->good()) // some error during output
134  {
135  throw std::ios_base::failure("Some error during contour writing.");
136  }
137 }
138 
140 {
141  return new ContourModelWriter(*this);
142 }
143 
144 void mitk::ContourModelWriter::WriteXML(const mitk::ContourModel *contourModel, std::ostream &out)
145 {
146  /*++++ <contourModel> ++++*/
147  WriteStartElement(XML_CONTOURMODEL, out);
148 
149  /*++++ <head> ++++*/
150  WriteStartElement(XML_HEAD, out);
151 
152  /*++++ <geometryInfo> ++++*/
153  WriteStartElement(XML_GEOMETRY_INFO, out);
154 
155  WriteGeometryInformation(contourModel->GetTimeGeometry(), out);
156 
157  /*++++ </geometryInfo> ++++*/
158  WriteEndElement(XML_GEOMETRY_INFO, out);
159 
160  /*++++ </head> ++++*/
161  WriteEndElement(XML_HEAD, out);
162 
163  /*++++ <data> ++++*/
164  WriteStartElement(XML_DATA, out);
165 
166  unsigned int timecount = contourModel->GetTimeSteps();
167 
168  for (unsigned int i = 0; i < timecount; i++)
169  {
170  /*++++ <timestep> ++++*/
171  std::vector<std::string> at;
172  at.push_back("n");
173  std::vector<std::string> val;
174  val.push_back(ConvertToString(i));
175 
176  at.push_back("isClosed");
177  val.push_back(ConvertToString(contourModel->IsClosed()));
178 
179  WriteStartElementWithAttribut(XML_TIME_STEP, at, val, out);
180 
181  /*++++ <controlPoints> ++++*/
182  WriteStartElement(XML_CONTROL_POINTS, out);
183 
185  mitk::ContourModel::VertexIterator end = contourModel->IteratorEnd();
186 
187  while (it != end)
188  {
190 
191  /*++++ <point> ++++*/
192  std::vector<std::string> attr;
193  attr.push_back("IsControlPoint");
194  std::vector<std::string> value;
195  value.push_back(ConvertToString(v->IsControlPoint));
196  WriteStartElementWithAttribut(XML_POINT, attr, value, out);
197 
198  /*++++ <x> ++++*/
199  WriteStartElement(XML_X, out);
200  WriteCharacterData(ConvertToString(v->Coordinates[0]).c_str(), out);
201  /*++++ </x> ++++*/
202  WriteEndElement(XML_X, out, false);
203 
204  /*++++ <y> ++++*/
205  WriteStartElement(XML_Y, out);
206  WriteCharacterData(ConvertToString(v->Coordinates[1]).c_str(), out);
207  /*++++ </y> ++++*/
208  WriteEndElement(XML_Y, out, false);
209 
210  /*++++ <z> ++++*/
211  WriteStartElement(XML_Z, out);
212  WriteCharacterData(ConvertToString(v->Coordinates[2]).c_str(), out);
213  /*++++ </z> ++++*/
214  WriteEndElement(XML_Z, out, false);
215 
216  /*++++ </point> ++++*/
217  WriteEndElement(XML_POINT, out);
218 
219  it++;
220  }
221 
222  /*++++ </controlPoints> ++++*/
223  WriteEndElement(XML_CONTROL_POINTS, out);
224 
225  /*++++ </timestep> ++++*/
226  WriteEndElement(XML_TIME_STEP, out);
227  }
228 
229  /*++++ </data> ++++*/
230  WriteEndElement(XML_DATA, out);
231 
232  /*++++ </contourModel> ++++*/
233  WriteEndElement(XML_CONTOURMODEL, out);
234 }
235 
236 void mitk::ContourModelWriter::WriteGeometryInformation(const mitk::TimeGeometry * /*geometry*/, std::ostream &out)
237 {
238  WriteCharacterData("<!-- geometry information -->", out);
239 }
240 
241 template <typename T>
243 {
244  std::ostringstream o;
245  std::locale I("C");
246  o.imbue(I);
247 
248  if (o << value)
249  {
250  return o.str();
251  }
252  else
253  return "conversion error";
254 }
255 
257 {
258  file << "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
259 }
260 
261 void mitk::ContourModelWriter::WriteStartElement(const char *const tag, std::ostream &file)
262 {
263  file << std::endl;
264  WriteIndent(file);
265  file << '<' << tag << '>';
266  m_IndentDepth++;
267 }
268 
269 void mitk::ContourModelWriter::WriteStartElementWithAttribut(const char *const tag,
270  std::vector<std::string> attributes,
271  std::vector<std::string> values,
272  std::ostream &file)
273 {
274  file << std::endl;
275  WriteIndent(file);
276  file << '<' << tag;
277 
278  unsigned int attributesSize = attributes.size();
279  unsigned int valuesSize = values.size();
280 
281  if (attributesSize == valuesSize)
282  {
283  std::vector<std::string>::iterator attributesIt = attributes.begin();
284  std::vector<std::string>::iterator end = attributes.end();
285 
286  std::vector<std::string>::iterator valuesIt = values.begin();
287 
288  while (attributesIt != end)
289  {
290  file << ' ';
291  WriteCharacterData(*attributesIt, file);
292  file << '=' << '"';
293  WriteCharacterData(*valuesIt, file);
294  file << '"';
295  attributesIt++;
296  valuesIt++;
297  }
298  }
299 
300  file << '>';
301  m_IndentDepth++;
302 }
303 
304 void mitk::ContourModelWriter::WriteEndElement(const char *const tag, std::ostream &file, const bool &indent)
305 {
306  m_IndentDepth--;
307  if (indent)
308  {
309  file << std::endl;
310  WriteIndent(file);
311  }
312  file << '<' << '/' << tag << '>';
313 }
314 
315 void mitk::ContourModelWriter::WriteCharacterData(const char *const data, std::ostream &file)
316 {
317  file << data;
318 }
319 
320 void mitk::ContourModelWriter::WriteStartElement(std::string &tag, std::ostream &file)
321 {
322  WriteStartElement(tag.c_str(), file);
323 }
324 
325 void mitk::ContourModelWriter::WriteEndElement(std::string &tag, std::ostream &file, const bool &indent)
326 {
327  WriteEndElement(tag.c_str(), file, indent);
328 }
329 
330 void mitk::ContourModelWriter::WriteCharacterData(std::string &data, std::ostream &file)
331 {
332  WriteCharacterData(data.c_str(), file);
333 }
334 
335 void mitk::ContourModelWriter::WriteIndent(std::ostream &file)
336 {
337  std::string spaces(m_IndentDepth * m_Indent, ' ');
338  file << spaces.c_str();
339 }
ContourModel is a structure of linked vertices defining a contour in 3D space. The vertices are store...
mitk::Point3D Coordinates
Coordinates in 3D space.
void WriteGeometryInformation(const mitk::TimeGeometry *geometry, std::ostream &out)
mitk::ContourElement::VertexIterator VertexIterator
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:52
static const char * XML_GEOMETRY_INFO
unsigned int GetTimeSteps() const
Get the number of time steps from the TimeGeometry As the base data has not a data vector given by it...
Definition: mitkBaseData.h:346
VertexIterator IteratorBegin(int timestep=0) const
Returns a const VertexIterator at the start element of the contour.
void WriteXMLHeader(std::ostream &file)
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
static const char * XML_CONTROL_POINTS
static const char * XML_TIME_STEP
void WriteStartElement(const char *const tag, std::ostream &file)
#define mitkThrow()
virtual void Write() override
Write the base data to the specified location or output stream.
static const char * GetStaticNameOfClass()
void AddExtension(const std::string &extension)
void SetCategory(const std::string &category)
std::string ConvertToString(T value)
us::ServiceRegistration< IFileWriter > RegisterService(us::ModuleContext *context=us::GetModuleContext())
bool IsClosed(int timestep=0) const
Return if the contour is closed or not.
void SetMimeType(const CustomMimeType &mimeType)
static const char * XML_CONTOURMODEL
void WriteXML(const mitk::ContourModel *contourModel, std::ostream &out)
virtual mitk::ContourModelWriter * Clone() const override
VertexIterator IteratorEnd(int timestep=0) const
Returns a const VertexIterator at the end element of the contour.
Base class for writing mitk::BaseData objects to files or streams.
void SetDescription(const std::string &description)
Sets a human readable description of this writer.
Represents a single vertex of contour.