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 )
57 double targetGeoTransform[6];
61 QMap< QString, GDALRasterBandH > mInputRasterBands;
62 QMap< QString, QgsRasterMatrix* > inputScanLineData;
63 QVector< GDALDatasetH > mInputDatasets;
65 QVector<QgsRasterCalculatorEntry>::const_iterator it =
mRasterEntries.constBegin();
72 GDALDatasetH inputDataset = GDALOpen(
TO8F( it->raster->source() ), GA_ReadOnly );
73 if ( inputDataset == NULL )
79 double inputGeoTransform[6];
80 if ( GDALGetGeoTransform( inputDataset, inputGeoTransform ) == CE_None
81 && ( inputGeoTransform[1] < 0.0
82 || inputGeoTransform[2] != 0.0
83 || inputGeoTransform[4] != 0.0
84 || inputGeoTransform[5] > 0.0 ) )
86 GDALDatasetH vDataset = GDALAutoCreateWarpedVRT( inputDataset, NULL, NULL, GRA_NearestNeighbour, 0.2, NULL );
87 mInputDatasets.push_back( vDataset );
88 mInputDatasets.push_back( inputDataset );
89 inputDataset = vDataset;
93 mInputDatasets.push_back( inputDataset );
97 GDALRasterBandH inputRasterBand = GDALGetRasterBand( inputDataset, it->bandNumber );
98 if ( inputRasterBand == NULL )
104 double nodataValue = GDALGetRasterNoDataValue( inputRasterBand, &nodataSuccess );
106 mInputRasterBands.insert( it->ref, inputRasterBand );
112 if ( outputDriver == NULL )
126 if ( OSRSetFromUserInput( ogrSRS, rl->
crs().
authid().toUtf8().constData() ) == OGRERR_NONE )
128 OSRExportToWkt( ogrSRS, &crsWKT );
129 GDALSetProjection( outputDataset, crsWKT );
133 GDALSetProjection( outputDataset,
TO8( rl->
crs().
toWkt() ) );
135 OSRDestroySpatialReference( ogrSRS );
141 GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 );
143 float outputNodataValue = -FLT_MAX;
144 GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue );
146 float* resultScanLine = (
float * ) CPLMalloc(
sizeof(
float ) *
mNumOutputColumns );
163 if ( p && p->wasCanceled() )
169 QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin();
170 for ( ; bufferIt != inputScanLineData.end(); ++bufferIt )
172 double sourceTransformation[6];
173 GDALRasterBandH sourceRasterBand = mInputRasterBands[bufferIt.key()];
174 GDALGetGeoTransform( GDALGetBandDataset( sourceRasterBand ), sourceTransformation );
179 if ( calcNode->
calculate( inputScanLineData, resultMatrix ) )
181 bool resultIsNumber = resultMatrix.
isNumber();
184 if ( resultIsNumber )
189 calcData[j] = resultMatrix.
number();
194 calcData = resultMatrix.
data();
202 calcData[j] = outputNodataValue;
207 if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None )
209 qWarning(
"RasterIO error!" );
212 if ( resultIsNumber )
222 p->setValue( mNumOutputRows );
227 QMap< QString, QgsRasterMatrix* >::iterator bufferIt = inputScanLineData.begin();
228 for ( ; bufferIt != inputScanLineData.end(); ++bufferIt )
230 delete bufferIt.value();
232 inputScanLineData.clear();
234 QVector< GDALDatasetH >::iterator datasetIt = mInputDatasets.begin();
235 for ( ; datasetIt != mInputDatasets.end(); ++ datasetIt )
237 GDALClose( *datasetIt );
240 if ( p && p->wasCanceled() )
246 GDALClose( outputDataset );
247 CPLFree( resultScanLine );
257 char **driverMetadata;
260 GDALDriverH outputDriver = GDALGetDriverByName(
mOutputFormat.toLocal8Bit().data() );
262 if ( outputDriver == NULL )
267 driverMetadata = GDALGetMetadata( outputDriver, NULL );
268 if ( !CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) )
279 char **papszOptions = NULL;
281 if ( outputDataset == NULL )
283 return outputDataset;
287 double geotransform[6];
289 GDALSetGeoTransform( outputDataset, geotransform );
291 return outputDataset;
294 void QgsRasterCalculator::readRasterPart(
double* targetGeotransform,
int xOffset,
int yOffset,
int nCols,
int nRows,
double* sourceTransform, GDALRasterBandH sourceBand,
float* rasterBuffer )
299 GDALRasterIO( sourceBand, GF_Read, xOffset, yOffset, nCols, nRows, rasterBuffer, nCols, nRows, GDT_Float32, 0, 0 );
303 int sourceBandXSize = GDALGetRasterBandXSize( sourceBand );
304 int sourceBandYSize = GDALGetRasterBandYSize( sourceBand );
308 double nodataValue = GDALGetRasterNoDataValue( sourceBand, &nodataSuccess );
309 QgsRectangle targetRect( targetGeotransform[0] + targetGeotransform[1] * xOffset, targetGeotransform[3] + yOffset * targetGeotransform[5] + nRows * targetGeotransform[5]
310 , targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] * nCols, targetGeotransform[3] + yOffset * targetGeotransform[5] );
311 QgsRectangle sourceRect( sourceTransform[0], sourceTransform[3] + GDALGetRasterBandYSize( sourceBand ) * sourceTransform[5],
312 sourceTransform[0] + GDALGetRasterBandXSize( sourceBand )* sourceTransform[1], sourceTransform[3] );
318 int nPixels = nCols * nRows;
319 for (
int i = 0; i < nPixels; ++i )
321 rasterBuffer[i] = nodataValue;
327 int sourcePixelOffsetXMin = floor(( intersection.
xMinimum() - sourceTransform[0] ) / sourceTransform[1] );
328 int sourcePixelOffsetXMax = ceil(( intersection.
xMaximum() - sourceTransform[0] ) / sourceTransform[1] );
329 if ( sourcePixelOffsetXMax > sourceBandXSize )
331 sourcePixelOffsetXMax = sourceBandXSize;
333 int nSourcePixelsX = sourcePixelOffsetXMax - sourcePixelOffsetXMin;
335 int sourcePixelOffsetYMax = floor(( intersection.
yMaximum() - sourceTransform[3] ) / sourceTransform[5] );
336 int sourcePixelOffsetYMin = ceil(( intersection.
yMinimum() - sourceTransform[3] ) / sourceTransform[5] );
337 if ( sourcePixelOffsetYMin > sourceBandYSize )
339 sourcePixelOffsetYMin = sourceBandYSize;
341 int nSourcePixelsY = sourcePixelOffsetYMin - sourcePixelOffsetYMax;
342 float* sourceRaster = (
float * ) CPLMalloc(
sizeof(
float ) * nSourcePixelsX * nSourcePixelsY );
343 double sourceRasterXMin = sourceRect.
xMinimum() + sourcePixelOffsetXMin * sourceTransform[1];
344 double sourceRasterYMax = sourceRect.
yMaximum() + sourcePixelOffsetYMax * sourceTransform[5];
345 if ( GDALRasterIO( sourceBand, GF_Read, sourcePixelOffsetXMin, sourcePixelOffsetYMax, nSourcePixelsX, nSourcePixelsY,
346 sourceRaster, nSourcePixelsX, nSourcePixelsY, GDT_Float32, 0, 0 ) != CE_None )
349 CPLFree( sourceRaster );
350 int npixels = nRows * nCols;
351 for (
int i = 0; i < npixels; ++i )
353 rasterBuffer[i] = nodataValue;
360 double targetPixelXMin = targetGeotransform[0] + targetGeotransform[1] * xOffset + targetGeotransform[1] / 2.0;
361 double targetPixelY = targetGeotransform[3] + targetGeotransform[5] * yOffset + targetGeotransform[5] / 2.0;
362 int sourceIndexX, sourceIndexY;
364 for (
int i = 0; i < nRows; ++i )
366 targetPixelX = targetPixelXMin;
367 for (
int j = 0; j < nCols; ++j )
369 sx = ( targetPixelX - sourceRasterXMin ) / sourceTransform[1];
370 sourceIndexX = sx > 0 ? sx : floor( sx );
371 sy = ( targetPixelY - sourceRasterYMax ) / sourceTransform[5];
372 sourceIndexY = sy > 0 ? sy : floor( sy );
373 if ( sourceIndexX >= 0 && sourceIndexX < nSourcePixelsX
374 && sourceIndexY >= 0 && sourceIndexY < nSourcePixelsY )
376 rasterBuffer[j + i*nRows] = sourceRaster[ sourceIndexX + nSourcePixelsX * sourceIndexY ];
380 rasterBuffer[j + i*j] = nodataValue;
382 targetPixelX += targetGeotransform[1];
384 targetPixelY += targetGeotransform[5];
387 CPLFree( sourceRaster );
393 for (
int i = 0; i < 6; ++i )