diff --git a/Code/UtilitiesAdapters/OGRAdapters/CMakeLists.txt b/Code/UtilitiesAdapters/OGRAdapters/CMakeLists.txt index e14833d7f635c032d142f22feb3d6662f418d1f3..5087fde1398b4b28c5969efe58316bec42f123b2 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/CMakeLists.txt +++ b/Code/UtilitiesAdapters/OGRAdapters/CMakeLists.txt @@ -1,5 +1,16 @@ -# Sources of non-templated classes. +# Decompose GDAL version +STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" GDAL_VERSION_MAJOR "${GDAL_VERSION}") +STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" GDAL_VERSION_MINOR "${GDAL_VERSION}") +STRING(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" GDAL_VERSION_PATCH "${GDAL_VERSION}") +SET(GDAL_VERSION_MAJOR_STRING "${GDAL_VERSION_MAJOR}" CACHE STRING "Major Version Number of GDAL package found") +SET(GDAL_VERSION_MINOR_STRING "${GDAL_VERSION_MINOR}" CACHE STRING "Minor Version Number of GDAL package found") +SET(GDAL_VERSION_PATCH_STRING "${GDAL_VERSION_PATCH}" CACHE STRING "Patch Version Number of GDAL package found") +MATH(EXPR GDAL_NUM_VERSION "((${GDAL_VERSION_MAJOR})*100+${GDAL_VERSION_MINOR})*100+${GDAL_VERSION_PATCH}") +MESSAGE(STATUS "GDAL Num version: ${GDAL_NUM_VERSION}") +ADD_DEFINITIONS(-DGDAL_VERSION=${GDAL_NUM_VERSION}) + +# Sources of non-templated classes. FILE(GLOB OTBOGRAdapters_SRCS "*.cxx" ) # IF(OTB_USE_EXTERNAL_OSSIM) diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h index f06e44e44252202536e2fe9372efbfdc3d2940f5..d09d9795354e6caee9434a8278e53c4b0a5978e9 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h @@ -429,7 +429,7 @@ namespace otb { namespace ogr { * dialect. * \return a new \c Layer that contains the matching \c Features. In case of * error, or no matching result sets, a \em null Layer will be returned. - * Check for \ยข Layer's validity before doing anything else. + * Check for \c Layer's validity before doing anything else. * \throw None even when there is an error -- OGR can not report errors, * neither this wrapping. * \note the returned \c Layer will be automatically collected on its @@ -457,7 +457,7 @@ namespace otb { namespace ogr { return m_DataSource ? &boolean::i : 0; } - /** + /*otb::ogr::* * Flushes all changes to disk. * \throw itd::ExceptionObject in case the flush operation failed. * \sa OGRDataSource::SyncToDisk diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx index 002235436b448e2327ff869c46b260b1a470a9c7..d976c77130dd8f154f7cb4daf57af481b5eb5180 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx @@ -112,7 +112,11 @@ void otb::ogr::Layer::SetFeature(Feature feature) std::string otb::ogr::Layer::GetName() const { assert(m_Layer && "null layer"); +#if GDAL_VERSION >= 10800 return m_Layer->GetName(); +#else + return GetLayerDefn().GetName(); +#endif } OGRLayer & otb::ogr::Layer::ogr() @@ -155,3 +159,88 @@ void otb::ogr::Layer::SetSpatialFilter(OGRGeometry const* spatialFilter) m_Layer->SetSpatialFilter(const_cast <OGRGeometry*>(spatialFilter)); } +/*===========================================================================*/ +/*==========================[ Feature Definition ]===========================*/ +/*===========================================================================*/ +OGRFeatureDefn & otb::ogr::Layer::GetLayerDefn() const +{ + assert(m_Layer && "OGRLayer not initialized"); + return *const_cast <OGRLayer*>(m_Layer.get())->GetLayerDefn(); +} + +void otb::ogr::Layer::CreateField( + OGRFieldDefn const& field, bool bApproxOK/* = true */) +{ + assert(m_Layer && "OGRLayer not initialized"); + const OGRErr res = m_Layer->CreateField(const_cast <OGRFieldDefn*>(&field), bApproxOK); + if (res != OGRERR_NONE) + { + itkGenericExceptionMacro(<< "Cannot create a new field in the layer <"<<GetName()<<">."); + } +} + +void otb::ogr::Layer::DeleteField(size_t fieldIndex) +{ + assert(m_Layer && "OGRLayer not initialized"); +#if GDAL_VERSION < 10900 + itkGenericExceptionMacro("OGRLayer::AlterFieldDefn is not supported by OGR v" + << GDAL_VERSION << ". Upgrade to a version >= 1.9.0, and recompile OTB.") +#else + const OGRErr res = m_Layer->DeleteField(int(fieldIndex)); + if (res != OGRERR_NONE) + { + itkGenericExceptionMacro(<< "Cannot delete the "<<fieldIndex << "th field in the layer <" + <<GetName() <<">."); + } +#endif +} + +void otb::ogr::Layer::AlterFieldDefn( + size_t fieldIndex, OGRFieldDefn& newFieldDefn, int nFlags) +{ + assert(m_Layer && "OGRLayer not initialized"); +#if GDAL_VERSION < 10900 + itkGenericExceptionMacro("OGRLayer::AlterFieldDefn is not supported by OGR v" + << GDAL_VERSION << ". Upgrade to a version >= 1.9.0, and recompile OTB.") +#else + const OGRErr res = m_Layer->AlterFieldDefn(int(fieldIndex), &newFieldDefn, nFlags); + if (res != OGRERR_NONE) + { + itkGenericExceptionMacro(<< "Cannot alter the "<<fieldIndex << "th field in the layer <" + <<GetName() <<">."); + } +#endif +} + +void otb::ogr::Layer::ReorderField(size_t oldPos, size_t newPos) +{ + assert(m_Layer && "OGRLayer not initialized"); +#if GDAL_VERSION < 10900 + itkGenericExceptionMacro("OGRLayer::ReorderField is not supported by OGR v" + << GDAL_VERSION << ". Upgrade to a version >= 1.9.0, and recompile OTB.") +#else + const OGRErr res = m_Layer->ReorderField(int(oldPos), int(newPos)); + if (res != OGRERR_NONE) + { + itkGenericExceptionMacro(<< "Cannot move the "<<oldPos << "th field to the " + << newPos << "th position in the layer <" <<GetName() <<">."); + } +#endif +} + +void otb::ogr::Layer::ReorderFields(int * map) +{ + assert(m_Layer && "OGRLayer not initialized"); +#if GDAL_VERSION < 10900 + itkGenericExceptionMacro("OGRLayer::ReorderField is not supported by OGR v" + << GDAL_VERSION << ". Upgrade to a version >= 1.9.0, and recompile OTB.") +#else + const OGRErr res = m_Layer->ReorderFields(map); + if (res != OGRERR_NONE) + { + itkGenericExceptionMacro(<< "Cannot reorder the fields of the layer <" + <<GetName() <<">."); + } +#endif +} + diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h index da27e849317e2e60093da9d18d13db8ea05fb11a..dd4356f23f29f096e3483b3629609d53ab250968 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h @@ -28,6 +28,8 @@ PURPOSE. See the above copyright notices for more information. class OGRLayer; // fwd declarations class OGRDataSource; class OGRGeometry; +class OGRFeatureDefn; +class OGRFieldDefn; namespace otb { namespace ogr { /**\ingroup Geometry @@ -133,6 +135,17 @@ public: /**\name Iteration */ //@{ + /**\ingroup Geometry + * \class feature_iter + * Implementation class for \c Feature iterator. + * \internal + * \sa otb::ogr::Layer::iterator + * \sa otb::ogr::Layer::const_iterator + * \note Naming policy is compliant with C++ standard as the iterator are as + * well. This will permit transparent integration with all standard and boost + * algorithms, and C++11 <em>for-range loops</em> for instance. + * \see http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/iterator_facade.html#tutorial-example + */ template <class Value> class feature_iter : public boost::iterator_facade<feature_iter<Value>, Value, boost::single_pass_traversal_tag> { @@ -179,7 +192,28 @@ public: iterator begin() ; iterator end() { return iterator(); } //@} + + /**\name Features definition */ + //@{ + OGRFeatureDefn & GetLayerDefn() const; + + void CreateField(OGRFieldDefn const& field, bool bApproxOK = true); + void DeleteField(size_t fieldIndex); + void AlterFieldDefn(size_t fieldIndex, OGRFieldDefn& newFieldDefn, int nFlags); + void ReorderField(size_t oldPos, size_t newPos); + void ReorderFields(int *map); + void SetIgnoredFields(int *); + //@} private: + /** + * Internal encapsulation of \c OGRLayer::GetNextFeature(). + * + * \return the next \c OGRFeature of the layer, encapsulated in a \c Feature. + * \throw None + * \internal + * Required to implement iterators without exposing/including \c OGRFeature + * class definition. + */ Feature GetNextFeature(); /** Data implementation.