/* * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef otbStatisticsXMLFileWriter_hxx #define otbStatisticsXMLFileWriter_hxx #include "otbStatisticsXMLFileWriter.h" #include "itkMacro.h" #include "itksys/SystemTools.hxx" #include "otb_tinyxml.h" #include "otbStringUtils.h" namespace otb { template StatisticsXMLFileWriter::StatisticsXMLFileWriter() : m_FileName("") { } template void StatisticsXMLFileWriter::AddInput(const char* name, const MeasurementVectorType& inputVector) { InputDataType inputData; inputData.first = name; // Check if the statistic name is already added for (unsigned int idx = 0; idx < m_MeasurementVectorContainer.size(); ++idx) { if (m_MeasurementVectorContainer[idx].first == name) { itkExceptionMacro(<< "Token selected (" << name << ") is already added to the XML file"); } } inputData.second = inputVector; m_MeasurementVectorContainer.push_back(inputData); } template void StatisticsXMLFileWriter::GenerateData() { // Check if the input are not null if (m_MeasurementVectorContainer.size() == 0 && m_GenericMapContainer.size() == 0) itkExceptionMacro(<< "At least one input is required, please set input using the methods AddInput or AddInputMap"); // Check if the filename is not empty if (m_FileName.empty()) itkExceptionMacro(<< "The XML output FileName is empty, please set the filename via the method SetFileName"); // Check that the right extension is given : expected .xml */ const std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName); if (itksys::SystemTools::LowerCase(extension) != ".xml") { itkExceptionMacro(<< extension << " is a wrong Extension FileName : Expected .xml"); } // Write the XML file TiXmlDocument doc; TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", ""); doc.LinkEndChild(decl); TiXmlElement* root = nullptr; if (m_MeasurementVectorContainer.size()) { root = new TiXmlElement("FeatureStatistics"); doc.LinkEndChild(root); } // Iterate through the input for (unsigned int i = 0; i < m_MeasurementVectorContainer.size(); ++i) { std::string featureName = m_MeasurementVectorContainer[i].first; MeasurementVectorType currentMeasurementVector = m_MeasurementVectorContainer[i].second; // The current statistic TiXmlElement* feature = new TiXmlElement("Statistic"); feature->SetAttribute("name", featureName.c_str()); root->LinkEndChild(feature); // Store the value for this statistic for (unsigned int cindex = 0; cindex < currentMeasurementVector.Size(); ++cindex) { // For each value in Measurementvector TiXmlElement* curStatisticVector = new TiXmlElement("StatisticVector"); curStatisticVector->SetDoubleAttribute("value", currentMeasurementVector.GetElement(cindex)); feature->LinkEndChild(curStatisticVector); } } // Iterate on map containers TiXmlElement* mapRoot = nullptr; if (m_GenericMapContainer.size()) { mapRoot = new TiXmlElement("GeneralStatistics"); doc.LinkEndChild(mapRoot); } GenericMapContainer::const_iterator containerIt; for (containerIt = m_GenericMapContainer.begin(); containerIt != m_GenericMapContainer.end(); ++containerIt) { std::string mapName = containerIt->first; GenericMapType::const_iterator mapIter; // The current statistic TiXmlElement* feature = new TiXmlElement("Statistic"); feature->SetAttribute("name", mapName.c_str()); mapRoot->LinkEndChild(feature); // Store the value for this statistic for (mapIter = containerIt->second.begin(); mapIter != containerIt->second.end(); ++mapIter) { // For each value in Measurementvector TiXmlElement* curStatisticMap = new TiXmlElement("StatisticMap"); curStatisticMap->SetAttribute("key", mapIter->first.c_str()); curStatisticMap->SetAttribute("value", mapIter->second.c_str()); feature->LinkEndChild(curStatisticMap); } } // Finally, write the file if (!doc.SaveFile(m_FileName.c_str())) { itkExceptionMacro(<< "Unable to write the XML file in " << itksys::SystemTools::GetFilenamePath(m_FileName) << " (permission issue? Directory does not exist?)."); } } template template void StatisticsXMLFileWriter::AddInputMap(const char* name, const MapType& map) { std::string token(name); if (m_GenericMapContainer.count(token) > 0) { itkExceptionMacro(<< "Token selected (" << name << ") is already added to the XML file"); } typename MapType::const_iterator it; GenericMapType insideMap; std::string tmpKey; std::string tmpVal; for (it = map.begin(); it != map.end(); ++it) { tmpKey = boost::lexical_cast(it->first); tmpVal = boost::lexical_cast(it->second); insideMap[tmpKey] = tmpVal; } m_GenericMapContainer[token] = insideMap; } template void StatisticsXMLFileWriter::CleanInputs() { // clear both containers m_MeasurementVectorContainer.clear(); m_GenericMapContainer.clear(); } template void StatisticsXMLFileWriter::PrintSelf(std::ostream& os, itk::Indent indent) const { // Call superclass implementation Superclass::PrintSelf(os, indent); // Print Writer state os << indent << "Input FileName: " << m_FileName << std::endl; os << indent << "Vector statistics: "; for (unsigned int i = 0; i < m_MeasurementVectorContainer.size(); ++i) { if (i > 0) os << ", "; os << m_MeasurementVectorContainer[i].first; } os << std::endl; os << indent << "Map statistics: "; for (GenericMapContainer::const_iterator it = m_GenericMapContainer.begin(); it != m_GenericMapContainer.end(); ++it) { if (it != m_GenericMapContainer.begin()) os << ", "; os << it->first; } os << std::endl; } } // End namespace otb #endif