diff --git a/Code/OBIA/otbFusionOGRTileFilter.h b/Code/OBIA/otbFusionOGRTileFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2a4a4a58bccc2406abce3c254c9ac7174222663
--- /dev/null
+++ b/Code/OBIA/otbFusionOGRTileFilter.h
@@ -0,0 +1,122 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#ifndef __otbFusionOGRTileFilter_h
+#define __otbFusionOGRTileFilter_h
+
+#include "itkProcessObject.h"
+#include "ogrsf_frmts.h"
+
+namespace otb
+{
+
+/** \class FusionOGRTileFilter
+ *  \brief This filter fusion the geometries in a layer (ogr) along streaming lines.
+ *  The SetStreamSize() method allows to retrieve the number of streams in row and column,
+ *  and their pixel coordinates.
+ *  The input image is used to transform pixel coordinates of the streaming lines into 
+ *  coordinate system of the image, which must be the same as the one in the OGR input file.
+ *  The input OGR file is updated with the fusionned polygons.
+ *
+ *
+ *  \ingroup OBIA
+ *
+ *
+ */
+template <class TInputImage>
+class ITK_EXPORT FusionOGRTileFilter :
+    public itk::ProcessObject
+{
+public:
+
+   /** typedef for the classes standards. */
+  typedef FusionOGRTileFilter                 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;
+
+  
+  /** Set/Get the input image of this process object.  */
+  virtual void SetInput(const InputImageType *input);
+  virtual const InputImageType * GetInput(void);
+  
+  /** Method for management of the object factory. */
+  itkNewMacro(Self);
+
+  /** Return the name of the class. */
+  itkTypeMacro(FusionOGRTileFilter, ProcessObject);
+  
+  /** Set/Get Input OGR filename */
+  itkSetMacro(InputFileName, std::string);
+  itkGetMacro(InputFileName, std::string);
+  
+  /** Set/Get the size of the stream */
+  itkSetMacro(StreamSize, SizeType);
+  itkGetMacro(StreamSize, SizeType);
+  
+  /** Generate Data method*/
+  virtual void GenerateData();
+  
+protected:
+  FusionOGRTileFilter();
+  virtual ~FusionOGRTileFilter() {}
+  
+  struct FusionStruct
+  {
+     unsigned int indStream1;
+     unsigned int indStream2;
+     double overlap;
+  };
+  struct FeatureStruct
+  {
+     OGRFeature * feat;
+     bool fusioned;
+  };
+  struct SortFeatureStruct
+  {
+     bool operator() (FusionStruct f1, FusionStruct f2) { return (f1.overlap > f2.overlap);}
+  } SortFeature;
+  
+private:
+  FusionOGRTileFilter(const Self &);  //purposely not implemented
+  void operator =(const Self&);      //purposely not implemented
+  
+  std::string m_InputFileName;
+  SizeType m_StreamSize;
+  unsigned int m_Radius;
+
+
+};
+
+
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbFusionOGRTileFilter.txx"
+#endif
+
+#endif
diff --git a/Code/OBIA/otbFusionOGRTileFilter.txx b/Code/OBIA/otbFusionOGRTileFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..409497111116a2001dc2e84f5435ab3a79e8a0cb
--- /dev/null
+++ b/Code/OBIA/otbFusionOGRTileFilter.txx
@@ -0,0 +1,418 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#ifndef __otbFusionOGRTileFilter_txx
+#define __otbFusionOGRTileFilter_txx
+
+#include "otbFusionOGRTileFilter.h"
+
+#include "ogrsf_frmts.h"
+#include <iomanip>
+
+namespace otb
+{
+
+template<class TImage>
+FusionOGRTileFilter<TImage>
+::FusionOGRTileFilter() : m_InputFileName("")
+{
+   OGRRegisterAll();
+   m_StreamSize.Fill(0);
+   m_Radius = 2;
+
+}
+
+template <class TInputImage>
+void
+FusionOGRTileFilter<TInputImage>
+::SetInput(const InputImageType *input)
+{
+  this->Superclass::SetNthInput(0, const_cast<InputImageType *>(input));
+}
+
+template <class TInputImage>
+const typename FusionOGRTileFilter<TInputImage>
+::InputImageType *
+FusionOGRTileFilter<TInputImage>
+::GetInput(void)
+{
+  if (this->GetNumberOfInputs() < 1)
+    {
+    return 0;
+    }
+
+  return static_cast<const InputImageType *>(this->Superclass::GetInput(0));
+}
+
+template<class TImage>
+void
+FusionOGRTileFilter<TImage>
+::GenerateData(void)
+{
+   
+   typename InputImageType::ConstPointer inputImage = this->GetInput();
+
+   OGRDataSource * inputDataSource = OGRSFDriverRegistrar::Open(this->m_InputFileName.c_str(), TRUE);
+   OGRLayer * inputLayer = inputDataSource->GetLayer(0);
+
+   unsigned int nbFeature = 0;
+   unsigned int f = 0;
+   
+   //compute the number of stream division in row and column
+   SizeType imageSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
+   unsigned int nbRowStream = static_cast<unsigned int>(imageSize[1] / m_StreamSize[1] + 1);
+   unsigned int nbColStream = static_cast<unsigned int>(imageSize[0] / m_StreamSize[0] + 1);
+   
+   //process column
+   for(unsigned int x=1; x<=nbColStream; x++)
+   {
+      for(unsigned int y=1; y<=nbRowStream; y++)
+      {
+         //First compute the intersection between polygons and the streaming line (upper stream)
+         std::vector<FeatureStruct> upperStreamFeatureList;
+         upperStreamFeatureList.clear();
+         
+         //Compute the spatial filter of the upper stream
+         IndexType  UpperLeftCorner;
+         UpperLeftCorner[0] = x*m_StreamSize[0] - 1 - m_Radius;
+         UpperLeftCorner[1] = m_StreamSize[1]*(y-1) + 1;
+         
+         IndexType  LowerRightCorner;
+         LowerRightCorner[0] = m_StreamSize[0]*x - 1 - 1;
+         LowerRightCorner[1] = m_StreamSize[1]*y - 1 - 1;
+
+         OriginType  ulCorner;
+         inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
+         OriginType  lrCorner;
+         inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
+         
+         inputLayer->SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
+         
+         inputLayer->ResetReading();
+         nbFeature = inputLayer->GetFeatureCount(true);
+         
+         f = 0;
+         while (f<nbFeature)
+         {
+            OGRFeature * feature = NULL;
+            feature = inputLayer->GetNextFeature();
+            
+            FeatureStruct s;
+            s.feat = feature;
+            s.fusioned = false;
+            upperStreamFeatureList.push_back(s);
+
+            f++;
+            
+         }
+         
+         //Do the same thing for the lower stream
+         std::vector<FeatureStruct> lowerStreamFeatureList;
+         lowerStreamFeatureList.clear();
+         
+         //Compute the spatial filter of the lower stream
+         UpperLeftCorner[0] = x*m_StreamSize[0] + 1;
+         UpperLeftCorner[1] = m_StreamSize[1]*(y-1) + 1;
+         
+         LowerRightCorner[0] = m_StreamSize[0]*x + 1 + m_Radius;
+         LowerRightCorner[1] = m_StreamSize[1]*y - 1 - 1; 
+         
+         inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
+         inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
+         
+         inputLayer->SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
+         
+         inputLayer->ResetReading();
+         nbFeature = inputLayer->GetFeatureCount(true);
+         
+         f = 0;
+         while (f<nbFeature)
+         {
+            OGRFeature * feature = NULL;
+            feature = inputLayer->GetNextFeature();
+
+            FeatureStruct s;
+            s.feat = feature;
+            s.fusioned = false;
+            lowerStreamFeatureList.push_back(s);
+
+            f++;
+         }
+      
+         unsigned int nbUpperPolygons = upperStreamFeatureList.size();
+         unsigned int nbLowerPolygons = lowerStreamFeatureList.size();
+         std::vector<FusionStruct> fusionList;
+         fusionList.clear();
+         for(unsigned int u=0; u<nbUpperPolygons; u++)
+         {
+            for(unsigned int l=0; l<nbLowerPolygons; l++)
+            {
+               FeatureStruct upper = upperStreamFeatureList.at(u);
+               FeatureStruct lower = lowerStreamFeatureList.at(l);
+               if (upper.feat->GetGeometryRef()->Intersects(lower.feat->GetGeometryRef()))
+               {
+
+                  OGRGeometry * intersection;
+                  intersection = upper.feat->GetGeometryRef()->Intersection(lower.feat->GetGeometryRef());
+                  if (intersection != NULL)
+                  {
+                     FusionStruct fusion;
+                     fusion.indStream1 = u;
+                     fusion.indStream2 = l;
+                     fusion.overlap = 0.;
+                     
+                     if(intersection->getGeometryType() == wkbPolygon)
+                     {
+                        fusion.overlap = dynamic_cast<OGRPolygon *>(intersection)->get_Area();
+                     }
+                     else if(intersection->getGeometryType() == wkbMultiPolygon)
+                     {
+                        fusion.overlap = dynamic_cast<OGRMultiPolygon *>(intersection)->get_Area();
+                     }
+                     else if(intersection->getGeometryType() == wkbGeometryCollection)
+                     {
+                        fusion.overlap = dynamic_cast<OGRGeometryCollection *>(intersection)->get_Area();
+                     }
+                     else if(intersection->getGeometryType() == wkbLineString)
+                     {
+                        fusion.overlap = dynamic_cast<OGRLineString *>(intersection)->get_Length();
+                     }
+                     else if (intersection->getGeometryType() == wkbMultiLineString)
+                     {
+                        fusion.overlap = dynamic_cast<OGRMultiLineString *>(intersection)->get_Length();
+                     }
+                     
+                     long upperFID = upper.feat->GetFID();
+                     long lowerFID = lower.feat->GetFID();
+                     fusionList.push_back(fusion);
+                  }
+               }
+            }
+         }
+         unsigned int fusionListSize = fusionList.size();
+         std::sort(fusionList.begin(),fusionList.end(),SortFeature);
+         for(unsigned int i=0; i<fusionListSize; i++)
+         {
+            FeatureStruct upper = upperStreamFeatureList.at(fusionList.at(i).indStream1);
+            FeatureStruct lower = lowerStreamFeatureList.at(fusionList.at(i).indStream2);
+            if( !upper.fusioned && !lower.fusioned )
+            {
+               upperStreamFeatureList.at(fusionList.at(i).indStream1).fusioned = true;
+               lowerStreamFeatureList.at(fusionList.at(i).indStream2).fusioned = true;
+               OGRGeometry * fusionPolygon;
+               fusionPolygon = upper.feat->GetGeometryRef()->Union(lower.feat->GetGeometryRef());
+               upper.feat->SetGeometry(fusionPolygon);
+               
+               //inputLayer->SetFeature(upper.feat);
+               OGRFeature * fusionFeature;
+               fusionFeature = OGRFeature::CreateFeature( inputLayer->GetLayerDefn() );
+               fusionFeature->SetGeometry( fusionPolygon );
+               fusionFeature->SetField(0,upper.feat->GetFieldAsInteger(0));
+               inputLayer->CreateFeature(fusionFeature);
+               inputLayer->DeleteFeature(lower.feat->GetFID());
+               inputLayer->DeleteFeature(upper.feat->GetFID());
+               OGRFeature::DestroyFeature( fusionFeature );
+            }
+         }
+         
+         //free memory
+         for(unsigned int u=0; u<nbUpperPolygons; u++)
+         {
+            OGRFeature::DestroyFeature( upperStreamFeatureList.at(u).feat );
+         }
+         for(unsigned int l=0; l<nbLowerPolygons; l++)
+         {
+            OGRFeature::DestroyFeature( lowerStreamFeatureList.at(l).feat );
+         }
+      
+      } //end for x
+   } //end for y
+
+   //Process line
+   for(unsigned int y=1; y<=nbRowStream; y++)
+   {
+      for(unsigned int x=1; x<=nbColStream; x++)
+      {
+         //First compute the intersection between polygons and the streaming line (upper stream)
+         std::vector<FeatureStruct> upperStreamFeatureList;
+         upperStreamFeatureList.clear();
+         
+         //Compute the spatial filter of the upper stream
+         IndexType  UpperLeftCorner;
+         UpperLeftCorner[0] = (x-1)*m_StreamSize[0] + 1;
+         UpperLeftCorner[1] = m_StreamSize[1]*y - 1 - 1 - m_Radius;
+         
+         IndexType  LowerRightCorner;
+         LowerRightCorner[0] = m_StreamSize[0]*x - 1 - 1;
+         LowerRightCorner[1] = m_StreamSize[1]*y - 1 - 1; //-1 to stop just before stream line
+         
+         OriginType  ulCorner;
+         inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
+         OriginType  lrCorner;
+         inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
+         
+         inputLayer->SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
+         
+         inputLayer->ResetReading();
+         nbFeature = inputLayer->GetFeatureCount(true);
+         
+         f = 0;
+         while (f<nbFeature)
+         {
+            OGRFeature * feature = NULL;
+            feature = inputLayer->GetNextFeature();
+            
+            FeatureStruct s;
+            s.feat = feature;
+            s.fusioned = false;
+            upperStreamFeatureList.push_back(s);
+
+            f++;
+            
+         }
+         
+         //Do the same thing for the lower stream
+         std::vector<FeatureStruct> lowerStreamFeatureList;
+         lowerStreamFeatureList.clear();
+         
+         //Compute the spatial filter of the lower stream
+         UpperLeftCorner[0] = (x-1)*m_StreamSize[0] + 1;
+         UpperLeftCorner[1] = m_StreamSize[1]*y + 1;
+         
+         LowerRightCorner[0] = m_StreamSize[0]*x - 1 - 1;
+         LowerRightCorner[1] = m_StreamSize[1]*y + 1 + m_Radius;
+         
+         inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
+         inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
+         
+         inputLayer->SetSpatialFilterRect(ulCorner[0],lrCorner[1],lrCorner[0],ulCorner[1]);
+         
+         inputLayer->ResetReading();
+         nbFeature = inputLayer->GetFeatureCount(true);
+         
+         f = 0;
+         while (f<nbFeature)
+         {
+            OGRFeature * feature = NULL;
+            feature = inputLayer->GetNextFeature();
+
+            FeatureStruct s;
+            s.feat = feature;
+            s.fusioned = false;
+            lowerStreamFeatureList.push_back(s);
+
+            f++;
+         }
+      
+         unsigned int nbUpperPolygons = upperStreamFeatureList.size();
+         unsigned int nbLowerPolygons = lowerStreamFeatureList.size();
+         std::vector<FusionStruct> fusionList;
+         fusionList.clear();
+         for(unsigned int u=0; u<nbUpperPolygons; u++)
+         {
+            for(unsigned int l=0; l<nbLowerPolygons; l++)
+            {
+               FeatureStruct upper = upperStreamFeatureList.at(u);
+               FeatureStruct lower = lowerStreamFeatureList.at(l);
+               if (upper.feat->GetGeometryRef()->Intersects(lower.feat->GetGeometryRef()))
+               {
+
+                  OGRGeometry * intersection;
+                  intersection = upper.feat->GetGeometryRef()->Intersection(lower.feat->GetGeometryRef());
+                  if (intersection != NULL)
+                  {
+                     FusionStruct fusion;
+                     fusion.indStream1 = u;
+                     fusion.indStream2 = l;
+                     fusion.overlap = 0.;
+                     
+                     if(intersection->getGeometryType() == wkbPolygon)
+                     {
+                        fusion.overlap = dynamic_cast<OGRPolygon *>(intersection)->get_Area();
+                     }
+                     else if(intersection->getGeometryType() == wkbMultiPolygon)
+                     {
+                        fusion.overlap = dynamic_cast<OGRMultiPolygon *>(intersection)->get_Area();
+                     }
+                     else if(intersection->getGeometryType() == wkbGeometryCollection)
+                     {
+                        fusion.overlap = dynamic_cast<OGRGeometryCollection *>(intersection)->get_Area();
+                     }
+                     else if(intersection->getGeometryType() == wkbLineString)
+                     {
+                        fusion.overlap = dynamic_cast<OGRLineString *>(intersection)->get_Length();
+                     }
+                     else if (intersection->getGeometryType() == wkbMultiLineString)
+                     {
+                        fusion.overlap = dynamic_cast<OGRMultiLineString *>(intersection)->get_Length();
+                     }
+                     long upperFID = upper.feat->GetFID();
+                     long lowerFID = lower.feat->GetFID();
+                     fusionList.push_back(fusion);
+                  }
+               }
+            }
+         }
+         unsigned int fusionListSize = fusionList.size();
+         std::sort(fusionList.begin(),fusionList.end(),SortFeature);
+         for(unsigned int i=0; i<fusionListSize; i++)
+         {
+            FeatureStruct upper = upperStreamFeatureList.at(fusionList.at(i).indStream1);
+            FeatureStruct lower = lowerStreamFeatureList.at(fusionList.at(i).indStream2);
+            if( !upper.fusioned && !lower.fusioned )
+            {
+               upperStreamFeatureList.at(fusionList.at(i).indStream1).fusioned = true;
+               lowerStreamFeatureList.at(fusionList.at(i).indStream2).fusioned = true;
+               OGRGeometry * fusionPolygon;
+               fusionPolygon = upper.feat->GetGeometryRef()->Union(lower.feat->GetGeometryRef());
+               upper.feat->SetGeometry(fusionPolygon);
+               OGRFeature * fusionFeature;
+               fusionFeature = OGRFeature::CreateFeature( inputLayer->GetLayerDefn() );
+               fusionFeature->SetGeometry( fusionPolygon );
+               fusionFeature->SetField(0,upper.feat->GetFieldAsInteger(0));
+               inputLayer->CreateFeature(fusionFeature);
+               inputLayer->DeleteFeature(lower.feat->GetFID());
+               inputLayer->DeleteFeature(upper.feat->GetFID());
+               OGRFeature::DestroyFeature( fusionFeature );
+            }
+         }
+         
+         //free memory
+         for(unsigned int u=0; u<nbUpperPolygons; u++)
+         {
+            OGRFeature::DestroyFeature( upperStreamFeatureList.at(u).feat );
+         }
+         for(unsigned int l=0; l<nbLowerPolygons; l++)
+         {
+            OGRFeature::DestroyFeature( lowerStreamFeatureList.at(l).feat );
+         }
+      
+      } //end for x
+   } //end for y
+   
+   
+   //Free memory
+   OGRDataSource::DestroyDataSource(inputDataSource);
+   
+
+}
+
+
+} // end namespace otb
+
+#endif
+
diff --git a/Code/OBIA/otbPersistentImageToOGRDataFilter.h b/Code/OBIA/otbPersistentImageToOGRDataFilter.h
index 0f6ca15358424afb8a75c4b0488aae2179fd9594..7e13c6e2372defbaa28a9da3e516300f1cc2c6b0 100644
--- a/Code/OBIA/otbPersistentImageToOGRDataFilter.h
+++ b/Code/OBIA/otbPersistentImageToOGRDataFilter.h
@@ -95,6 +95,8 @@ protected:
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
   virtual void GenerateData();
+  
+  void GenerateInputRequestedRegion();
 
 
 private:
@@ -108,6 +110,7 @@ private:
   std::string m_FieldName;
   std::string m_FileName;
   unsigned int m_TileNum;
+  SizeType m_StreamSize;
   OGRDataSource * m_DataSource;
 
 }; // end of class
