diff --git a/Documentation/Cookbook/rst/AdvancedUse.rst b/Documentation/Cookbook/rst/AdvancedUse.rst index 604380e57a96fd41d45411e905f6380256f6c21c..5ce7228d2f45f4db63d51ed917a8283c3a9e4d0e 100644 --- a/Documentation/Cookbook/rst/AdvancedUse.rst +++ b/Documentation/Cookbook/rst/AdvancedUse.rst @@ -315,6 +315,36 @@ The available syntax for boolean options are: - OFF, Off, off, false, False, 0 are available for setting a ’false’ boolean value +OGR DataSource options +^^^^^^^^^^^^^^^^^^^^^^^ + +We extended this process to OGR DataSource. There are three different type of +option : open, creation and layer creation. Those options come from the GDAL +API. In order to use them one just need to specify to which of this family +the option one want to use is from. + +For open option : + +:: + + &gdal:oo:<GDALKEY>=<VALUE> + + +For creation option : + +:: + + &gdal:co:<GDALKEY>=<VALUE> + + +For layer creation option : + +:: + + &gdal:lco:<GDALKEY>=<VALUE> + + + Examples ^^^^^^^^^^^^^^ diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h b/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h index eb6daff5f0510f2a9908ac88f3c5566df747ebd2..b06a173fd978e0d7237157fed617e3c90d9ad6f8 100644 --- a/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h +++ b/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h @@ -46,6 +46,7 @@ #include "otbOGRLayerWrapper.h" #include "otbOGRVersionProxy.h" +#include "otbOGRExtendedFilenameToOptions.h" class OGRLayer; class OGRSpatialReference; @@ -88,6 +89,7 @@ public: typedef itk::SmartPointer<const Self> ConstPointer; //@} + typedef OGRExtendedFilenameToOptions FileNameHelperType; /**\name Standard macros */ //@{ /** Default builder. @@ -162,7 +164,7 @@ public: * \note No condition is assumed on the non-nullity of \c source. * \see \c DataSource(GDALDataset *) */ - static Pointer New(ogr::version_proxy::GDALDatasetType * sourcemode, Modes::type mode = Modes::Read); + static Pointer New(ogr::version_proxy::GDALDatasetType * sourcemode, Modes::type mode = Modes::Read , const std::vector< std::string > & layerOptions = std::vector< std::string >() ); //@} /**\name Projection Reference property */ @@ -368,7 +370,7 @@ public: Layer CopyLayer( Layer & srcLayer, std::string const& newName, - char ** papszOptions = ITK_NULLPTR); + std::vector<std::string> const& papszOptions = std::vector<std::string>() ); //@} /**\name Layers access @@ -497,6 +499,10 @@ public: */ ogr::version_proxy::GDALDatasetType & ogr(); + void SetLayerCreationOptions( const std::vector< std::string > & options ); + void AddLayerCreationOptions( std::vector< std::string > options ); + const std::vector< std::string > & GetLayerCreationOptions() const ; + protected: /** Default constructor. * The actual \c GDALDataset is using the <em>in-memory</em> \c @@ -511,7 +517,7 @@ protected: /** Init constructor. * \post The newly constructed object owns the \c source parameter. */ - DataSource(ogr::version_proxy::GDALDatasetType * source, Modes::type mode); + DataSource(ogr::version_proxy::GDALDatasetType * source, Modes::type mode , const std::vector< std::string > & layerOption = std::vector< std::string >() ); /** Destructor. * \post The \c GDALDataset owned is released (if not null). */ @@ -549,6 +555,7 @@ private: private: ogr::version_proxy::GDALDatasetType *m_DataSource; + std::vector< std::string > m_LayerOptions; Modes::type m_OpenMode; int m_FirstModifiableLayerID; }; // end class DataSource diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRExtendedFilenameToOptions.h b/Modules/Adapters/GdalAdapters/include/otbOGRExtendedFilenameToOptions.h new file mode 100644 index 0000000000000000000000000000000000000000..6ae631531fd5d2de3f6198851deace861b11b1ec --- /dev/null +++ b/Modules/Adapters/GdalAdapters/include/otbOGRExtendedFilenameToOptions.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2005-2017 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 otbOGRExtendedFilenameToOptions_h +#define otbOGRExtendedFilenameToOptions_h + +#include <unordered_map> +#include "otbExtendedFilenameHelper.h" + +namespace otb +{ + +/** \class OGRExtendedFilenameToOptions + * \brief This class aim at processing GDAL option that can be pass through + * extended filename. + * \ingroup OTBExtendedFilename + * \ingroup OTBGdalAdapters + * + */ +#include "OTBGdalAdaptersExport.h" + +class OTBGdalAdapters_EXPORT OGRExtendedFilenameToOptions : public ExtendedFilenameHelper +{ +public: + /** Standard class typedefs. */ + typedef OGRExtendedFilenameToOptions Self; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + typedef ExtendedFilenameHelper Superclass; + + typedef Superclass::OptionMapType OptionMapType; + typedef OptionMapType::const_iterator ConstMapIteratorType; + typedef std::vector<std::string> GDALOptionType; + + itkTypeMacro(OGRExtendedFilenameToOptions, otb::ExtendedFilenameHelper); + itkNewMacro(Self); + + + /** The creation option structure. */ + struct OpenOptionType + { + GDALOptionType gdalOptions; + // std::unordered_map< std::string , bool > availableOptions; + }; + + struct CreationOptionType + { + GDALOptionType gdalOptions; + // std::unordered_map< std::string , bool > availableOptions; + }; + + struct LayerOptionType + { + std::unordered_map< std::string , std::string > gdalOptions; + }; + + /** Set extended filename */ + void SetExtendedFileName(const char * extFname) override; + + /** Get the GDAL option for type operation */ + GDALOptionType GetGDALOptions( const std::string & type ) const ; + + /** Get the deffierent GDAL options*/ + GDALOptionType GetGDALOpenOptions() const ; + GDALOptionType GetGDALCreationOptions() const ; + GDALOptionType GetGDALLayerOptions() const ; + + bool SimpleFileNameIsSet() const; + bool HasGDALLayerOption() const; + + /** Set GDAL layer option through a vector of string */ + void SetGDALLayerOptions( const GDALOptionType & options ); + + /** Add GDAL layer option to existing one */ + void AddGDALLayerOptions( const GDALOptionType & options ); + + /** Constructor that return a pointer to an OGRExtendedFilename with + * GDAL layer option as options + */ + static Pointer GetGDALLayerOptionsHelper( const GDALOptionType & options ); + +protected: + OGRExtendedFilenameToOptions(); + OGRExtendedFilenameToOptions( const GDALOptionType & options ); + ~OGRExtendedFilenameToOptions() override {}; + +private: + OGRExtendedFilenameToOptions(const Self &) = delete ; + void operator =(const Self&) = delete ; + + OpenOptionType m_OpenOptions; + CreationOptionType m_CreationOptions; + LayerOptionType m_LayerOptions; + bool m_HasFileName; +}; + +} //end namespace otb + +#endif // otbOGRExtendedFilenameToOptions_h diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h b/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h index 7fdc308413d2a912eba471b90fe74576e1ef5310..7cae3f6dba4cf94203bfcb7e3cd52f431a5309c9 100644 --- a/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h +++ b/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h @@ -97,7 +97,7 @@ OTBGdalAdapters_EXPORT bool IsOFTInteger64(OGRFieldType type); * \return NULL if file could not be open. */ OTBGdalAdapters_EXPORT - GDALDatasetType * Open(const char * filename, bool readOnly = true); + GDALDatasetType * Open(const char * filename, bool readOnly = true , std::vector< std::string > const & options = std::vector< std::string >() ); /** * This function closes a dataset. @@ -126,7 +126,7 @@ OTBGdalAdapters_EXPORT bool IsOFTInteger64(OGRFieldType type); * \return NULL if dataset could not be created. */ OTBGdalAdapters_EXPORT - GDALDatasetType * Create(GDALDriverType * driver, const char * name); + GDALDatasetType * Create(GDALDriverType * driver, const char * name , std::vector< std::string > const & options = std::vector< std::string >() ); /** diff --git a/Modules/Adapters/GdalAdapters/otb-module.cmake b/Modules/Adapters/GdalAdapters/otb-module.cmake index 637a63ed4226e96af21f3fb7b3a1136c6db100b0..c985c5fb0e477a9f35de9a629e506d865239ee5e 100644 --- a/Modules/Adapters/GdalAdapters/otb-module.cmake +++ b/Modules/Adapters/GdalAdapters/otb-module.cmake @@ -29,6 +29,9 @@ ENABLE_SHARED OTBGDAL OTBITK + TEST_DEPENDS + OTBTestKernel + DESCRIPTION "${DOCUMENTATION}" ) diff --git a/Modules/Adapters/GdalAdapters/src/CMakeLists.txt b/Modules/Adapters/GdalAdapters/src/CMakeLists.txt index 4ba50ff1e286f05842703510931bffec1d5f0f21..0f73c07a03e044b6c89d6a19b5df6fc6b9ae4851 100644 --- a/Modules/Adapters/GdalAdapters/src/CMakeLists.txt +++ b/Modules/Adapters/GdalAdapters/src/CMakeLists.txt @@ -29,6 +29,7 @@ set(OTBGdalAdapters_SRC otbGeometriesToGeometriesFilter.cxx otbOGRDataSourceWrapper.cxx otbOGRVersionProxy.cxx + otbOGRExtendedFilenameToOptions.cxx ) add_library(OTBGdalAdapters ${OTBGdalAdapters_SRC}) diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx index ac43afbb4d837ce66ed40327bb4b8d1664626cc4..d5cfec4ef94e8efe1c21c105921974236dc7893a 100644 --- a/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx +++ b/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx @@ -41,6 +41,7 @@ /*===========================================================================*/ /*=======================[ construction/destruction ]========================*/ /*===========================================================================*/ + bool otb::ogr::DataSource::Clear() { Reset(ITK_NULLPTR); @@ -117,22 +118,29 @@ char const* DeduceDriverName(std::string filename) otb::ogr::DataSource::DataSource() : m_DataSource(ITK_NULLPTR), + m_LayerOptions() , m_OpenMode(Modes::Update_LayerUpdate), m_FirstModifiableLayerID(0) { Drivers::Init(); - ogr::version_proxy::GDALDriverType * d = ogr::version_proxy::GetDriverByName("Memory"); + ogr::version_proxy::GDALDriverType * d = + ogr::version_proxy::GetDriverByName("Memory"); assert(d && "OGR Memory driver not found"); m_DataSource = ogr::version_proxy::Create(d,"in-memory"); if (!m_DataSource) { - itkExceptionMacro(<< "Failed to create OGRMemDataSource: " << CPLGetLastErrorMsg()); + itkExceptionMacro(<< "Failed to create OGRMemDataSource: " + << CPLGetLastErrorMsg()); } } -otb::ogr::DataSource::DataSource(otb::ogr::version_proxy::GDALDatasetType * source, Modes::type mode) -: m_DataSource(source), - m_OpenMode(mode), +otb::ogr::DataSource::DataSource( + otb::ogr::version_proxy::GDALDatasetType * source , + Modes::type mode , + const std::vector< std::string > & options /*NULL*/ ) +: m_DataSource(source) , + m_LayerOptions(options) , + m_OpenMode(mode) , m_FirstModifiableLayerID(0) { m_FirstModifiableLayerID = GetLayersCount(); @@ -140,9 +148,15 @@ otb::ogr::DataSource::DataSource(otb::ogr::version_proxy::GDALDatasetType * sour otb::ogr::DataSource::Pointer otb::ogr::DataSource::OpenDataSource(std::string const& datasourceName, Modes::type mode) { - bool update = (mode != Modes::Read); + FileNameHelperType::Pointer fileNameHelper = FileNameHelperType::New(); + fileNameHelper->SetExtendedFileName( datasourceName.c_str() ); + std::string simpleFileName = fileNameHelper->GetSimpleFileName(); - ogr::version_proxy::GDALDatasetType * source = ogr::version_proxy::Open(datasourceName.c_str(),!update); + bool update = (mode != Modes::Read); + ogr::version_proxy::GDALDatasetType * source = + ogr::version_proxy::Open( simpleFileName.c_str() , + !update , + fileNameHelper->GetGDALOpenOptions() ); if (!source) { // In read mode, this is a failure @@ -150,39 +164,51 @@ otb::ogr::DataSource::Pointer otb::ogr::DataSource::OpenDataSource(std::string c if (mode == Modes::Read) { itkGenericExceptionMacro(<< "Failed to open GDALDataset file " - << datasourceName<<" : " << CPLGetLastErrorMsg()); + << simpleFileName<<" : " << CPLGetLastErrorMsg()); } // Hand made factory based on file extension. - char const* driverName = DeduceDriverName(datasourceName); + char const* driverName = DeduceDriverName(simpleFileName); if (!driverName) { - itkGenericExceptionMacro(<< "No OGR driver known to OTB to create and handle a DataSource named <" - <<datasourceName<<">."); + itkGenericExceptionMacro(<< "No OGR driver known to OTB to create and " + "handle a DataSource named <" + <<simpleFileName<<">."); } - ogr::version_proxy::GDALDriverType * d = ogr::version_proxy::GetDriverByName(driverName); + ogr::version_proxy::GDALDriverType * d = + ogr::version_proxy::GetDriverByName( driverName ); if(!d) { - itkGenericExceptionMacro(<<"Could not create OGR driver "<<driverName<<", check your OGR configuration for available drivers."); + itkGenericExceptionMacro(<< "Could not create OGR driver " << driverName + << ", check your OGR configuration for available drivers." ); } - source = ogr::version_proxy::Create(d,datasourceName.c_str()); + source = ogr::version_proxy::Create( + d , + simpleFileName.c_str() , + fileNameHelper->GetGDALCreationOptions() ); if (!source) { - itkGenericExceptionMacro(<< "Failed to create GDALDataset <"<<datasourceName - <<"> (driver name: <" << driverName<<">: " << CPLGetLastErrorMsg()); + itkGenericExceptionMacro(<< "Failed to create GDALDataset <" + << simpleFileName << "> (driver name: <" << driverName + <<">: " << CPLGetLastErrorMsg()); } } - return otb::ogr::DataSource::New(source, mode); + return otb::ogr::DataSource::New( source , mode , fileNameHelper->GetGDALLayerOptions() ); } void DeleteDataSource(std::string const& datasourceName) { - bool ret = otb::ogr::version_proxy::Delete(datasourceName.c_str()); + otb::OGRExtendedFilenameToOptions::Pointer fileNameHelper = + otb::OGRExtendedFilenameToOptions::New(); + fileNameHelper->SetExtendedFileName( datasourceName.c_str() ); + std::string simpleFileName = fileNameHelper->GetSimpleFileName(); + + bool ret = otb::ogr::version_proxy::Delete(simpleFileName.c_str()); if (!ret) { - itkGenericExceptionMacro(<< "Deletion of data source " << datasourceName + itkGenericExceptionMacro(<< "Deletion of data source " << simpleFileName << " failed: " << CPLGetLastErrorMsg()); } } @@ -190,14 +216,18 @@ void DeleteDataSource(std::string const& datasourceName) otb::ogr::DataSource::Pointer otb::ogr::DataSource::New(std::string const& datasourceName, Modes::type mode) { + FileNameHelperType::Pointer fileNameHelper = FileNameHelperType::New(); + fileNameHelper->SetExtendedFileName( datasourceName.c_str() ); + std::string simpleFileName = fileNameHelper->GetSimpleFileName(); + if (mode < Modes::Read || mode >= Modes::MAX__) { - itkGenericExceptionMacro(<< "Wrong mode when opening " << datasourceName); + itkGenericExceptionMacro(<< "Wrong mode when opening " << simpleFileName ); } Drivers::Init(); - - ogr::version_proxy::GDALDatasetType * ds = ogr::version_proxy::Open(datasourceName.c_str(),true); + ogr::version_proxy::GDALDatasetType * ds = + ogr::version_proxy::Open( simpleFileName.c_str() , true ); bool ds_exists = (ds!=ITK_NULLPTR); @@ -214,9 +244,9 @@ otb::ogr::DataSource::New(std::string const& datasourceName, Modes::type mode) /*static*/ otb::ogr::DataSource::Pointer -otb::ogr::DataSource::New(otb::ogr::version_proxy::GDALDatasetType * source, Modes::type mode) +otb::ogr::DataSource::New(otb::ogr::version_proxy::GDALDatasetType * source , Modes::type mode , const std::vector< std::string > & layerOptions ) { - Pointer res = new DataSource(source, mode); + Pointer res = new DataSource( source , mode , layerOptions ); res->UnRegister(); return res; } @@ -262,13 +292,20 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( if (m_OpenMode == Modes::Read) { otb::ogr::Layer l = GetLayerChecked(name); // will throw if not existing - itkGenericOutputMacro(<< "Requesting layer creation in read-only GDALDataset. Returning the existing layer"); + itkGenericOutputMacro(<< "Requesting layer creation in read-only " + "GDALDataset. Returning the existing layer"); return l; } // Other mode : Check if the layer already exists. otb::ogr::Layer layer = GetLayer(name); // won't throw on failure + FileNameHelperType::Pointer layerOptionHelper = + FileNameHelperType::GetGDALLayerOptionsHelper( m_LayerOptions ); + layerOptionHelper->AddGDALLayerOptions( papszOptions ); + std::vector<std::string> layerOptions = + layerOptionHelper->GetGDALLayerOptions(); + switch (m_OpenMode) { case Modes::Update_LayerOverwrite: @@ -281,11 +318,15 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( // Then create it OGRLayer * ol = m_DataSource->CreateLayer( - name.c_str(), poSpatialRef, eGType, otb::ogr::StringListConverter(papszOptions).to_ogr()); + name.c_str() , + poSpatialRef , + eGType , + otb::ogr::StringListConverter( layerOptions ).to_ogr() ); + if (!ol) { itkGenericExceptionMacro(<< "Failed to create the layer <"<<name - << "> in the GDALDataset file <" << GetDatasetDescription() + << "> in the GDALDataset file <" << GetDatasetDescription() <<">: " << CPLGetLastErrorMsg()); } @@ -304,11 +345,15 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( { // Then create it OGRLayer * ol = m_DataSource->CreateLayer( - name.c_str(), poSpatialRef, eGType, otb::ogr::StringListConverter(papszOptions).to_ogr()); + name.c_str() , + poSpatialRef , + eGType , + otb::ogr::StringListConverter( layerOptions ).to_ogr() ); + if (!ol) { itkGenericExceptionMacro(<< "Failed to create the layer <"<<name - << "> in the GDALDataset file <" << GetDatasetDescription() + << "> in the GDALDataset file <" << GetDatasetDescription() <<">: " << CPLGetLastErrorMsg()); } @@ -328,11 +373,15 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( // Case where the layer does not exists OGRLayer * ol = m_DataSource->CreateLayer( - name.c_str(), poSpatialRef, eGType, otb::ogr::StringListConverter(papszOptions).to_ogr()); + name.c_str() , + poSpatialRef , + eGType , + otb::ogr::StringListConverter( layerOptions ).to_ogr() ); + if (!ol) { itkGenericExceptionMacro(<< "Failed to create the layer <"<<name - << "> in the GDALDataset file <" << GetDatasetDescription() + << "> in the GDALDataset file <" << GetDatasetDescription() <<">: " << CPLGetLastErrorMsg()); } @@ -353,7 +402,7 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer( otb::ogr::Layer otb::ogr::DataSource::CopyLayer( Layer & srcLayer, std::string const& newName, - char ** papszOptions/* = NULL */) + std::vector<std::string> const& papszOptions/* = NULL */) { assert(m_DataSource && "Datasource not initialized"); @@ -364,23 +413,33 @@ otb::ogr::Layer otb::ogr::DataSource::CopyLayer( itkGenericExceptionMacro(<< "Invalid GDALDataset opening mode"); break; case Modes::Read: - itkGenericExceptionMacro(<< "GDALDataset is opened in Read mode : cannot create a layer"); + itkGenericExceptionMacro(<< "GDALDataset is opened in Read mode : " + "cannot create a layer"); break; default: break; } + + FileNameHelperType::Pointer layerOptionHelper = + FileNameHelperType::GetGDALLayerOptionsHelper( m_LayerOptions ); + layerOptionHelper->AddGDALLayerOptions( papszOptions ); + std::vector<std::string> layerOptions = + layerOptionHelper->GetGDALLayerOptions(); OGRLayer * l0 = &srcLayer.ogr(); - OGRLayer * ol = m_DataSource->CopyLayer(l0, newName.c_str(), papszOptions); + OGRLayer * ol = m_DataSource->CopyLayer( + l0 , + newName.c_str() , + otb::ogr::StringListConverter( layerOptions ).to_ogr() ); if (!ol) { itkGenericExceptionMacro(<< "Failed to copy the layer <" - << srcLayer.GetName() << "> into the new layer <" <<newName - << "> in the GDALDataset file <" << GetDatasetDescription() + << srcLayer.GetName() << "> into the new layer <" << newName + << "> in the GDALDataset file <" << GetDatasetDescription() <<">: " << CPLGetLastErrorMsg()); } const bool modifiable = true; - Layer l(ol, modifiable); + Layer l( ol , modifiable ); return l; } @@ -395,10 +454,12 @@ void otb::ogr::DataSource::DeleteLayer(size_t i) itkGenericExceptionMacro(<< "Invalid GDALDataset opening mode"); break; case Modes::Read: - itkGenericExceptionMacro(<< "GDALDataset is opened in Read mode : cannot delete a layer"); + itkGenericExceptionMacro(<< "GDALDataset is opened in Read mode : " + "cannot delete a layer"); break; case Modes::Update_LayerCreateOnly: - itkGenericExceptionMacro(<< "GDALDataset is opened in Update_LayerCreateOnly mode : cannot delete a layer"); + itkGenericExceptionMacro(<< "GDALDataset is opened in " + "Update_LayerCreateOnly mode : cannot delete a layer"); break; default: break; @@ -407,14 +468,16 @@ void otb::ogr::DataSource::DeleteLayer(size_t i) const int nb_layers = GetLayersCount(); if (int(i) >= nb_layers) { - itkExceptionMacro(<< "Cannot delete " << i << "th layer in the GDALDataset <" - << GetDatasetDescription() << "> as it contains only " << nb_layers << "layers."); + itkExceptionMacro(<< "Cannot delete " << i + << "th layer in the GDALDataset <" << GetDatasetDescription() + << "> as it contains only " << nb_layers << "layers."); } const OGRErr err = m_DataSource->DeleteLayer(int(i)); if (err != OGRERR_NONE) { - itkExceptionMacro(<< "Cannot delete " << i << "th layer in the GDALDataset <" - << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg()); + itkExceptionMacro(<< "Cannot delete " << i + << "th layer in the GDALDataset <" << GetDatasetDescription() + << ">: " << CPLGetLastErrorMsg()); } } @@ -471,7 +534,7 @@ size_t otb::ogr::DataSource::GetLayerID(std::string const& name) const if (id < 0) { itkExceptionMacro( << "Cannot fetch any layer named <" << name - << "> in the GDALDataset <" << GetDatasetDescription() << ">: " + << "> in the GDALDataset <" << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg()); } return 0; // keep compiler happy @@ -484,13 +547,15 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(size_t i) if (int(i) >= nb_layers) { itkExceptionMacro(<< "Cannot fetch " << i << "th layer in the GDALDataset <" - << GetDatasetDescription() << "> as it contains only " << nb_layers << "layers."); + << GetDatasetDescription() << "> as it contains only " << nb_layers + << "layers."); } OGRLayer * layer_ptr = m_DataSource->GetLayer(int(i)); if (!layer_ptr) { - itkExceptionMacro( << "Unexpected error: cannot fetch " << i << "th layer in the GDALDataset <" - << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg()); + itkExceptionMacro( << "Unexpected error: cannot fetch " << i + << "th layer in the GDALDataset <" << GetDatasetDescription() + << ">: " << CPLGetLastErrorMsg()); } return otb::ogr::Layer(layer_ptr, IsLayerModifiable(i)); } @@ -540,8 +605,9 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL( if (!layer_ptr) { #if defined(PREFER_EXCEPTION) - itkExceptionMacro( << "Unexpected error: cannot execute the SQL request <" << statement - << "> in the GDALDataset <" << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg()); + itkExceptionMacro( << "Unexpected error: cannot execute the SQL request <" + << statement << "> in the GDALDataset <" << GetDatasetDescription() + << ">: " << CPLGetLastErrorMsg()); #else // Cannot use the deleter made for result sets obtained from // GDALDataset::ExecuteSQL because it checks for non-nullity.... @@ -552,7 +618,33 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL( return otb::ogr::Layer(layer_ptr, *m_DataSource, modifiable); } +void +otb::ogr::DataSource:: +SetLayerCreationOptions( const std::vector< std::string > & options ) +{ + FileNameHelperType::Pointer helper = FileNameHelperType::New(); + helper->SetGDALLayerOptions( options ); + m_LayerOptions = helper->GetGDALLayerOptions(); + // perf : do we move code from helper->SetGDALLayerOptions in here? +} +void +otb::ogr::DataSource:: +AddLayerCreationOptions( std::vector< std::string > options ) +{ + FileNameHelperType::Pointer helper = FileNameHelperType::New(); + helper->SetGDALLayerOptions( m_LayerOptions ); + helper->AddGDALLayerOptions( options ); + m_LayerOptions = helper->GetGDALLayerOptions(); + // perf : do we move code from helper->AddGDALLayerOptions in here? +} + +const std::vector< std::string > & +otb::ogr::DataSource:: +GetLayerCreationOptions() const +{ + return m_LayerOptions; +} /*===========================================================================*/ /*===============================[ features ]================================*/ /*===========================================================================*/ @@ -591,7 +683,8 @@ OGREnvelope otb::ogr::DataSource::GetGlobalExtent(bool force/* = false */, std:: if(lit==this->end()) { - itkGenericExceptionMacro(<< "Cannot compute global extent because there are no layers in the DataSource"); + itkGenericExceptionMacro(<< "Cannot compute global extent because there " + "are no layers in the DataSource"); } const OGRSpatialReference * ref_srs = lit->GetSpatialRef(); @@ -695,16 +788,18 @@ void otb::ogr::DataSource::SyncToDisk() if(!ret) { itkExceptionMacro( << "Cannot flush the pending of the OGRDataSource <" - << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg()); + << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg()); } } std::string otb::ogr::DataSource::GetDatasetDescription() const { - std::vector<std::string> files = otb::ogr::version_proxy::GetFileListAsStringVector(m_DataSource); + std::vector<std::string> files = + otb::ogr::version_proxy::GetFileListAsStringVector( m_DataSource ); std::string description = ""; - for(std::vector<std::string>::const_iterator it = files.begin();it!=files.end();++it) + for( std::vector<std::string>::const_iterator it = files.begin() ; + it!=files.end() ; ++it ) description+=(*it)+", "; return description; diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRExtendedFilenameToOptions.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRExtendedFilenameToOptions.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a34e70947138645f0d660570c6abdefedb7aa141 --- /dev/null +++ b/Modules/Adapters/GdalAdapters/src/otbOGRExtendedFilenameToOptions.cxx @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2005-2017 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 "otbOGRExtendedFilenameToOptions.h" +#include "otb_boost_string_header.h" +#include "otb_boost_tokenizer_header.h" + +namespace otb +{ + +OGRExtendedFilenameToOptions:: +OGRExtendedFilenameToOptions(): +m_HasFileName(false) +{ +} + +OGRExtendedFilenameToOptions:: +OGRExtendedFilenameToOptions( const GDALOptionType & options ): +m_LayerOptions(), +m_HasFileName(false) +{ + this->SetGDALLayerOptions( options ); +} + +OGRExtendedFilenameToOptions::Pointer +OGRExtendedFilenameToOptions:: +GetGDALLayerOptionsHelper( const GDALOptionType & options ) +{ + Pointer res = new OGRExtendedFilenameToOptions( options ); + res->UnRegister(); + return res; +} + + +void +OGRExtendedFilenameToOptions:: +SetExtendedFileName(const char *extFname) +{ + Superclass::SetExtendedFileName(extFname); + m_HasFileName = true; + + const OptionMapType & map = GetOptionMap(); + + ConstMapIteratorType it; + for ( it=map.begin(); it != map.end(); it++ ) + { + std::vector<std::string> tmp; + boost::split(tmp, it->first, boost::is_any_of(":"), boost::token_compress_on); + + if (tmp.size()>2 && (tmp[0]=="gdal") ) + { + if ( tmp[1]=="oo" ) + { + m_OpenOptions.gdalOptions.push_back(tmp[2] + "=" +it->second); + } + else if ( tmp[1]=="co" ) + { + m_CreationOptions.gdalOptions.push_back(tmp[2] + "=" +it->second); + } + else if ( tmp[1]=="lco" ) + { + m_LayerOptions.gdalOptions[tmp[2]] = it->second; + } + else + { + // log a warning + } + } + + } +} + +OGRExtendedFilenameToOptions:: +GDALOptionType +OGRExtendedFilenameToOptions:: +GetGDALOptions( const std::string & type ) const +{ + if ( type == "layer" ) + return GetGDALLayerOptions(); + else if ( type == "creation" ) + return m_CreationOptions.gdalOptions; + else if ( type == "open" ) + return m_OpenOptions.gdalOptions; + else + { + // warn user : wrong option + return GDALOptionType(); + } +} + +void +OGRExtendedFilenameToOptions:: +SetGDALLayerOptions( const OGRExtendedFilenameToOptions::GDALOptionType & options ) +{ + std::vector<std::string> tmp; + for ( const auto & option : options ) + { + boost::split(tmp, option , boost::is_any_of(":"), boost::token_compress_on); + if ( tmp.size()<2 ) + boost::split(tmp, option , boost::is_any_of("="), boost::token_compress_on); + m_LayerOptions.gdalOptions[ tmp[0] ] = tmp[1] ; + } +} + +void +OGRExtendedFilenameToOptions:: +AddGDALLayerOptions( const OGRExtendedFilenameToOptions::GDALOptionType & options ) +{ + for ( const auto & option : options ) + { + std::vector<std::string> tmp; + boost::split(tmp, option , boost::is_any_of(":"), boost::token_compress_on); + if ( tmp.size()<2 ) + boost::split(tmp, option , boost::is_any_of("="), boost::token_compress_on); + m_LayerOptions.gdalOptions[ tmp[0] ] = tmp[1] ; + } +} + +bool +OGRExtendedFilenameToOptions:: +SimpleFileNameIsSet() const +{ + return m_HasFileName; +} + +bool +OGRExtendedFilenameToOptions:: +HasGDALLayerOption() const +{ + return ! m_LayerOptions.gdalOptions.empty() ; +} + +OGRExtendedFilenameToOptions:: +GDALOptionType +OGRExtendedFilenameToOptions:: +GetGDALLayerOptions() const +{ + GDALOptionType options; + for (const auto & option : m_LayerOptions.gdalOptions ) + { + options.push_back( option.first + "=" + option.second ); + } + return options; +} + +#define GetGDALOptionMacro( Type ) \ +OGRExtendedFilenameToOptions:: \ +GDALOptionType \ +OGRExtendedFilenameToOptions:: \ +GetGDAL##Type##Options() const \ +{ \ + return m_##Type##Options.gdalOptions; \ +} \ + +GetGDALOptionMacro( Open ) +GetGDALOptionMacro( Creation ) +// GetGDALOptionMacro( Layer ) + + + +} //end namespace otb diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx index 22b7a612ca3f7f557eeed7abe2da3c2e1d047fe9..54fc19e190104557ee0f0c670507709924e6b5c9 100644 --- a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx +++ b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx @@ -19,6 +19,7 @@ */ #include "otbOGRVersionProxy.h" +#include "otbOGRHelpers.h" #include "itkMacro.h" @@ -60,12 +61,17 @@ OTBGdalAdapters_EXPORT bool IsOFTInteger64(OGRFieldType type) } -GDALDatasetType * Open(const char * filename, bool readOnly) +GDALDatasetType * Open(const char * filename, bool readOnly , std::vector< std::string > const & options ) { #if GDAL_VERSION_NUM<2000000 return OGRSFDriverRegistrar::Open(filename,!readOnly); #else - return (GDALDatasetType *)GDALOpenEx(filename, (readOnly? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR,NULL,NULL,NULL); + return (GDALDatasetType *)GDALOpenEx( + filename, + (readOnly? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR, + NULL, + otb::ogr::StringListConverter( options ).to_ogr(), + NULL); #endif } @@ -78,7 +84,7 @@ void Close(GDALDatasetType * dataset) #endif } -GDALDatasetType * Create(GDALDriverType * driver, const char * name) +GDALDatasetType * Create(GDALDriverType * driver, const char * name , std::vector< std::string > const & options ) { #if GDAL_VERSION_NUM<2000000 GDALDatasetType * ds = driver->CreateDataSource(name); @@ -88,7 +94,12 @@ GDALDatasetType * Create(GDALDriverType * driver, const char * name) return ds; #else - return driver->Create(name,0,0,0,GDT_Unknown,NULL); + return driver->Create( name , + 0 , + 0 , + 0 , + GDT_Unknown , + otb::ogr::StringListConverter( options ).to_ogr() ); #endif } diff --git a/Modules/Adapters/GdalAdapters/test/CMakeLists.txt b/Modules/Adapters/GdalAdapters/test/CMakeLists.txt index 5a0de851487aa4484815aa06e6b244c57d23f480..fcfa7640790b04580ce5507651bb946c27b24452 100644 --- a/Modules/Adapters/GdalAdapters/test/CMakeLists.txt +++ b/Modules/Adapters/GdalAdapters/test/CMakeLists.txt @@ -35,5 +35,52 @@ endif() add_executable(otbOGRTestsIO otbOGRDataSourceWrapperIO.cxx) target_link_libraries(otbOGRTestsIO ${OTBGdalAdapters-Test_LIBRARIES}) -add_test(NAME coTuOGRDataSourceWrapperIO +otb_add_test(NAME coTuOGRDataSourceWrapperIO COMMAND otbOGRTestsIO ${INPUTDATA}/ToulousePoints-examples.shp ) + +set(OTBOGRTests +otbOGRTestDriver.cxx +otbOGRExtendedFilenameToOptionsTest.cxx +otbOGRExtendedFilenameToOptionsGDALTest.cxx +) + +add_executable(otbOGRTestDriver ${OTBOGRTests}) +target_link_libraries(otbOGRTestDriver ${OTBGdalAdapters-Test_LIBRARIES}) +otb_module_target_label(otbOGRTestDriver) + +otb_add_test(NAME TvOGRExtendedFilename + COMMAND otbOGRTestDriver + --compare-ascii ${NOTOL} + ${BASELINE}/TvOGRExtendedFilename.txt + ${TEMP}/TvOGRExtendedFilenameTest.txt + otbOGRExtendedFileName + test.shp?&writegeom=ON&gdal:co:QUALITY=75&gdal:co:TILED=YES&gdal:co:BLOCKYSIZE=1024&gdal:lco:layeroption=OPTION&gdal:oo:openoption=OPTION + ${TEMP}/TvOGRExtendedFilenameTest.txt ) + +#Problem with error thrown by GDAL : unable to catch it with "CPLGetLastErrorMsg" +# otb_add_test(NAME TvOGRExtendedFilenameGDALOpen +# COMMAND otbOGRTestDriver +# otbOGRExtendedFileNameGDALOpen +# ${INPUTDATA}/ToulousePoints-examples.shp?&gdal:oo:openOption=OPTION +# ) + +otb_add_test(NAME TvOGRExtendedFilenameGDALCreate + COMMAND otbOGRTestDriver + otbOGRExtendedFileNameGDALCreate + test.shp?gdal:co:creationOption=OPTION + ) + +otb_add_test(NAME TvOGRExtendedFilenameGDALLayer + COMMAND otbOGRTestDriver + otbOGRExtendedFileNameGDALLayer + test.shp?&gdal:lco:layeroption=OPTION + ) + +otb_add_test(NAME TvOGRExtendedFilenameGDALLayerOption + COMMAND otbOGRTestDriver + otbOGRExtendedFileNameGDALLayerOption + test.shp + ) + + +message(STATUS "Test link : ${OTBGdalAdapters-Test_LIBRARIES}") \ No newline at end of file diff --git a/Modules/Adapters/GdalAdapters/test/otbOGRExtendedFilenameToOptionsGDALTest.cxx b/Modules/Adapters/GdalAdapters/test/otbOGRExtendedFilenameToOptionsGDALTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..37368ea11836c6de38f616d14f368e51a611f702 --- /dev/null +++ b/Modules/Adapters/GdalAdapters/test/otbOGRExtendedFilenameToOptionsGDALTest.cxx @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005-2017 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 "cpl_error.h" +#include "otbOGRExtendedFilenameToOptions.h" +#include "otbOGRDataSourceWrapper.h" +#include <iostream> +#include <fstream> + + +int otbOGRExtendedFileNameGDALOpen(int , char* argv[]) +{ + auto test = otb::ogr::DataSource::New( argv[1] ); + std::string error = CPLGetLastErrorMsg(); + return 0; +} + +int otbOGRExtendedFileNameGDALCreate(int , char* argv[]) +{ + auto test = otb::ogr::DataSource::New( argv[1] , otb::ogr::DataSource::Modes::Overwrite); + std::string error = CPLGetLastErrorMsg(); + if ( error.find( "does not support creation option creationOption" ) ) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + +int otbOGRExtendedFileNameGDALLayer(int , char* argv[]) +{ + auto test = otb::ogr::DataSource::New( argv[1] , otb::ogr::DataSource::Modes::Update_LayerOverwrite); + test->CreateLayer( "2layertest" , + ITK_NULLPTR , + wkbUnknown ); + std::string error = CPLGetLastErrorMsg(); + if ( error.find( "does not support layer creation option layeroption" ) ) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + +int otbOGRExtendedFileNameGDALLayerOption(int , char* argv[]) +{ + auto test = otb::ogr::DataSource::New( argv[1] , otb::ogr::DataSource::Modes::Update_LayerOverwrite); + std::vector<std::string> option { "vectorlayeroption=OPTION" }; + test->CreateLayer( "2layertest" , + ITK_NULLPTR , + wkbUnknown , + option ); + std::string error = CPLGetLastErrorMsg(); + if ( error.find( "does not support layer creation option vectorlayeroption" ) ) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + diff --git a/Modules/Adapters/GdalAdapters/test/otbOGRExtendedFilenameToOptionsTest.cxx b/Modules/Adapters/GdalAdapters/test/otbOGRExtendedFilenameToOptionsTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..63df6eeed09ed3c5b63ff8369dd95467bdaadb3c --- /dev/null +++ b/Modules/Adapters/GdalAdapters/test/otbOGRExtendedFilenameToOptionsTest.cxx @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2005-2017 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 "otbOGRExtendedFilenameToOptions.h" +#include <algorithm> +#include <iostream> +#include <fstream> + + +using namespace otb; + + +typedef OGRExtendedFilenameToOptions FilenameHelperType; + +int otbOGRExtendedFileName(int , char* argv[]) +{ + // Verify the number of parameters in the command line + const char * inputExtendedFilename = argv[1]; + const char * outputFilename = argv[2]; + + std::cout<< argv[1] <<" "<<argv[2]<<std::endl; + FilenameHelperType::Pointer helper = FilenameHelperType::New(); + + helper->SetExtendedFileName(inputExtendedFilename); + + std::ofstream file; + file.open(outputFilename); + + file << helper->SimpleFileNameIsSet() << std::endl; + file << helper->GetSimpleFileName() << std::endl; + + file << "Open option :"<<std::endl; + FilenameHelperType::GDALOptionType open = helper->GetGDALOpenOptions(); + for ( auto option : open ) + { + file<< option << std::endl; + } + + file << "Create option :"<<std::endl; + FilenameHelperType::GDALOptionType create = helper->GetGDALOptions("creation"); + for ( auto option : create ) + { + file<< option << std::endl; + } + + file << "Layer option :"<<std::endl; + FilenameHelperType::GDALOptionType layer = helper->GetGDALOptions("layer"); + for ( auto option : layer ) + { + file<< option << std::endl; + } + + file<< "End of classic helper."<<std::endl; + + layer.push_back("TOTO=first"); + FilenameHelperType::Pointer layerHelper = + FilenameHelperType::GetGDALLayerOptionsHelper ( layer ); + std::cout<< layerHelper->GetGDALLayerOptions()[0] <<std::endl; + FilenameHelperType::GDALOptionType newOptions; + // std::vector< std::string> newOptions; + newOptions.push_back("TOTO=second"); + newOptions.push_back("TiTi=option"); + layerHelper->AddGDALLayerOptions( newOptions ); + + file << layerHelper->SimpleFileNameIsSet() << std::endl; + file << layerHelper->HasGDALLayerOption() << std::endl; + file << "Layer option from layer helper:"<<std::endl; + FilenameHelperType::GDALOptionType latestOptions = layerHelper->GetGDALOptions("layer"); + // need to sort for dummy windows + std::sort( latestOptions.begin() , latestOptions.end() ); + for ( auto option : latestOptions ) + { + file<< option << std::endl; + } + + file.close(); + return EXIT_SUCCESS; +} + diff --git a/Modules/Adapters/GdalAdapters/test/otbOGRTestDriver.cxx b/Modules/Adapters/GdalAdapters/test/otbOGRTestDriver.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dba04ea4d743cc89be61e25aa01978fd87882a5b --- /dev/null +++ b/Modules/Adapters/GdalAdapters/test/otbOGRTestDriver.cxx @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2005-2017 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 "otbTestMain.h" + +void RegisterTests() +{ + REGISTER_TEST(otbOGRExtendedFileName); + REGISTER_TEST(otbOGRExtendedFileNameGDALOpen); + REGISTER_TEST(otbOGRExtendedFileNameGDALCreate); + REGISTER_TEST(otbOGRExtendedFileNameGDALLayer); + REGISTER_TEST(otbOGRExtendedFileNameGDALLayerOption); +} diff --git a/Modules/IO/ExtendedFilename/include/otbExtendedFilenameHelper.h b/Modules/Core/Common/include/otbExtendedFilenameHelper.h similarity index 94% rename from Modules/IO/ExtendedFilename/include/otbExtendedFilenameHelper.h rename to Modules/Core/Common/include/otbExtendedFilenameHelper.h index 72123839c76f922c32d63296abd6c3559f92f705..549ad2451d85745f196db750ceea2ba3a9156c12 100644 --- a/Modules/IO/ExtendedFilename/include/otbExtendedFilenameHelper.h +++ b/Modules/Core/Common/include/otbExtendedFilenameHelper.h @@ -23,6 +23,7 @@ #include "itkObject.h" #include "itkObjectFactory.h" +#include "OTBCommonExport.h" namespace otb { @@ -33,9 +34,10 @@ namespace otb * \sa ImageFileReader * * \ingroup OTBExtendedFilename + * \ingroup OTBCommon */ -class ITK_EXPORT ExtendedFilenameHelper : public itk::Object +class OTBCommon_EXPORT ExtendedFilenameHelper : public itk::Object { public: /** Standard class typedefs. */ @@ -55,7 +57,7 @@ public: itkGetStringMacro(ExtendedFileName); itkGetStringMacro(SimpleFileName); - struct GenericBandRange : std::pair<int,int> + struct OTBCommon_EXPORT GenericBandRange : std::pair<int,int> { GenericBandRange() {} diff --git a/Modules/Core/Common/otb-module.cmake b/Modules/Core/Common/otb-module.cmake index 97ba992dd7ca4a88b6ce1ac6475678f27eb1368b..b3276d69422b566872290eba6a5d817cb2b45be1 100644 --- a/Modules/Core/Common/otb-module.cmake +++ b/Modules/Core/Common/otb-module.cmake @@ -27,6 +27,8 @@ ENABLE_SHARED OTBITK #Add dependency to OTBGDAL as GDAL module need to set OTB_USE_GDAL_20 before configuring otbConfigure.h OTBGDAL + #Add dependency for extended filename helper class + OTBBoostAdapters TEST_DEPENDS OTBImageBase diff --git a/Modules/Core/Common/src/CMakeLists.txt b/Modules/Core/Common/src/CMakeLists.txt index ce5d20761e59a5e57cf7f3b909317dc1c072f7aa..1aee98f792eca87f73212b1892b60e4571698bf2 100644 --- a/Modules/Core/Common/src/CMakeLists.txt +++ b/Modules/Core/Common/src/CMakeLists.txt @@ -29,6 +29,7 @@ set(OTBCommon_SRC otbWriterWatcherBase.cxx otbStopwatch.cxx otbStringToHTML.cxx + otbExtendedFilenameHelper.cxx otbLogger.cxx ) diff --git a/Modules/IO/ExtendedFilename/src/otbExtendedFilenameHelper.cxx b/Modules/Core/Common/src/otbExtendedFilenameHelper.cxx similarity index 100% rename from Modules/IO/ExtendedFilename/src/otbExtendedFilenameHelper.cxx rename to Modules/Core/Common/src/otbExtendedFilenameHelper.cxx diff --git a/Modules/IO/ExtendedFilename/otb-module.cmake b/Modules/IO/ExtendedFilename/otb-module.cmake index cf194a8edde1a755df8dd5343ffaeefbb56b65c9..1e46b70a5bfefcc72cda05d38d35e428fba5d6f5 100644 --- a/Modules/IO/ExtendedFilename/otb-module.cmake +++ b/Modules/IO/ExtendedFilename/otb-module.cmake @@ -26,8 +26,8 @@ product by skipping either geographic or sensor-model information.") otb_module(OTBExtendedFilename DEPENDS + OTBCommon OTBIOGDAL - OTBBoostAdapters OTBITK TEST_DEPENDS diff --git a/Modules/IO/ExtendedFilename/src/CMakeLists.txt b/Modules/IO/ExtendedFilename/src/CMakeLists.txt index 033f0db2d93dfe762ed49684cdbf8cba0eed68b8..35ec302ad43392100078862ecc954abce105eeaa 100644 --- a/Modules/IO/ExtendedFilename/src/CMakeLists.txt +++ b/Modules/IO/ExtendedFilename/src/CMakeLists.txt @@ -20,15 +20,13 @@ set(OTBExtendedFilename_SRC otbExtendedFilenameToReaderOptions.cxx - otbExtendedFilenameHelper.cxx otbExtendedFilenameToWriterOptions.cxx ) add_library(OTBExtendedFilename ${OTBExtendedFilename_SRC}) target_link_libraries(OTBExtendedFilename + ${OTBCommon_LIBRARIES} ${OTBIOGDAL_LIBRARIES} - ${OTBBoost_LIBRARIES} - ) otb_module_target(OTBExtendedFilename)