From 2b7961bc547eddbe67549097ab35aa0a34d0cc4a Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Fri, 22 Jun 2012 16:29:33 +0200
Subject: [PATCH] ENH/ Adapting filter to process layers, not datasources

---
 .../otbOGRLayerStreamStitchingFilter.h        | 68 ++++++++-----------
 .../otbOGRLayerStreamStitchingFilter.txx      | 53 +++++++--------
 2 files changed, 56 insertions(+), 65 deletions(-)

diff --git a/Code/Segmentation/otbOGRLayerStreamStitchingFilter.h b/Code/Segmentation/otbOGRLayerStreamStitchingFilter.h
index 39515b4084..7e4e584e8c 100644
--- a/Code/Segmentation/otbOGRLayerStreamStitchingFilter.h
+++ b/Code/Segmentation/otbOGRLayerStreamStitchingFilter.h
@@ -15,14 +15,14 @@
      PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
-#ifndef __otbOGRDataSourceStreamStitchingFilter_h
-#define __otbOGRDataSourceStreamStitchingFilter_h
+#ifndef __otbOGRLayerStreamStitchingFilter_h
+#define __otbOGRLayerStreamStitchingFilter_h
 
 #include "otbOGRDataSourceWrapper.h"
 #include "otbMacro.h"
 
 //#if(GDAL_VERSION_NUM < 1800)
-//#error OGRDataSourceStreamStitchingFilter requires GDAL version >= 1.8.0
+//#error OGRLayerStreamStitchingFilter requires GDAL version >= 1.8.0
 //#endif
 
 #include "itkProcessObject.h"
