From 67c1b0365f915f2859bfb9a5e1acc047e7e78fa6 Mon Sep 17 00:00:00 2001
From: Luc Hermitte <luc.hermitte@c-s.fr>
Date: Thu, 14 Jun 2012 20:40:39 +0200
Subject: [PATCH] REFAC: OTB-151/GeometriesProjectionFilter

---
 .../otbGeometriesProjectionFilter.cxx         |  4 +-
 .../otbGeometriesToGeometriesFilter.h         | 83 +++++++------------
 .../otbGeometriesToGeometriesFilter.txx       | 78 +++++++++++++++++
 3 files changed, 111 insertions(+), 54 deletions(-)

diff --git a/Code/Projections/otbGeometriesProjectionFilter.cxx b/Code/Projections/otbGeometriesProjectionFilter.cxx
index d5ca0baab5..96e770eb26 100644
--- a/Code/Projections/otbGeometriesProjectionFilter.cxx
+++ b/Code/Projections/otbGeometriesProjectionFilter.cxx
@@ -256,8 +256,8 @@ OGRSpatialReference* otb::GeometriesProjectionFilter::DoDefineNewLayerSpatialRef
   if (!m_OutputProjectionRef.empty())
     {
     char const* wkt_string = m_OutputProjectionRef.c_str();
-    OGRSpatialReference * res = static_cast <OGRSpatialReference*>(OSRNewSpatialReference(wkt_string));
-    return res;
+    OGRSpatialReference * osr = static_cast <OGRSpatialReference*>(OSRNewSpatialReference(wkt_string));
+    return osr;
     }
   else
     {
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h
index 5f2c96f159..4e8d2d9dac 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h
@@ -164,19 +164,34 @@ struct TransformationFunctorDispatcher<TransformationFunctor, ogr::Layer>
   BOOST_MPL_ASSERT((boost::is_same<ogr::Layer, TransformedElementType>));
   TransformationFunctorDispatcher() { }
   TransformationFunctorDispatcher(TransformationFunctor functor) : m_functor(functor){ }
-  void operator()(ogr::Layer const& in, ogr::Layer & out) const
-    {
-    m_functor(in, out);
-    }
-  void operator()(ogr::Layer & inout) const
-    {
-    m_functor(inout);
-    }
+  void operator()(ogr::Layer const& in, ogr::Layer & out) const;
+  void operator()(ogr::Layer & inout) const;
   TransformationFunctor * operator->() { return &m_functor; }
 private:
   TransformationFunctor m_functor;
   };
 
+template <class TransformationFunctor>
+struct FieldTransformationPolicy
+  {
+  OGRFeatureDefn & getDefinition(ogr::Layer & outLayer) const
+    {
+    return outLayer.GetLayerDefn();
+    }
+  void fieldsTransform(ogr::Feature const& inoutFeature)
+    {
+    // default => do nothing for in-place transformation
+    }
+  void fieldsTransform(ogr::Feature const& inFeature, ogr::Feature & outFeature)
+    {
+    // default => copy all fields for copy transformation
+    assert(inFeature.GetSize() == outFeature.GetSize());
+    for (size_t i=0,N=inFeature.GetSize(); i!=N; ++i)
+      {
+      outFeature[i] = inFeature[i];
+      }
+    }
+  };
 
 /**\ingroup GeometriesFilters
  * Specialization for \c OGRGeometry.
@@ -189,37 +204,10 @@ struct TransformationFunctorDispatcher<TransformationFunctor, OGRGeometry>
   typedef typename TransformationFunctor::TransformedElementType TransformedElementType;
   BOOST_MPL_ASSERT((boost::is_same<OGRGeometry, TransformedElementType>));
   TransformationFunctorDispatcher() { }
-  TransformationFunctorDispatcher(TransformationFunctor functor) : m_functor(functor){ }
+  TransformationFunctorDispatcher(TransformationFunctor functor) : m_functor(functor){}
 
-  void operator()(ogr::Layer const& in, ogr::Layer & out) const
-    {
-    OGRFeatureDefn & defn = out.GetLayerDefn();
-    for (ogr::Layer::const_iterator b = in.begin(), e = in.end(); b != e; ++b)
-      {
-      ogr::Feature const feat = *b;
-      // TODO: field transformations...
-      ogr::UniqueGeometryPtr g = m_functor(feat.GetGeometry());
-      ogr::Feature dest(defn);
-      dest.SetGeometryDirectly(boost::move(g));
-      out.CreateFeature(dest);
-      }
-    }
-
-  void operator()(ogr::Layer & inout) const
-    {
-    OGRFeatureDefn & defn = inout.GetLayerDefn();
-    // NB: We can't iterate with begin()/end() as SetFeature may invalidate the
-    // iterators depending of the underlying drivers
-    // => we use start_at(), i.e. SetNextByIndex()
-    for (int i=0, N=inout.GetFeatureCount(true); i!=N; ++i)
-      {
-      ogr::Feature feat = *inout.start_at(i);
-      // TODO: field transformations...
-      ogr::UniqueGeometryPtr g = m_functor(feat.GetGeometry());
-      feat.SetGeometryDirectly(boost::move(g));
-      inout.SetFeature(feat);
-      }
-    }
+  void operator()(ogr::Layer const& in, ogr::Layer & out) const;
+  void operator()(ogr::Layer & inout) const;
   TransformationFunctor * operator->() { return &m_functor; }
 private:
   TransformationFunctor m_functor;
@@ -233,7 +221,9 @@ private:
  * \todo Find a better name
  */
 template <class TransformationFunctor>
