diff --git a/Code/Projections/otbGeometriesProjectionFilter.cxx b/Code/Projections/otbGeometriesProjectionFilter.cxx
index ffb86c6bb189e6037f0ad2b5f27fe768cd2b0241..d3297b54f812571c61ecbd41c9990b5147e7223f 100644
--- a/Code/Projections/otbGeometriesProjectionFilter.cxx
+++ b/Code/Projections/otbGeometriesProjectionFilter.cxx
@@ -278,3 +278,11 @@ void otb::GeometriesProjectionFilter::DoProcessLayer(ogr::Layer const& source, o
     m_TransformationFunctor(destination); // if TransformedElementType == layer
     }
 }
+
+/*virtual*/
+void otb::GeometriesProjectionFilter::DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const
+
+{
+  std::cout << "otb::GeometriesProjectionFilter::DoDefineNewLayerFields\n";
+  m_TransformationFunctor.DefineFields(source, dest);
+}
diff --git a/Code/Projections/otbGeometriesProjectionFilter.h b/Code/Projections/otbGeometriesProjectionFilter.h
index e5ccfb5723c068a5451bcafb7390ca86086ebdef..f77fb231320ab5e9c6a347a288a5f023341bdf06 100644
--- a/Code/Projections/otbGeometriesProjectionFilter.h
+++ b/Code/Projections/otbGeometriesProjectionFilter.h
@@ -117,6 +117,7 @@ private:
   virtual OGRSpatialReference* DoDefineNewLayerSpatialReference(ogr::Layer const& source) const;
   virtual void DoProcessLayer(ogr::Layer const& source, ogr::Layer & destination) const;
   virtual void DoFinalizeInitialisation();
+  virtual void DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const;
 
 protected:
   /** Default constructor. */
@@ -160,7 +161,7 @@ private:
   //@{
   typedef ReprojectTransformationFunctor                          TransformationFunctorType;
   typedef TransformationFunctorType::TransformedElementType       TransformedElementType;
-  typedef TransformationFunctorDispatcher<TransformationFunctorType, TransformedElementType>
+  typedef TransformationFunctorDispatcher<TransformationFunctorType, TransformedElementType, FieldCopyTransformation>
                                                                   TransformationFunctorDispatcherType;
 
   TransformationFunctorDispatcherType             m_TransformationFunctor;
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx
index d8319220d71067882324d2bad5501da4dcd19642..a8af687f2325e2fe9c902fe6a03fb8d9d54277d5 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.cxx
@@ -61,6 +61,7 @@ struct ProcessVisitor : boost::static_visitor<>
         m_filter.DoDefineNewLayerGeometryType(sourceLayer),
         otb::ogr::StringListConverter(m_filter.DoDefineNewLayerOptions(sourceLayer)).to_ogr()
       );
+      m_filter.DoDefineNewLayerFields(sourceLayer, destLayer);
       m_filter.DoProcessLayer(sourceLayer, destLayer);
       }
     }
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h
index 4e8d2d9dac18b2162790d4e7eab34b9e756aa6bf..14c1e43072b29db9a52587ee1fdcc1181dbaddd5 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.h
@@ -120,6 +120,8 @@ private:
    */
   virtual std::vector<std::string> DoDefineNewLayerOptions(ogr::Layer const& source) const;
 
+  virtual void DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const = 0;
+
   /** Hook used to conclude the initialization phase.
    * As ITK doesn't follow a <em>the constructor set the object in a final, and
    * ready to be used, state</em>, this step is required to do that once all
@@ -132,6 +134,38 @@ private:
   friend struct ::ProcessVisitor;
   };
 
+struct FieldCopyTransformation
+  {
+  OGRFeatureDefn & getDefinition(ogr::Layer & outLayer) const
+    {
+    return outLayer.GetLayerDefn();
+    }
+  void fieldsTransform(ogr::Feature const& inoutFeature) const
+    {
+    // default => do nothing for in-place transformation
+    }
+  void fieldsTransform(ogr::Feature const& inFeature, ogr::Feature & outFeature) const
+    {
+    // 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].Assign(inFeature[i]);
+      }
+    }
+
+  void DefineFields(ogr::Layer const& source, ogr::Layer & dest) const
+    {
+    std::cout << " FieldCopyTransformation::DefineFields()\n";
+    OGRFeatureDefn & inDefinition = source.GetLayerDefn();
+    for (int i=0,N=inDefinition.GetFieldCount(); i!=N; ++i)
+      {
+      std::cout << "  - " << ogr::FieldDefn(*inDefinition.GetFieldDefn(i)) << "\n";
+      dest.CreateField(*inDefinition.GetFieldDefn(i));
+      }
+    }
+  };
+
 
 /**\ingroup GeometriesFilters
  * \class TransformationFunctorDispatcher
@@ -147,7 +181,7 @@ private:
  * \since OTB v 3.14.0
  * \todo Add a specialization for \c ogr::Feature.
  */
