136 changes: 76 additions & 60 deletions src/core/raster/qgsrasterpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@
#include <QByteArray>

QgsRasterPipe::QgsRasterPipe()
: mProvider(0)
, mRenderer(0)
, mResampleFilter(0)
, mProjector(0)
{
}

QgsRasterPipe::~QgsRasterPipe()
{
foreach ( QgsRasterInterface* filter, mFilters )
{
//delete filter; // TODO enable
delete filter;
}
}

Expand All @@ -48,16 +52,6 @@ bool QgsRasterPipe::connectFilters ( QVector<QgsRasterInterface*> theFilters )
return true;
}

/*
bool QgsRasterPipe::addFilter ( QgsRasterInterface * theFilter )
{
mFilters.append ( theFilter );
if ( mFilters.size() < 2 ) {
return true;
}
return theFilter->setInput ( mFilters[ mFilters.size()-2 ] );
}
*/
bool QgsRasterPipe::insert ( int idx, QgsRasterInterface* theFilter )
{
QgsDebugMsg( QString ( "insert %1 at %2" ).arg( typeid(*theFilter).name() ).arg ( idx ) );
Expand All @@ -75,6 +69,7 @@ bool QgsRasterPipe::insert ( int idx, QgsRasterInterface* theFilter )
{
success = true;
mFilters.insert ( idx, theFilter );
setRole ( theFilter, idx );
QgsDebugMsg( "inserted ok" );
}

Expand Down Expand Up @@ -103,6 +98,7 @@ bool QgsRasterPipe::replace ( int idx, QgsRasterInterface* theFilter )
success = true;
delete mFilters[idx];
mFilters[idx] = theFilter;
setRole ( theFilter, idx );
QgsDebugMsg( "replaced ok" );
}

Expand All @@ -111,85 +107,105 @@ bool QgsRasterPipe::replace ( int idx, QgsRasterInterface* theFilter )
return success;
}

bool QgsRasterPipe::insertOrReplace( QgsRasterInterface* theFilter )
QgsRasterPipe::Role QgsRasterPipe::filterRole ( QgsRasterInterface * filter ) const
{
if ( dynamic_cast<QgsRasterDataProvider *>( filter ) ) return ProviderRole;
if ( dynamic_cast<QgsRasterRenderer *>( filter ) ) return RendererRole;
if ( dynamic_cast<QgsRasterResampleFilter *>( filter ) ) return ResamplerRole;
if ( dynamic_cast<QgsRasterProjector *>( filter ) ) return ProjectorRole;
return UnknownRole;
}

void QgsRasterPipe::setRole ( QgsRasterInterface * theFilter, int idx )
{
Role role = filterRole ( theFilter );
if ( role == UnknownRole ) return;
mRoleMap.insert ( role, idx );
}

bool QgsRasterPipe::setFilter( QgsRasterInterface* theFilter )
{
QgsDebugMsg( QString ( "%1" ).arg( typeid(*theFilter).name() ) );

if ( !theFilter ) return false;
int idx = indexOf ( theFilter->role() );
if ( idx >= 0 )

QgsRasterDataProvider * provider = dynamic_cast<QgsRasterDataProvider *>( theFilter );
QgsRasterRenderer * renderer;
QgsRasterResampleFilter * resampleFilter;
QgsRasterProjector * projector;

Role role = filterRole ( theFilter );

// We dont know where to place unknown filter
if ( role == UnknownRole ) return false;

//if ( mFiltersMap.value ( role ) )
if ( mRoleMap.contains ( role ) )
{
return replace ( idx, theFilter ); // replace may still fail and return false
// An old filter of the same role exists -> replace
// replace may still fail and return false
return replace ( mRoleMap.value(role), theFilter );
}

int idx = 0;

// Not found, find the best default position for this kind of filter
// The default order is:
// QgsRasterDataProvider - ProviderRole
// QgsRasterRenderer - RendererRole
// QgsRasterResampler - ResamplerRole
// QgsRasterProjector - ProjectorRole
int providerIdx = indexOf ( QgsRasterInterface::ProviderRole );
int rendererIdx = indexOf ( QgsRasterInterface::RendererRole );
int resamplerIdx = indexOf ( QgsRasterInterface::ResamplerRole );
if ( theFilter->role() == QgsRasterInterface::ProviderRole )

int providerIdx = mRoleMap.value( ProviderRole,-1);
int rendererIdx = mRoleMap.value( RendererRole, -1 );
int resamplerIdx = mRoleMap.value( ResamplerRole, -1 );

if ( role == ProviderRole )
{
idx = 0;
}
else if ( theFilter->role() == QgsRasterInterface::RendererRole )
else if ( role == RendererRole )
{
idx = providerIdx + 1;
}
else if ( theFilter->role() == QgsRasterInterface::ResamplerRole )
else if ( role == ResamplerRole )
{
idx = qMax ( providerIdx, rendererIdx ) + 1;
}
else if ( theFilter->role() == QgsRasterInterface::ProjectorRole )
else if ( role == ProjectorRole )
{
idx = qMax ( qMax( providerIdx,rendererIdx ), resamplerIdx ) + 1;
}

return insert ( idx, theFilter ); // insert may still fail and return false
}

