Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPointSetWriterService.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 
18 #include "mitkGeometry3DToXML.h"
19 #include "mitkIOMimeTypes.h"
20 #include "mitkLocaleSwitch.h"
21 
22 #include "mitkGeometry3D.h"
23 
24 #include <tinyxml.h>
25 
26 #include <fstream>
27 #include <iostream>
28 #include <locale>
29 
30 //
31 // Initialization of the xml tags.
32 //
33 const std::string mitk::PointSetWriterService::XML_POINT_SET_FILE = "point_set_file";
34 const std::string mitk::PointSetWriterService::XML_FILE_VERSION = "file_version";
35 const std::string mitk::PointSetWriterService::XML_POINT_SET = "point_set";
36 const std::string mitk::PointSetWriterService::XML_TIME_SERIES = "time_series";
37 const std::string mitk::PointSetWriterService::XML_TIME_SERIES_ID = "time_series_id";
38 const std::string mitk::PointSetWriterService::XML_POINT = "point";
39 const std::string mitk::PointSetWriterService::XML_ID = "id";
40 const std::string mitk::PointSetWriterService::XML_SPEC = "specification";
41 const std::string mitk::PointSetWriterService::XML_X = "x";
42 const std::string mitk::PointSetWriterService::XML_Y = "y";
43 const std::string mitk::PointSetWriterService::XML_Z = "z";
44 const std::string mitk::PointSetWriterService::VERSION_STRING = "0.1";
45 
48  PointSet::GetStaticNameOfClass(), CustomMimeType(IOMimeTypes::POINTSET_MIMETYPE()), "MITK Point Set Writer")
49 {
51 }
52 
54 {
55 }
56 
58 {
59 }
60 
62 {
63  mitk::LocaleSwitch localeC("C");
64 
65  TiXmlDocument doc;
66 
67  TiXmlDeclaration *decl = new TiXmlDeclaration(
68  "1.0", "UTF-8", ""); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere...
69  doc.LinkEndChild(decl);
70 
71  TiXmlElement *rootNode = new TiXmlElement(XML_POINT_SET_FILE);
72  doc.LinkEndChild(rootNode);
73 
74  TiXmlElement *versionNode = new TiXmlElement(XML_FILE_VERSION);
75  TiXmlText *versionText = new TiXmlText(VERSION_STRING);
76  versionNode->LinkEndChild(versionText);
77  rootNode->LinkEndChild(versionNode);
78 
79  TiXmlElement *pointSetNode = ToXML(static_cast<const PointSet *>(this->GetInput()));
80  if (!pointSetNode)
81  {
82  mitkThrow() << "Serialization error during PointSet writing.";
83  }
84  rootNode->LinkEndChild(pointSetNode);
85 
86  // out << doc; // streaming of TinyXML write no new-lines,
87  // rendering XML files unreadable (for humans)
88 
89  LocalFile f(this);
90  if (!doc.SaveFile(f.GetFileName()))
91  {
92  mitkThrow() << "Some error during point set writing.";
93  }
94 }
95 
96 mitk::PointSetWriterService *mitk::PointSetWriterService::Clone() const
97 {
98  return new PointSetWriterService(*this);
99 }
100 
101 TiXmlElement *mitk::PointSetWriterService::ToXML(const mitk::PointSet *pointSet)
102 {
103  // the following is rather bloated and could be expressed in more compact XML
104  // (e.g. using attributes instead of tags for x/y/z). The current format is
105  // kept to be compatible with the previous writer.
106  TiXmlElement *pointSetElement = new TiXmlElement(XML_POINT_SET);
107  unsigned int timecount = pointSet->GetTimeSteps();
108 
109  for (unsigned int i = 0; i < timecount; i++)
110  {
111  TiXmlElement *timeSeriesElement = new TiXmlElement(XML_TIME_SERIES);
112  pointSetElement->LinkEndChild(timeSeriesElement);
113 
114  TiXmlElement *timeSeriesIDElement = new TiXmlElement(XML_TIME_SERIES_ID);
115  timeSeriesElement->LinkEndChild(timeSeriesIDElement);
116  TiXmlText *timeSeriesIDText = new TiXmlText(ConvertToString(i));
117  timeSeriesIDElement->LinkEndChild(timeSeriesIDText);
118 
119  PointSet::PointsContainer *pointsContainer = pointSet->GetPointSet(i)->GetPoints();
120  PointSet::PointsContainer::Iterator it;
121 
122  Geometry3D *geometry = dynamic_cast<Geometry3D *>(pointSet->GetGeometry(i));
123  if (geometry == nullptr)
124  {
125  MITK_WARN << "Writing a PointSet with something other that a Geometry3D. This is not foreseen and not handled.";
126  // we'll continue anyway, this imitates previous behavior
127  }
128  else
129  {
130  TiXmlElement *geometryElement = Geometry3DToXML::ToXML(geometry);
131  timeSeriesElement->LinkEndChild(geometryElement);
132  }
133 
134  for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it)
135  {
136  TiXmlElement *pointElement = new TiXmlElement(XML_POINT);
137  timeSeriesElement->LinkEndChild(pointElement);
138 
139  TiXmlElement *pointIDElement = new TiXmlElement(XML_ID);
140  TiXmlText *pointIDText = new TiXmlText(ConvertToString(it->Index()));
141  pointIDElement->LinkEndChild(pointIDText);
142  pointElement->LinkEndChild(pointIDElement);
143 
144  mitk::PointSet::PointType point = it->Value();
145 
146  TiXmlElement *pointSpecElement = new TiXmlElement(XML_SPEC);
147  TiXmlText *pointSpecText = new TiXmlText(ConvertToString(pointSet->GetSpecificationTypeInfo(it->Index(), i)));
148  pointSpecElement->LinkEndChild(pointSpecText);
149  pointElement->LinkEndChild(pointSpecElement);
150 
151  TiXmlElement *pointXElement = new TiXmlElement(XML_X);
152  TiXmlText *pointXText = new TiXmlText(ConvertToString(point[0]));
153  pointXElement->LinkEndChild(pointXText);
154  pointElement->LinkEndChild(pointXElement);
155 
156  TiXmlElement *pointYElement = new TiXmlElement(XML_Y);
157  TiXmlText *pointYText = new TiXmlText(ConvertToString(point[1]));
158  pointYElement->LinkEndChild(pointYText);
159  pointElement->LinkEndChild(pointYElement);
160 
161  TiXmlElement *pointZElement = new TiXmlElement(XML_Z);
162  TiXmlText *pointZText = new TiXmlText(ConvertToString(point[2]));
163  pointZElement->LinkEndChild(pointZText);
164  pointElement->LinkEndChild(pointZElement);
165  }
166  }
167 
168  return pointSetElement;
169 }
170 
171 template <typename T>
172 std::string mitk::PointSetWriterService::ConvertToString(T value)
173 {
174  std::ostringstream o;
175  std::locale I("C");
176  o.imbue(I);
177 
178  if (o << std::setprecision(12) << value)
179  {
180  return o.str();
181  }
182  else
183  {
184  return "conversion error";
185  }
186 }
The IOMimeTypes class.
virtual PointSpecificationType GetSpecificationTypeInfo(int position, int t) const
to get the type of the point at the position and the moment
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
static TiXmlElement * ToXML(const Geometry3D *geometry)
Serialize given geometry to XML.
virtual void Write() override
Write the base data to the specified location or output stream.
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
#define MITK_WARN
Definition: mitkLogMacros.h:23
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:79
Convenience class to temporarily change the current locale.
virtual DataType::Pointer GetPointSet(int t=0) const
returns the pointset
#define mitkThrow()
static const char * GetStaticNameOfClass()
A local file representation for streams.
DataType::PointsContainer PointsContainer
Definition: mitkPointSet.h:136
us::ServiceRegistration< IFileWriter > RegisterService(us::ModuleContext *context=us::GetModuleContext())
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:129
Base class for writing mitk::BaseData objects to files or streams.