diff --git a/Code/OBIA/otbPersistentImageToOGRDataFilter.txx b/Code/OBIA/otbPersistentImageToOGRDataFilter.txx
index 6f4e23e2f764767ad7b707dfd20fcb3af64a1833..cca4197e9f5546b954aa9940fdb6726d9cb33db1 100644
--- a/Code/OBIA/otbPersistentImageToOGRDataFilter.txx
+++ b/Code/OBIA/otbPersistentImageToOGRDataFilter.txx
@@ -25,15 +25,17 @@
 #include "ogrsf_frmts.h"
 #include "itksys/SystemTools.hxx"
 #include "otbSystem.h"
+#include "otbFusionOGRTileFilter.h"
+#include "itkTimeProbe.h"
 
 namespace otb
 {
 
-
 template<class TImage>
 PersistentImageToOGRDataFilter<TImage>
 ::PersistentImageToOGRDataFilter() : m_FieldName("DN"), m_FileName(""), m_TileNum(0)
 {
+   m_StreamSize.Fill(0);
    // OGR factory registration
    OGRRegisterAll();
 }
@@ -48,6 +50,19 @@ PersistentImageToOGRDataFilter<TImage>
     }
 }
 
+template<class TImage>
+void
+PersistentImageToOGRDataFilter<TImage>
+::GenerateInputRequestedRegion()
+{
+   Superclass::GenerateInputRequestedRegion();
+   if (this->m_StreamSize[0]==0 && this->m_StreamSize[1]==0)
+   {
+      this->m_StreamSize = this->GetInput()->GetRequestedRegion().GetSize();
+   }
+}
+
+
 template<class TImage>
 std::string
 PersistentImageToOGRDataFilter<TImage>
