43 changes: 24 additions & 19 deletions src/core/qgsrasterprojector.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,22 @@ 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;

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; }
Expand All @@ -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 );

Expand All @@ -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();

Expand Down Expand Up @@ -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;

Expand Down
4 changes: 1 addition & 3 deletions src/core/raster/qgsrasterchecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand Down
22 changes: 11 additions & 11 deletions src/core/raster/qgsrasterpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<QgsRasterDataProvider *>( iface( ProviderRole ) );
return dynamic_cast<QgsRasterDataProvider *>( interface( ProviderRole ) );
}

QgsRasterRenderer * QgsRasterPipe::renderer() const
{
return dynamic_cast<QgsRasterRenderer *>( iface( RendererRole ) );
return dynamic_cast<QgsRasterRenderer *>( interface( RendererRole ) );
}

QgsRasterResampleFilter * QgsRasterPipe::resampleFilter() const
{
return dynamic_cast<QgsRasterResampleFilter *>( iface( ResamplerRole ) );
return dynamic_cast<QgsRasterResampleFilter *>( interface( ResamplerRole ) );
}

QgsRasterProjector * QgsRasterPipe::projector() const
{
return dynamic_cast<QgsRasterProjector*>( iface( ProjectorRole ) );
return dynamic_cast<QgsRasterProjector*>( interface( ProjectorRole ) );
}

bool QgsRasterPipe::remove( int idx )
Expand Down
16 changes: 8 additions & 8 deletions src/core/raster/qgsrasterpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<QgsRasterInterface*> theInterfaces );
~QgsRasterPipe();

/** Try to insert interface at specified index and connect
* if connection would fail, the interface is not inserted and false is returned */
Expand All @@ -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 );

Expand Down Expand Up @@ -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<QgsRasterInterface*> theInterfaces );
};

#endif
Expand Down
24 changes: 12 additions & 12 deletions tests/src/core/testqgsrasterfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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 );
Expand All @@ -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;
Expand All @@ -122,15 +122,15 @@ 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 + "<br>";

QgsRasterFileWriter fileWriter( tmpName );
QgsRasterPipe* pipe = new QgsRasterPipe();
if ( !pipe->set( provider->clone() ) )
{
logError ( "Cannot set pipe provider" );
logError( "Cannot set pipe provider" );
return false;
}
qDebug() << "provider set";
Expand All @@ -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 ) )
Expand All @@ -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 + "<br>";
}

void TestQgsRasterFileWriter::logError ( QString msg )
void TestQgsRasterFileWriter::logError( QString msg )
{
mReport += "Error:<font color='red'>" + msg + "</font><br>";
qDebug() << msg;
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
79 changes: 79 additions & 0 deletions tests/src/python/test_qgsrasterfilewriter.py
Original file line number Diff line number Diff line change
@@ -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 = "<h1>Python Raster File Writer Tests</h1>\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()