Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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.