@@ -102,7 +117,13 @@ void
 PersistentImageToOGRDataFilter<TImage>
 ::Synthetize()
 {
-
+   typedef FusionOGRTileFilter<InputImageType> FusionFilterType;
+   typename FusionFilterType::Pointer filter = FusionFilterType::New();
+   
+   filter->SetInput(this->GetInput());
+   filter->SetInputFileName(this->m_FileName);
+   filter->SetStreamSize(this->m_StreamSize);
+   filter->GenerateData();
 }
 
 template<class TImage>
@@ -144,7 +165,6 @@ PersistentImageToOGRDataFilter<TImage>
    {
       itkExceptionMacro(<< "No OGR driver found to write file " << this->m_FileName);
    }
-
 }
 
 
@@ -161,9 +181,10 @@ PersistentImageToOGRDataFilter<TImage>
   poDstLayer = m_DataSource->GetLayer(0);
   
   //Copy features in the output layer
+  itk::TimeProbe chrono;
+  chrono.Start();
   poSrcLayer->ResetReading();
   unsigned int nbFeatures = poSrcLayer->GetFeatureCount(true);
-//  std::cout<< "pppppp"<<std::endl;
   unsigned int i = 0;
   OGRFeature  *poFeature;
   while (i<nbFeatures)
@@ -184,6 +205,8 @@ PersistentImageToOGRDataFilter<TImage>
       
       i++;
   }
