QgsRasterBlock* QgsRasterResampleFilter::block2( int bandNo, QgsRectangle const & extent, int width, int height, QgsRasterBlockFeedback *feedback ) { Q_UNUSED( bandNo ); QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) ); QgsRasterBlock *outputBlock = new QgsRasterBlock(); if ( !mInput ) return outputBlock; double oversampling = 1.0; // approximate global oversampling factor if ( mZoomedInResampler || mZoomedOutResampler ) { QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() ); if ( provider && ( provider->capabilities() & QgsRasterDataProvider::Size ) ) { double xRes = extent.width() / width; double providerXRes = provider->extent().width() / provider->xSize(); double pixelRatio = xRes / providerXRes; oversampling = ( pixelRatio > mMaxOversampling ) ? mMaxOversampling : pixelRatio; QgsDebugMsg( QString( "xRes = %1 providerXRes = %2 pixelRatio = %3 oversampling = %4" ).arg( xRes ).arg( providerXRes ).arg( pixelRatio ).arg( oversampling ) ); } else { // We don't know exact data source resolution (WMS) so we expect that // server data have higher resolution (which is not always true) and use // mMaxOversampling oversampling = mMaxOversampling; } } QgsDebugMsg( QString( "oversampling %1" ).arg( oversampling ) ); int bandNumber = 1; // Do no oversampling if no resampler for zoomed in / zoomed out (nearest neighbour) // We do mZoomedInResampler if oversampling == 1 (otherwise for example reprojected // zoom in rasters are never resampled because projector limits resolution. if ((( oversampling < 1.0 || qgsDoubleNear( oversampling, 1.0 ) ) && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) ) { QgsDebugMsg( "No oversampling." ); delete outputBlock; return mInput->block2( bandNumber, extent, width, height, feedback ); } //effective oversampling factors are different to global one because of rounding double oversamplingX = (( double )width * oversampling ) / width; double oversamplingY = (( double )height * oversampling ) / height; // TODO: we must also increase the extent to get correct result on borders of parts int resWidth = width * oversamplingX; int resHeight = height * oversamplingY; QgsRasterBlock *inputBlock = mInput->block2( bandNumber, extent, resWidth, resHeight, feedback ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( "No raster data!" ); delete inputBlock; return outputBlock; } if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; return outputBlock; } //resample image QImage img = inputBlock->image(); QImage dstImg = QImage( width, height, QImage::Format_ARGB32_Premultiplied ); if ( mZoomedInResampler && ( oversamplingX < 1.0 || qgsDoubleNear( oversampling, 1.0 ) ) ) { QgsDebugMsg( "zoomed in resampling" ); mZoomedInResampler->resample( img, dstImg ); } else if ( mZoomedOutResampler && oversamplingX > 1.0 ) { QgsDebugMsg( "zoomed out resampling" ); mZoomedOutResampler->resample( img, dstImg ); } else { // Should not happen QgsDebugMsg( "Unexpected resampling" ); dstImg = img.scaled( width, height ); } outputBlock->setImage( &dstImg ); delete inputBlock; return outputBlock; // No resampling }
QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const & extent, int width, int height ) { Q_UNUSED( bandNo ); QgsDebugMsg( "Entered" ); QgsRasterBlock *outputBlock = new QgsRasterBlock(); if ( !mInput ) return outputBlock; double oversampling = 1.0; // approximate global oversampling factor if ( mZoomedInResampler || mZoomedOutResampler ) { QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() ); // Do not oversample if data source does not have fixed resolution (WMS) if ( provider && ( provider->capabilities() & QgsRasterDataProvider::ExactResolution ) ) { double xRes = extent.width() / width; double providerXRes = provider->extent().width() / provider->xSize(); double pixelRatio = xRes / providerXRes; oversampling = ( pixelRatio > mMaxOversampling ) ? mMaxOversampling : pixelRatio; QgsDebugMsg( QString( "xRes = %1 providerXRes = %2 pixelRatio = %3 oversampling = %4" ).arg( xRes ).arg( providerXRes ).arg( pixelRatio ).arg( oversampling ) ); } } //set oversampling back to 1.0 if no resampler for zoomed in / zoomed out (nearest neighbour) if (( oversampling < 1.0 && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) ) { oversampling = 1.0; } QgsDebugMsg( QString( "oversampling %1" ).arg( oversampling ) ); //effective oversampling factors are different to global one because of rounding double oversamplingX = (( double )width * oversampling ) / width; double oversamplingY = (( double )height * oversampling ) / height; // TODO: we must also increase the extent to get correct result on borders of parts int resWidth = width * oversamplingX; int resHeight = height * oversamplingY; // At moment we know that we read rendered image int bandNumber = 1; //void *rasterData = mInput->block( bandNumber, extent, resWidth, resHeight ); QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, resWidth, resHeight ); if ( !inputBlock || inputBlock->isEmpty() ) { QgsDebugMsg( "No raster data!" ); delete inputBlock; return outputBlock; } if ( doubleNear( oversamplingX, 1.0 ) || doubleNear( oversamplingY, 1.0 ) ) { QgsDebugMsg( "No oversampling." ); delete outputBlock; return inputBlock; } if ( !outputBlock->reset( QgsRasterBlock::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; return outputBlock; } //resample image QImage img = inputBlock->image(); QImage dstImg = QImage( width, height, QImage::Format_ARGB32_Premultiplied ); if ( mZoomedInResampler && oversamplingX < 1.0 ) { QgsDebugMsg( "zoomed in resampling" ); mZoomedInResampler->resample( img, dstImg ); } else if ( mZoomedOutResampler && oversamplingX > 1.0 ) { QgsDebugMsg( "zoomed out resampling" ); mZoomedOutResampler->resample( img, dstImg ); } else { // Should not happen QgsDebugMsg( "Unexpected resampling" ); dstImg = img.scaled( width, height ); } outputBlock->setImage( &dstImg ); delete inputBlock; return outputBlock; // No resampling }