From 6b5f48a8154d339822c4fd5ba0f16be4e16c863a Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Fri, 22 Jun 2012 13:45:07 +0200
Subject: [PATCH] ENH: The persistent filter works at the layer level, not at
 the datasource one

---
 .../otbPersistentImageToOGRDataSourceFilter.h |  65 +++-----
 ...tbPersistentImageToOGRDataSourceFilter.txx | 140 +++++++-----------
 2 files changed, 76 insertions(+), 129 deletions(-)

diff --git a/Code/Common/otbPersistentImageToOGRDataSourceFilter.h b/Code/Common/otbPersistentImageToOGRDataSourceFilter.h
index 1197ace819..24a673a8b3 100644
--- a/Code/Common/otbPersistentImageToOGRDataSourceFilter.h
+++ b/Code/Common/otbPersistentImageToOGRDataSourceFilter.h
@@ -18,13 +18,13 @@
      PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
-#ifndef __otbPersistentImageToOGRDataSourceFilter_h
-#define __otbPersistentImageToOGRDataSourceFilter_h
+#ifndef __otbPersistentImageToOGRLayerFilter_h
+#define __otbPersistentImageToOGRLayerFilter_h
 
 #include "otbPersistentImageFilter.h"
 
 #include "otbLabelImageToOGRDataSourceFilter.h"
-#include "otbOGRDataSourceWrapper.h"
+#include "otbOGRLayerWrapper.h"
 
 #include "itkMacro.h"
 #include <string>