+  chrono.Stop();
+  std::cout<< "write ogr tile took " << chrono.GetTotal() << " sec"<<std::endl;
   
 //   OGRDataSource::DestroyDataSource(currentTileVD->Get()->GetDataSource());
   
diff --git a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx
index 100e18762ccc6c35302ecaf6272e4fa547e17f8d..c7265e020c15bbffbdb1b1c9810014808860b1c8 100644
--- a/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx
+++ b/Code/OBIA/otbStreamingVectorizedSegmentationOGR.txx
@@ -51,8 +51,7 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter>
 ::GenerateInputRequestedRegion()
 {
   Superclass::GenerateInputRequestedRegion();
-
-  if (this->GetInput())
+  /*if (this->GetInput())
     {
     InputImagePointerType input = const_cast<InputImageType *> (this->GetInput());
 
@@ -62,7 +61,7 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter>
     region.Crop(input->GetLargestPossibleRegion());
 
     input->SetRequestedRegion(region);
-    }
+    }*/
 }
 
 template <class TImageType, class TSegmentationFilter>
@@ -82,11 +81,9 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter>
   typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractImageFilterType;
   typename ExtractImageFilterType::Pointer extract = ExtractImageFilterType::New();
   extract->SetInput( this->GetInput() );
-  extract->SetExtractionRegion( this->GetInput()->GetBufferedRegion() );
+  extract->SetExtractionRegion( this->GetInput()->GetRequestedRegion() );
   extract->Update();
   
