From 7c4c0b655d0cae3fa1f4c4f288d13e61fffbd239 Mon Sep 17 00:00:00 2001 From: Luc Hermitte <luc.hermitte@c-s.fr> Date: Wed, 25 Apr 2012 17:21:18 +0200 Subject: [PATCH] ENH: OTB-134/OGR: geometry helpers --- .../OGRAdapters/otbOGRFeatureWrapper.cxx | 2 +- .../OGRAdapters/otbOGRFeatureWrapper.h | 9 +- .../OGRAdapters/otbOGRGeometryWrapper.cxx | 110 ++++++++++++++++++ .../OGRAdapters/otbOGRGeometryWrapper.h | 88 ++++++++++++++ .../OGRAdapters/otbOGRLayerWrapper.cxx | 27 +++++ .../OGRAdapters/otbOGRLayerWrapper.h | 20 +++- 6 files changed, 244 insertions(+), 12 deletions(-) create mode 100644 Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.cxx create mode 100644 Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.h diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx index 2077dedaa5..a5da28e9bc 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.cxx @@ -190,7 +190,7 @@ void otb::ogr::Feature::SetGeometryDirectly(UniqueGeometryPtr geometry) assert(! geometry); } -otb::ogr::Feature::UniqueGeometryPtr otb::ogr::Feature::StealGeometry() +otb::ogr::UniqueGeometryPtr otb::ogr::Feature::StealGeometry() { CheckInvariants(); OGRGeometry * g = m_Feature->StealGeometry(); diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h index 0321c799f6..2ac36ef9e1 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFeatureWrapper.h @@ -21,12 +21,11 @@ // #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" +#include "otbOGRGeometryWrapper.h" class OGRFeature; -class OGRGeometry; class OGRFeatureDefn; namespace otb { @@ -90,12 +89,6 @@ public: 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(); diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.cxx new file mode 100644 index 0000000000..a15587b6ee --- /dev/null +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.cxx @@ -0,0 +1,110 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +/*===========================================================================*/ +/*===============================[ Includes ]================================*/ +/*===========================================================================*/ +#include "otbOGRGeometryWrapper.h" +#include "ogr_geometry.h" + +/*===========================================================================*/ +/*================================[ Deleter ]================================*/ +/*===========================================================================*/ +void otb::ogr::internal::GeometryDeleter::operator()(OGRGeometry* p) +{ + OGRGeometryFactory::destroyGeometry (p); +} + +/*===========================================================================*/ +/*======================[ Double dispatched functions ]======================*/ +/*===========================================================================*/ +bool otb::ogr::Intersects(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + // OGRGeometry::Intersects is not const-correct ... + return lhs.Intersects(const_cast <OGRGeometry*>(&rhs)); +} + +bool otb::ogr::Equals(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + // OGRGeometry::Equals is not const-correct ... + return lhs.Equals(const_cast <OGRGeometry*>(&rhs)); +} + +bool otb::ogr::Disjoint(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Disjoint(&rhs); +} + +bool otb::ogr::Touches(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Touches(&rhs); +} + +bool otb::ogr::Crosses(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Crosses(&rhs); +} + +bool otb::ogr::Within(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Within(&rhs); +} + +bool otb::ogr::Contains(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Contains(&rhs); +} + +bool otb::ogr::Overlaps(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Overlaps(&rhs); +} + +double otb::ogr::Distance(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return lhs.Distance(&rhs); +} + +otb::ogr::UniqueGeometryPtr otb::ogr::Intersection(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return UniqueGeometryPtr(lhs.Intersection(&rhs)); +} + +otb::ogr::UniqueGeometryPtr otb::ogr::Union(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return UniqueGeometryPtr(lhs.Union(&rhs)); +} + +otb::ogr::UniqueGeometryPtr otb::ogr::UnionCascaded(OGRGeometry const& this_) +{ + return UniqueGeometryPtr(this_.UnionCascaded()); +} + +otb::ogr::UniqueGeometryPtr otb::ogr::Difference(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ + return UniqueGeometryPtr(lhs.Difference(&rhs)); +} + +otb::ogr::UniqueGeometryPtr otb::ogr::SymDifference(OGRGeometry const& lhs, OGRGeometry const& rhs) +{ +#if GDAL_VERSION_NUM >= 1800 + return UniqueGeometryPtr(lhs.SymDifference(&rhs)); +#else + return UniqueGeometryPtr(lhs.SymmetricDifference(&rhs)); +#endif +} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.h new file mode 100644 index 0000000000..244976f30a --- /dev/null +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRGeometryWrapper.h @@ -0,0 +1,88 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __otbOGRGeometryWrapper_h +#define __otbOGRGeometryWrapper_h + +#include <boost/interprocess/smart_ptr/unique_ptr.hpp> +class OGRGeometry; + +namespace otb { namespace ogr { +namespace internal { +struct GeometryDeleter + { + void operator()(OGRGeometry* p); + }; +} // metaprog namespace + + +// we don't encapsulate OGRGeometry, but please, don't create new geometries with a new. + +/**\ingroup Geometry + * \defgroup OGRGeometryWrapper OGRGeometry Wrappers + * Helper definition to hangle \c OGRGeometry objects. + * + * @note %OTB doesn't provide anything on top of \c OGRGeometryFactory to create + * new factories. Please, never create new \c OGRGeometry by hand with + * <tt>new</tt> operator as there is no garanty they'll get destroyed within the + * proper memory context when released from an owning \c OGRFeature. + * + * Thus, always use \c OGRGeometryFactory functions to create new geometries. + * You can then manage their lifetime manually or rely on \c UniqueGeometryPtr + * that provides a non-copyable, but movable RAII wrapper around \c OGRGeometry. + * @{ + */ +typedef boost::interprocess::unique_ptr<OGRGeometry, internal::GeometryDeleter> UniqueGeometryPtr; +///Do these features intersect? +bool Intersects (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Returns wheither if two geometries are equivalent. +bool Equals (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Tests for disjointness. +bool Disjoint (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Tests for touching. +bool Touches (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Tests for crossing. +bool Crosses (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Tests for containment. +bool Within (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Tests for containment. +bool Contains (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Tests for overlap. +bool Overlaps (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Computes distance between two geometries. +double Distance (OGRGeometry const& lhs, OGRGeometry const& rhs); + +/// Computes intersection. +UniqueGeometryPtr Intersection (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Computes union. +UniqueGeometryPtr Union (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Computes union using cascading. +UniqueGeometryPtr UnionCascaded (OGRGeometry const& this_); +/// Computes difference. +UniqueGeometryPtr Difference (OGRGeometry const& lhs, OGRGeometry const& rhs); +/// Computes symmetric difference. +UniqueGeometryPtr SymDifference (OGRGeometry const& lhs, OGRGeometry const& rhs); // -1.8 + +/** @} */ + +} } // end namespace otb::ogr + +#ifndef OTB_MANUAL_INSTANTIATION +// #include "otbOGRGeometryWrapper.txx" +#endif + +#endif // __otbOGRGeometryWrapper_h diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx index 92434357fc..ab798e9f66 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.cxx @@ -83,6 +83,20 @@ otb::ogr::Layer::const_iterator otb::ogr::Layer::cbegin() const return const_iterator(*const_cast <Layer*>(this)); } +otb::ogr::Layer::iterator otb::ogr::Layer::start(size_t index) +{ + assert(m_Layer && "OGRLayer not initialized"); + m_Layer->SetNextByIndex(index); + return iterator(*this); +} + +otb::ogr::Layer::const_iterator otb::ogr::Layer::cstart(size_t index) const +{ + assert(m_Layer && "OGRLayer not initialized"); + m_Layer->SetNextByIndex(index); + return const_iterator(*const_cast <Layer*>(this)); +} + void otb::ogr::Layer::CreateFeature(Feature feature) { assert(m_Layer && "OGRLayer not initialized"); @@ -163,6 +177,19 @@ void otb::ogr::Layer::SetSpatialFilter(OGRGeometry const* spatialFilter) m_Layer->SetSpatialFilter(const_cast <OGRGeometry*>(spatialFilter)); } +void otb::ogr::Layer::SetSpatialFilterRect( + double dfMinX, double dfMinY, double dfMaxX, double dfMaxY) +{ + assert(m_Layer && "OGRLayer not initialized"); + m_Layer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY); +} + +OGRSpatialReference const* otb::ogr::Layer::GetSpatialRef() const +{ + assert(m_Layer && "OGRLayer not initialized"); + return m_Layer->GetSpatialRef(); +} + /*===========================================================================*/ /*==========================[ Feature Definition ]===========================*/ /*===========================================================================*/ diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h index 235fda9970..f3e6f91917 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRLayerWrapper.h @@ -126,13 +126,23 @@ public: OGRLayer & ogr(); /**\name Spatial filter property - * \internal the I/O geometry is an undeletable pointer, can be may be null. + * \internal the I/O geometry is an undeletable pointer, that may be null. * \todo we'll see later if a Geometry capsule is defined, or a * \c nondeletable<> pointer type. */ //@{ - OGRGeometry const* GetSpatialFilter() const; - void SetSpatialFilter(OGRGeometry const* spatialFilter); + OGRGeometry const* GetSpatialFilter() const; // not a ref because it may be null + void SetSpatialFilter(OGRGeometry const* spatialFilter); // not a ref because it may be null + /// Sets a new rectangular spatial filter. + void SetSpatialFilterRect(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY); + //@} + + /**\name Spatial Reference property + * \internal the I/O spatial reference is an undeletable pointer, that may be null. + * \note read-only property + */ + //@{ + OGRSpatialReference const* GetSpatialRef() const; //@} /**\name Iteration */ @@ -193,6 +203,10 @@ public: const_iterator cend () const { return iterator(); } iterator begin (); iterator end () { return iterator(); } + + const_iterator start (size_t index) const { return cstart(index); } + const_iterator cstart(size_t index) const; + iterator start (size_t index); //@} /**\name Features definition */ -- GitLab