@@ -32,33 +32,31 @@
 namespace otb
 {
 
-/** \class PersistentImageToOGRDataSourceFilter
+/** \class PersistentImageToOGRLayerFilter
  *  \brief Perform vectorization in a persistent way.
  *
  *  This filter is a generic filter. It is the base class of the Large scale segmentation framework.
- *  The \c Initialize() method is used to create the new layer (LayerName) in the input \c OGRDataSource,
- *  and the field (FieldName) in the layer. This field will contain the label of the polygon in the input image.
  *  The \c ProcessTile() method is pure virtual and is implemented in sub class
  *  (@see \c PersistentStreamingLabelImageToOGRDataFilter). It returns a "memory" DataSource.
- *  This filter only copy each feature of the layer in the "memory" DataSource into the LayerName layer in the
- *  input \c OGRDataSource set by \c SetOGRDataSource() method.
+ *  This filter only copy each feature of the layer in the "memory" DataSource into the
+ *  input \c OGRLayer set by \c SetOGRLayer() method.
  *
  * \sa PersistentImageFilter
  *
  */
 template<class TImage>
-class ITK_EXPORT PersistentImageToOGRDataSourceFilter :
+class ITK_EXPORT PersistentImageToOGRLayerFilter :
   public PersistentImageFilter<TImage, TImage>
 {
 public:
   /** Standard Self typedef */
-  typedef PersistentImageToOGRDataSourceFilter                  Self;
+  typedef PersistentImageToOGRLayerFilter                  Self;
   typedef PersistentImageFilter<TImage, TImage>           Superclass;
   typedef itk::SmartPointer<Self>                         Pointer;
   typedef itk::SmartPointer<const Self>                   ConstPointer;
 
   /** Runtime information support. */
-  itkTypeMacro(PersistentImageToOGRDataSourceFilter, PersistentImageFilter);
+  itkTypeMacro(PersistentImageToOGRLayerFilter, PersistentImageFilter);
 
   typedef TImage                                     InputImageType;
   typedef typename InputImageType::Pointer           InputImagePointer;
@@ -68,28 +66,20 @@ public:
   typedef typename InputImageType::PixelType         PixelType;
   typedef typename InputImageType::InternalPixelType InternalPixelType;
 
-  typedef ogr::DataSource                            OGRDataSourceType;
-  typedef typename OGRDataSourceType::Pointer        OGRDataSourcePointerType;
   typedef ogr::Layer                                 OGRLayerType;
-  typedef ogr::Feature                               OGRFeatureType;
 
 
   void AllocateOutputs();
   virtual void Reset(void);
   virtual void Synthetize(void);
   
-  /** This method creates the output layer in the OGRDataSource set by the user.
-   * The name of the layer is set by \c SetLayerName .
+  /** This method creates the output layer in the OGRLayer set by the user.
    * \note This methode must be called before the call of Update .
    */
   virtual void Initialize(void);
-  
-  /** Set/Get the name of the output layer to write in the \c ogr::DataSource. */
-  itkSetStringMacro(LayerName);
-  itkGetStringMacro(LayerName);
-  
+    
   /** Set the Field Name in which labels will be written. (default is "DN")
-   * A field FieldName is created in the output layer LayerName. The Field type is Integer.
+   * A field FieldName is created in the Layer. The Field type is Integer.
    */
   itkSetMacro(FieldName, std::string);
   
@@ -104,23 +94,14 @@ public:
    */
   itkGetMacro(StreamSize, SizeType);
   
-  /** Set the \c ogr::DataSource in which the layer LayerName will be created. */
-  void SetOGRDataSource( OGRDataSourcePointerType ogrDS );
-  /** Get the \c ogr::DataSource output. */
-  OGRDataSourceType * GetOGRDataSource( void );
-
-  /** Add one option for OGR layer creation */
-  void AddOGRLayerCreationOption(const std::string& option);
-
-  /** Clear all OGR layer creation options */
-  void ClearOGRLayerCreationOptions();
-  
-  /** Set the OGR layer creation options */
-  void SetOGRLayerCreationOptions(const std::vector<std::string> & options);
+  /** Set the \c ogr::Layer in which the geometries will be dumped */
+  void SetOGRLayer( OGRLayerType * ogrLayer );
+  /** Get the \c ogr::Layer output. */
+  OGRLayerType * GetOGRLayer( void );
 
 protected:
-  PersistentImageToOGRDataSourceFilter();
-  virtual ~PersistentImageToOGRDataSourceFilter();
+  PersistentImageToOGRLayerFilter();
+  virtual ~PersistentImageToOGRLayerFilter();
 
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
@@ -128,22 +109,18 @@ protected:
 
 
 private:
-  PersistentImageToOGRDataSourceFilter(const Self &); //purposely not implemented
+  PersistentImageToOGRLayerFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
 
-  virtual OGRDataSourcePointerType ProcessTile() = 0;
+  virtual OGRLayerPointerType ProcessTile() = 0;
   
   std::string m_FieldName;
-  std::string m_LayerName;
-  OGRwkbGeometryType m_GeometryType;
   SizeType m_StreamSize;
-  std::vector<std::string> m_OGRLayerCreationOptions;
-
 }; // end of class
 } // end namespace otb
 
 #ifndef OTB_MANUAL_INSTANTIATION
-#include "otbPersistentImageToOGRDataSourceFilter.txx"
+#include "otbPersistentImageToOGRLayerFilter.txx"
 #endif
 
 #endif
diff --git a/Code/Common/otbPersistentImageToOGRDataSourceFilter.txx b/Code/Common/otbPersistentImageToOGRDataSourceFilter.txx
index 21a9a119bf..10d6c991ed 100644
--- a/Code/Common/otbPersistentImageToOGRDataSourceFilter.txx
+++ b/Code/Common/otbPersistentImageToOGRDataSourceFilter.txx
@@ -18,10 +18,10 @@
      PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
-#ifndef __otbPersistentImageToOGRDataSourceFilter_txx
-#define __otbPersistentImageToOGRDataSourceFilter_txx
+#ifndef __otbPersistentImageToOGRLayerFilter_txx
+#define __otbPersistentImageToOGRLayerFilter_txx
 
-#include "otbPersistentImageToOGRDataSourceFilter.h"
+#include "otbPersistentImageToOGRLayerFilter.h"
 #include "itkTimeProbe.h"
 #include <boost/foreach.hpp>
 #include <stdio.h>
@@ -32,67 +32,38 @@ namespace otb
 {
 
 template<class TImage>
-PersistentImageToOGRDataSourceFilter<TImage>
-::PersistentImageToOGRDataSourceFilter() : m_FieldName("DN"), m_LayerName("Layer"), m_GeometryType(wkbMultiPolygon)
+PersistentImageToOGRLayerFilter<TImage>
+::PersistentImageToOGRLayerFilter() : m_Layer()
 {
-   this->SetNumberOfInputs(2);
-   this->SetNumberOfRequiredInputs(2);
    m_StreamSize.Fill(0);
 }
 
 template<class TImage>
-PersistentImageToOGRDataSourceFilter<TImage>
-::~PersistentImageToOGRDataSourceFilter()
+PersistentImageToOGRLayerFilter<TImage>
+::~PersistentImageToOGRLayerFilter()
 {
 }
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
-::SetOGRDataSource( OGRDataSourcePointerType ogrDS )
+PersistentImageToOGRLayerFilter<TImage>
+::SetOGRLayer(const OGRLayerType & ogrLayer)
 {
-   this->itk::ProcessObject::SetNthInput(1, ogrDS);
-}
-
-template<class TImage>
-typename PersistentImageToOGRDataSourceFilter<TImage>::OGRDataSourceType *
-PersistentImageToOGRDataSourceFilter<TImage>
-::GetOGRDataSource( void )
-{
-   return static_cast<OGRDataSourceType *> (this->itk::ProcessObject::GetInput(1));
-}
-
-template<class TImage>
-void
-PersistentImageToOGRDataSourceFilter<TImage>
-::AddOGRLayerCreationOption(const std::string& option)
-{
-  m_OGRLayerCreationOptions.push_back(option);
+  m_OGRLayer = ogrLayer;
   this->Modified();
 }
 
 template<class TImage>
-void
-PersistentImageToOGRDataSourceFilter<TImage>
-::ClearOGRLayerCreationOptions()
+const typename PersistentImageToOGRLayerFilter<TImage>::OGRLayerType&
+PersistentImageToOGRLayerFilter<TImage>
+::GetOGRLayer( void )
 {
-  m_OGRLayerCreationOptions.clear();
-  this->Modified();
+  return m_OGRLayer;
 }
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
-::SetOGRLayerCreationOptions(const std::vector<std::string>&  options)
-{
-  m_OGRLayerCreationOptions = options;
-  this->Modified();
-}
-
-
-template<class TImage>
-void
-PersistentImageToOGRDataSourceFilter<TImage>
+PersistentImageToOGRLayerFilter<TImage>
 ::AllocateOutputs()
 {
   // Nothing that needs to be allocated for the outputs : the output is not meant to be used
@@ -100,75 +71,74 @@ PersistentImageToOGRDataSourceFilter<TImage>
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
+PersistentImageToOGRLayerFilter<TImage>
 ::Reset()
 {
 }
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
+PersistentImageToOGRLayerFilter<TImage>
 ::Synthetize()
 {
 }
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
+PersistentImageToOGRLayerFilter<TImage>
 ::Initialize()
 {
    
-   std::string projectionRefWkt = this->GetInput()->GetProjectionRef();
-   bool projectionInformationAvailable = !projectionRefWkt.empty();
-   OGRSpatialReference * oSRS = NULL;
-   if(projectionInformationAvailable)
-   {
-      oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str()));
-   }
+   // std::string projectionRefWkt = this->GetInput()->GetProjectionRef();
+   // bool projectionInformationAvailable = !projectionRefWkt.empty();
+   // OGRSpatialReference * oSRS = NULL;
+   // if(projectionInformationAvailable)
+   // {
+   //    oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str()));
+   // }
    
    
-   OGRDataSourcePointerType ogrDS = this->GetOGRDataSource();
+   // OGRLayerPointerType ogrDS = this->GetOGRLayer();
 
-   ogrDS->CreateLayer(m_LayerName, oSRS ,m_GeometryType, otb::ogr::StringListConverter(m_OGRLayerCreationOptions).to_ogr());
-   OGRFieldDefn field(m_FieldName.c_str(),OFTInteger);
+   // ogrDS->CreateLayer(m_LayerName, oSRS ,m_GeometryType, otb::ogr::StringListConverter(m_OGRLayerCreationOptions).to_ogr());
+   // OGRFieldDefn field(m_FieldName.c_str(),OFTInteger);
    
-   //Handle the case of shapefile. A shapefile is a layer and not a datasource.
-   //The layer name in a shapefile is the shapefile's name.
-   //This is not the case for a database as sqlite or PG.
-   if (ogrDS->GetLayersCount() == 1)
-   {
-      ogrDS->GetLayer(0).CreateField(field, true);
-   }
-   else
-   {
-      ogrDS->GetLayer(m_LayerName).CreateField(field, true);
-   }
-
-   //CSLDestroy( options );
+   // //Handle the case of shapefile. A shapefile is a layer and not a datasource.
+   // //The layer name in a shapefile is the shapefile's name.
+   // //This is not the case for a database as sqlite or PG.
+   // if (ogrDS->GetLayersCount() == 1)
+   // {
+   //    ogrDS->GetLayer(0).CreateField(field, true);
+   // }
+   // else
+   // {
+   //    ogrDS->GetLayer(m_LayerName).CreateField(field, true);
+   // }
+
+   // //CSLDestroy( options );
 
 }
 
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
+PersistentImageToOGRLayerFilter<TImage>
 ::GenerateData()
 {
-  
+  if(!m_OGRLayer)
+    {
+    itkExceptionMacro(<<"Output OGRLayer is null.");
+    }
+
   if (this->GetStreamSize()[0]==0 && this->GetStreamSize()[1]==0)
   {
      this->m_StreamSize = this->GetInput()->GetRequestedRegion().GetSize();
   }
-  
-  // call the processing function for this tile
-  OGRDataSourcePointerType currentTileVD = this->ProcessTile();
-  OGRLayerType srcLayer = currentTileVD->GetLayerChecked(0);
 
-  OGRDataSourcePointerType ogrDS = this->GetOGRDataSource();
-  OGRLayerType dstLayer = ogrDS->GetLayersCount() == 1
-                          ? ogrDS->GetLayer(0)
-                          : ogrDS->GetLayer(m_LayerName);
-  
+
+  // call the processing function for this tile
+  OGRLayerPointerType currentTileVD = this->ProcessTile();
+  OGRLayerType srcLayer = currentTileVD->GetLayerChecked(0);  
   
   //Copy features contained in the memory layer (srcLayer) in the output layer
   itk::TimeProbe chrono;
@@ -177,12 +147,12 @@ PersistentImageToOGRDataSourceFilter<TImage>
   OGRLayerType::const_iterator featIt = srcLayer.begin();
   for(; featIt!=srcLayer.end(); ++featIt)
   {
-      OGRFeatureType dstFeature(dstLayer.GetLayerDefn());
+      OGRFeatureType dstFeature(m_OGRLayer.GetLayerDefn());
       dstFeature.SetFrom( *featIt, TRUE );
-      dstLayer.CreateFeature( dstFeature );
+      m_OGRLayer.CreateFeature( dstFeature );
   }
   
-  dstLayer.ogr().CommitTransaction();
+  m_OGRLayer.ogr().CommitTransaction();
   chrono.Stop();
   otbMsgDebugMacro(<< "write ogr tile took " << chrono.GetTotal() << " sec");
   
@@ -190,7 +160,7 @@ PersistentImageToOGRDataSourceFilter<TImage>
 
 template<class TImage>
 void
-PersistentImageToOGRDataSourceFilter<TImage>
+PersistentImageToOGRLayerFilter<TImage>
 ::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
   Superclass::PrintSelf(os, indent);
-- 
GitLab