diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx index 59021f328be7a54291a0140ac05f8815c71f9197..2077dedaa5f8fdb9f8f12a49b6816c4c1425d666 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx @@ -177,3 +177,38 @@ OGRFeatureDefn& otb::ogr::Feature::GetDefn() const CheckInvariants(); return *m_Feature->GetDefnRef(); } + +/*===========================================================================*/ +/*==============================[ Geometries ]===============================*/ +/*===========================================================================*/ + +void otb::ogr::Feature::SetGeometryDirectly(UniqueGeometryPtr geometry) +{ + CheckInvariants(); + OGRGeometry * g = geometry.release(); + m_Feature->SetGeometryDirectly(g); + assert(! geometry); +} + +otb::ogr::Feature::UniqueGeometryPtr otb::ogr::Feature::StealGeometry() +{ + CheckInvariants(); + OGRGeometry * g = m_Feature->StealGeometry(); + UniqueGeometryPtr res(g); + assert(! m_Feature->GetGeometryRef()); + return UniqueGeometryPtr(g); +} + +void otb::ogr::Feature::SetGeometry(OGRGeometry const* geometry) +{ + CheckInvariants(); + // OGR copies the input geometry => should have been const + m_Feature->SetGeometryDirectly(const_cast <OGRGeometry*>(geometry)); + assert(m_Feature->GetGeometryRef() == geometry); +} + +OGRGeometry const* otb::ogr::Feature::GetGeometry() const +{ + CheckInvariants(); + return m_Feature->GetGeometryRef(); +} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h index 7be8f3e4f4c4b1e37ce56ee614d16cc828799686..0321c799f6061231e013b096d6b162c763e7b1a0 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h @@ -21,6 +21,7 @@ // #include <iosfwd> // std::ostream& #include <cassert> #include <boost/shared_ptr.hpp> +#include <boost/interprocess/smart_ptr/unique_ptr.hpp> #include "itkIndent.h" #include "otbOGRFieldWrapper.h" @@ -75,6 +76,31 @@ public: FieldDefn GetFieldDefn(std::string const& name) const; //@} + /**\name Geometries + * @todo we should detect whether the official C++11 \c std::unique_ptr<> is + * available instead of always using <tt>boost.interprocess.unique_ptr<></tt>. + * + * @warning OGR does not provide a dedicated deleter/destroyer for \c OGRGeometry + * instances. As a consequence, \c OGRFeature::SetGeometryDirectly and \c + * OGRFeature::StealGeometry may end up trying to release the memory with the + * wrong allocator. They are still provided, but beware that problems may + * happen -- with or without this %OTB wrapping. + */ + //@{ + void SetGeometry(OGRGeometry const* geometry); // not a ref because it may be null + OGRGeometry const* GetGeometry() const; // not a ref because it may be null + + struct JustDelete { + template <typename T> + void operator()(T* p) {delete p; } + }; + typedef boost::interprocess::unique_ptr<OGRGeometry, JustDelete> UniqueGeometryPtr; + + void SetGeometryDirectly(UniqueGeometryPtr geometry); + UniqueGeometryPtr StealGeometry(); + + //@} + friend bool otb::ogr::operator==(Feature const& lhs, Feature const& rhs); private: void CheckInvariants() const;