Skip to content

Commit

Permalink
Unit tests and dox for QgsRasterIterator
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 14, 2018
1 parent bde8b43 commit 76eb29d
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 5 deletions.
40 changes: 40 additions & 0 deletions python/core/auto_generated/raster/qgsrasteriterator.sip.in
Expand Up @@ -20,6 +20,9 @@ Iterator for sequentially processing raster cells.
public:

QgsRasterIterator( QgsRasterInterface *input );
%Docstring
Constructor for QgsRasterIterator, iterating over the specified ``input`` raster source.
%End

void startRasterRead( int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback = 0 );
%Docstring
Expand Down Expand Up @@ -52,16 +55,53 @@ caller should delete the block.


void stopRasterRead( int bandNumber );
%Docstring
Cancels the raster iteration and resets the iterator.
%End

const QgsRasterInterface *input() const;
%Docstring
Returns the input raster interface which is being iterated over.
%End

void setMaximumTileWidth( int w );
%Docstring
Sets the maximum tile width returned during iteration.

.. seealso:: :py:func:`maximumTileWidth`

.. seealso:: :py:func:`setMinimumTileWidth`
%End

int maximumTileWidth() const;
%Docstring
Returns the maximum tile width returned during iteration.

.. seealso:: :py:func:`setMaximumTileWidth`

.. seealso:: :py:func:`minimumTileWidth`
%End

void setMaximumTileHeight( int h );
%Docstring
Sets the minimum tile width returned during iteration.

.. seealso:: :py:func:`minimumTileWidth`

.. seealso:: :py:func:`setMaximumTileWidth`
%End

int maximumTileHeight() const;
%Docstring
Returns the minimum tile width returned during iteration.

.. seealso:: :py:func:`setMinimumTileWidth`

.. seealso:: :py:func:`maximumTileWidth`
%End

static const int DEFAULT_MAXIMUM_TILE_WIDTH;

static const int DEFAULT_MAXIMUM_TILE_HEIGHT;

};
Expand Down
44 changes: 39 additions & 5 deletions src/core/raster/qgsrasteriterator.h
Expand Up @@ -34,15 +34,18 @@ class CORE_EXPORT QgsRasterIterator
{
public:

/**
* Constructor for QgsRasterIterator, iterating over the specified \a input raster source.
*/
QgsRasterIterator( QgsRasterInterface *input );

/**
* Start reading of raster band. Raster data can then be retrieved by calling readNextRasterPart until it returns false.
\param bandNumber number of raster band to read
\param nCols number of columns
\param nRows number of rows
\param extent area to read
\param feedback optional raster feedback object for cancelation/preview. Added in QGIS 3.0.
* \param bandNumber number of raster band to read
* \param nCols number of columns
* \param nRows number of rows
* \param extent area to read
* \param feedback optional raster feedback object for cancelation/preview. Added in QGIS 3.0.
*/
void startRasterRead( int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback = nullptr );

Expand Down Expand Up @@ -81,17 +84,48 @@ class CORE_EXPORT QgsRasterIterator
int &topLeftCol, int &topLeftRow,
QgsRectangle *blockExtent = nullptr ) SIP_SKIP;

/**
* Cancels the raster iteration and resets the iterator.
*/
void stopRasterRead( int bandNumber );

/**
* Returns the input raster interface which is being iterated over.
*/
const QgsRasterInterface *input() const { return mInput; }

/**
* Sets the maximum tile width returned during iteration.
* \see maximumTileWidth()
* \see setMinimumTileWidth()
*/
void setMaximumTileWidth( int w ) { mMaximumTileWidth = w; }

/**
* Returns the maximum tile width returned during iteration.
* \see setMaximumTileWidth()
* \see minimumTileWidth()
*/
int maximumTileWidth() const { return mMaximumTileWidth; }

/**
* Sets the minimum tile width returned during iteration.
* \see minimumTileWidth()
* \see setMaximumTileWidth()
*/
void setMaximumTileHeight( int h ) { mMaximumTileHeight = h; }

/**
* Returns the minimum tile width returned during iteration.
* \see setMinimumTileWidth()
* \see maximumTileWidth()
*/
int maximumTileHeight() const { return mMaximumTileHeight; }

//! Default maximum tile width
static const int DEFAULT_MAXIMUM_TILE_WIDTH = 2000;

//! Default maximum tile height
static const int DEFAULT_MAXIMUM_TILE_HEIGHT = 2000;