-  //std::cout<< "extract region " << extract->GetOutput()->GetLargestPossibleRegion()<<std::endl;
-  
   chrono.Stop();
   //std::cout<< "extract took " << chrono.GetTotal() << " sec"<<std::endl;
 
@@ -165,7 +162,7 @@ PersistentStreamingLabelImageToOGRDataFilter<TImageType, TSegmentationFilter>
   std::cout<< "relabel took " << chrono3.GetTotal() << " sec"<<std::endl;
   
   return output;
-  return const_cast<OGRDataSourceObjectType *>(labelImageToOGRDataFilter->GetOutput());
+  //return const_cast<OGRDataSourceObjectType *>(labelImageToOGRDataFilter->GetOutput());
 }
 
 
diff --git a/Testing/Code/OBIA/CMakeLists.txt b/Testing/Code/OBIA/CMakeLists.txt
index 2d0975166134e2f1530a4e73c1b51eca19ac6d93..d2263fcda5497d98f5d68bb0f3da8b5b6f307422 100644
--- a/Testing/Code/OBIA/CMakeLists.txt
+++ b/Testing/Code/OBIA/CMakeLists.txt
@@ -248,12 +248,28 @@ ADD_TEST(obTuStreamingVectorizedSegmentationOGRNew ${OBIA_TESTS1}
     otbStreamingVectorizedSegmentationOGRNew)
 
 ADD_TEST(obTvStreamingVectorizedSegmentationOGR ${OBIA_TESTS1}
+     #--compare-ogr  ${EPSILON_8}
+     #${BASELINE_FILES}/obTvStreamingVectorizedSegmentationOutput.sqlite
+     #${TEMP}/obTvStreamingVectorizedSegmentationOutput.sqlite
      otbStreamingVectorizedSegmentationOGR
      ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
-     ${TEMP}/obTvStreamingVectorizedSegmentationOutputOGR.shp
+     ${TEMP}/obTvStreamingVectorizedSegmentationOGR.sqlite
      100
      )
 
