69 changes: 54 additions & 15 deletions src/core/raster/qgsrasternuller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,31 @@ QgsRasterInterface * QgsRasterNuller::clone() const
QgsDebugMsg( "Entered" );
QgsRasterNuller * nuller = new QgsRasterNuller( 0 );
nuller->mNoData = mNoData;
nuller->mOutputNoData = mOutputNoData;
nuller->mHasOutputNoData = mHasOutputNoData;
return nuller;
}

void QgsRasterNuller::setOutputNoDataValue( int bandNo, double noData )
{
if ( bandNo > mOutputNoData.size() )
{
mOutputNoData.resize( bandNo );
mHasOutputNoData.resize( bandNo );
}
mOutputNoData[bandNo-1] = noData;
mHasOutputNoData[bandNo-1] = true;
}

void QgsRasterNuller::setNoData( int bandNo, QgsRasterRangeList noData )
{
if ( bandNo > mNoData.size() )
{
mNoData.resize( bandNo );
}
mNoData[bandNo-1] = noData;
}

int QgsRasterNuller::bandCount() const
{
if ( mInput ) return mInput->bandCount();
Expand All @@ -56,34 +78,51 @@ QgsRasterBlock * QgsRasterNuller::block( int bandNo, QgsRectangle const & exten
return outputBlock;
}

//void * rasterData = mInput->block( bandNo, extent, width, height );
QgsRasterBlock *inputBlock = mInput->block( bandNo, extent, width, height );
QgsRasterBlock *outputBlock = 0;

// Input may be without no data value
//double noDataValue = mInput->noDataValue( bandNo );
double noDataValue = mOutputNoData;
if ( mHasOutputNoData.value( bandNo - 1 ) || inputBlock->hasNoDataValue() )
{
double noDataValue;
if ( mHasOutputNoData.value( bandNo - 1 ) )
{
noDataValue = mOutputNoData.value( bandNo - 1 );
}
else
{
noDataValue = inputBlock->noDataValue();
}
outputBlock = new QgsRasterBlock( inputBlock->dataType(), width, height, noDataValue );
}
else
{
outputBlock = new QgsRasterBlock( inputBlock->dataType(), width, height );
}

for ( int i = 0; i < height; i++ )
{
for ( int j = 0; j < width; j++ )
{
//int index = i * width + j;

//double value = readValue( rasterData, dataType, index );
double value = inputBlock->value( i, j );

foreach ( NoData noData, mNoData )
bool isNoData = inputBlock->isNoData( i, j );
if ( QgsRasterRange::contains( value, mNoData.value( bandNo - 1 ) ) )
{
isNoData = true;
}
outputBlock->setValue( i, j, inputBlock->value( i, j ) );
if ( isNoData )
{
outputBlock->setIsNoData( i, j );
}
else
{
if (( value >= noData.min && value <= noData.max ) ||
qgsDoubleNear( value, noData.min ) ||
qgsDoubleNear( value, noData.max ) )
{
inputBlock->setValue( i, j, noDataValue );
}
outputBlock->setValue( i, j, value );
}
}
}
delete inputBlock;

return inputBlock;
return outputBlock;
}

15 changes: 9 additions & 6 deletions src/core/raster/qgsrasternuller.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define QGSRASTERNULLER_H

#include "qgsrasterdataprovider.h"
#include "qgsrasterrange.h"
#include "qgsrasterinterface.h"

#include <QList>
Expand Down Expand Up @@ -46,17 +47,19 @@ class CORE_EXPORT QgsRasterNuller : public QgsRasterInterface

QgsRasterBlock* block( int bandNo, const QgsRectangle &extent, int width, int height );

void setNoData( QList<QgsRasterNuller::NoData> noData ) { mNoData = noData; }
void setNoData( int bandNo, QgsRasterRangeList noData );

QList<QgsRasterNuller::NoData> noData() const { return mNoData; }
QgsRasterRangeList noData( int bandNo ) const { return mNoData.value( bandNo -1 ); }

/** \brief Set output no data value. */
void setOutputNoData( double noData ) { mOutputNoData = noData; }
void setOutputNoDataValue( int bandNo, double noData );

private:
QList<QgsRasterNuller::NoData> mNoData;
// no data to be set in output
double mOutputNoData;
// no data indext from 0
QVector< QgsRasterRangeList > mNoData;
// no data to be set in output, indexed form 0
QVector<double> mOutputNoData;
QVector<bool> mHasOutputNoData;
};

#endif // QGSRASTERNULLER_H
13 changes: 7 additions & 6 deletions src/core/raster/qgsrasterprojector.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
***************************************************************************/

