22 #include "cpl_string.h"
23 #include <QProgressDialog>
26 #include "gdalwarper.h"
27 #include <ogr_srs_api.h>
29 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
30 #define TO8(x) (x).toUtf8().constData()
31 #define TO8F(x) (x).toUtf8().constData()
33 #define TO8(x) (x).toLocal8Bit().constData()
34 #define TO8F(x) QFile::encodeName( x ).constData()
38 const QgsRectangle& outputExtent,
int nOutputColumns,
int nOutputRows,
const QVector<QgsRasterCalculatorEntry>& rasterEntries ): mFormulaString( formulaString ), mOutputFile( outputFile ), mOutputFormat( outputFormat ),
39 mOutputRectangle( outputExtent ), mNumOutputColumns( nOutputColumns ), mNumOutputRows( nOutputRows ), mRasterEntries( rasterEntries )
58 double targetGeoTransform[6];
62 QMap< QString, GDALRasterBandH > mInputRasterBands;
63 QMap< QString, QgsRasterMatrix* > inputScanLineData;
64 QVector< GDALDatasetH > mInputDatasets;
66 QVector<QgsRasterCalculatorEntry>::const_iterator it =
mRasterEntries.constBegin();
73 GDALDatasetH inputDataset = GDALOpen(
TO8F( it->raster->source() ), GA_ReadOnly );
74 if ( inputDataset == NULL )
80 double inputGeoTransform[6];
81 if ( GDALGetGeoTransform( inputDataset, inputGeoTransform ) == CE_None
82 && ( inputGeoTransform[1] < 0.0
83 || inputGeoTransform[2] != 0.0
84 || inputGeoTransform[4] != 0.0
85 || inputGeoTransform[5] > 0.0 ) )
87 GDALDatasetH vDataset = GDALAutoCreateWarpedVRT( inputDataset, NULL, NULL, GRA_NearestNeighbour, 0.2, NULL );
88 mInputDatasets.push_back( vDataset );
89 mInputDatasets.push_back( inputDataset );
90 inputDataset = vDataset;
94 mInputDatasets.push_back( inputDataset );
98 GDALRasterBandH inputRasterBand = GDALGetRasterBand( inputDataset, it->bandNumber );
99 if ( inputRasterBand == NULL )
105 double nodataValue = GDALGetRasterNoDataValue( inputRasterBand, &nodataSuccess );
107 mInputRasterBands.insert( it->ref, inputRasterBand );
113 if ( outputDriver == NULL )
127 if ( OSRSetFromUserInput( ogrSRS, rl->
crs().
authid().toUtf8().constData() ) == OGRERR_NONE )
129 OSRExportToWkt( ogrSRS, &crsWKT );
130 GDALSetProjection( outputDataset, crsWKT );
134 GDALSetProjection( outputDataset,
TO8( rl->
crs().
toWkt() ) );
136 OSRDestroySpatialReference( ogrSRS );
142 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 );
144 float outputNodataValue = -FLT_MAX;
145 GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue );
147 float* resultScanLine = (
float * ) CPLMalloc(
sizeof(
float ) *
mNumOutputColumns );
164 if ( p && p->wasCanceled() )
170 QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin();
171 for ( ; bufferIt != inputScanLineData.end(); ++bufferIt )
173 double sourceTransformation[6];
174 GDALRasterBandH sourceRasterBand = mInputRasterBands[bufferIt.key()];
175 GDALGetGeoTransform( GDALGetBandDataset( sourceRasterBand ), sourceTransformation );
180 if ( calcNode->
calculate( inputScanLineData, resultMatrix ) )
182 bool resultIsNumber = resultMatrix.
isNumber();
185 if ( resultIsNumber )
190 calcData[j] = resultMatrix.
number();
195 calcData = resultMatrix.
data();
203 calcData[j] = outputNodataValue;
208 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
210 qWarning(
"RasterIO error!" );
213 if ( resultIsNumber )
223 p->setValue( mNumOutputRows );
228 QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin();
229 for ( ; bufferIt != inputScanLineData.end(); ++bufferIt )
231 delete bufferIt.value();
233 inputScanLineData.clear();
235 QVector< GDALDatasetH >::iterator datasetIt = mInputDatasets.begin();
236 for ( ; datasetIt != mInputDatasets.end(); ++ datasetIt )
238 GDALClose( *datasetIt );
241 if ( p && p->wasCanceled() )
247 GDALClose( outputDataset );
248 CPLFree( resultScanLine );
258 char **driverMetadata;
261 GDALDriverH outputDriver = GDALGetDriverByName(
mOutputFormat.toLocal8Bit().data() );
263 if ( outputDriver == NULL )
268 driverMetadata = GDALGetMetadata( outputDriver, NULL );
269 if ( !CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) )
280 char **papszOptions = NULL;
282 if ( outputDataset == NULL )
284 return outputDataset;
288 double geotransform[6];
290 GDALSetGeoTransform( outputDataset, geotransform );
292 return outputDataset;
295 void QgsRasterCalculator::readRasterPart(
double* targetGeotransform,
int xOffset,
int yOffset,
int nCols,
int nRows,
double* sourceTransform, GDALRasterBandH sourceBand,
float* rasterBuffer )
300 GDALRasterIO( sourceBand, GF_Read, xOffset, yOffset, nCols, nRows, rasterBuffer, nCols, nRows, GDT_Float32, 0, 0 );
304 int sourceBandXSize = GDALGetRasterBandXSize( sourceBand );
305 int sourceBandYSize = GDALGetRasterBandYSize( sourceBand );
309 double nodataValue = GDALGetRasterNoDataValue( sourceBand, &nodataSuccess );
310 QgsRectangle targetRect( targetGeotransform[0] + targetGeotransform[1] * xOffset, targetGeotransform[3] + yOffset * targetGeotransform[5] + nRows * targetGeotransform[5]
311 , targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] * nCols, targetGeotransform[3] + yOffset * targetGeotransform[5] );
312 QgsRectangle sourceRect( sourceTransform[0], sourceTransform[3] + GDALGetRasterBandYSize( sourceBand ) * sourceTransform[5],
313 sourceTransform[0] + GDALGetRasterBandXSize( sourceBand )* sourceTransform[1], sourceTransform[3] );
319 int nPixels = nCols * nRows;
320 for (
int i = 0; i < nPixels; ++i )
322 rasterBuffer[i] = nodataValue;
328 int sourcePixelOffsetXMin = floor(( intersection.
xMinimum() - sourceTransform[0] ) / sourceTransform[1] );
329 int sourcePixelOffsetXMax = ceil(( intersection.
xMaximum() - sourceTransform[0] ) / sourceTransform[1] );
330 if ( sourcePixelOffsetXMax > sourceBandXSize )
332 sourcePixelOffsetXMax = sourceBandXSize;
334 int nSourcePixelsX = sourcePixelOffsetXMax - sourcePixelOffsetXMin;
336 int sourcePixelOffsetYMax = floor(( intersection.
yMaximum() - sourceTransform[3] ) / sourceTransform[5] );
337 int sourcePixelOffsetYMin = ceil(( intersection.
yMinimum() - sourceTransform[3] ) / sourceTransform[5] );
338 if ( sourcePixelOffsetYMin > sourceBandYSize )
340 sourcePixelOffsetYMin = sourceBandYSize;
342 int nSourcePixelsY = sourcePixelOffsetYMin - sourcePixelOffsetYMax;
343 float* sourceRaster = (
float * ) CPLMalloc(
sizeof(
float ) * nSourcePixelsX * nSourcePixelsY );
344 double sourceRasterXMin = sourceRect.
xMinimum() + sourcePixelOffsetXMin * sourceTransform[1];
345 double sourceRasterYMax = sourceRect.
yMaximum() + sourcePixelOffsetYMax * sourceTransform[5];
346 if ( GDALRasterIO( sourceBand, GF_Read, sourcePixelOffsetXMin, sourcePixelOffsetYMax, nSourcePixelsX, nSourcePixelsY,
347 sourceRaster, nSourcePixelsX, nSourcePixelsY, GDT_Float32, 0, 0 ) != CE_None )
350 CPLFree( sourceRaster );
351 int npixels = nRows * nCols;
352 for (
int i = 0; i < npixels; ++i )
354 rasterBuffer[i] = nodataValue;
361 double targetPixelXMin = targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] / 2.0;
362 double targetPixelY = targetGeotransform[3] + targetGeotransform[5] * yOffset + targetGeotransform[5] / 2.0;
363 int sourceIndexX, sourceIndexY;
365 for (
int i = 0; i < nRows; ++i )
367 targetPixelX = targetPixelXMin;
368 for (
int j = 0; j < nCols; ++j )
370 sx = ( targetPixelX - sourceRasterXMin ) / sourceTransform[1];
371 sourceIndexX = sx > 0 ? sx : floor( sx );
372 sy = ( targetPixelY - sourceRasterYMax ) / sourceTransform[5];
373 sourceIndexY = sy > 0 ? sy : floor( sy );
374 if ( sourceIndexX >= 0 && sourceIndexX < nSourcePixelsX
375 && sourceIndexY >= 0 && sourceIndexY < nSourcePixelsY )
377 rasterBuffer[j + i*nRows] = sourceRaster[ sourceIndexX + nSourcePixelsX * sourceIndexY ];
381 rasterBuffer[j + i*j] = nodataValue;
383 targetPixelX += targetGeotransform[1];
385 targetPixelY += targetGeotransform[5];
388 CPLFree( sourceRaster );
394 for (
int i = 0; i < 6; ++i )