Skip to content

Commit

Permalink
Also account for oversampling along tile edges
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 14, 2019
1 parent a19cdf2 commit 1d3b3fc
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 7 deletions.
6 changes: 3 additions & 3 deletions src/core/raster/qgsrasterresamplefilter.cpp
Expand Up @@ -172,11 +172,11 @@ QgsRasterBlock *QgsRasterResampleFilter::block( int bandNo, QgsRectangle const
{
if ( mZoomedInResampler && ( oversamplingX < 1.0 || qgsDoubleNear( oversampling, 1.0 ) ) )
{
tileBufferPixels = mZoomedInResampler->tileBufferPixels();
tileBufferPixels = static_cast< int >( std::ceil( mZoomedInResampler->tileBufferPixels() * oversampling ) );
}
else if ( mZoomedOutResampler && oversamplingX > 1.0 )
{
tileBufferPixels = mZoomedOutResampler->tileBufferPixels();
tileBufferPixels = static_cast< int >( std::ceil( mZoomedOutResampler->tileBufferPixels() * oversampling ) );
}
}
const double sourceTileBufferSize = providerXRes * tileBufferPixels;
Expand Down Expand Up @@ -252,7 +252,7 @@ QgsRasterBlock *QgsRasterResampleFilter::block( int bandNo, QgsRectangle const

// extract desired part of dstImage
QImage cropped = tileBufferPixels > 0 ? dstImg.copy( ( resampleWidth - width ) / 2, ( resampleHeight - height ) / 2, width, height )
: dstImg; // otherwise implicity copy, nice and cheap
: dstImg; // otherwise implicit copy, nice and cheap
outputBlock->setImage( &cropped );

return outputBlock.release(); // No resampling
Expand Down
154 changes: 150 additions & 4 deletions tests/src/python/test_qgsrasterresampler.py
Expand Up @@ -100,6 +100,79 @@ def testBilinearResample(self):
[125, 125, 125, 125, 125, 125, 126, 126]]
)

# with oversampling
extent = QgsRectangle(785878.92593475803732872, 3346136.27493690419942141, 786223.56509550288319588, 3346477.7564090033993125)
block = filter.block(1, extent, 2, 2)
self.checkBlockContents(block, [[127, 126], [125, 126]])

block = filter.block(1, extent, 4, 4)
self.checkBlockContents(block,
[[125, 127, 127, 127],
[126, 127, 127, 126],
[125, 126, 126, 126],
[127, 125, 125, 125]]
)

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[126, 126, 126, 126, 125, 125, 125, 126],
[126, 126, 125, 125, 125, 126, 126, 126],
[126, 125, 124, 124, 125, 126, 126, 126],
[126, 125, 124, 124, 125, 126, 126, 126],
[125, 125, 124, 124, 124, 126, 126, 126],
[125, 125, 125, 125, 125, 126, 126, 126],
[125, 125, 125, 125, 125, 126, 126, 126],
[125, 125, 126, 126, 125, 125, 125, 125]]
)

filter.setMaxOversampling(2)
block = filter.block(1, extent, 2, 2)
self.checkBlockContents(block, [[127, 126], [125, 126]])

block = filter.block(1, extent, 4, 4)
self.checkBlockContents(block,
[[125, 127, 127, 127],
[126, 127, 127, 126],
[125, 126, 126, 126],
[127, 125, 125, 125]]
)

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[126, 126, 126, 126, 125, 125, 125, 126],
[126, 126, 125, 125, 125, 126, 126, 126],
[126, 125, 124, 124, 125, 126, 126, 126],
[126, 125, 124, 124, 125, 126, 126, 126],
[125, 125, 124, 124, 124, 126, 126, 126],
[125, 125, 125, 125, 125, 126, 126, 126],
[125, 125, 125, 125, 125, 126, 126, 126],
[125, 125, 126, 126, 125, 125, 125, 125]]
)

filter.setMaxOversampling(4)
block = filter.block(1, extent, 2, 2)
self.checkBlockContents(block, [[127, 126], [125, 126]])

