Commit b9a74362 authored by Julien Osman's avatar Julien Osman

ENH: Add class otbXMLMetadataSupplier

Changes in otbMetadataSupplierInterface: method
- GetRessourceFile now takes a parameter
- new method GetRessourceFiles
parent f6ea5b55
......@@ -66,11 +66,12 @@ public:
class OTBMetadata_EXPORT MetadataSupplierInterface
{
public:
virtual std::string GetResourceFile(std::string="") const = 0;
virtual std::vector<std::string> GetResourceFiles() const
{
return std::vector<std::string>{this->GetResourceFile()};
}
virtual std::string GetResourceFile() const = 0;
// Maybe not needed
// virtual std::vector<std::string> GetResourceFiles() = 0;
/** Get the metadata value corresponding to a given path (meaning of this path
* depends on the specific implementation. Returns NULL when path is not found
......@@ -93,7 +94,7 @@ public:
}
catch (boost::bad_lexical_cast&)
{
otbGenericExceptionMacro(MissingMetadataException,<<"Bad metadata value for '"<<path<<"', got :"<<ret)
otbGenericExceptionMacro(MissingMetadataException,<<"Bad metadata value for '"<<path<<"', got: "<<ret)
}
}
......
/*
* Copyright (C) 2005-2020 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 otbXMLMetadataSupplier_h
#define otbXMLMetadataSupplier_h
#include "cpl_minixml.h"
#include "cpl_string.h"
#include "OTBMetadataExport.h"
#include "otbMetadataSupplierInterface.h"
#include "otbStringUtilities.h"
namespace otb
{
/** \class XMLMetadataSupplier
*
* \brief Class to access metadata information in a XML file
*
* \ingroup OTBMetadata
*/
class OTBMetadata_EXPORT XMLMetadataSupplier
: public MetadataSupplierInterface
{
public:
XMLMetadataSupplier(const std::string &);
/** Get the metadata value corresponding to a given path
* Returns NULL when path is not found
* If band >= 0, the metadata value is looked in the specified band*/
const char * GetMetadataValue(const char * path, int band=1) const override;
std::string GetResourceFile(std::string="") const override;
std::string PrintSelf();
protected:
/**
* @brief ReadXMLToList Transform xml to list of NULL terminated name=value
* strings
* @param psNode A xml node to process
* @param papszList A list to fill with name=value strings
* @param pszName A name of parent node. For root xml node should be empty.
* If name is not empty, the sibling nodes will not proceed
* @return An input list filled with values
*
* This method originates from a work by GDAL in the class GDALMDReaderBase.
*/
virtual char** ReadXMLToList(CPLXMLNode* psNode, char** papszList,
const char* pszName = "");
private:
/** List of resource files */
std::string m_FileName;
/** Dictionary containing the metadata */
char** m_MetadataDic = nullptr;
};
} // end namespace otb
#endif
/*
* Copyright (C) 2005-2020 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.
*/
#include "otbXMLMetadataSupplier.h"
namespace otb
{
XMLMetadataSupplier::XMLMetadataSupplier(const std::string & fileName)
: m_FileName(fileName)
{
CPLXMLNode* psNode = CPLParseXMLFile(m_FileName.c_str());
if(psNode != nullptr)
{
//if(std::string(psNode->pszValue) == "?xml")
// if(EQUAL(psNode->pszValue, "?xml"))
// psNode = psNode->psNext;
m_MetadataDic = ReadXMLToList(psNode, m_MetadataDic);
}
else
{
otbLogMacro(Warning, <<"Unable to parse XML file " << fileName);
m_MetadataDic = nullptr;
}
CPLDestroyXMLNode(psNode);
}
const char * XMLMetadataSupplier::GetMetadataValue(const char * path, int band) const
{
return CSLFetchNameValue(m_MetadataDic, path);
}
std::string XMLMetadataSupplier::GetResourceFile(std::string) const
{
return m_FileName;
}
// This method originates from a work by GDAL in the class GDALMDReaderBase.
char** XMLMetadataSupplier::ReadXMLToList(CPLXMLNode* psNode, char** papszList,
const char* pszName)
{
if(nullptr == psNode)
return papszList;
if (psNode->eType == CXT_Text)
{
papszList = CSLAddNameValue(papszList, pszName, psNode->pszValue);
}
if (psNode->eType == CXT_Element)
{
int nAddIndex = 0;
bool bReset = false;
for(CPLXMLNode* psChildNode = psNode->psChild; nullptr != psChildNode;
psChildNode = psChildNode->psNext)
{
if (psChildNode->eType == CXT_Element)
{
// check name duplicates
if(nullptr != psChildNode->psNext)
{
if(bReset)
{
bReset = false;
nAddIndex = 0;
}
if(EQUAL(psChildNode->pszValue, psChildNode->psNext->pszValue))
{
nAddIndex++;
}
else
{ // the name changed
if(nAddIndex > 0)
{
bReset = true;
nAddIndex++;
}
}
}
else
{
if(bReset)
{
bReset = false;
nAddIndex = 0;
}
if(nAddIndex > 0)
{
nAddIndex++;
}
}
char szName[512];
if(nAddIndex > 0)
{
CPLsnprintf( szName, 511, "%s_%d", psChildNode->pszValue,
nAddIndex);
}
else
{
CPLStrlcpy(szName, psChildNode->pszValue, 511);
}
char szNameNew[512];
if(CPLStrnlen( pszName, 511 ) > 0) //if no prefix just set name to node name
{
CPLsnprintf( szNameNew, 511, "%s.%s", pszName, szName );
}
else
{
CPLsnprintf( szNameNew, 511, "%s.%s", psNode->pszValue, szName );
}
papszList = ReadXMLToList(psChildNode, papszList, szNameNew);
}
else if( psChildNode->eType == CXT_Attribute )
{
papszList = CSLAddNameValue(papszList,
CPLSPrintf("%s.%s", pszName, psChildNode->pszValue),
psChildNode->psChild->pszValue);
}
else
{
// Text nodes should always have name
if(EQUAL(pszName, ""))
{
papszList = ReadXMLToList(psChildNode, papszList, psNode->pszValue);
}
else
{
papszList = ReadXMLToList(psChildNode, papszList, pszName);
}
}
}
}
// proceed next only on top level
if(nullptr != psNode->psNext && EQUAL(pszName, ""))
{
papszList = ReadXMLToList(psNode->psNext, papszList, pszName);
}
return papszList;
}
std::string XMLMetadataSupplier::PrintSelf()
{
std::ostringstream oss;
oss << "XMLMetadataSupplier: " << this->m_FileName << '\n';
for (char ** string = this->m_MetadataDic; *string != nullptr ; ++string)
oss << *string << '\n';
return oss.str();
}
} // end namespace otb
......@@ -206,7 +206,8 @@ public:
// MetadataSupplierInterface overrides
/** Get main image file */
std::string GetResourceFile() const override;
std::string GetResourceFile(std::string="") const override;
std::vector<std::string> GetResourceFiles() const override;
/** Get metadata item in GDALDataset, domain can specified as "domain/key" */
const char * GetMetadataValue(const char * path, int band = -1) const override;
......
......@@ -42,6 +42,9 @@
#include "ogr_spatialref.h"
#include "ogr_srs_api.h"
#include "itksys/RegularExpression.hxx"
#include "otbGDALDriverManagerWrapper.h"
#include "otb_boost_string_header.h"
......@@ -1803,11 +1806,27 @@ std::string GDALImageIO::GetGdalPixelTypeAsString() const
}
std::string GDALImageIO::GetResourceFile() const
std::string GDALImageIO::GetResourceFile(std::string str) const
{
return m_FileName;
if (str.empty())
return m_FileName;
itksys::RegularExpression reg;
reg.compile(str);
for (auto & filename : GetResourceFiles())
if (reg.find(filename))
return filename;
return std::string("");
}
std::vector<std::string> GDALImageIO::GetResourceFiles() const
{
std::vector<std::string> result;
for (char ** file = this->m_Dataset->GetDataSet()->GetFileList() ; *file != nullptr ; ++ file)
result.push_back(*file);
return result;
}
const char * GDALImageIO::GetMetadataValue(const char * path, int band) const
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment