From ea86b93e0d7050bf8588210b7c7614be2cd0eb9e Mon Sep 17 00:00:00 2001 From: Radim Blazek Date: Thu, 6 Sep 2012 19:16:05 +0200 Subject: [PATCH] more raster Python bindings, raster write test in Python --- python/core/core.sip | 5 ++ python/core/qgsrasterchecker.sip | 20 +++++ python/core/qgsrasterdataprovider.sip | 66 +++++++++++++++- python/core/qgsrasterfilewriter.sip | 56 ++++++++++++++ python/core/qgsrasterpipe.sip | 51 +++++++++++++ python/core/qgsrasterprojector.sip | 57 ++++++++++++++ python/core/qgsrasterresamplefilter.sip | 26 ++++--- src/core/qgsrasterprojector.cpp | 28 ++++++- src/core/qgsrasterprojector.h | 43 ++++++----- src/core/raster/qgsrasterchecker.h | 4 +- src/core/raster/qgsrasterpipe.cpp | 22 +++--- src/core/raster/qgsrasterpipe.h | 16 ++-- tests/src/core/testqgsrasterfilewriter.cpp | 24 +++--- tests/src/python/CMakeLists.txt | 1 + tests/src/python/test_qgsrasterfilewriter.py | 79 ++++++++++++++++++++ 15 files changed, 432 insertions(+), 66 deletions(-) create mode 100644 python/core/qgsrasterchecker.sip create mode 100644 python/core/qgsrasterfilewriter.sip create mode 100644 python/core/qgsrasterpipe.sip create mode 100644 python/core/qgsrasterprojector.sip create mode 100644 tests/src/python/test_qgsrasterfilewriter.py diff --git a/python/core/core.sip b/python/core/core.sip index ef254911ee3..2cb0d9d7da3 100644 --- a/python/core/core.sip +++ b/python/core/core.sip @@ -63,10 +63,15 @@ %Include qgsproviderregistry.sip %Include qgsrasterbandstats.sip %Include qgsrasterdataprovider.sip +%Include qgsrasterchecker.sip +%Include qgsrasterfilewriter.sip %Include qgsrasterinterface.sip %Include qgsrasterlayer.sip +%Include qgsrasterpipe.sip %Include qgsrasterpyramid.sip +%Include qgsrasterprojector.sip %Include qgsrasterrenderer.sip +%Include qgsrasterresamplefilter.sip %Include qgsrasterresampler.sip %Include qgsrastershader.sip %Include qgsrastershaderfunction.sip diff --git a/python/core/qgsrasterchecker.sip b/python/core/qgsrasterchecker.sip new file mode 100644 index 00000000000..ec32d67e28b --- /dev/null +++ b/python/core/qgsrasterchecker.sip @@ -0,0 +1,20 @@ + +/** Raster checker for tests in python */ + +class QgsRasterChecker +{ +%TypeHeaderCode +#include +%End + public: + + QgsRasterChecker(); + + ~QgsRasterChecker(); + + QString report(); + + bool runTest( QString theVerifiedKey, QString theVerifiedUri, + QString theExpectedKey, QString theExpectedUri ); +}; + diff --git a/python/core/qgsrasterdataprovider.sip b/python/core/qgsrasterdataprovider.sip index 6a40c617fc5..dcc00809087 100644 --- a/python/core/qgsrasterdataprovider.sip +++ b/python/core/qgsrasterdataprovider.sip @@ -18,11 +18,63 @@ class QgsRasterDataProvider : QgsDataProvider //! If you add to this, please also add to capabilitiesString() enum Capability { - NoCapabilities = 0, - Identify = 1 -// Capability2 = 1 << 1, etc + NoCapabilities, + Identify, + ExactMinimumMaximum, + ExactResolution, + EstimatedMinimumMaximum, + BuildPyramids, + Histogram, + Size, + Create, + Remove }; + // This is modified copy of GDALColorInterp + enum ColorInterpretation + { + UndefinedColorInterpretation = 0, + /*! Greyscale */ GrayIndex = 1, + /*! Paletted (see associated color table) */ PaletteIndex = 2, // indexed color table + /*! Red band of RGBA image */ RedBand = 3, + /*! Green band of RGBA image */ GreenBand = 4, + /*! Blue band of RGBA image */ BlueBand = 5, + /*! Alpha (0=transparent, 255=opaque) */ AlphaBand = 6, + /*! Hue band of HLS image */ HueBand = 7, + /*! Saturation band of HLS image */ SaturationBand = 8, + /*! Lightness band of HLS image */ LightnessBand = 9, + /*! Cyan band of CMYK image */ CyanBand = 10, + /*! Magenta band of CMYK image */ MagentaBand = 11, + /*! Yellow band of CMYK image */ YellowBand = 12, + /*! Black band of CMLY image */ BlackBand = 13, + /*! Y Luminance */ YCbCr_YBand = 14, + /*! Cb Chroma */ YCbCr_CbBand = 15, + /*! Cr Chroma */ YCbCr_CrBand = 16, + /*! Continuous palette, QGIS addition, GRASS */ ContinuousPalette = 17, + /*! Max current value */ ColorInterpretationMax = 17 + }; + + // Progress types + enum RasterProgressType + { + ProgressHistogram = 0, + ProgressPyramids = 1, + ProgressStatistics = 2 + }; + + enum RasterBuildPyramids + { + PyramidsFlagNo = 0, + PyramidsFlagYes = 1, + CopyExisting = 2 + }; + + enum RasterPyramidsFormat + { + PyramidsGTiff = 0, + PyramidsInternal = 1, + PyramidsErdas = 2 + }; QgsRasterDataProvider(); @@ -179,6 +231,14 @@ class QgsRasterDataProvider : QgsDataProvider @note: this method was added in version 1.2*/ void setDpi( int dpi ); + /** Get block size */ + int xBlockSize() const; + int yBlockSize() const; + + /** Get raster size */ + int xSize() const; + int ySize() const; + /** read block of data using give extent and size */ /*virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, diff --git a/python/core/qgsrasterfilewriter.sip b/python/core/qgsrasterfilewriter.sip new file mode 100644 index 00000000000..10720dad6fe --- /dev/null +++ b/python/core/qgsrasterfilewriter.sip @@ -0,0 +1,56 @@ + +/** Raster file writer */ + +class QgsRasterFileWriter +{ +%TypeHeaderCode +#include +#include +%End + public: + enum WriterError + { + NoError = 0, + SourceProviderError = 1, + DestProviderError = 2, + CreateDatasourceError = 3, + WriteError = 4, + NoDataConflict = 5 + }; + + QgsRasterFileWriter( const QString& outputUrl ); + ~QgsRasterFileWriter(); + WriterError writeRaster( const QgsRasterPipe* pipe, int nCols, int nRows, QgsRectangle outputExtent, + const QgsCoordinateReferenceSystem& crs, QProgressDialog* p = 0 ); + + void setOutputFormat( const QString& format ); + QString outputFormat() const; + + void setOutputProviderKey( const QString& key ); + QString outputProviderKey() const; + + void setTiledMode( bool t ); + bool tiledMode() const; + + void setMaxTileWidth( int w ); + int maxTileWidth() const; + + QgsRasterDataProvider::RasterBuildPyramids buildPyramidsFlag() const; + void setBuildPyramidsFlag( QgsRasterDataProvider::RasterBuildPyramids f ); + + QList< int > pyramidsList() const; + void setPyramidsList( const QList< int > & list ); + + QString pyramidsResampling() const; + void setPyramidsResampling( const QString & str ); + + QgsRasterDataProvider::RasterPyramidsFormat pyramidsFormat() const; + void setPyramidsFormat( QgsRasterDataProvider::RasterPyramidsFormat f ); + + void setMaxTileHeight( int h ); + int maxTileHeight() const; + + void setCreateOptions( const QStringList& list ); + QStringList createOptions() const; +}; + diff --git a/python/core/qgsrasterpipe.sip b/python/core/qgsrasterpipe.sip new file mode 100644 index 00000000000..1545192cadd --- /dev/null +++ b/python/core/qgsrasterpipe.sip @@ -0,0 +1,51 @@ + +/** Raster pipe */ + +class QgsRasterPipe +{ +%TypeHeaderCode +#include +#include +#include +%End + public: + enum Role + { + UnknownRole = 0, + ProviderRole = 1, + RendererRole = 2, + ResamplerRole = 3, + ProjectorRole = 4 + }; + + QgsRasterPipe(); + QgsRasterPipe( const QgsRasterPipe& thePipe ); + + ~QgsRasterPipe(); + + bool insert( int idx, QgsRasterInterface* theInterface ); + + bool replace( int idx, QgsRasterInterface* theInterface ); + + bool set( QgsRasterInterface * theInterface ); + + bool remove( int idx ); + + bool remove( QgsRasterInterface * theInterface ); + + int size() const; + QgsRasterInterface * at( int idx ) const; + QgsRasterInterface * last() const; + + bool setOn( int idx, bool on ); + + bool canSetOn( int idx, bool on ); + + QgsRasterDataProvider * provider() const; + QgsRasterRenderer * renderer() const; + QgsRasterResampleFilter * resampleFilter() const; + QgsRasterProjector * projector() const; + + void setStatsOn( bool on ); +}; + diff --git a/python/core/qgsrasterprojector.sip b/python/core/qgsrasterprojector.sip new file mode 100644 index 00000000000..a7ee2578653 --- /dev/null +++ b/python/core/qgsrasterprojector.sip @@ -0,0 +1,57 @@ + +/** Raster projector */ + +class QgsRasterProjector +{ +%TypeHeaderCode +#include +#include +%End + public: + QgsRasterProjector( + QgsCoordinateReferenceSystem theSrcCRS, + QgsCoordinateReferenceSystem theDestCRS, + QgsRectangle theDestExtent, + int theDestRows, int theDestCols, + double theMaxSrcXRes, double theMaxSrcYRes, + QgsRectangle theExtent + ); + QgsRasterProjector( + QgsCoordinateReferenceSystem theSrcCRS, + QgsCoordinateReferenceSystem theDestCRS, + double theMaxSrcXRes, double theMaxSrcYRes, + QgsRectangle theExtent + ); + QgsRasterProjector(); + + ~QgsRasterProjector(); + + QgsRasterInterface * clone() const; + + int bandCount() const; + + QgsRasterInterface::DataType dataType( int bandNo ) const; + + void setCRS( const QgsCoordinateReferenceSystem & theSrcCRS, const QgsCoordinateReferenceSystem & theDestCRS ); + + QgsCoordinateReferenceSystem srcCrs() const; + + QgsCoordinateReferenceSystem destCrs() const; + + void setMaxSrcRes( double theMaxSrcXRes, double theMaxSrcYRes ); + + QgsRectangle srcExtent(); + + int srcRows(); + int srcCols(); + void setSrcRows( int theRows ); + void setSrcCols( int theCols ); + + void srcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol ); + + int dstRows() const; + int dstCols() const; + + void * readBlock( int bandNo, const QgsRectangle & extent, int width, int height ); +}; + diff --git a/python/core/qgsrasterresamplefilter.sip b/python/core/qgsrasterresamplefilter.sip index 5733265e334..65e866dfde8 100644 --- a/python/core/qgsrasterresamplefilter.sip +++ b/python/core/qgsrasterresamplefilter.sip @@ -1,29 +1,37 @@ + +/** Raster resample filter */ + class QgsRasterResampleFilter { %TypeHeaderCode - #include "qgsrasterresamplefilter.h" +#include %End + QgsRasterResampleFilter(); + QgsRasterResampleFilter( const QgsRasterResampleFilter& thePipe ); - public: - QgsRasterResampleFilter( QgsRasterFace* input = 0 ); ~QgsRasterResampleFilter(); + QgsRasterInterface * clone() const; + + int bandCount() const; + + QgsRasterInterface::DataType dataType( int bandNo ) const; + + bool setInput( QgsRasterInterface* input ); + void * readBlock( int bandNo, const QgsRectangle & extent, int width, int height ); - /**Set resampler for zoomed in scales. Takes ownership of the object*/ void setZoomedInResampler( QgsRasterResampler* r ); - const QgsRasterResampler* zoomedInResampler(); + const QgsRasterResampler* zoomedInResampler() const; - /**Set resampler for zoomed out scales. Takes ownership of the object*/ void setZoomedOutResampler( QgsRasterResampler* r ); const QgsRasterResampler* zoomedOutResampler() const; void setMaxOversampling( double os ); double maxOversampling() const; - virtual void writeXML( QDomDocument& doc, QDomElement& parentElem ) const = 0; + void writeXML( QDomDocument& doc, QDomElement& parentElem ); - /**Sets base class members from xml. Usually called from create() methods of subclasses*/ - void readXML( const QDomElement& rendererElem ); + void readXML( const QDomElement& resamplefilterElem ); }; diff --git a/src/core/qgsrasterprojector.cpp b/src/core/qgsrasterprojector.cpp index 148d5dbaf9b..07e14ec9eb8 100644 --- a/src/core/qgsrasterprojector.cpp +++ b/src/core/qgsrasterprojector.cpp @@ -66,6 +66,32 @@ QgsRasterProjector::QgsRasterProjector() QgsDebugMsg( "Entered" ); } +QgsRasterProjector::QgsRasterProjector( const QgsRasterProjector &projector ) +{ + mSrcCRS = projector.mSrcCRS; + mDestCRS = projector.mDestCRS; + mMaxSrcXRes = projector.mMaxSrcXRes; + mMaxSrcYRes = projector.mMaxSrcYRes; + mExtent = projector.mExtent; + mCoordinateTransform.setSourceCrs( mSrcCRS ); + mCoordinateTransform.setDestCRS( mDestCRS ); +} + +QgsRasterProjector & QgsRasterProjector::operator=( const QgsRasterProjector & projector ) +{ + if ( &projector != this ) + { + mSrcCRS = projector.mSrcCRS; + mDestCRS = projector.mDestCRS; + mMaxSrcXRes = projector.mMaxSrcXRes; + mMaxSrcYRes = projector.mMaxSrcYRes; + mExtent = projector.mExtent; + mCoordinateTransform.setSourceCrs( mSrcCRS ); + mCoordinateTransform.setDestCRS( mDestCRS ); + } + return *this; +} + QgsRasterInterface * QgsRasterProjector::clone() const { QgsDebugMsg( "Entered" ); @@ -93,7 +119,7 @@ QgsRasterInterface::DataType QgsRasterProjector::dataType( int bandNo ) const return QgsRasterInterface::UnknownDataType; } -void QgsRasterProjector::setCRS( QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS ) +void QgsRasterProjector::setCRS( const QgsCoordinateReferenceSystem & theSrcCRS, const QgsCoordinateReferenceSystem & theDestCRS ) { mSrcCRS = theSrcCRS; mDestCRS = theDestCRS; diff --git a/src/core/qgsrasterprojector.h b/src/core/qgsrasterprojector.h index dd265f3ca59..790bdd75946 100644 --- a/src/core/qgsrasterprojector.h +++ b/src/core/qgsrasterprojector.h @@ -57,10 +57,14 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface QgsRectangle theExtent ); QgsRasterProjector(); + // * copy constructor to avoid synthesized which fails on copy of QgsCoordinateTransform (QObject child) in Python bindings + QgsRasterProjector( const QgsRasterProjector &projector ); /** \brief The destructor */ ~QgsRasterProjector(); + QgsRasterProjector & operator=( const QgsRasterProjector &projector ); + QgsRasterInterface * clone() const; int bandCount() const; @@ -68,7 +72,7 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface QgsRasterInterface::DataType dataType( int bandNo ) const; /** \brief set source and destination CRS */ - void setCRS( QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS ); + void setCRS( const QgsCoordinateReferenceSystem & theSrcCRS, const QgsCoordinateReferenceSystem & theDestCRS ); /** \brief Get source CRS */ QgsCoordinateReferenceSystem srcCrs() const { return mSrcCRS; } @@ -82,6 +86,25 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface mMaxSrcXRes = theMaxSrcXRes; mMaxSrcYRes = theMaxSrcYRes; } + /** get source extent */ + QgsRectangle srcExtent() { return mSrcExtent; } + + /** get/set source width/height */ + int srcRows() { return mSrcRows; } + int srcCols() { return mSrcCols; } + void setSrcRows( int theRows ) { mSrcRows = theRows; mSrcXRes = mSrcExtent.height() / mSrcRows; } + void setSrcCols( int theCols ) { mSrcCols = theCols; mSrcYRes = mSrcExtent.width() / mSrcCols; } + + /** \brief Get source row and column indexes for current source extent and resolution */ + void srcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol ); + + int dstRows() const { return mDestRows; } + int dstCols() const { return mDestCols; } + + void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height ); + + + private: /** \brief get destination point for _current_ destination position */ void destPointOnCPMatrix( int theRow, int theCol, double *theX, double *theY ); @@ -98,9 +121,6 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface /** \brief Get approximate source row and column indexes for current source extent and resolution */ inline void approximateSrcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol ); - /** \brief Get source row and column indexes for current source extent and resolution */ - void srcRowCol( int theDestRow, int theDestCol, int *theSrcRow, int *theSrcCol ); - /** \brief Calculate matrix */ void calc(); @@ -139,24 +159,9 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface /** Calc / switch helper */ void nextHelper(); - /** get source extent */ - QgsRectangle srcExtent() { return mSrcExtent; } - - /** get/set source width/height */ - int srcRows() { return mSrcRows; } - int srcCols() { return mSrcCols; } - void setSrcRows( int theRows ) { mSrcRows = theRows; mSrcXRes = mSrcExtent.height() / mSrcRows; } - void setSrcCols( int theCols ) { mSrcCols = theCols; mSrcYRes = mSrcExtent.width() / mSrcCols; } - /** get mCPMatrix as string */ QString cpToString(); - int dstRows() const { return mDestRows; } - int dstCols() const { return mDestCols; } - - void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height ); - - private: /** Source CRS */ QgsCoordinateReferenceSystem mSrcCRS; diff --git a/src/core/raster/qgsrasterchecker.h b/src/core/raster/qgsrasterchecker.h index 04a40f6e5a9..24626fdc6e6 100644 --- a/src/core/raster/qgsrasterchecker.h +++ b/src/core/raster/qgsrasterchecker.h @@ -35,8 +35,6 @@ class CORE_EXPORT QgsRasterChecker //! Destructor ~QgsRasterChecker() {}; - QString controlImagePath() const; - QString report() { return mReport; }; /** * Test using renderer to generate the image to be compared. @@ -45,7 +43,7 @@ class CORE_EXPORT QgsRasterChecker * @param theExpectedKey expected provider key * @param theExpectedUri URI of the expected (control) raster */ - bool runTest( QString theVerifiedKey, QString theVerifiedUri, + bool runTest( QString theVerifiedKey, QString theVerifiedUri, QString theExpectedKey, QString theExpectedUri ); private: QString mReport; diff --git a/src/core/raster/qgsrasterpipe.cpp b/src/core/raster/qgsrasterpipe.cpp index 332f55c3cc2..546876d948b 100644 --- a/src/core/raster/qgsrasterpipe.cpp +++ b/src/core/raster/qgsrasterpipe.cpp @@ -195,34 +195,34 @@ bool QgsRasterPipe::set( QgsRasterInterface* theInterface ) return insert( idx, theInterface ); // insert may still fail and return false } -QgsRasterInterface * QgsRasterPipe::iface( Role role ) const -{ - QgsDebugMsg( QString( "role = %1" ).arg( role ) ); - if ( mRoleMap.contains( role ) ) +QgsRasterInterface * QgsRasterPipe::interface( Role role ) const { - return mInterfaces.value( mRoleMap.value( role ) ); + QgsDebugMsg( QString( "role = %1" ).arg( role ) ); + if ( mRoleMap.contains( role ) ) + { + return mInterfaces.value( mRoleMap.value( role ) ); + } + return 0; } - return 0; -} QgsRasterDataProvider * QgsRasterPipe::provider() const { - return dynamic_cast( iface( ProviderRole ) ); + return dynamic_cast( interface( ProviderRole ) ); } QgsRasterRenderer * QgsRasterPipe::renderer() const { - return dynamic_cast( iface( RendererRole ) ); + return dynamic_cast( interface( RendererRole ) ); } QgsRasterResampleFilter * QgsRasterPipe::resampleFilter() const { - return dynamic_cast( iface( ResamplerRole ) ); + return dynamic_cast( interface( ResamplerRole ) ); } QgsRasterProjector * QgsRasterPipe::projector() const { - return dynamic_cast( iface( ProjectorRole ) ); + return dynamic_cast( interface( ProjectorRole ) ); } bool QgsRasterPipe::remove( int idx ) diff --git a/src/core/raster/qgsrasterpipe.h b/src/core/raster/qgsrasterpipe.h index 3840fec1201..82a25eab047 100644 --- a/src/core/raster/qgsrasterpipe.h +++ b/src/core/raster/qgsrasterpipe.h @@ -47,11 +47,7 @@ class CORE_EXPORT QgsRasterPipe QgsRasterPipe( ); QgsRasterPipe( const QgsRasterPipe& thePipe ); - virtual ~QgsRasterPipe(); - - /** \brief Try to connect interfaces in pipe and to the provider at beginning. - Returns true if connected or false if connection failed */ - bool connect( QVector theInterfaces ); + ~QgsRasterPipe(); /** Try to insert interface at specified index and connect * if connection would fail, the interface is not inserted and false is returned */ @@ -69,9 +65,6 @@ class CORE_EXPORT QgsRasterPipe */ bool set( QgsRasterInterface * theInterface ); - /** Get known interface by role */ - QgsRasterInterface * iface( Role role ) const; - /** Remove and delete interface at given index if possible */ bool remove( int idx ); @@ -115,6 +108,13 @@ class CORE_EXPORT QgsRasterPipe // Check if index is in bounds bool checkBounds( int idx ) const; + + /** Get known interface by role */ + QgsRasterInterface * interface( Role role ) const; + + /** \brief Try to connect interfaces in pipe and to the provider at beginning. + Returns true if connected or false if connection failed */ + bool connect( QVector theInterfaces ); }; #endif diff --git a/tests/src/core/testqgsrasterfilewriter.cpp b/tests/src/core/testqgsrasterfilewriter.cpp index 3c8f6d8785a..a5133756816 100644 --- a/tests/src/core/testqgsrasterfilewriter.cpp +++ b/tests/src/core/testqgsrasterfilewriter.cpp @@ -47,8 +47,8 @@ class TestQgsRasterFileWriter: public QObject void writeTest(); private: bool writeTest( QString rasterName ); - void log ( QString msg ); - void logError ( QString msg ); + void log( QString msg ); + void logError( QString msg ); QString mTestDataDir; QString mReport; }; @@ -85,7 +85,7 @@ void TestQgsRasterFileWriter::cleanupTestCase() void TestQgsRasterFileWriter::writeTest() { QDir dir( mTestDataDir + "/raster" ); - + QStringList filters; filters << "*.tif"; QStringList rasterNames = dir.entryList( filters, QDir::Files ); @@ -108,7 +108,7 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName ) QFileInfo myRasterFileInfo( myFileName ); QgsRasterLayer * mpRasterLayer = new QgsRasterLayer( myRasterFileInfo.filePath(), - myRasterFileInfo.completeBaseName() ); + myRasterFileInfo.completeBaseName() ); qDebug() << theRasterName << " metadata: " << mpRasterLayer->dataProvider()->metadata(); if ( !mpRasterLayer->isValid() ) return false; @@ -122,7 +122,7 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName ) QString tmpName = tmpFile.fileName(); tmpFile.close(); // do not remove when class is destroyd so that we can read the file and see difference - tmpFile.setAutoRemove ( false ); + tmpFile.setAutoRemove( false ); qDebug() << "temporary output file: " << tmpName; mReport += "temporary output file: " + tmpName + "
"; @@ -130,7 +130,7 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName ) QgsRasterPipe* pipe = new QgsRasterPipe(); if ( !pipe->set( provider->clone() ) ) { - logError ( "Cannot set pipe provider" ); + logError( "Cannot set pipe provider" ); return false; } qDebug() << "provider set"; @@ -145,7 +145,7 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName ) } qDebug() << "nuller set"; - // Reprojection not really done + // Reprojection not really done QgsRasterProjector *projector = new QgsRasterProjector; projector->setCRS( provider->crs(), provider->crs() ); if ( !pipe->insert( 2, projector ) ) @@ -155,26 +155,26 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName ) } qDebug() << "projector set"; - fileWriter.writeRaster( pipe, provider->xSize() + 1, provider->ySize(), provider->extent(), provider->crs() ); + fileWriter.writeRaster( pipe, provider->xSize(), provider->ySize(), provider->extent(), provider->crs() ); delete pipe; QgsRasterChecker checker; - bool ok = checker.runTest( "gdal", tmpName, "gdal", myRasterFileInfo.filePath() ); + bool ok = checker.runTest( "gdal", tmpName, "gdal", myRasterFileInfo.filePath() ); mReport += checker.report(); // All OK, we can delete the file - tmpFile.setAutoRemove ( ok ); + tmpFile.setAutoRemove( ok ); return true; } -void TestQgsRasterFileWriter::log ( QString msg ) +void TestQgsRasterFileWriter::log( QString msg ) { mReport += msg + "
"; } -void TestQgsRasterFileWriter::logError ( QString msg ) +void TestQgsRasterFileWriter::logError( QString msg ) { mReport += "Error:" + msg + "
"; qDebug() << msg; diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 0baaf9ee526..c254feb918d 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -4,6 +4,7 @@ ADD_PYTHON_TEST(PyQgsComposerHtml test_qgscomposerhtml.py) ADD_PYTHON_TEST(PyQgsComposerMap test_qgscomposermap.py) ADD_PYTHON_TEST(PyQgsGeometry test_qgsgeometry.py) ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py) +ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py) ADD_PYTHON_TEST(PyQgsMemoryProvider test_qgsmemoryprovider.py) ADD_PYTHON_TEST(PyQgsLogger test_qgslogger.py) ADD_PYTHON_TEST(PyQgsCoordinateTransform test_qgscoordinatetransform.py) diff --git a/tests/src/python/test_qgsrasterfilewriter.py b/tests/src/python/test_qgsrasterfilewriter.py new file mode 100644 index 00000000000..2943ca70372 --- /dev/null +++ b/tests/src/python/test_qgsrasterfilewriter.py @@ -0,0 +1,79 @@ +import os, glob +import unittest + +from qgis.core import QgsRasterLayer, QgsRasterChecker, QgsRasterPipe, QgsRasterFileWriter, QgsRasterProjector +from PyQt4.QtCore import QFileInfo, QString, QStringList, QTemporaryFile, QDir + +# Convenience instances in case you may need them +# not used in this test +from utilities import getQgisTestApp +QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp() + +class TestQgsRasterFileWriter(unittest.TestCase): + def __init__(self,methodName): + unittest.TestCase.__init__(self,methodName) + self.testDataDir = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'testdata')) + self.report = "

Python Raster File Writer Tests

\n" + + def write(self, theRasterName): + print theRasterName + + path = "%s/%s" % ( self.testDataDir, theRasterName ) + #myFileInfo = QFileInfo( path ) + #myBaseName = myFileInfo.baseName() + rasterLayer = QgsRasterLayer(path, "test") + if not rasterLayer.isValid(): return False + provider = rasterLayer.dataProvider() + + tmpFile = QTemporaryFile() + tmpFile.open() # fileName is no avialable until open + tmpName = tmpFile.fileName() + tmpFile.close(); + # do not remove when class is destroyd so that we can read the file and see difference + tmpFile.setAutoRemove ( False ) + + fileWriter = QgsRasterFileWriter ( tmpName ) + pipe = QgsRasterPipe() + if not pipe.set( provider.clone() ): + print "Cannot set pipe provider" + return False + + #nuller = QgsRasterNuller() + #nuller.setNoData( ... ) + #if not pipe.insert( 1, nuller ): + # print "Cannot set pipe nuller" + # return False + + projector = QgsRasterProjector() + projector.setCRS( provider.crs(), provider.crs() ) + if not pipe.insert( 2, projector.clone() ): + print "Cannot set pipe projector" + return False + + fileWriter.writeRaster( pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs() ) + + checker = QgsRasterChecker() + ok = checker.runTest( "gdal", tmpName, "gdal", path ); + self.report += checker.report(); + + # All OK, we can delete the file + tmpFile.setAutoRemove ( ok ); + + return ok + + def testWrite(self): + for name in glob.glob( "%s/raster/*.tif" % self.testDataDir ): + baseName = os.path.basename ( name ) + allOk = True + ok = self.write( "raster/%s" % baseName ) + if not ok: allOk = False + + reportFilePath = "%s/qgistest.html" % QDir.tempPath() + reportFile = open(reportFilePath,'a') + reportFile.write( self.report ) + reportFile.close() + + assert allOk, "Raster file writer test failed" + +if __name__ == '__main__': + unittest.main()