private:
Expand Down
1 change: 1 addition & 0 deletions tests/src/core/CMakeLists.txt
Expand Up @@ -163,6 +163,7 @@ SET(TESTS
testqgis.cpp
testqgsrasterfilewriter.cpp
testqgsrasterfill.cpp
testqgsrasteriterator.cpp
testqgsrasterblock.cpp
testqgsrasterlayer.cpp
testqgsrastersublayer.cpp
Expand Down
238 changes: 238 additions & 0 deletions tests/src/core/testqgsrasteriterator.cpp
@@ -0,0 +1,238 @@
/***************************************************************************
testqgsrasteriterator.cpp
--------------------------------------
Date : June 2018
Copyright : (C) 2018 by Nyall Dawson
Email : nyall dot dawson at gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgstest.h"
#include <QObject>
#include <QString>
#include <QTemporaryFile>

#include "qgsrasterlayer.h"
#include "qgsrasterdataprovider.h"
#include "qgsrasteriterator.h"

/**
* \ingroup UnitTests
* This is a unit test for the QgsRasterIterator class.
*/
class TestQgsRasterIterator : public QObject
{
Q_OBJECT
public:
TestQgsRasterIterator() = default;

private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init() {} // will be called before each testfunction is executed.
void cleanup() {} // will be called after every testfunction.

void testBasic();

private:

QString mTestDataDir;
QgsRasterLayer *mpRasterLayer = nullptr;
};


//runs before all tests
void TestQgsRasterIterator::initTestCase()
{
// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();

mTestDataDir = QStringLiteral( TEST_DATA_DIR ); //defined in CmakeLists.txt
QString band1byteRaster = mTestDataDir + "/big_raster.tif";

mpRasterLayer = new QgsRasterLayer( band1byteRaster, QStringLiteral( "big_raster" ) );

QVERIFY( mpRasterLayer && mpRasterLayer->isValid() );
}

//runs after all tests
void TestQgsRasterIterator::cleanupTestCase()
{
delete mpRasterLayer;

QgsApplication::exitQgis();
}

void TestQgsRasterIterator::testBasic()
{
QgsRasterDataProvider *provider = mpRasterLayer->dataProvider();
QVERIFY( provider );
QgsRasterIterator it( provider );

QCOMPARE( it.input(), provider );

it.setMaximumTileHeight( 2500 );
QCOMPARE( it.maximumTileHeight(), 2500 );

it.setMaximumTileWidth( 3000 );
QCOMPARE( it.maximumTileWidth(), 3000 );

it.startRasterRead( 1, mpRasterLayer->width(), mpRasterLayer->height(), mpRasterLayer->extent() );

int nCols;
int nRows;
int topLeftCol;
int topLeftRow;
QgsRectangle blockExtent;
std::unique_ptr< QgsRasterBlock > block;

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 3000 );
QCOMPARE( nRows, 2500 );
QCOMPARE( topLeftCol, 0 );
QCOMPARE( topLeftRow, 0 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 3000 );
QCOMPARE( block->height(), 2500 );
QCOMPARE( blockExtent.xMinimum(), 497470.0 );
QCOMPARE( blockExtent.xMaximum(), 497770.0 );
QCOMPARE( blockExtent.yMinimum(), 7050880.0 );
QCOMPARE( blockExtent.yMaximum(), 7051130.0 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - nRows * mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 3000 );
QCOMPARE( nRows, 2500 );
QCOMPARE( topLeftCol, 3000 );
QCOMPARE( topLeftRow, 0 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 3000 );
QCOMPARE( block->height(), 2500 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - nRows * mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 1200 );
QCOMPARE( nRows, 2500 );
QCOMPARE( topLeftCol, 6000 );
QCOMPARE( topLeftRow, 0 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 1200 );
QCOMPARE( block->height(), 2500 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - nRows * mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 3000 );
QCOMPARE( nRows, 2500 );
QCOMPARE( topLeftCol, 0 );
QCOMPARE( topLeftRow, 2500 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 3000 );
QCOMPARE( block->height(), 2500 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - ( nRows + topLeftRow )* mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 3000 );
QCOMPARE( nRows, 2500 );
QCOMPARE( topLeftCol, 3000 );
QCOMPARE( topLeftRow, 2500 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 3000 );
QCOMPARE( block->height(), 2500 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - ( nRows + topLeftRow )* mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 1200 );
QCOMPARE( nRows, 2500 );
QCOMPARE( topLeftCol, 6000 );
QCOMPARE( topLeftRow, 2500 );
QVERIFY( block.get() );
QCOMPARE( block->width(), 1200 );
QCOMPARE( block->height(), 2500 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - ( nRows + topLeftRow )* mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 3000 );
QCOMPARE( nRows, 450 );
QCOMPARE( topLeftCol, 0 );
QCOMPARE( topLeftRow, 5000 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 3000 );
QCOMPARE( block->height(), 450 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - ( nRows + topLeftRow )* mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 3000 );
QCOMPARE( nRows, 450 );
QCOMPARE( topLeftCol, 3000 );
QCOMPARE( topLeftRow, 5000 );
QVERIFY( block.get() );
QCOMPARE( block->width(), 3000 );
QCOMPARE( block->height(), 450 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - ( nRows + topLeftRow )* mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QCOMPARE( nCols, 1200 );
QCOMPARE( nRows, 450 );
QCOMPARE( topLeftCol, 6000 );
QCOMPARE( topLeftRow, 5000 );
QVERIFY( block.get() );
QVERIFY( block->isValid() );
QCOMPARE( block->value( 1, 1 ), 1.0 );
QCOMPARE( block->width(), 1200 );
QCOMPARE( block->height(), 450 );
QCOMPARE( blockExtent.xMinimum(), mpRasterLayer->extent().xMinimum() + topLeftCol * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.yMinimum(), mpRasterLayer->extent().yMaximum() - ( nRows + topLeftRow )* mpRasterLayer->rasterUnitsPerPixelY() );
QCOMPARE( blockExtent.width(), nCols * mpRasterLayer->rasterUnitsPerPixelX() );
QCOMPARE( blockExtent.height(), nRows * mpRasterLayer->rasterUnitsPerPixelY() );

QVERIFY( !it.readNextRasterPart( 1, nCols, nRows, block, topLeftCol, topLeftRow, &blockExtent ) );
QVERIFY( !block.get() );
}


QGSTEST_MAIN( TestQgsRasterIterator )

#include "testqgsrasteriterator.moc"
Binary file added tests/testdata/big_raster.tif
Binary file not shown.

0 comments on commit 76eb29d

Please sign in to comment.