block = filter.block(1, extent, 4, 4)
self.checkBlockContents(block,
[[125, 127, 127, 127],
[126, 127, 127, 126],
[125, 126, 126, 126],
[127, 125, 125, 125]]
)

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[126, 126, 126, 126, 125, 125, 125, 126],
[126, 126, 125, 125, 125, 126, 126, 126],
[126, 125, 124, 124, 125, 126, 126, 126],
[126, 125, 124, 124, 125, 126, 126, 126],
[125, 125, 124, 124, 124, 126, 126, 126],
[125, 125, 125, 125, 125, 126, 126, 126],
[125, 125, 125, 125, 125, 126, 126, 126],
[125, 125, 126, 126, 125, 125, 125, 125]]
)

def testCubicResample(self):
path = os.path.join(unitTestDataPath(), 'landsat.tif')
raster_layer = QgsRasterLayer(path, 'test')
Expand Down Expand Up @@ -149,16 +222,89 @@ def testCubicResample(self):

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[124, 124, 124, 125, 126, 127, 127, 127],
[124, 124, 124, 125, 126, 127, 127, 127],
[124, 124, 124, 125, 126, 127, 127, 127],
[125, 124, 124, 125, 126, 126, 127, 126],
[[125, 124, 124, 125, 126, 127, 127, 127],
[125, 124, 124, 125, 126, 127, 127, 127],
[125, 124, 124, 125, 126, 127, 127, 127],
[125, 124, 124, 125, 126, 126, 127, 127],
[125, 125, 125, 125, 126, 126, 126, 126],
[125, 125, 125, 125, 126, 126, 126, 126],
[125, 125, 125, 125, 126, 126, 126, 126],
[125, 125, 125, 125, 126, 126, 126, 126]]
)

# with oversampling
extent = QgsRectangle(785878.92593475803732872, 3346136.27493690419942141, 786223.56509550288319588, 3346477.7564090033993125)
block = filter.block(1, extent, 2, 2)
self.checkBlockContents(block, [[127, 126], [125, 126]])

block = filter.block(1, extent, 4, 4)
self.checkBlockContents(block,
[[125, 127, 127, 127],
[126, 127, 127, 126],
[125, 126, 126, 126],
[127, 125, 125, 125]]
)

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[127, 126, 127, 126, 126, 125, 126, 126],
[127, 127, 127, 126, 126, 126, 126, 126],
[126, 127, 125, 125, 126, 127, 127, 127],
[126, 126, 126, 124, 126, 127, 126, 127],
[126, 126, 125, 124, 125, 126, 126, 127],
[126, 126, 125, 125, 125, 126, 127, 127],
[126, 125, 127, 125, 125, 127, 128, 126],
[126, 125, 127, 127, 126, 125, 125, 126]]
)

filter.setMaxOversampling(2)
block = filter.block(1, extent, 2, 2)
self.checkBlockContents(block, [[127, 126], [125, 126]])

block = filter.block(1, extent, 4, 4)
self.checkBlockContents(block,
[[125, 127, 127, 127],
[126, 127, 127, 126],
[125, 126, 126, 126],
[127, 125, 125, 125]]
)

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[127, 126, 127, 126, 126, 125, 126, 126],
[127, 127, 127, 126, 126, 126, 126, 126],
[126, 127, 125, 125, 126, 127, 127, 127],
[126, 126, 126, 124, 126, 127, 126, 127],
[126, 126, 125, 124, 125, 126, 126, 127],
[126, 126, 125, 125, 125, 126, 127, 127],
[126, 125, 127, 125, 125, 127, 128, 126],
[126, 125, 127, 127, 126, 125, 125, 126]]
)

filter.setMaxOversampling(4)
block = filter.block(1, extent, 2, 2)
self.checkBlockContents(block, [[127, 126], [125, 126]])

block = filter.block(1, extent, 4, 4)
self.checkBlockContents(block,
[[125, 127, 127, 127],
[126, 127, 127, 126],
[125, 126, 126, 126],
[127, 125, 125, 125]]
)

block = filter.block(1, extent, 8, 8)
self.checkBlockContents(block,
[[127, 126, 127, 126, 126, 125, 126, 126],
[127, 127, 127, 126, 126, 126, 126, 126],
[126, 127, 125, 125, 126, 127, 127, 127],
[126, 126, 126, 124, 126, 127, 126, 127],
[126, 126, 125, 124, 125, 126, 126, 127],
[126, 126, 125, 125, 125, 126, 127, 127],
[126, 125, 127, 125, 125, 127, 128, 126],
[126, 125, 127, 127, 126, 125, 125, 126]]
)


if __name__ == '__main__':
unittest.main()

0 comments on commit 1d3b3fc

Please sign in to comment.