int QgsRasterPipe::indexOf ( QgsRasterInterface::Role theRole ) const
{
QgsDebugMsg( QString ( "role = %1" ).arg( theRole ) );
//foreach ( QgsRasterInterface * filter, mFilters )

for ( int i = 0; i < mFilters.size(); i++ )
{
if ( !mFilters[i] ) continue;

if ( mFilters[i]->role() == theRole )
{
return i;
}
/*
if ( typeid ( *theFilter ) == typeid ( *(mFilters[i]) ) )
{
QgsDebugMsg( QString ( "%1 found at %2" ).arg( typeid(*(mFilters[i])).name() ).arg(i) );
return i;
}
// known ancestor
if ( ( dynamic_cast<QgsRasterRenderer*>( theFilter ) && dynamic_cast<QgsRasterRenderer*>( mFilters[i] ) )
|| ( dynamic_cast<QgsRasterDataProvider*>( theFilter ) && dynamic_cast<QgsRasterDataProvider*>( mFilters[i] ) ) )
{
QgsDebugMsg( QString ( "%1 found at %2" ).arg( typeid(*(mFilters[i])).name() ).arg(i) );
return i;
}
*/
}
QgsDebugMsg( "role not found");
return -1;
}
QgsRasterInterface * QgsRasterPipe::filter ( QgsRasterInterface::Role role ) const
QgsRasterInterface * QgsRasterPipe::filter ( Role role ) const
{
QgsDebugMsg( QString ( "role = %1" ).arg ( role ) );
int idx = indexOf ( role );
if ( idx >= 0 )
if ( mRoleMap.contains ( role ) )
{
return mFilters[idx];
return mFilters.value( mRoleMap.value( role) );
}
return 0;
}

QgsRasterDataProvider * QgsRasterPipe::provider() const
{
return dynamic_cast<QgsRasterDataProvider *>(filter( ProviderRole));
}

QgsRasterRenderer * QgsRasterPipe::renderer() const
{
return dynamic_cast<QgsRasterRenderer *>(filter( RendererRole ));
}

QgsRasterResampleFilter * QgsRasterPipe::resampleFilter() const
{
return dynamic_cast<QgsRasterResampleFilter *>(filter( ResamplerRole ));
}

QgsRasterProjector * QgsRasterPipe::projector() const
{
return dynamic_cast<QgsRasterProjector*>(filter ( ProjectorRole ));
}

41 changes: 30 additions & 11 deletions src/core/raster/qgsrasterpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ class CORE_EXPORT QgsRasterPipe //: public QObject
//Q_OBJECT

public:
// Role of known filters
enum Role
{
UnknownRole = 0,
ProviderRole = 1,
RendererRole = 2,
ResamplerRole = 3,
ProjectorRole = 4
};

QgsRasterPipe( );

virtual ~QgsRasterPipe();
Expand All @@ -45,10 +55,6 @@ class CORE_EXPORT QgsRasterPipe //: public QObject
bool connectFilters ( QVector<QgsRasterInterface*> theFilters );


/** Add filter at the end of pipe and connect.
Returns true if connected or false if connection failed */
//bool addFilter ( QgsRasterInterface * theFilter );

/** Try to insert filter at specified index and connect
* if connection would fail, the filter is not inserted and false is returned */
bool insert ( int idx, QgsRasterInterface* theFilter );
Expand All @@ -59,24 +65,37 @@ class CORE_EXPORT QgsRasterPipe //: public QObject

/** Insert a new filter in prefered place or replace similar filter if it
* already exists */
bool insertOrReplace ( QgsRasterInterface * theFilter );
bool setFilter ( QgsRasterInterface * theFilter );

//QgsRasterInterface * filter ( QgsRasterInterface::Role role );
QgsRasterInterface * filter ( QgsRasterInterface::Role role ) const;
QgsRasterInterface * filter ( Role role ) const;

int size() { return mFilters.size(); }
QgsRasterInterface * at( int idx ) { return mFilters.at(idx); }
QgsRasterInterface * last() { return mFilters.last(); }

/** Delete all filters */
//void clear();
// Getters for special types of interfaces
QgsRasterDataProvider * provider() const;
QgsRasterRenderer * renderer() const;
QgsRasterResampleFilter * resampleFilter() const;
QgsRasterProjector * projector() const;

private:
/** \brief Find index of existing filter of the given role */
int indexOf ( QgsRasterInterface::Role role ) const;
/** Get known parent type_info of interface parent */
Role filterRole ( QgsRasterInterface * filter ) const;

// Filters in pipe, the first is always provider
QVector<QgsRasterInterface*> mFilters;

// Special types of interfaces
QgsRasterDataProvider * mProvider;
QgsRasterRenderer * mRenderer;
QgsRasterResampleFilter * mResampleFilter;
QgsRasterProjector * mProjector;

QMap<Role,int> mRoleMap;

// Set role in mFiltersMap
void setRole ( QgsRasterInterface * theFilter, int idx );
};

#endif
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include <QPainter>

QgsRasterRenderer::QgsRasterRenderer( QgsRasterInterface* input, const QString& type )
: QgsRasterInterface( input, QgsRasterInterface::RendererRole ),
: QgsRasterInterface( input ),
mType( type ), mOpacity( 1.0 ), mRasterTransparency( 0 ),
mAlphaBand( -1 ), mInvertColor( false ), mMaxOversampling( 2.0 )
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterresamplefilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <QPainter>

QgsRasterResampleFilter::QgsRasterResampleFilter( QgsRasterInterface* input )
: QgsRasterInterface( input, QgsRasterInterface::ResamplerRole ),
: QgsRasterInterface( input ),
mZoomedInResampler( 0 ), mZoomedOutResampler( 0 ),
mMaxOversampling( 2.0 )
{
Expand Down