30 #include <cpl_string.h> 31 #include <gdalwarper.h> 34 const QgsRectangle &outputExtent,
int nOutputColumns,
int nOutputRows,
const QVector<QgsRasterCalculatorEntry> &rasterEntries )
35 : mFormulaString( formulaString )
36 , mOutputFile( outputFile )
37 , mOutputFormat( outputFormat )
38 , mOutputRectangle( outputExtent )
39 , mNumOutputColumns( nOutputColumns )
40 , mNumOutputRows( nOutputRows )
41 , mRasterEntries( rasterEntries )
44 mOutputCrs = mRasterEntries.at( 0 ).raster->crs();
49 : mFormulaString( formulaString )
50 , mOutputFile( outputFile )
51 , mOutputFormat( outputFormat )
52 , mOutputRectangle( outputExtent )
53 , mOutputCrs( outputCrs )
54 , mNumOutputColumns( nOutputColumns )
55 , mNumOutputRows( nOutputRows )
56 , mRasterEntries( rasterEntries )
71 QMap< QString, QgsRasterBlock * > inputBlocks;
72 QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin();
73 for ( ; it != mRasterEntries.constEnd(); ++it )
78 qDeleteAll( inputBlocks );
84 if ( it->raster->crs() != mOutputCrs )
87 proj.
setCrs( it->raster->crs(), mOutputCrs );
88 proj.
setInput( it->raster->dataProvider() );
93 block = proj.
block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows, rasterBlockFeedback );
98 qDeleteAll( inputBlocks );
99 return static_cast< int >(
Canceled );
104 block = it->raster->dataProvider()->block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows );
110 qDeleteAll( inputBlocks );
113 inputBlocks.insert( it->ref, block );
117 GDALDriverH outputDriver = openOutputDriver();
124 if ( !outputDataset )
129 GDALSetProjection( outputDataset.get(), mOutputCrs.
toWkt().toLocal8Bit().data() );
130 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
132 float outputNodataValue = -FLT_MAX;
133 GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue );
139 for (
int i = 0; i < mNumOutputRows; ++i )
143 feedback->
setProgress( 100.0 * static_cast< double >( i ) / mNumOutputRows );
151 if ( calcNode->
calculate( inputBlocks, resultMatrix, i ) )
153 bool resultIsNumber = resultMatrix.
isNumber();
154 float *calcData =
new float[mNumOutputColumns];
156 for (
int j = 0; j < mNumOutputColumns; ++j )
158 calcData[j] = ( float )( resultIsNumber ? resultMatrix.
number() : resultMatrix.
data()[j] );
162 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
179 qDeleteAll( inputBlocks );
186 return static_cast< int >(
Canceled );
188 return static_cast< int >(
Success );
191 GDALDriverH QgsRasterCalculator::openOutputDriver()
193 char **driverMetadata =
nullptr;
196 GDALDriverH outputDriver = GDALGetDriverByName( mOutputFormat.toLocal8Bit().data() );
203 driverMetadata = GDALGetMetadata( outputDriver,
nullptr );
204 if ( !CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) )
215 char **papszOptions =
nullptr;
216 gdal::dataset_unique_ptr outputDataset( GDALCreate( outputDriver, mOutputFile.toUtf8().constData(), mNumOutputColumns, mNumOutputRows, 1, GDT_Float32, papszOptions ) );
217 if ( !outputDataset )
223 double geotransform[6];
224 outputGeoTransform( geotransform );
225 GDALSetGeoTransform( outputDataset.get(), geotransform );
227 return outputDataset;
230 void QgsRasterCalculator::outputGeoTransform(
double *transform )
const 232 transform[0] = mOutputRectangle.
xMinimum();
233 transform[1] = mOutputRectangle.
width() / mNumOutputColumns;
235 transform[3] = mOutputRectangle.
yMaximum();
237 transform[5] = -mOutputRectangle.
height() / mNumOutputRows;
A rectangle specified with double values.
bool isNumber() const
Returns true if matrix is 1x1 (=scalar number)
void cancel()
Tells the internal routines that the current operation should be canceled. This should be run by the ...
Error allocating memory for result.
void setNodataValue(double d)
void setProgress(double progress)
Sets the current progress for the feedback object.
void canceled()
Internal routines can connect to this signal if they use event loop.
QgsRasterCalculator(const QString &formulaString, const QString &outputFile, const QString &outputFormat, const QgsRectangle &outputExtent, int nOutputColumns, int nOutputRows, const QVector< QgsRasterCalculatorEntry > &rasterEntries)
QgsRasterCalculator constructor.
int processCalculation(QgsFeedback *feedback=nullptr)
Starts the calculation and writes a new raster.
User canceled calculation.
void setCrs(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS, int srcDatumTransform=-1, int destDatumTransform=-1)
set source and destination CRS
Base class for feedback objects to be used for cancelation of something running in a worker thread...
bool calculate(QMap< QString, QgsRasterBlock * > &rasterData, QgsRasterMatrix &result, int row=-1) const
Calculates result of raster calculation (might be real matrix or single number).
void CORE_EXPORT fast_delete_and_close(dataset_unique_ptr &dataset, GDALDriverH driver, const QString &path)
Performs a fast close of an unwanted GDAL dataset handle by deleting the underlying data store...
Error reading input layer.
double width() const
Returns the width of the rectangle.
bool isEmpty() const
Returns true if block is empty, i.e.
Error creating output data file.
std::unique_ptr< void, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
void setPrecision(Precision precision)
QgsRasterProjector implements approximate projection support for it calculates grid of points in sour...
virtual bool setInput(QgsRasterInterface *input)
Set input.
bool isCanceled() const
Tells whether the operation has been canceled already.
This class represents a coordinate reference system (CRS).
QString toWkt() const
Returns a WKT representation of this CRS.
double * data()
Returns data array (but not ownership)
double xMinimum() const
Returns the x minimum value (left side of rectangle).
static QgsRasterCalcNode * parseRasterCalcString(const QString &str, QString &parserErrorMsg)
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Feedback object tailored for raster block reading.
double height() const
Returns the height of the rectangle.