@@ -32,7 +32,7 @@
 namespace otb
 {
 
-/** \class OGRDataSourceStreamStitchingFilter
+/** \class OGRLayerStreamStitchingFilter
  *  \brief This filter fusion the geometries in a layer (\c OGRLayer) along streaming lines.
  *  It is a in-line filter which means that the result of the fusion overwrites the input layer.
  *  The strategy for merging polygons is quite simple. A polygon P1 is merge with a polygon P2 if:
@@ -51,33 +51,30 @@ namespace otb
  *
  */
 template <class TInputImage>
-class ITK_EXPORT OGRDataSourceStreamStitchingFilter :
+class ITK_EXPORT OGRLayerStreamStitchingFilter :
     public itk::ProcessObject
 {
 public:
 
    /** typedef for the classes standards. */
-  typedef OGRDataSourceStreamStitchingFilter                 Self;
-  typedef itk::ProcessObject                  Superclass;
-  typedef itk::SmartPointer<Self>             Pointer;
-  typedef itk::SmartPointer<const Self>       ConstPointer;
+  typedef OGRLayerStreamStitchingFilter        Self;
+  typedef itk::ProcessObject                   Superclass;
+  typedef itk::SmartPointer<Self>              Pointer;
+  typedef itk::SmartPointer<const Self>        ConstPointer;
   
   /** Definition of the input image */
-  typedef TInputImage                           InputImageType;
-  typedef typename InputImageType::PixelType    InputPixelType;
-  typedef typename InputImageType::IndexType    InputIndexType;
-  typedef typename InputImageType::SizeType     SizeType;
-  typedef typename InputImageType::RegionType   RegionType;
-  typedef typename InputImageType::SpacingType  SpacingType;
-  typedef typename InputImageType::PointType    OriginType;
-  typedef typename InputImageType::IndexType    IndexType;
+  typedef TInputImage                          InputImageType;
+  typedef typename InputImageType::PixelType   InputPixelType;
+  typedef typename InputImageType::IndexType   InputIndexType;
+  typedef typename InputImageType::SizeType    SizeType;
+  typedef typename InputImageType::RegionType  RegionType;
+  typedef typename InputImageType::SpacingType SpacingType;
+  typedef typename InputImageType::PointType   OriginType;
+  typedef typename InputImageType::IndexType   IndexType;
   
-  typedef ogr::DataSource                            OGRDataSourceType;
-  typedef typename OGRDataSourceType::Pointer        OGRDataSourcePointerType;
-  typedef ogr::Layer                                 OGRLayerType;
-  typedef ogr::Feature                               OGRFeatureType;
+  typedef ogr::Layer                           OGRLayerType;
+  typedef ogr::Feature                         OGRFeatureType;
 
-  
   /** Set the input image of this process object.  */
   virtual void SetInput(const InputImageType *input);
   /** Get the input image. */
@@ -87,12 +84,12 @@ public:
   itkNewMacro(Self);
 
   /** Return the name of the class. */
-  itkTypeMacro(OGRDataSourceStreamStitchingFilter, ProcessObject);
+  itkTypeMacro(OGRLayerStreamStitchingFilter, ProcessObject);
   
-  /** Set the input OGRDataSource */
-  void SetOGRDataSource( OGRDataSourcePointerType ogrDS );
-  /** Get the input OGRDataSource*/
-  OGRDataSourceType * GetOGRDataSource( void );
+  /** Set the input OGRLayer */
+  void SetOGRLayer( const OGRLayerType & ogrLayer );
+  /** Get the input OGRLayer */
+  const OGRLayerType & GetOGRLayer( void ) const;
   
   /** Set the stream size.
    * As this filter is intended to be used right after the \c StreamingVectorizedSegmentation,
@@ -101,18 +98,13 @@ public:
   itkSetMacro(StreamSize, SizeType);
   /** Get stream size*/
   itkGetMacro(StreamSize, SizeType);
-  
-  /** Set the name of the layer in the input \c OGRDataSource, that contains the polygons to merge.*/
-  itkSetStringMacro(LayerName);
-  /** Get the layer name. */
-  itkGetStringMacro(LayerName);
-  
+    
   /** Generate Data method. This method must be called explicitly (not through the \c Update method). */
   virtual void GenerateData();
   
 protected:
-  OGRDataSourceStreamStitchingFilter();
-  virtual ~OGRDataSourceStreamStitchingFilter() {}
+  OGRLayerStreamStitchingFilter();
+  virtual ~OGRLayerStreamStitchingFilter() {}
   
   struct FusionStruct
   {
@@ -145,12 +137,12 @@ protected:
   double GetLengthOGRGeometryCollection(OGRGeometryCollection * intersection);
 
 private:
-  OGRDataSourceStreamStitchingFilter(const Self &);  //purposely not implemented
+  OGRLayerStreamStitchingFilter(const Self &);  //purposely not implemented
   void operator =(const Self&);      //purposely not implemented
   
   SizeType m_StreamSize;
   unsigned int m_Radius;
-  std::string m_LayerName;
+  OGRLayerType m_OGRLayer;
 
 
 };
@@ -159,7 +151,7 @@ private:
 } // end namespace otb
 
 #ifndef OTB_MANUAL_INSTANTIATION
-#include "otbOGRDataSourceStreamStitchingFilter.txx"
+#include "otbOGRLayerStreamStitchingFilter.txx"
 #endif
 
 #endif
diff --git a/Code/Segmentation/otbOGRLayerStreamStitchingFilter.txx b/Code/Segmentation/otbOGRLayerStreamStitchingFilter.txx
index 2bfe6cd194..9adee5c560 100644
--- a/Code/Segmentation/otbOGRLayerStreamStitchingFilter.txx
+++ b/Code/Segmentation/otbOGRLayerStreamStitchingFilter.txx
@@ -31,7 +31,7 @@ namespace otb
 
 template<class TImage>
 OGRDataSourceStreamStitchingFilter<TImage>
-::OGRDataSourceStreamStitchingFilter() : m_Radius(2), m_LayerName("Layer")
+::OGRDataSourceStreamStitchingFilter() : m_Radius(2), m_OGRLayer(NULL)
 {
    m_StreamSize.Fill(0);
 }
@@ -61,17 +61,18 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
 template<class TInputImage>
 void
 OGRDataSourceStreamStitchingFilter<TInputImage>
-::SetOGRDataSource( OGRDataSourcePointerType ogrDS )
+::SetOGRLayer( const OGRLayerType& ogrLayer )
 {
-   this->itk::ProcessObject::SetNthInput(1, ogrDS);
+  m_OGRLayer = ogrLayer;
+  this->Modified();
 }
 
 template<class TInputImage>
-typename OGRDataSourceStreamStitchingFilter<TInputImage>::OGRDataSourceType *
+const typename OGRDataSourceStreamStitchingFilter<TInputImage>::OGRLayerType &
 OGRDataSourceStreamStitchingFilter<TInputImage>
-::GetOGRDataSource( void )
+::GetOGRDataSource( void ) const
 {
-   return static_cast<OGRDataSourceType *> (this->itk::ProcessObject::GetInput(1));
+   return m_OGRLayer;
 }
 
 template<class TInputImage>
@@ -104,13 +105,6 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
 ::ProcessStreamingLine( bool line )
 {
    typename InputImageType::ConstPointer inputImage = this->GetInput();
-   OGRDataSourcePointerType inputDataSource = this->GetOGRDataSource();
-   //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.
-   OGRLayerType inputLayer = inputDataSource->GetLayersCount() == 1
-                          ? inputDataSource->GetLayer(0)
-                          : inputDataSource->GetLayerChecked(m_LayerName);
 
    //compute the number of stream division in row and column
    SizeType imageSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
@@ -121,7 +115,7 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
 
    for(unsigned int x=1; x<=nbColStream; x++)
    {
-      inputLayer.ogr().StartTransaction();
+      m_OGRLayer.ogr().StartTransaction();
       for(unsigned int y=1; y<=nbRowStream; y++)
       {
          //First we get all the feature that intersect the streaming line of the Upper/left stream
@@ -155,12 +149,12 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
          OriginType  lrCorner;
          inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
 
-         inputLayer.SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
+         m_OGRLayer.SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
 
-         OGRLayerType::const_iterator featIt = inputLayer.begin();
-         for(; featIt!=inputLayer.end(); ++featIt)
+         OGRLayerType::const_iterator featIt = m_OGRLayer.begin();
+         for(; featIt!=m_OGRLayer.end(); ++featIt)
          {
-            FeatureStruct s(inputLayer.GetLayerDefn());
+            FeatureStruct s(m_OGRLayer.GetLayerDefn());
             s.feat = *featIt;
             s.fusioned = false;
             upperStreamFeatureList.push_back(s);
@@ -192,11 +186,11 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
          inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
          inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
 
-         inputLayer.SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
+         m_OGRLayer.SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
 
-         for(featIt = inputLayer.begin(); featIt!=inputLayer.end(); ++featIt)
+         for(featIt = m_OGRLayer.begin(); featIt!=m_OGRLayer.end(); ++featIt)
          {
-            FeatureStruct s(inputLayer.GetLayerDefn());
+            FeatureStruct s(m_OGRLayer.GetLayerDefn());
             s.feat = *featIt;
             s.fusioned = false;
             lowerStreamFeatureList.push_back(s);
@@ -266,16 +260,16 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
                upperStreamFeatureList[fusionList[i].indStream1].fusioned = true;
                lowerStreamFeatureList[fusionList[i].indStream2].fusioned = true;
                ogr::UniqueGeometryPtr fusionPolygon = ogr::Union(*upper.feat.GetGeometry(),*lower.feat.GetGeometry());
-               OGRFeatureType fusionFeature(inputLayer.GetLayerDefn());
+               OGRFeatureType fusionFeature(m_OGRLayer.GetLayerDefn());
                fusionFeature.SetGeometry( fusionPolygon.get() );
 
                ogr::Field field = upper.feat[0];
                try
                  {
                  fusionFeature[0].SetValue(field.GetValue<int>());
-                 inputLayer.CreateFeature(fusionFeature);
-                 inputLayer.DeleteFeature(lower.feat.GetFID());
-                 inputLayer.DeleteFeature(upper.feat.GetFID());
+                 m_OGRLayer.CreateFeature(fusionFeature);
+                 m_OGRLayer.DeleteFeature(lower.feat.GetFID());
+                 m_OGRLayer.DeleteFeature(upper.feat.GetFID());
                  }
                catch(itk::ExceptionObject& err)
                  {
@@ -284,12 +278,12 @@ OGRDataSourceStreamStitchingFilter<TInputImage>
             }
          }
       } //end for x
-      inputLayer.ogr().CommitTransaction();
+      m_OGRLayer.ogr().CommitTransaction();
 
       // Update progress
       progress.CompletedPixel();
    } //end for y
-   inputLayer.ogr().CommitTransaction();
+   m_OGRLayer.ogr().CommitTransaction();
 
 }
 
@@ -298,6 +292,11 @@ void
 OGRDataSourceStreamStitchingFilter<TImage>
 ::GenerateData(void)
 {
+  if(!m_OGRLayer)
+    {
+    itkExceptionMacro(<<"Input OGR layer is null!");
+    }
+
    //Process column
    this->ProcessStreamingLine(false);
    //Process row
-- 
GitLab