-class ITK_EXPORT DefaultGeometriesToGeometriesFilter : public GeometriesToGeometriesFilter
+class ITK_EXPORT DefaultGeometriesToGeometriesFilter
+: public GeometriesToGeometriesFilter
+, public TransformationFunctorDispatcher<TransformationFunctor, typename TransformationFunctor::TransformedElementType>
 {
 public:
   /**\name Standard ITK typedefs */
@@ -266,22 +256,11 @@ protected:
   /** Destructor. */
   virtual ~DefaultGeometriesToGeometriesFilter();
 
-  virtual void DoProcessLayer(ogr::Layer const& source, ogr::Layer & destination) const
-    {
-    if (source != destination)
-      {
-      m_TransformationFunctor(source, destination); // if TransformedElementType == layer
-      }
-    else
-      {
-      m_TransformationFunctor(destination); // if TransformedElementType == layer
-      }
-    };
+  virtual void DoProcessLayer(ogr::Layer const& source, ogr::Layer & destination) const;
 private:
-  TransformationFunctorDispatcherType m_TransformationFunctor;
+  // TransformationFunctorDispatcherType m_TransformationFunctor;
 };
 
-
 } // end namespace otb
 
 #ifndef OTB_MANUAL_INSTANTIATION
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx
index db670ed69f..5f54b78af6 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx
@@ -33,3 +33,81 @@ inline
 /*virtual*/
 otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor>::~DefaultGeometriesToGeometriesFilter()
 {}
+
+template <class TransformationFunctor>
+inline
+/*virtual*/
+void otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor>::DoProcessLayer(
+  otb::ogr::Layer const& source, otb::ogr::Layer & destination) const
+{
+  if (source != destination)
+    {
+    (*this)(source, destination); // if TransformedElementType == layer
+    // m_TransformationFunctor(source, destination); // if TransformedElementType == layer
+    }
+  else
+    {
+    // m_TransformationFunctor(destination); // if TransformedElementType == layer
+    (*this)(destination); // if TransformedElementType == layer
+    }
+}
+
+/*===========================================================================*/
+/*================[ TransformationFunctorDispatcher<layer> ]=================*/
+/*===========================================================================*/
+
+template <class TransformationFunctor>
+inline
+void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer>::operator()(
+  otb::ogr::Layer const& in, otb::ogr::Layer & out) const
+{
+  m_functor(in, out);
+}
+
+template <class TransformationFunctor>
+inline
+void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer>::operator()(
+  otb::ogr::Layer & inout) const
+
+{
+  m_functor(inout);
+}
+
+/*===========================================================================*/
+/*=============[ TransformationFunctorDispatcher<OGRGeometry> ]==============*/
+/*===========================================================================*/
+template <class TransformationFunctor>
+inline
+void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry>::operator()(
+  otb::ogr::Layer const& in, otb::ogr::Layer & out) const
+{
+  OGRFeatureDefn & defn = out.GetLayerDefn();
+  for (ogr::Layer::const_iterator b = in.begin(), e = in.end(); b != e; ++b)
+    {
+    ogr::Feature const feat = *b;
+    // TODO: field transformations...
+    ogr::UniqueGeometryPtr g = m_functor(feat.GetGeometry());
+    ogr::Feature dest(defn);
+    dest.SetGeometryDirectly(boost::move(g));
+    out.CreateFeature(dest);
+    }
+}
+
+template <class TransformationFunctor>
+inline
+void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry>::operator()(
+  otb::ogr::Layer & inout) const
+{
+  OGRFeatureDefn & defn = inout.GetLayerDefn();
+  // NB: We can't iterate with begin()/end() as SetFeature may invalidate the
+  // iterators depending of the underlying drivers
+  // => we use start_at(), i.e. SetNextByIndex()
+  for (int i=0, N=inout.GetFeatureCount(true); i!=N; ++i)
+    {
+    ogr::Feature feat = *inout.start_at(i);
+    // TODO: field transformations...
+    ogr::UniqueGeometryPtr g = m_functor(feat.GetGeometry());
+    feat.SetGeometryDirectly(boost::move(g));
+    inout.SetFeature(feat);
+    }
+}
-- 
GitLab