/* This code takes ideas from WarpBuilder in Geotools.
* Thank you to Ing. Andrea Aime, Ing. Simone Giannecchini and GeoSolutions S.A.S.
* Thank to Ing. Andrea Aime, Ing. Simone Giannecchini and GeoSolutions S.A.S.
* See : http://geo-solutions.blogspot.com/2011/01/developers-corner-improving.html
*/

Expand Down Expand Up @@ -57,7 +57,9 @@ 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
/** \brief Copy constructor */
// To avoid synthesized which fails on copy of QgsCoordinateTransform
// (QObject child) in Python bindings
QgsRasterProjector( const QgsRasterProjector &projector );

/** \brief The destructor */
Expand Down Expand Up @@ -86,6 +88,9 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
mMaxSrcXRes = theMaxSrcXRes; mMaxSrcYRes = theMaxSrcYRes;
}

QgsRasterBlock *block( int bandNo, const QgsRectangle & extent, int width, int height );

private:
/** get source extent */
QgsRectangle srcExtent() { return mSrcExtent; }

Expand All @@ -101,10 +106,6 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
int dstRows() const { return mDestRows; }
int dstCols() const { return mDestCols; }

QgsRasterBlock *block( int bandNo, const QgsRectangle & 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 Down
35 changes: 17 additions & 18 deletions src/core/raster/qgsrasterviewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,27 @@

struct QgsRasterViewPort
{
// NOT IN MAP SPACE BUT DEVICE SPACE
/** \brief Coordinate (in geographic coordinate system) of top left corner of the part of the raster that
* is to be rendered.*/
QgsPoint topLeftPoint;
/** \brief Coordinate (in geographic coordinate system) of bottom right corner of the part of the raster that
* is to be rendered.*/
QgsPoint bottomRightPoint;
/** \brief Distance in map units from left edge to right edge for the part of the raster that
* is to be rendered.*/

int drawableAreaXDim;
/** \brief Distance in map units from bottom edge to top edge for the part of the raster that
* is to be rendered.*/
int drawableAreaYDim;

// intersection of current map extent and layer extent
/** \brief Coordinate (in output device coordinate system) of top left corner
* of the part of the raster that is to be rendered.*/
QgsPoint mTopLeftPoint;
/** \brief Coordinate (in output device coordinate system) of bottom right corner
* of the part of the raster that is to be rendered.*/
QgsPoint mBottomRightPoint;

/** \brief Width, number of columns to be rendered */
int mWidth;
/** \brief Distance in map units from bottom edge to top edge for the part of
* the raster that is to be rendered.*/
/** \brief Height, number of rows to be rendered */
int mHeight;

/** \brief Intersection of current map extent and layer extent */
QgsRectangle mDrawnExtent;

// Source coordinate system
/** \brief Source coordinate system */
QgsCoordinateReferenceSystem mSrcCRS;

// Target coordinate system
/** \brief Target coordinate system */
QgsCoordinateReferenceSystem mDestCRS;
};

Expand Down
9 changes: 4 additions & 5 deletions src/gui/qgsrasterlayersaveasdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,18 +797,17 @@ void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
lineEdit->setFixedWidth( width );
}

QList<QgsRasterNuller::NoData> QgsRasterLayerSaveAsDialog::noData() const
QgsRasterRangeList QgsRasterLayerSaveAsDialog::noData() const
{
QList<QgsRasterNuller::NoData> noDataList;
QgsRasterRangeList noDataList;
if ( ! mNoDataGroupBox->isChecked() )
return noDataList;

for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
{
QgsRasterNuller::NoData noData;
noData.min = noDataCellValue( r, 0 );
noData.max = noDataCellValue( r, 1 );
QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
noDataList.append( noData );

}
return noDataList;
}
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgsrasterlayersaveasdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "ui_qgsrasterlayersaveasdialogbase.h"
#include "qgsrectangle.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsrasternuller.h"
#include "qgsrasterrange.h"

class QgsRasterLayer;
class QgsRasterDataProvider;
Expand Down Expand Up @@ -70,7 +70,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
QgsCoordinateReferenceSystem outputCrs();
QStringList createOptions() const;
QgsRectangle outputRectangle() const;
QList<QgsRasterNuller::NoData> noData() const;
QgsRasterRangeList noData() const;

QList< int > pyramidsList() const;
QgsRaster::RasterBuildPyramids buildPyramidsFlag() const;
Expand Down
5 changes: 4 additions & 1 deletion tests/src/core/testqgsrasterfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ bool TestQgsRasterFileWriter::writeTest( QString theRasterName )

// Nuller currently is not really used
QgsRasterNuller *nuller = new QgsRasterNuller();
//nuller->setNoData( ... );
for ( int band = 1; band <= provider->bandCount(); band++ )
{
//nuller->setNoData( ... );
}
if ( !pipe->insert( 1, nuller ) )
{
logError( "Cannot set pipe nuller" );
Expand Down