Medical Imaging Interaction Toolkit  2018.4.99-1bab67a2
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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkContourModelWriter.h"
14 #include "mitkIOMimeTypes.h"
15 #include "mitkTimeGeometry.h"
16 #include <fstream>
17 #include <iostream>
18 #include <locale>
19 
20 /*
21  * The xml file will look like:
22  *
23  * <?xml version="1.0" encoding="utf-8"?>
24  * <contourModel>
25  * <head>
26  * <geometryInfo>
27  * </geometryInfo>
28  * </head>
29  * <data>
30  * <timestep n="0">
31  * <controlPoints>
32  * <point>
33  * <x></x>
34  * <y></y>
35  * <z></z>
36  * </point>
37  * </controlPoint>
38  * </timestep>
39  * </data>
40  * </contourModel>
41  */
42 
43 //
44 // Initialization of the xml tags.
45 //
46 
47 const char *mitk::ContourModelWriter::XML_CONTOURMODEL = "contourModel";
48 
49 const char *mitk::ContourModelWriter::XML_HEAD = "head";
50 
51 const char *mitk::ContourModelWriter::XML_GEOMETRY_INFO = "geometryInfo";
52 
53 const char *mitk::ContourModelWriter::XML_DATA = "data";
54 
55 const char *mitk::ContourModelWriter::XML_TIME_STEP = "timestep";
56 
57 const char *mitk::ContourModelWriter::XML_CONTROL_POINTS = "controlPoints";
58 
59 const char *mitk::ContourModelWriter::XML_POINT = "point";
60 
61 const char *mitk::ContourModelWriter::XML_X = "x";
62 
63 const char *mitk::ContourModelWriter::XML_Y = "y";
64 
65 const char *mitk::ContourModelWriter::XML_Z = "z";
66 
68  : AbstractFileWriter(ContourModel::GetStaticNameOfClass()), m_IndentDepth(0), m_Indent(2)
69 {
70  std::string category = "Contour File";
71  mitk::CustomMimeType customMimeType;
72  customMimeType.SetCategory(category);
73  customMimeType.AddExtension("cnt");
74 
75  this->SetDescription(category);
76  this->SetMimeType(customMimeType);
77 
79 }
80 
83 {
84 }
85 
87 {
88 }
89 
91 {
92  std::ostream *out;
93  std::ofstream outStream;
94 
95  if (this->GetOutputStream())
96  {
97  out = this->GetOutputStream();
98  }
99  else
100  {
101  outStream.open(this->GetOutputLocation().c_str());
102  out = &outStream;
103  }
104 
105  if (!out->good())
106  {
107  mitkThrow() << "Stream not good.";
108  }
109 
110  std::locale previousLocale(out->getloc());
111  std::locale I("C");
112  out->imbue(I);
113 
114  /*+++++++++++ Here the actual xml writing begins +++++++++*/
115 
116  /*++++ <?xml version="1.0" encoding="utf-8"?> ++++*/
117  WriteXMLHeader(*out);
118 
119  //
120  // for each input object write its xml representation to
121  // the stream
122  //
123  mitk::ContourModel::ConstPointer contourModel = dynamic_cast<const mitk::ContourModel *>(this->GetInput());
124  assert(contourModel.IsNotNull());
125  WriteXML(contourModel.GetPointer(), *out);
126 
127  out->imbue(previousLocale);
128 
129  if (!out->good()) // some error during output
130  {
131  throw std::ios_base::failure("Some error during contour writing.");
132  }
133 }
134 
136 {
137  return new ContourModelWriter(*this);
138 }
139 
140 void mitk::ContourModelWriter::WriteXML(const mitk::ContourModel *contourModel, std::ostream &out)
141 {
142  /*++++ <contourModel> ++++*/
144 
145  /*++++ <head> ++++*/
147 
148  /*++++ <geometryInfo> ++++*/
150 
151  WriteGeometryInformation(contourModel->GetTimeGeometry(), out);
152 
153  /*++++ </geometryInfo> ++++*/
155 
156  /*++++ </head> ++++*/
158 
159  /*++++ <data> ++++*/
161 
162  unsigned int timecount = contourModel->GetTimeSteps();
163 
164  for (unsigned int i = 0; i < timecount; i++)
165  {
166  /*++++ <timestep> ++++*/
167  std::vector<std::string> at;
168  at.push_back("n");
169  std::vector<std::string> val;
170  val.push_back(ConvertToString(i));
171 
172  at.push_back("isClosed");
173  val.push_back(ConvertToString(contourModel->IsClosed()));
174 
176 
177  /*++++ <controlPoints> ++++*/
179 
180  auto it = contourModel->IteratorBegin();
181  auto end = contourModel->IteratorEnd();
182 
183  while (it != end)
184  {
186 
187  /*++++ <point> ++++*/
188  std::vector<std::string> attr;
189  attr.push_back("IsControlPoint");
190  std::vector<std::string> value;
191  value.push_back(ConvertToString(v->IsControlPoint));
192  WriteStartElementWithAttribut(XML_POINT, attr, value, out);
193 
194  /*++++ <x> ++++*/
195  WriteStartElement(XML_X, out);
196  WriteCharacterData(ConvertToString(v->Coordinates[0]).c_str(), out);
197  /*++++ </x> ++++*/
198  WriteEndElement(XML_X, out, false);
199 
200  /*++++ <y> ++++*/
201  WriteStartElement(XML_Y, out);
202  WriteCharacterData(ConvertToString(v->Coordinates[1]).c_str(), out);
203  /*++++ </y> ++++*/
204  WriteEndElement(XML_Y, out, false);
205 
206  /*++++ <z> ++++*/
207  WriteStartElement(XML_Z, out);
208  WriteCharacterData(ConvertToString(v->Coordinates[2]).c_str(), out);
209  /*++++ </z> ++++*/
210  WriteEndElement(XML_Z, out, false);
211 
212  /*++++ </point> ++++*/
214 
215  it++;
216  }
217 
218  /*++++ </controlPoints> ++++*/
220 
221  /*++++ </timestep> ++++*/
223  }
224 
225  /*++++ </data> ++++*/
227 
228  /*++++ </contourModel> ++++*/
230 }
231 
232 void mitk::ContourModelWriter::WriteGeometryInformation(const mitk::TimeGeometry * /*geometry*/, std::ostream &out)
233 {
234  WriteCharacterData("<!-- geometry information -->", out);
235 }
236 
237 template <typename T>
239 {
240  std::ostringstream o;
241  std::locale I("C");
242  o.imbue(I);
243 
244  if (o << value)
245  {
246  return o.str();
247  }
248  else
249  return "conversion error";
250 }
251 
253 {
254  file << "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
255 }
256 
257 void mitk::ContourModelWriter::WriteStartElement(const char *const tag, std::ostream &file)
258 {
259  file << std::endl;
260  WriteIndent(file);
261  file << '<' << tag << '>';
262  m_IndentDepth++;
263 }
264 
265 void mitk::ContourModelWriter::WriteStartElementWithAttribut(const char *const tag,
266  std::vector<std::string> attributes,
267  std::vector<std::string> values,
268  std::ostream &file)
269 {
270  file << std::endl;
271  WriteIndent(file);
272  file << '<' << tag;
273 
274  unsigned int attributesSize = attributes.size();
275  unsigned int valuesSize = values.size();
276 
277  if (attributesSize == valuesSize)
278  {
279  auto attributesIt = attributes.begin();
280  auto end = attributes.end();
281 
282  auto valuesIt = values.begin();
283 
284  while (attributesIt != end)
285  {
286  file << ' ';
287  WriteCharacterData(*attributesIt, file);
288  file << '=' << '"';
289  WriteCharacterData(*valuesIt, file);
290  file << '"';
291  attributesIt++;
292  valuesIt++;
293  }
294  }
295 
296  file << '>';
297  m_IndentDepth++;
298 }
299 
300 void mitk::ContourModelWriter::WriteEndElement(const char *const tag, std::ostream &file, const bool &indent)
301 {
302  m_IndentDepth--;
303  if (indent)
304  {
305  file << std::endl;
306  WriteIndent(file);
307  }
308  file << '<' << '/' << tag << '>';
309 }
310 
311 void mitk::ContourModelWriter::WriteCharacterData(const char *const data, std::ostream &file)
312 {
313  file << data;
314 }
315 
316 void mitk::ContourModelWriter::WriteStartElement(std::string &tag, std::ostream &file)
317 {
318  WriteStartElement(tag.c_str(), file);
319 }
320 
321 void mitk::ContourModelWriter::WriteEndElement(std::string &tag, std::ostream &file, const bool &indent)
322 {
323  WriteEndElement(tag.c_str(), file, indent);
324 }
325 
326 void mitk::ContourModelWriter::WriteCharacterData(std::string &data, std::ostream &file)
327 {
328  WriteCharacterData(data.c_str(), file);
329 }
330 
331 void mitk::ContourModelWriter::WriteIndent(std::ostream &file)
332 {
333  std::string spaces(m_IndentDepth * m_Indent, ' ');
334  file << spaces.c_str();
335 }
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 WriteIndent(std::ostream &file)
void WriteGeometryInformation(const mitk::TimeGeometry *geometry, std::ostream &out)
void WriteStartElementWithAttribut(const char *const tag, std::vector< std::string > attributes, std::vector< std::string > values, std::ostream &file)
static const char * XML_GEOMETRY_INFO
void WriteXMLHeader(std::ostream &file)
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:61
static const char * XML_CONTROL_POINTS
static const char * XML_TIME_STEP
void WriteStartElement(const char *const tag, std::ostream &file)
#define mitkThrow()
void Write() override
Write the base data to the specified location or output stream.
const BaseData * GetInput() const override
Get the input data set via SetInput().
VertexIterator IteratorEnd(int timestep=0) const
Returns a const VertexIterator at the end element of the contour.
void WriteEndElement(const char *const tag, std::ostream &file, const bool &indent=true)
bool IsClosed(int timestep=0) const
Return if the contour is closed or not.
void AddExtension(const std::string &extension)
void WriteCharacterData(const char *const data, std::ostream &file)
void SetCategory(const std::string &category)
std::ostream * GetOutputStream() const override
Get the output stream.
std::string ConvertToString(T value)
us::ServiceRegistration< IFileWriter > RegisterService(us::ModuleContext *context=us::GetModuleContext())
void SetMimeType(const CustomMimeType &mimeType)
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:355
static const char * XML_CONTOURMODEL
std::string GetOutputLocation() const override
Get the current output location.
void WriteXML(const mitk::ContourModel *contourModel, std::ostream &out)
VertexIterator IteratorBegin(int timestep=0) const
Returns a const VertexIterator at the start element of the contour.
mitk::ContourModelWriter * Clone() const override
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.