From 9bf19e59b6ab3ca7fe4557d2e9b3532edf69cf55 Mon Sep 17 00:00:00 2001 From: Luc Hermitte <luc.hermitte@c-s.fr> Date: Fri, 29 Jun 2012 18:30:24 +0200 Subject: [PATCH] DOC: REFAC: OTB-191 - GeometriesProjection - doxygenation completed --- .../otbGeometriesProjectionFilter.cxx | 56 +++------ .../otbGeometriesProjectionFilter.h | 119 ++++++++++++------ .../otbGeometriesProjectionFilter.txx | 99 +++++++++++++++ .../otbGeometriesToGeometriesFilter.cxx | 67 ++++++++-- .../otbGeometriesToGeometriesFilter.h | 84 ++++++++++++- 5 files changed, 333 insertions(+), 92 deletions(-) create mode 100644 Code/Projections/otbGeometriesProjectionFilter.txx diff --git a/Code/Projections/otbGeometriesProjectionFilter.cxx b/Code/Projections/otbGeometriesProjectionFilter.cxx index 7a90b12f23..521c6fc64b 100644 --- a/Code/Projections/otbGeometriesProjectionFilter.cxx +++ b/Code/Projections/otbGeometriesProjectionFilter.cxx @@ -43,27 +43,6 @@ const double k_averageElevation = -32768.0; /*======================[ Reprojection Transformation ]======================*/ /*===========================================================================*/ - -template <typename TGeometry> -otb::ogr::UniqueGeometryPtr -otb::ReprojectTransformationFunctor::ByCopy::operator()(TGeometry const* in) const -{ - boost::interprocess::unique_ptr<TGeometry, ogr::internal::GeometryDeleter> - out(in ? static_cast <TGeometry*>(in->clone()) : 0); // OGR clone doesn't use covariant return ... - if (out) - m_Reprojector.do_transform(*out); - ogr::UniqueGeometryPtr res(out.release()); - return otb::move(res); -} - -template <typename TGeometry> -void -otb::ReprojectTransformationFunctor::InPlace::operator()(TGeometry * inout) const -{ - if (inout) - m_Reprojector.do_transform(*inout); -} - #if 0 void do_transform(OGRLinearRing & g) const { @@ -71,7 +50,7 @@ void do_transform(OGRLinearRing & g) const } #endif -void otb::ReprojectTransformationFunctor::do_transform(OGRPoint & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRPoint & g) const { typedef InternalTransformType::InputPointType InputPointType; typedef InternalTransformType::OutputPointType OutputPointType; @@ -84,7 +63,7 @@ void otb::ReprojectTransformationFunctor::do_transform(OGRPoint & g) const g.setY(outPoint[1]); } -void otb::ReprojectTransformationFunctor::do_transform(OGRLineString & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRLineString & g) const { OGRPoint point; for (int i=0, N=g.getNumPoints(); i!=N; ++i) @@ -96,13 +75,13 @@ void otb::ReprojectTransformationFunctor::do_transform(OGRLineString & g) const } #if 0 -void otb::ReprojectTransformationFunctor::do_transform(OGRCurve & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRCurve & g) const { assert(!"OGRCurve is just an interface, they can't be reprojected yet"); } #endif -void otb::ReprojectTransformationFunctor::do_transform(OGRPolygon & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRPolygon & g) const { // Note: OGRPolygon interface states that rings obtained through // getInteriorRing() and getExteriorRing() shall not be modified. @@ -131,25 +110,25 @@ void otb::ReprojectTransformationFunctor::do_transform(OGRPolygon & g) const } #if 0 -void otb::ReprojectTransformationFunctor::do_transform(OGRSurface & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRSurface & g) const { assert(!"OGRSurface is just an interface, they can't be reprojected yet"); } -void otb::ReprojectTransformationFunctor::do_transform(OGRMultiLineString & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRMultiLineString & g) const { } -void otb::ReprojectTransformationFunctor::do_transform(OGRMultiPoint & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRMultiPoint & g) const { } -void otb::ReprojectTransformationFunctor::do_transform(OGRMultiPolygon & g) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRMultiPolygon & g) const { } #endif -void otb::ReprojectTransformationFunctor::do_transform(OGRGeometryCollection & col) const +void otb::internal::ReprojectTransformationFunctor::do_transform(OGRGeometryCollection & col) const { for (int i=0, N=col.getNumGeometries(); i!=N; ++i) { @@ -160,15 +139,15 @@ void otb::ReprojectTransformationFunctor::do_transform(OGRGeometryCollection & c } otb::ogr::UniqueGeometryPtr -otb::ReprojectTransformationFunctor::operator()(OGRGeometry const* in) const -// otb::ReprojectTransformationFunctor::apply(OGRGeometry const* in) const +otb::internal::ReprojectTransformationFunctor::operator()(OGRGeometry const* in) const +// otb::internal::ReprojectTransformationFunctor::apply(OGRGeometry const* in) const { otb::ogr::UniqueGeometryPtr res = ogr::apply<otb::ogr::UniqueGeometryPtr>(in, ByCopy(*this)); return otb::move(res); } -void otb::ReprojectTransformationFunctor::apply_inplace(OGRGeometry * inout) const +void otb::internal::ReprojectTransformationFunctor::apply_inplace(OGRGeometry * inout) const { if (inout) ogr::apply<void>(inout, InPlace(*this)); @@ -260,14 +239,13 @@ void otb::GeometriesProjectionFilter::DoProcessLayer(ogr::Layer const& source, o m_Transform->SetInputProjectionRef(source.GetProjectionRef()); m_Transform->InstanciateTransform(); - if (source != destination) + if (source == destination) { - m_TransformationFunctor(source, destination); // if TransformedElementType == layer - } - else - { - m_TransformationFunctor(destination); // if TransformedElementType == layer + itkExceptionMacro(<<"Geometries projection filter cannot work in-place as the resulting layers will have a new spatial reference." + " Please supply too different geometries sets to work on."); } + + m_TransformationFunctor(source, destination); // if TransformedElementType == layer } /*virtual*/ diff --git a/Code/Projections/otbGeometriesProjectionFilter.h b/Code/Projections/otbGeometriesProjectionFilter.h index 1f97e983b0..7dfebab709 100644 --- a/Code/Projections/otbGeometriesProjectionFilter.h +++ b/Code/Projections/otbGeometriesProjectionFilter.h @@ -29,19 +29,20 @@ class OGRCoordinateTransformation; namespace otb { +namespace internal +{ /**\ingroup Projection GeometriesFilters - * Internal functor used to reproject a \c OGRGeometry. + * Internal functor used to reproject an \c OGRGeometry. * * \internal * As \c OGRGeometry isn't open to new functions through a \em Visitor design - * pattern, this class use a nasty hack: it try to downcast to any possible + * pattern, this class uses a nasty hack: it try to downcast to any possible * subtype of \c OGRGeometry. * * \since OTB v 3.14.0 - * \todo Move into an \c internal namespace. */ struct ReprojectTransformationFunctor -{ + { typedef OGRGeometry TransformedElementType; /**\ingroup Projection GeometriesFilters @@ -72,20 +73,36 @@ struct ReprojectTransformationFunctor ogr::UniqueGeometryPtr operator()(OGRGeometry const* in) const; - // ogr::UniqueGeometryPtr apply(OGRGeometry const* in) const; void apply_inplace (OGRGeometry * inout) const; typedef otb::GenericRSTransform<double, 2, 2> InternalTransformType; typedef InternalTransformType::Pointer InternalTransformPointerType; - void SetOnePointTransformation(InternalTransformPointerType transform) - { - m_Transform = transform; - } + /** + * Setter for the 1-point transformation functor. + * \param[in] transform transformation functor to apply on single points. + * \throw None + */ + void SetOnePointTransformation(InternalTransformPointerType transform); private: + /** + * Transforms one single point thanks to \c m_Transform. + * \param[in,out] g point to transform + * \throw Whatever is thrown by \c m_Transform::operator() + */ void do_transform(OGRPoint & g) const; // void do_transform(OGRLinearRing & g) const; + /** + * Transforms all the points from a line-string, thanks to \c m_Transform. + * \param[in,out] g line-string to transform + * \throw Whatever is thrown by \c m_Transform::operator() + */ void do_transform(OGRLineString & g) const; // void do_transform(OGRCurve & g) const; + /** + * Transforms all the rings from a polygon. + * \param[in,out] g polygon to transform + * \throw Whatever is thrown by \c m_Transform::operator() + */ void do_transform(OGRPolygon & g) const; #if 0 void do_transform(OGRSurface & g) const; @@ -93,10 +110,18 @@ private: void do_transform(OGRMultiPoint & g) const; void do_transform(OGRMultiPolygon & g) const; #endif + /** + * Transforms all the geometries from a geometreis collection. + * \param[in,out] g polygon to transform + * \throw Whatever is thrown by \c m_Transform::operator() + */ void do_transform(OGRGeometryCollection & g) const; + /** Transformation functor that operates on one single \c OGRPoint. + */ InternalTransformPointerType m_Transform; -}; + }; +} // internal namespace /**\ingroup Projection GeometriesFilters @@ -120,6 +145,9 @@ private: * \note Unlike \c VectorDataProjectionFilter, we have to explicitly set which * to use between projection reference or keyword list. There is no \em * MetaDataDictionary property. + * + * \note This filter does not support \em in-place transformation as the spatial + * references of the new layer are expected to change. */ class ITK_EXPORT GeometriesProjectionFilter : public GeometriesToGeometriesFilter { @@ -152,9 +180,41 @@ public: //@} private: + /** + * Hook used to determine the \c OGRSpatialReference when creating a new layer. + * \param[in] source source \c Layer for reference (in case it has relevant + * information). + * \return a \c OGRSpatialReference that matches the \em OutputProjectionRef + * of the filter. It's up to the caller to take responsibility of the returned + * object. + */ virtual OGRSpatialReference* DoDefineNewLayerSpatialReference(ogr::Layer const& source) const; + /** + * Hook that actually filters an OGR \c Layer. + * \param[in] source Input layer + * \param[in,out] destination Output layer + * + * Before forwarding the transformation to the \c m_TransformationFunctor, + * this specialization finishes initializing the inner transformation functor. + * Indeed some values depend on the current layer to reproject and thus, the + * inner-filter working on \c ogr::DataSource cannot be globally configured + * once and for all. + */ virtual void DoProcessLayer(ogr::Layer const& source, ogr::Layer & destination) const; + /** Hook used to conclude the initialization phase. + * Global \c ogr::DataSource settings for the \c m_Transform functor are + * forwarded to the functor. \c ogr::Layer specific settings will be set at + * the last moment from \c DoProcessLayer(). + */ virtual void DoFinalizeInitialisation(); + /** + * Hook used to define the fields of the new layer. + * \param[in] source source \c Layer -- for reference + * \param[in,out] dest destination \c Layer + * + * Just forwards the fields definition to the \c FieldTransformationPolicy + * encapsuled in the \c TransformationFunctorDispatcherType. + */ virtual void DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const; protected: @@ -163,43 +223,26 @@ protected: /** Destructor. */ virtual ~GeometriesProjectionFilter(); + /** Computes output information. + * \post \c m_OutputProjectionRef contains all its related meta-data + */ virtual void GenerateOutputInformation(void); public: /**\name Image Reference (origin, spacing) */ //@{ - void SetInputSpacing(ImageReference::SpacingType const& spacing) - { - m_InputImageReference.SetSpacing(spacing); - } - void SetOutputSpacing(ImageReference::SpacingType const& spacing) - { - m_OutputImageReference.SetSpacing(spacing); - } - void SetInputOrigin(ImageReference::OriginType const& origin) - { - m_InputImageReference.SetOrigin(origin); - } - void SetOutputOrigin(ImageReference::OriginType const& origin) - { - m_OutputImageReference.SetOrigin(origin); - } + void SetInputSpacing(ImageReference::SpacingType const& spacing); + void SetOutputSpacing(ImageReference::SpacingType const& spacing); + void SetInputOrigin(ImageReference::OriginType const& origin); + void SetOutputOrigin(ImageReference::OriginType const& origin); //@} /**\name Keywords lists accessors and mutators */ //@{ itkGetMacro(InputKeywordList, ImageKeywordlist); - void SetInputKeywordList(const ImageKeywordlist& kwl) - { - this->m_InputKeywordList = kwl; - this->Modified(); - } + void SetInputKeywordList(const ImageKeywordlist& kwl); itkGetMacro(OutputKeywordList, ImageKeywordlist); - void SetOutputKeywordList(const ImageKeywordlist& kwl) - { - this->m_OutputKeywordList = kwl; - this->Modified(); - } + void SetOutputKeywordList(const ImageKeywordlist& kwl); //@} /**\name Projection references accessors and mutators @@ -214,7 +257,7 @@ public: private: /**\name Functor definition */ //@{ - typedef ReprojectTransformationFunctor TransformationFunctorType; + typedef internal::ReprojectTransformationFunctor TransformationFunctorType; typedef TransformationFunctorType::TransformedElementType TransformedElementType; typedef TransformationFunctorDispatcher<TransformationFunctorType, TransformedElementType, FieldCopyTransformation> TransformationFunctorDispatcherType; @@ -246,7 +289,7 @@ private: } // end namespace otb #ifndef OTB_MANUAL_INSTANTIATION -// #include "otbGeometriesProjectionFilter.txx" +#include "otbGeometriesProjectionFilter.txx" #endif #endif // __otbGeometriesProjectionFilter_h diff --git a/Code/Projections/otbGeometriesProjectionFilter.txx b/Code/Projections/otbGeometriesProjectionFilter.txx new file mode 100644 index 0000000000..c6c3fdf32c --- /dev/null +++ b/Code/Projections/otbGeometriesProjectionFilter.txx @@ -0,0 +1,99 @@ +/*========================================================================= + + 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 "otbGeometriesProjectionFilter.h" + + +/*===========================================================================*/ +/*====================[ ReprojectTransformationFunctor ]=====================*/ +/*===========================================================================*/ + +template <typename TGeometry> +inline +otb::ogr::UniqueGeometryPtr +otb::internal::ReprojectTransformationFunctor::ByCopy::operator()(TGeometry const* in) const +{ + boost::interprocess::unique_ptr<TGeometry, ogr::internal::GeometryDeleter> + out(in ? static_cast <TGeometry*>(in->clone()) : 0); // OGR clone doesn't use covariant return ... + if (out) + m_Reprojector.do_transform(*out); + ogr::UniqueGeometryPtr res(out.release()); + return otb::move(res); +} + +template <typename TGeometry> +inline +void +otb::internal::ReprojectTransformationFunctor::InPlace::operator()(TGeometry * inout) const +{ + if (inout) + m_Reprojector.do_transform(*inout); +} + +inline +void otb::internal::ReprojectTransformationFunctor::SetOnePointTransformation(InternalTransformPointerType transform) +{ + m_Transform = transform; +} + + +/*===========================================================================*/ +/*======================[ GeometriesProjectionFilter ]=======================*/ +/*===========================================================================*/ + +inline +void otb::GeometriesProjectionFilter::SetInputSpacing(ImageReference::SpacingType const& spacing) +{ + m_InputImageReference.SetSpacing(spacing); +} + +inline +void otb::GeometriesProjectionFilter::SetOutputSpacing(ImageReference::SpacingType const& spacing) +{ + m_OutputImageReference.SetSpacing(spacing); +} + +inline +void otb::GeometriesProjectionFilter::SetInputOrigin(ImageReference::OriginType const& origin) +{ + m_InputImageReference.SetOrigin(origin); +} + +inline +void otb::GeometriesProjectionFilter::SetOutputOrigin(ImageReference::OriginType const& origin) +{ + m_OutputImageReference.SetOrigin(origin); +} + + +inline +void otb::GeometriesProjectionFilter::SetInputKeywordList(const ImageKeywordlist& kwl) +{ + this->m_InputKeywordList = kwl; + this->Modified(); +} + +inline +void otb::GeometriesProjectionFilter::SetOutputKeywordList(const ImageKeywordlist& kwl) +{ + this->m_OutputKeywordList = kwl; + this->Modified(); +} diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx index 7b274240dc..5e88264fff 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx @@ -31,19 +31,47 @@ /*===========================================================================*/ /**\ingroup GeometriesFilters * \class ProcessVisitor + * Internal class used to dispatch filters on either \c ogr::DataSource, or \c + * ogr::Layer. + * As \c GeometriesSet is a variant that can contain either a \c ogr::DataSource + * or a \c ogr::Layer, we need a way to dispath filtering operations on the + * right type. This is done thanks to \c ProcessVisitor. * \since OTB v 3.14.0 - * \todo Group -> internal - * \todo Namespace -> ogr::internal ? */ -struct ProcessVisitor : boost::static_visitor<> +struct otb::internal::ProcessVisitor : boost::static_visitor<> { ProcessVisitor(otb::GeometriesToGeometriesFilter const& filter) : m_filter(filter) {} + /** + * Processes layers (\em by-copy). + * \param[in] source source layer + * \param[in,out] destination destination layer. + * \throw WhatEver the filter throws. + * + * This is the \em leaf operation that forwards the call to the polymorphic + * \c GeometriesToGeometriesFilter::DoProcessLayer() function. + */ void operator()(otb::ogr::Layer const& source, otb::ogr::Layer & destination) const { m_filter.DoProcessLayer(source, destination); } + /** + * Processes data sources (\em by-copy). + * \param[in] source source data source + * \param[in,out] destination destination data source + * \throw WhatEver the filter throws. + * \throw itk::ExceptionObject if the construction of a new layer fails + * + * For each layer in the \c source, this operation: + * - builds a new layer in the \c destination data source (according to the + * choices made in the actual specialization of \c + * GeometriesToGeometriesFilter regarding layer options, layer spatial + * reference, geometries type, ...); + * - defines new fileds in the new layer; + * - and finally processes the layer thanks to the polymorphic \c + * GeometriesToGeometriesFilter::DoProcessLayer() function. + */ void operator()(otb::ogr::DataSource::Pointer source, otb::ogr::DataSource::Pointer destination) const { assert(source && "can't filter a nil datasource"); @@ -66,11 +94,27 @@ struct ProcessVisitor : boost::static_visitor<> } } + /** + * Processes layers (\em in-place). + * \param[in,out] inout layer to modify + * \throw WhatEver the filter throws. + * + * This is the \em leaf operation that forwards the call to the polymorphic + * \c GeometriesToGeometriesFilter::DoProcessLayer() function. + */ void operator()(otb::ogr::Layer & inout) const { m_filter.DoProcessLayer(inout, inout); } + /** + * Processes data sources (\em in-place). + * \param[in,out] inout data source to modify + * \throw WhatEver the filter throws. + * + * This operation finally processes each layer of the \c source thanks to the + * polymorphic \c GeometriesToGeometriesFilter::DoProcessLayer() function. + */ void operator()(otb::ogr::DataSource::Pointer inout) const { assert(inout && "can't filter a nil datasource"); @@ -82,6 +126,13 @@ struct ProcessVisitor : boost::static_visitor<> } } + /** + * Fall-back visiting function for invalid mixed tranformations (layer -> + * datasource). + * The only transformations accepted are + * - layer -> layer, + * - and data source -> data source. + */ template <typename GT1, typename GT2> void operator()(GT1 const&, GT2 &) const { assert(!"You shall not mix DataSources and Layers in GeometriesToGeometriesFilter"); @@ -124,7 +175,7 @@ otb::GeometriesToGeometriesFilter::GetInput(void ) { // si layer, appelle virt process layer // si DS, loop et appelle virt process layer - source.apply(ProcessVisitor(*this), destination); + source.apply(internal::ProcessVisitor(*this), destination); } /*virtual*/ void otb::GeometriesToGeometriesFilter::Process( @@ -132,13 +183,7 @@ otb::GeometriesToGeometriesFilter::GetInput(void ) { // si layer, appelle virt process layer // si DS, loop et appelle virt process layer - inout.apply(ProcessVisitor(*this)); -} - -/*virtual*/ -void otb::GeometriesToGeometriesFilter::GenerateOutputInformation(void ) -{ - Superclass::GenerateOutputInformation(); + inout.apply(internal::ProcessVisitor(*this)); } /*virtual*/ diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h index a3aa7840fa..d7dfa2985b 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h @@ -18,6 +18,14 @@ #ifndef __otbGeometriesToGeometriesFilter_h #define __otbGeometriesToGeometriesFilter_h +/**\ingroup GeometriesFilters + * \file otbGeometriesToGeometriesFilter.h + * \since OTB v 3.14.0 + * Commons definitions for geometries filter definition. + * This file contains all the main classes required to define new geometries + * transformations. + */ + #include "otbGeometriesSource.h" #include <map> #include <boost/mpl/assert.hpp> @@ -25,7 +33,11 @@ #include "otbOGRFeatureWrapper.h" #include "otbOGRLayerWrapper.h" +// forward declarations +namespace otb { namespace internal { struct ProcessVisitor; +} } // otb::internal namespace + namespace otb { /**\ingroup GeometriesFilters @@ -74,11 +86,24 @@ protected: */ virtual ~GeometriesToGeometriesFilter(); - virtual void GenerateOutputInformation(void); + /** Processes the input to fill the output. + * This is the main processing function. It either works \em in-place or by + * \em copying the transformed input \c Feature s into the output. + */ virtual void GenerateData(void); private: + /** \e In-place processing function. + * \param[in,out] inout the geometries set that'll be modified by the filter. + * \pre The filter must have been initialized + */ void Process(OutputGeometriesType &inout); + /** \e By-copy processing function. + * \param[in] source the geometries set to transform + * \param[out] destination the resulting geometries set. + * \pre The filter must have been initialized + * \pre The \c destination must be ready to receive a result. + */ void Process(InputGeometriesType const& source, OutputGeometriesType &destination); /**\name Filter specialization hooks. @@ -138,7 +163,7 @@ private: */ virtual void DoFinalizeInitialisation() {} //@} - friend struct ::ProcessVisitor; + friend struct otb::internal::ProcessVisitor; }; /**\ingroup GeometriesFilters @@ -203,6 +228,16 @@ private: * This functor dispatcher is meant to work: * - on a single \c ogr::Layer (in that case, it acts as a in-place filter). * - or on a pair of \c ogr::Layer s (in that case, it acts as a copy filter). + * + * Specializations are expected to provide: + * - a typedef \c TransformedElementType which is expected to match \c + * TransformationFunctor::TransformedElementType; + * - one overload of \c operator() one that takes a reference to a \c ogr::Layer + * for \em in-place transformation; + * - another overload of \c operator() one that takes a const reference, and a + * reference to \c ogr::Layer for \em by-copy transformation; + * - and one overload to <tt>operator->()</tt> that returns a pointer to the + * actual \c TransformationFunctor. * \since OTB v 3.14.0 * \todo Add a specialization for \c ogr::Feature. */ @@ -213,6 +248,12 @@ struct TransformationFunctorDispatcher /**\ingroup GeometriesFilters * Specialization for \c ogr::Layer. + * It simply forwards the call to the internal functor that'll have to do all + * the transformation work. + * + * If you need to change the number of elements in a layer, use a \c + * TransformationFunctor that works on layers. The dispatching mecanism will + * automatically end up here. * \tparam TransformationFunctor actual transformation functor * \since OTB v 3.14.0 */ @@ -234,6 +275,19 @@ private: /**\ingroup GeometriesFilters * Specialization for \c OGRGeometry. * \tparam TransformationFunctor actual transformation functor + * + * In this case, the \c TransformationFunctor works on \c OGRGeometry (instead + * of \c ogr::Layer). The default behaviour provided is to loop on all the \c + * ogr::Feature s of the original layer, and for each feature: + * - build a new one (in case of the \emm by-copy policy), + * - build a new geometry thanks to the \c TransformationFunctor, which will be + * assigned to the output feature, + * - transform the fields from the input layer, + * - and update the feature in the output layer. + * + * \note In the case of the \em by-copy policy, fields transformation cannot + * change the number of fields nor their nature. Only field values may be + * modified. * \since OTB v 3.14.0 */ template <class TransformationFunctor, class FieldTransformationPolicy> @@ -256,6 +310,12 @@ private: /**\ingroup GeometriesFilters * \class DefaultGeometriesToGeometriesFilter * Generic helper class to filter geometries sets given a tranformation functor. + * This generic class provides the default behaviour for most filters that we + * may need to implement. + * + * Thanks to it, we just need to provide a \c TransformationFunctor, and a \c + * FieldTransformationPolicy (if the default no-transformation policy is not + * what we need). * \since OTB v 3.14.0 * \todo Find a better name */ @@ -295,13 +355,29 @@ protected: /** Destructor. */ virtual ~DefaultGeometriesToGeometriesFilter(); + /** + * Hook that actually filters an OGR \c Layer. + * \param[in] source Input layer + * \param[in,out] destination Output layer + * + * This specialization just forwards the transformation to the \c + * m_TransformationFunctor. + * \note When <tt>source == destination</tt>, it means this is an \em in-place + * filter. + */ virtual void DoProcessLayer(ogr::Layer const& source, ogr::Layer & destination) const; + /** + * Hook used to define the fields of the new layer. + * \param[in] source source \c Layer -- for reference + * \param[in,out] dest destination \c Layer + * + * Just forwards the fields definition to the \c FieldTransformationPolicy + * inherited from the \c TransformationFunctorDispatcherType. + */ virtual void DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const { this->DefineFields(source, dest); } -private: - // TransformationFunctorDispatcherType m_TransformationFunctor; }; } // end namespace otb -- GitLab