16#include <mitkLocaleSwitch.h>
19#include <itksys/SystemTools.hxx>
25 mitk::NavigationData::Pointer ReadNavigationData(
const tinyxml2::XMLElement* ndElem)
27 if (
nullptr == ndElem)
32 ndElem->QueryDoubleAttribute(
"Time", &timeStamp);
40 ndElem->QueryDoubleAttribute(
"X", &position[0]);
41 ndElem->QueryDoubleAttribute(
"Y", &position[1]);
42 ndElem->QueryDoubleAttribute(
"Z", &position[2]);
46 ndElem->QueryDoubleAttribute(
"QX", &orientation[0]);
47 ndElem->QueryDoubleAttribute(
"QY", &orientation[1]);
48 ndElem->QueryDoubleAttribute(
"QZ", &orientation[2]);
49 ndElem->QueryDoubleAttribute(
"QR", &orientation[3]);
54 ndElem->QueryDoubleAttribute(
"C00", &matrix[0][0]);
55 ndElem->QueryDoubleAttribute(
"C01", &matrix[0][1]);
56 ndElem->QueryDoubleAttribute(
"C02", &matrix[0][2]);
57 ndElem->QueryDoubleAttribute(
"C03", &matrix[0][3]);
58 ndElem->QueryDoubleAttribute(
"C04", &matrix[0][4]);
59 ndElem->QueryDoubleAttribute(
"C05", &matrix[0][5]);
60 ndElem->QueryDoubleAttribute(
"C10", &matrix[1][0]);
61 ndElem->QueryDoubleAttribute(
"C11", &matrix[1][1]);
62 ndElem->QueryDoubleAttribute(
"C12", &matrix[1][2]);
63 ndElem->QueryDoubleAttribute(
"C13", &matrix[1][3]);
64 ndElem->QueryDoubleAttribute(
"C14", &matrix[1][4]);
65 ndElem->QueryDoubleAttribute(
"C15", &matrix[1][5]);
68 ndElem->QueryIntAttribute(
"Valid", &attrib);
69 bool isValid = 0 != attrib;
72 ndElem->QueryIntAttribute(
"hP", &attrib);
73 bool hasPosition = 0 != attrib;
76 ndElem->QueryIntAttribute(
"hO", &attrib);
77 bool hasOrientation = 0 != attrib;
79 auto navData = mitk::NavigationData::New();
81 navData->SetIGTTimeStamp(timeStamp);
82 navData->SetPosition(position);
83 navData->SetOrientation(orientation);
84 navData->SetCovErrorMatrix(matrix);
85 navData->SetDataValid(isValid);
86 navData->SetHasPosition(hasPosition);
87 navData->SetHasOrientation(hasOrientation);
94 : AbstractFileReader(
IGTMimeTypes::NAVIGATIONDATASETXML_MIMETYPE(),
"MITK NavigationData Reader (XML)")
96 this->RegisterService();
104 : AbstractFileReader(other)
115 mitk::NavigationDataSet::Pointer dataset =
nullptr == this->GetInputStream()
116 ? this->Read(this->GetInputLocation())
117 : this->Read(*this->GetInputStream());
119 std::vector<mitk::BaseData::Pointer> result;
120 result.emplace_back(dataset.GetPointer());
125mitk::NavigationDataSet::Pointer mitk::NavigationDataReaderXML::Read(
const std::string& fileName)
127 std::ifstream stream(fileName);
128 stream.imbue(std::locale::classic());
130 return this->Read(stream);
133mitk::NavigationDataSet::Pointer mitk::NavigationDataReaderXML::Read(std::istream& stream)
135 std::string string(std::istreambuf_iterator<char>(stream), {});
136 tinyxml2::XMLDocument doc;
138 if (tinyxml2::XML_SUCCESS != doc.Parse(
string.c_str()))
139 mitkThrowException(IGTIOException) <<
"Could not parse stream.";
141 const auto* rootElem = doc.RootElement();
142 decltype(rootElem) dataElem =
nullptr;
144 if (
nullptr == rootElem)
148 auto err = tinyxml2::XML_SUCCESS;
150 std::string rootElemVal = rootElem->Value();
152 if (
"Version" == rootElemVal)
154 err = rootElem->QueryIntAttribute(
"Ver", &version);
155 dataElem = rootElem->NextSiblingElement(
"Data");
157 else if (
"Data" == rootElemVal)
159 err = rootElem->QueryIntAttribute(
"version", &version);
163 if (err != tinyxml2::XML_SUCCESS)
164 mitkThrowException(IGTIOException) <<
"Could not parse file format version.";
167 mitkThrowException(IGTIOException) <<
"File format version " << version <<
" is not supported.";
169 if (
nullptr == dataElem)
170 mitkThrowException(IGTIOException) <<
"Data element not found.";
174 if (tinyxml2::XML_SUCCESS != dataElem->QueryIntAttribute(
"ToolCount", &toolCount))
175 mitkThrowException(IGTIOException) <<
"ToolCount attribute missing from Data element.";
178 mitkThrowException(IGTIOException) <<
"Invalid ToolCount: " << toolCount <<
".";
180 auto navDataSet = NavigationDataSet::New(
static_cast<unsigned int>(toolCount));
181 NavigationData::Pointer navData;
183 const auto* ndElem = dataElem->FirstChildElement();
185 if (
nullptr != ndElem)
189 std::vector<NavigationData::Pointer> navDatas(toolCount);
191 for (
decltype(toolCount) i = 0; i < toolCount; ++i)
193 navData = ReadNavigationData(ndElem);
195 if (navData.IsNull())
198 MITK_WARN(
"mitkNavigationDataReaderXML") <<
"Different number of NavigationData objects for different tools. Ignoring last ones.";
203 navDatas[i] = navData;
204 ndElem = ndElem->NextSiblingElement();
207 if (navData.IsNotNull())
208 navDataSet->AddNavigationDatas(navDatas);
210 }
while (
nullptr != ndElem && navData.IsNotNull());
mitk::NavigationDataReaderXML * Clone() const override
std::vector< itk::SmartPointer< BaseData > > DoRead() override
NavigationDataReaderXML()
~NavigationDataReaderXML() override
itk::Matrix< mitk::ScalarType, 6, 6 > CovarianceMatrixType
type that holds the error characterization of the position and orientation measurements
mitk::Quaternion OrientationType
Type that holds the orientation part of the tracking data.
double TimeStampType
type that holds the time at which the data was recorded in milliseconds
mitk::Point3D PositionType
Type that holds the position part of the tracking data.