Skip to content
Snippets Groups Projects
Commit 2b7961bc authored by Julien Michel's avatar Julien Michel
Browse files

ENH/ Adapting filter to process layers, not datasources

parent 8be4017e
Branches
Tags
No related merge requests found
......@@ -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
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment