From 7d148026006cb57787b0c90a4678f0cb51852fab Mon Sep 17 00:00:00 2001 From: Radim Blazek Date: Sun, 1 Jul 2012 14:02:47 +0200 Subject: [PATCH] on/off rasterinterface switch --- src/core/qgsrasterprojector.cpp | 14 +++++++++ src/core/qgsrasterprojector.h | 4 +++ src/core/raster/qgsrasterinterface.cpp | 8 +++++ src/core/raster/qgsrasterinterface.h | 9 ++++++ src/core/raster/qgsrasterlayer.cpp | 6 +++- src/core/raster/qgsrasterpipe.cpp | 35 ++++++++++++++++----- src/core/raster/qgsrasterpipe.h | 7 +++++ src/core/raster/qgsrasterrenderer.cpp | 24 ++++++++++++-- src/core/raster/qgsrasterrenderer.h | 4 +++ src/core/raster/qgsrasterresamplefilter.cpp | 34 ++++++++++++++++++-- src/core/raster/qgsrasterresamplefilter.h | 4 +++ 11 files changed, 134 insertions(+), 15 deletions(-) diff --git a/src/core/qgsrasterprojector.cpp b/src/core/qgsrasterprojector.cpp index 3ec1434991c9..0183c3eb6599 100644 --- a/src/core/qgsrasterprojector.cpp +++ b/src/core/qgsrasterprojector.cpp @@ -72,6 +72,20 @@ QgsRasterProjector::~QgsRasterProjector() delete[] pHelperBottom; } +int QgsRasterProjector::bandCount() const +{ + if ( mInput ) return mInput->bandCount(); + + return 0; +} + +QgsRasterInterface::DataType QgsRasterProjector::dataType( int bandNo ) const +{ + if ( mInput ) return mInput->dataType( bandNo ); + + return QgsRasterInterface::UnknownDataType; +} + void QgsRasterProjector::setCRS( QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS ) { mSrcCRS = theSrcCRS; diff --git a/src/core/qgsrasterprojector.h b/src/core/qgsrasterprojector.h index 2dd0d3b7f2f5..a6449d009594 100644 --- a/src/core/qgsrasterprojector.h +++ b/src/core/qgsrasterprojector.h @@ -61,6 +61,10 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface /** \brief The destructor */ ~QgsRasterProjector(); + int bandCount() const; + + QgsRasterInterface::DataType dataType( int bandNo ) const; + /** \brief set source and destination CRS */ void setCRS( QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS ); diff --git a/src/core/raster/qgsrasterinterface.cpp b/src/core/raster/qgsrasterinterface.cpp index c84018d4fcf2..543c640282ab 100644 --- a/src/core/raster/qgsrasterinterface.cpp +++ b/src/core/raster/qgsrasterinterface.cpp @@ -25,6 +25,7 @@ QgsRasterInterface::QgsRasterInterface( QgsRasterInterface * input ) : mInput( input ) + , mOn( true ) , mStatsOn( false ) { } @@ -80,6 +81,13 @@ QImage * QgsRasterInterface::createImage( int width, int height, QImage::Format void * QgsRasterInterface::block( int bandNo, QgsRectangle const & extent, int width, int height ) { + if ( !mOn ) + { + // Switched off, pass input data unchanged + if ( !mInput ) return 0; + return mInput->block( bandNo, extent, width, height ); + } + QTime time; time.start(); void * b = readBlock( bandNo, extent, width, height ); diff --git a/src/core/raster/qgsrasterinterface.h b/src/core/raster/qgsrasterinterface.h index 7043d0a24f94..7ad31ea233d0 100644 --- a/src/core/raster/qgsrasterinterface.h +++ b/src/core/raster/qgsrasterinterface.h @@ -142,6 +142,12 @@ class CORE_EXPORT QgsRasterInterface * Returns true if set correctly, false if cannot use that input */ virtual bool setInput( QgsRasterInterface* input ) { mInput = input; return true; } + /** Is on/off */ + virtual bool on( ) { return mOn; } + + /** Set on/off */ + virtual void setOn( bool on ) { mOn = on; } + /** Get source / raw input, the first in pipe, usually provider. * It may be used to get info about original data, e.g. resolution to decide * resampling etc. @@ -166,6 +172,9 @@ class CORE_EXPORT QgsRasterInterface // QgsRasterInterface used as input QgsRasterInterface* mInput; + // On/off state, if off, it does not do anything, replicates input + bool mOn; + private: // Last rendering cumulative (this and all preceding interfaces) times, from index 1 QVector mTime; diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp index 22944d052adf..4ce99636101d 100644 --- a/src/core/raster/qgsrasterlayer.cpp +++ b/src/core/raster/qgsrasterlayer.cpp @@ -2109,7 +2109,11 @@ void QgsRasterLayer::setResampleFilter( QgsRasterResampleFilter* resampleFilter { QgsDebugMsg( "Entered" ); if ( !resampleFilter ) { return; } - mPipe.set( resampleFilter ); + if ( !mPipe.set( resampleFilter ) ) + { + // TODO: somehow notify (and delete?) + QgsDebugMsg( "Cannot set resample filter." ); + } } void QgsRasterLayer::showProgress( int theValue ) diff --git a/src/core/raster/qgsrasterpipe.cpp b/src/core/raster/qgsrasterpipe.cpp index 4501082acfed..42ee6f3628e0 100644 --- a/src/core/raster/qgsrasterpipe.cpp +++ b/src/core/raster/qgsrasterpipe.cpp @@ -77,10 +77,7 @@ bool QgsRasterPipe::insert( int idx, QgsRasterInterface* theInterface ) bool QgsRasterPipe::replace( int idx, QgsRasterInterface* theInterface ) { QgsDebugMsg( QString( "replace by %1 at %2" ).arg( typeid( *theInterface ).name() ).arg( idx ) ); - if ( idx < 0 || idx >= mInterfaces.size() ) - { - return false; - } + if ( !checkBounds( idx ) ) return false; if ( !theInterface ) return false; // make a copy of pipe to test connection, we test the connections @@ -216,10 +213,7 @@ bool QgsRasterPipe::remove( int idx ) { QgsDebugMsg( QString( "remove at %1" ).arg( idx ) ); - if ( idx < 0 || idx >= mInterfaces.size() ) - { - return false; - } + if ( !checkBounds( idx ) ) return false; // make a copy of pipe to test connection, we test the connections // of the whole pipe, because the types and band numbers may change @@ -247,3 +241,28 @@ bool QgsRasterPipe::remove( QgsRasterInterface * theInterface ) return remove( mInterfaces.indexOf( theInterface ) ); } + +bool QgsRasterPipe::setOn( int idx, bool on ) +{ + if ( !checkBounds( idx ) ) return false; + + // Because setting interface on/off may change its output we must check if + // connection is OK after such switch + bool onOrig = mInterfaces[idx]->on(); + + if ( onOrig == on ) return true; + + mInterfaces[idx]->setOn( on ); + + if ( connect( mInterfaces ) ) return true; + + mInterfaces[idx]->setOn( onOrig ); + connect( mInterfaces ); + return false; +} + +bool QgsRasterPipe::checkBounds( int idx ) const +{ + if ( idx < 0 || idx >= mInterfaces.size() ) return false; + return true; +} diff --git a/src/core/raster/qgsrasterpipe.h b/src/core/raster/qgsrasterpipe.h index 4caea77188c3..39c504f154e4 100644 --- a/src/core/raster/qgsrasterpipe.h +++ b/src/core/raster/qgsrasterpipe.h @@ -81,6 +81,10 @@ class CORE_EXPORT QgsRasterPipe QgsRasterInterface * at( int idx ) { return mInterfaces.at( idx ); } QgsRasterInterface * last() { return mInterfaces.last(); } + /** Set interface at index on/off + * Returns true on success */ + bool setOn( int idx, bool on ); + // Getters for special types of interfaces QgsRasterDataProvider * provider() const; QgsRasterRenderer * renderer() const; @@ -104,6 +108,9 @@ class CORE_EXPORT QgsRasterPipe // Unset role in mRoleMap void unsetRole( QgsRasterInterface * theInterface ); + + // Check if index is in bounds + bool checkBounds( int idx ) const; }; #endif diff --git a/src/core/raster/qgsrasterrenderer.cpp b/src/core/raster/qgsrasterrenderer.cpp index 7050f45df0a0..29ad66030ff1 100644 --- a/src/core/raster/qgsrasterrenderer.cpp +++ b/src/core/raster/qgsrasterrenderer.cpp @@ -42,14 +42,32 @@ QgsRasterRenderer::~QgsRasterRenderer() { } +int QgsRasterRenderer::bandCount() const +{ + if ( mOn ) return 1; + + if ( mInput ) return mInput->bandCount(); + + return 0; +} + +QgsRasterInterface::DataType QgsRasterRenderer::dataType( int bandNo ) const +{ + if ( mOn ) return QgsRasterInterface::ARGB32_Premultiplied; + + if ( mInput ) return mInput->dataType( bandNo ); + + return QgsRasterInterface::UnknownDataType; +} + bool QgsRasterRenderer::setInput( QgsRasterInterface* input ) { // Renderer can only work with numerical values in at least 1 band - if ( !mInput ) return false; + if ( !input ) return false; - for ( int i = 1; i <= mInput->bandCount(); i++ ) + for ( int i = 1; i <= input->bandCount(); i++ ) { - if ( typeIsNumeric( mInput->dataType( i ) ) ) + if ( typeIsNumeric( input->dataType( i ) ) ) { mInput = input; return true; diff --git a/src/core/raster/qgsrasterrenderer.h b/src/core/raster/qgsrasterrenderer.h index 808d17ce581a..e794879785a7 100644 --- a/src/core/raster/qgsrasterrenderer.h +++ b/src/core/raster/qgsrasterrenderer.h @@ -37,6 +37,10 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface QgsRasterRenderer( QgsRasterInterface* input = 0, const QString& type = "" ); virtual ~QgsRasterRenderer(); + virtual int bandCount() const; + + virtual QgsRasterInterface::DataType dataType( int bandNo ) const; + virtual QString type() const { return mType; } virtual bool setInput( QgsRasterInterface* input ); diff --git a/src/core/raster/qgsrasterresamplefilter.cpp b/src/core/raster/qgsrasterresamplefilter.cpp index 0b35efa02a04..1b2045a2a3b8 100644 --- a/src/core/raster/qgsrasterresamplefilter.cpp +++ b/src/core/raster/qgsrasterresamplefilter.cpp @@ -45,15 +45,43 @@ QgsRasterResampleFilter::~QgsRasterResampleFilter() delete mZoomedOutResampler; } +int QgsRasterResampleFilter::bandCount() const +{ + if ( mOn ) return 1; + + if ( mInput ) return mInput->bandCount(); + + return 0; +} + +QgsRasterInterface::DataType QgsRasterResampleFilter::dataType( int bandNo ) const +{ + if ( mOn ) return QgsRasterInterface::ARGB32_Premultiplied; + + if ( mInput ) return mInput->dataType( bandNo ); + + return QgsRasterInterface::UnknownDataType; +} + bool QgsRasterResampleFilter::setInput( QgsRasterInterface* input ) { + QgsDebugMsg( "Entered" ); // Resampler can only work with single band ARGB32_Premultiplied - if ( !mInput ) return false; + if ( !input ) return false; - if ( mInput->bandCount() < 1 ) return false; + if ( input->bandCount() < 1 ) + { + QgsDebugMsg( "No input band" ); + return false; + } - if ( mInput->dataType( 1 ) != QgsRasterInterface::ARGB32_Premultiplied ) return false; + if ( input->dataType( 1 ) != QgsRasterInterface::ARGB32_Premultiplied ) + { + return false; + QgsDebugMsg( "Unknown input data type" ); + } + mInput = input; return true; } diff --git a/src/core/raster/qgsrasterresamplefilter.h b/src/core/raster/qgsrasterresamplefilter.h index 325510498d51..a1cfd85e4646 100644 --- a/src/core/raster/qgsrasterresamplefilter.h +++ b/src/core/raster/qgsrasterresamplefilter.h @@ -31,6 +31,10 @@ class QgsRasterResampleFilter : public QgsRasterInterface QgsRasterResampleFilter( QgsRasterInterface* input = 0 ); ~QgsRasterResampleFilter(); + int bandCount() const; + + QgsRasterInterface::DataType dataType( int bandNo ) const; + bool setInput( QgsRasterInterface* input ); void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );