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