-template <class TransformationFunctor, class TransformedElementType>
+template <class TransformationFunctor, class TransformedElementType, class FieldTransformationPolicy = FieldCopyTransformation>
 struct TransformationFunctorDispatcher
   {
   };
@@ -157,8 +191,9 @@ struct TransformationFunctorDispatcher
  * \tparam TransformationFunctor actual transformation functor
  * \since OTB v 3.14.0
  */
-template <class TransformationFunctor>
-struct TransformationFunctorDispatcher<TransformationFunctor, ogr::Layer>
+template <class TransformationFunctor, class FieldTransformationPolicy>
+struct TransformationFunctorDispatcher<TransformationFunctor, ogr::Layer, FieldTransformationPolicy>
+: FieldTransformationPolicy
   {
   typedef typename TransformationFunctor::TransformedElementType TransformedElementType;
   BOOST_MPL_ASSERT((boost::is_same<ogr::Layer, TransformedElementType>));
@@ -171,35 +206,14 @@ 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.
  * \tparam TransformationFunctor actual transformation functor
  * \since OTB v 3.14.0
  */
-template <class TransformationFunctor>
-struct TransformationFunctorDispatcher<TransformationFunctor, OGRGeometry>
+template <class TransformationFunctor, class FieldTransformationPolicy>
+struct TransformationFunctorDispatcher<TransformationFunctor, OGRGeometry, FieldTransformationPolicy>
+: FieldTransformationPolicy
   {
   typedef typename TransformationFunctor::TransformedElementType TransformedElementType;
   BOOST_MPL_ASSERT((boost::is_same<OGRGeometry, TransformedElementType>));
@@ -220,10 +234,10 @@ private:
  * \since OTB v 3.14.0
  * \todo Find a better name
  */
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy = FieldCopyTransformation>
 class ITK_EXPORT DefaultGeometriesToGeometriesFilter
 : public GeometriesToGeometriesFilter
-, public TransformationFunctorDispatcher<TransformationFunctor, typename TransformationFunctor::TransformedElementType>
+, public TransformationFunctorDispatcher<TransformationFunctor, typename TransformationFunctor::TransformedElementType, FieldTransformationPolicy>
 {
 public:
   /**\name Standard ITK typedefs */
@@ -237,7 +251,7 @@ public:
   //@{
   typedef TransformationFunctor                                  TransformationFunctorType;
   typedef typename TransformationFunctor::TransformedElementType TransformedElementType;
-  typedef TransformationFunctorDispatcher<TransformationFunctorType, TransformedElementType>
+  typedef TransformationFunctorDispatcher<TransformationFunctorType, TransformedElementType, FieldTransformationPolicy>
                                                                  TransformationFunctorDispatcherType;
   //@}
 
@@ -257,6 +271,10 @@ protected:
   virtual ~DefaultGeometriesToGeometriesFilter();
 
   virtual void DoProcessLayer(ogr::Layer const& source, ogr::Layer & destination) const;
+  virtual void DoDefineNewLayerFields(ogr::Layer const& source, ogr::Layer & dest) const
+    {
+    this->DefineFields(source, dest);
+    }
 private:
   // TransformationFunctorDispatcherType m_TransformationFunctor;
 };
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx
index 91653bd1f7eb6d0aafb8bc0d0f79e8fcac7655dc..dddc59bfdc995f97654d2f47360c46df1a574d26 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbGeometriesToGeometriesFilter.txx
@@ -23,21 +23,21 @@
 /*===========================================================================*/
 /*==================[ DefaultGeometriesToGeometriesFilter ]==================*/
 /*===========================================================================*/
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
-otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor>::DefaultGeometriesToGeometriesFilter()
+otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor, FieldTransformationPolicy>::DefaultGeometriesToGeometriesFilter()
 {}
 
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
 /*virtual*/
-otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor>::~DefaultGeometriesToGeometriesFilter()
+otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor, FieldTransformationPolicy>::~DefaultGeometriesToGeometriesFilter()
 {}
 
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
 /*virtual*/
-void otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor>::DoProcessLayer(
+void otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor, FieldTransformationPolicy>::DoProcessLayer(
   otb::ogr::Layer const& source, otb::ogr::Layer & destination) const
 {
   if (source != destination)
@@ -56,17 +56,17 @@ void otb::DefaultGeometriesToGeometriesFilter<TransformationFunctor>::DoProcessL
 /*================[ TransformationFunctorDispatcher<layer> ]=================*/
 /*===========================================================================*/
 
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
-void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer>::operator()(
+void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer,FieldTransformationPolicy>::operator()(
   otb::ogr::Layer const& in, otb::ogr::Layer & out) const
 {
   m_functor(in, out);
 }
 
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
-void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer>::operator()(
+void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer,FieldTransformationPolicy>::operator()(
   otb::ogr::Layer & inout) const
 
 {
@@ -76,26 +76,26 @@ void otb::TransformationFunctorDispatcher<TransformationFunctor,otb::ogr::Layer>
 /*===========================================================================*/
 /*=============[ TransformationFunctorDispatcher<OGRGeometry> ]==============*/
 /*===========================================================================*/
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
-void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry>::operator()(
+void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry,FieldTransformationPolicy>::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(otb::move(g));
+    this->fieldsTransform(feat, dest);
     out.CreateFeature(dest);
     }
 }
 
-template <class TransformationFunctor>
+template <class TransformationFunctor, class FieldTransformationPolicy>
 inline
-void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry>::operator()(
+void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry,FieldTransformationPolicy>::operator()(
   otb::ogr::Layer & inout) const
 {
   OGRFeatureDefn & defn = inout.GetLayerDefn();
@@ -105,7 +105,7 @@ void otb::TransformationFunctorDispatcher<TransformationFunctor,OGRGeometry>::op
   for (int i=0, N=inout.GetFeatureCount(true); i!=N; ++i)
     {
     ogr::Feature feat = *inout.start_at(i);
-    // TODO: field transformations...
+    this->fieldsTransform(feat);
     ogr::UniqueGeometryPtr g = m_functor(feat.GetGeometry());
     feat.SetGeometryDirectly(otb::move(g));
     inout.SetFeature(feat);
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
index 8bcea0628765db9861cf7fd9c49772780243729a..d3f686c72b45f37246a4dbc48c49f6617eebca45 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.h
@@ -99,7 +99,8 @@ public:
    */
   Field(Feature & feature, size_t index);
   /// %Field definition accessor.
-  FieldDefn const& GetDefinition() const;
+  FieldDefn const& GetDefinition() const
+    { return m_Definition; }
   /// %Field type accessor.
   OGRFieldType GetType() const
     { return m_Definition.GetType(); }
diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx
index c821b416668253850bb9858bf1611a30edf31555..b213f5b7f359f4f11387f48f8899cf20890cdf1d 100644
--- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx
+++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRFieldWrapper.txx
@@ -435,7 +435,11 @@ void otb::ogr::Field::Assign(Field const& f)
 {
   CheckInvariants();
   f.CheckInvariants();
-  assert(f.GetDefinition() == this->GetDefinition() && "Cannot assign from a field that doesn't have the same definition");
+  assert(f.GetType() == this->GetType() && "Cannot assign from a field that doesn't have the same definition");
+  // We can't assume the following as sometimes field names are altered by the
+  // datasource driver; for instance, shp driver truncates field names to 8
+  // characters.
+  // assert(f.GetDefinition() == this->GetDefinition() && "Cannot assign from a field that doesn't have the same definition");
   UncheckedAssign(f);
   CheckInvariants();
 }