+# -------            otb::FusionOGRTileFilter   -------------
+CONFIGURE_FILE(${INPUTDATA}/QB_Toulouse_Ortho_withTiles.sqlite
+               ${TEMP}/obTvFusionOGRTile.sqlite COPYONLY)
+ADD_TEST(obTuFusionOGRTileFilterNew ${OBIA_TESTS1}
+    --compare-ogr  ${EPSILON_8}
+    ${BASELINE_FILES}/obTvFusionOGRTile.sqlite
+    ${TEMP}/obTvFusionOGRTile.sqlite
+    otbFusionOGRTileFilter
+    ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
+    ${TEMP}/obTvFusionOGRTile.sqlite
+    112
+    )
+
 # OBIATests2 (need PQXX)
 IF(OTB_USE_PQXX)
 ADD_TEST(obTuLabelMapToGISTableFilterNew ${OBIA_TESTS2}
@@ -318,6 +334,7 @@ otbLabelImageToVectorDataFilterNew.cxx
 otbLabelImageToVectorDataFilter.cxx
 otbLabelImageToOGRDataSourceFilter.cxx
 otbStreamingVectorizedSegmentationOGR.cxx
+otbFusionOGRTileFilter.cxx
 )
 
 IF(OTB_USE_PQXX)
diff --git a/Testing/Code/OBIA/otbFusionOGRTileFilter.cxx b/Testing/Code/OBIA/otbFusionOGRTileFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5d05db1522b1e32471c32fd30994a883ad9bf876
--- /dev/null
+++ b/Testing/Code/OBIA/otbFusionOGRTileFilter.cxx
@@ -0,0 +1,52 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+#include "otbFusionOGRTileFilter.h"
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+
+int otbFusionOGRTileFilter(int argc, char * argv[])
+{
+  const char * infname = argv[1];
+  const char * inOGRfname = argv[2];
+  unsigned int size = atoi(argv[3]);
+  
+  /** Typedefs */
+  const unsigned int Dimension = 2;
+  typedef float PixelType;
+  typedef otb::Image<PixelType, Dimension> ImageType;
+
+  typedef otb::FusionOGRTileFilter<ImageType>   FilterType;
+  typedef otb::ImageFileReader<ImageType>       ReaderType;
+  
+  ReaderType::Pointer reader = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  
+  reader->SetFileName(infname);
+  reader->UpdateOutputInformation();
+  
+  ImageType::SizeType streamSize;
+  streamSize.Fill(size);
+  
+  filter->SetInput(reader->GetOutput());
+  filter->SetInputFileName(inOGRfname);
+  filter->SetStreamSize(streamSize);
+  filter->GenerateData();
+
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/OBIA/otbOBIATests1.cxx b/Testing/Code/OBIA/otbOBIATests1.cxx
index a1438f51455e7310de938a9863993712698ffbd1..5ccce8f8b20e2fdb7625559cf5070b629bef43b9 100644
--- a/Testing/Code/OBIA/otbOBIATests1.cxx
+++ b/Testing/Code/OBIA/otbOBIATests1.cxx
@@ -66,4 +66,5 @@ REGISTER_TEST(otbLabelImageToOGRDataSourceFilterNew);
 REGISTER_TEST(otbLabelImageToOGRDataSourceFilter);
 REGISTER_TEST(otbStreamingVectorizedSegmentationOGRNew);
 REGISTER_TEST(otbStreamingVectorizedSegmentationOGR);
+REGISTER_TEST(otbFusionOGRTileFilter);
 }
diff --git a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx
index c3d1ce7fc3cf0ec4be282a987accbe885ab2f72a..cc295dfcb5465fe779b729a1611986635fca00b6 100644
--- a/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx
+++ b/Testing/Code/OBIA/otbStreamingVectorizedSegmentationOGR.cxx
@@ -126,14 +126,14 @@ int otbStreamingVectorizedSegmentationOGR(int argc, char * argv[])
   filter->GetStreamer()->SetTileDimensionTiledStreaming(atoi(argv[3]));
   filter->SetFieldName(fieldName);
   filter->SetStartLabel(1);
-  filter->SetUse8Connected(true);
+  filter->SetUse8Connected(false);
   filter->GetSegmentationFilter()->SetSpatialRadius(5);
   filter->GetSegmentationFilter()->SetRangeRadius(15);
   filter->GetSegmentationFilter()->SetMinimumRegionSize(100);
   //filter->GetSegmentationFilter()->GetFunctor().SetExpression("distance<15");
   
   filter->SetFileName(argv[2]);
-  filter->Initialize(); //must do this after SetFileName ...
+  filter->Initialize(); //must do this after SetFileName and SetInput...
   
   filter->Update();