Add error messages, fix reporting of grid offset

This commit is contained in:
Martin Dobias 2015-06-24 20:24:30 +08:00
parent 7bdbbb84cd
commit d7a9493445
5 changed files with 59 additions and 10 deletions

View File

@ -132,6 +132,10 @@ class QgsAlignRaster
//! @return true on success
bool run();
//! Return error from a previous run() call.
//! Error message is empty if run() succeeded (returned true)
QString errorMessage() const;
//! write contents of the object to standard error stream - for debugging
void dump() const;

View File

@ -42,6 +42,11 @@ static double floor_with_tolerance( double value )
return qFloor( value );
}
static double fmod_with_tolerance( double num, double denom )
{
return num - floor_with_tolerance( num / denom ) * denom;
}
static QgsRectangle transform_to_extent( const double* geotransform, double xSize, double ySize )
{
@ -173,7 +178,13 @@ bool QgsAlignRaster::determineTransformAndSize()
// handle (setting it to NULL).
void* hTransformArg = GDALCreateGenImgProjTransformer( info.mDataset, info.mCrsWkt.constData(), NULL, mCrsWkt.constData(), FALSE, 0, 1 );
if ( !hTransformArg )
{
mErrorMessage = QString( "GDALCreateGenImgProjTransformer failed.\n\n"
"Source WKT:\n%1\n\nDestination WKT:\n%2" )
.arg( QString::fromAscii( info.mCrsWkt ) )
.arg( QString::fromAscii( mCrsWkt ) );
return false;
}
// Get approximate output georeferenced bounds and resolution for file.
double adfDstGeoTransform[6];
@ -187,7 +198,10 @@ bool QgsAlignRaster::determineTransformAndSize()
r.srcCellSizeInDestCRS = fabs( adfDstGeoTransform[1] * adfDstGeoTransform[5] );
if ( eErr != CE_None )
{
mErrorMessage = QString( "GDALSuggestedWarpOutput2 failed.\n\n" + r.inputFilename );
return false;
}
if ( finalExtent[0] == 0 && finalExtent[1] == 0 && finalExtent[2] == 0 && finalExtent[3] == 0 )
{
@ -234,7 +248,10 @@ bool QgsAlignRaster::determineTransformAndSize()
mYSize = floor_with_tolerance(( finalExtent[3] - originY ) / mCellSizeY );
if ( mXSize <= 0 || mYSize <= 0 )
{
mErrorMessage = QObject::tr( "Configured inputs have no common intersecting area." );
return false;
}
// build final geotransform...
mGeoTransform[0] = originX;
@ -250,6 +267,8 @@ bool QgsAlignRaster::determineTransformAndSize()
bool QgsAlignRaster::run()
{
mErrorMessage.clear();
// consider extent of all layers and setup geotransform and output grid size
if ( !determineTransformAndSize() )
return false;
@ -283,12 +302,18 @@ bool QgsAlignRaster::createAndWarp( const Item& raster )
{
GDALDriverH hDriver = GDALGetDriverByName( "GTiff" );
if ( !hDriver )
{
mErrorMessage = QString( "GDALGetDriverByName(GTiff) failed." );
return false;
}
// Open the source file.
GDALDatasetH hSrcDS = GDALOpen( raster.inputFilename.toLocal8Bit().constData(), GA_ReadOnly );
if ( !hSrcDS )
{
mErrorMessage = QObject::tr( "Unable to open input file: " ) + raster.inputFilename;
return false;
}
// Create output with same datatype as first input band.
@ -302,6 +327,7 @@ bool QgsAlignRaster::createAndWarp( const Item& raster )
if ( !hDstDS )
{
GDALClose( hSrcDS );
mErrorMessage = QObject::tr( "Unable to create output file: " ) + raster.outputFilename;
return false;
}
@ -401,8 +427,8 @@ QSizeF QgsAlignRaster::RasterInfo::cellSize() const
QPointF QgsAlignRaster::RasterInfo::gridOffset() const
{
return QPointF( fmod( mGeoTransform[0], cellSize().width() ),
fmod( mGeoTransform[3], cellSize().height() ) );
return QPointF( fmod_with_tolerance( mGeoTransform[0], cellSize().width() ),
fmod_with_tolerance( mGeoTransform[3], cellSize().height() ) );
}
QgsRectangle QgsAlignRaster::RasterInfo::extent() const

View File

@ -178,6 +178,10 @@ class ANALYSIS_EXPORT QgsAlignRaster
//! @return true on success
bool run();
//! Return error from a previous run() call.
//! Error message is empty if run() succeeded (returned true)
QString errorMessage() const { return mErrorMessage; }
//! write contents of the object to standard error stream - for debugging
void dump() const;
@ -196,6 +200,9 @@ class ANALYSIS_EXPORT QgsAlignRaster
//! Object that facilitates reporting of progress / cancellation
ProgressHandler* mProgressHandler;
//! Last error message from run()
QString mErrorMessage;
//! List of rasters to be aligned (with their output files and other options)
List mRasters;

View File

@ -157,6 +157,7 @@ void QgsAlignRasterDialog::editLayer()
itemNew.resampleMethod = ( QgsAlignRaster::ResampleAlg ) d.resampleMethod();
itemNew.rescaleValues = d.rescaleValues();
list[current.row()] = itemNew;
mAlign->setRasters( list );
populateLayersView();
}
@ -207,8 +208,7 @@ void QgsAlignRasterDialog::runAlign()
}
else
{
// TODO: error message with reason
QMessageBox::critical( this, tr( "Align Rasters" ), tr( "Failed to align rasters." ) );
QMessageBox::critical( this, tr( "Align Rasters" ), tr( "Failed to align rasters:" ) + "\n\n" + mAlign->errorMessage() );
}
}

View File

@ -16,6 +16,7 @@
#include <QtTest/QtTest>
#include "qgsalignraster.h"
#include "qgsrectangle.h"
#include <QDir>
@ -43,6 +44,15 @@ class TestAlignRaster : public QObject
SRC_FILE = QString( TEST_DATA_DIR ) + QDir::separator() + "float1-16.tif";
}
void testRasterInfo()
{
QgsAlignRaster::RasterInfo out( SRC_FILE );
QVERIFY( out.isValid() );
QCOMPARE( out.cellSize(), QSizeF( 0.2, 0.2 ) );
QCOMPARE( out.gridOffset(), QPointF( 0.0, 0.0 ) );
QCOMPARE( out.extent(), QgsRectangle( 106.0, -7.0, 106.8, -6.2 ) );
}
void testClip()
{
QString tmpFile( _tempFile( "clip" ) );
@ -159,9 +169,10 @@ class TestAlignRaster : public QObject
align.setRasters( rasters );
align.setParametersFromRaster( SRC_FILE );
align.setCellSize( 0.4, 0.4 );
QPointF offset = align.gridOffset();
offset.rx() += 0.2;
align.setGridOffset( offset );
// a technicality: the raster's origin is at y=-7 so we need to shift the offset,
// because with zero Y offset the grid goes -6.8 ... -7.2 - with offset of 0.2
// the grid will start at -7 (with X axis no need for shift as 106 % 0.4 == 0)
align.setGridOffset( QPointF( 0.0, 0.2 ) );
bool res = align.run();
QVERIFY( res );
@ -185,9 +196,10 @@ class TestAlignRaster : public QObject
align.setRasters( rasters );
align.setParametersFromRaster( SRC_FILE );
align.setCellSize( 0.4, 0.4 );
QPointF offset = align.gridOffset();
offset.rx() += 0.2;
align.setGridOffset( offset );
// a technicality: the raster's origin is at y=-7 so we need to shift the offset,
// because with zero Y offset the grid goes -6.8 ... -7.2 - with offset of 0.2
// the grid will start at -7 (with X axis no need for shift as 106 % 0.4 == 0)
align.setGridOffset( QPointF( 0.0, 0.2 ) );
bool res = align.run();
QVERIFY( res );