21 #include "cpl_string.h"    38   : mInputFile( inputFile )
    39   , mOutputFile( outputFile )
    40   , mOutputFormat( outputFormat )
    53     if ( ! source.isEmpty() )
    57         QgsDebugMsg( QObject::tr( 
"Running OpenCL program: %1" ).arg( openClProgramBaseName( ) ) );
    58         return processRasterGPU( source, feedback );
    60       catch ( cl::Error &e )
    62         QString err = QObject::tr( 
"Error running OpenCL program: %1 - %2" ).arg( e.what( ), 
QgsOpenClUtils::errorText( e.err( ) ) );
    69       QString err = QObject::tr( 
"Error loading OpenCL program sources" );
    77     return processRasterCPU( feedback );
    81   return processRasterCPU( feedback );
    90     nCellsX = GDALGetRasterXSize( inputDataset.get() );
    91     nCellsY = GDALGetRasterYSize( inputDataset.get() );
    94     if ( GDALGetRasterCount( inputDataset.get() ) < 1 )
   102 GDALDriverH QgsNineCellFilter::openOutputDriver()
   105   GDALDriverH outputDriver = GDALGetDriverByName( 
mOutputFormat.toLocal8Bit().data() );
   128   int xSize = GDALGetRasterXSize( inputDataset );
   129   int ySize = GDALGetRasterYSize( inputDataset );
   132   char **papszOptions = 
nullptr;
   134   if ( !outputDataset )
   136     return outputDataset;
   140   double geotransform[6];
   141   if ( GDALGetGeoTransform( inputDataset, geotransform ) != CE_None )
   145   GDALSetGeoTransform( outputDataset.get(), geotransform );
   149   if ( mCellSizeX < 0 )
   159   const char *projection = GDALGetProjectionRef( inputDataset );
   160   GDALSetProjection( outputDataset.get(), projection );
   162   return outputDataset;
   168 int QgsNineCellFilter::processRasterGPU( 
const QString &source, 
QgsFeedback *feedback )
   182   GDALDriverH outputDriver = openOutputDriver();
   189   if ( !outputDataset )
   195   GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset.get(), 1 );
   202   GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
   203   if ( !outputRasterBand )
   208   GDALSetRasterNoDataValue( outputRasterBand, -9999 );
   225   std::vector<float> rasterParams;
   235   addExtraRasterParams( rasterParams );
   237   std::size_t bufferSize( 
sizeof( 
float ) * ( xSize + 2 ) );
   238   std::size_t inputSize( 
sizeof( 
float ) * ( xSize ) );
   240   cl::Buffer rasterParamsBuffer( queue, rasterParams.begin(), rasterParams.end(), 
true, 
false, nullptr );
   241   cl::Buffer scanLine1Buffer( ctx, CL_MEM_READ_ONLY, bufferSize, 
nullptr, 
nullptr );
   242   cl::Buffer scanLine2Buffer( ctx, CL_MEM_READ_ONLY, bufferSize, 
nullptr, 
nullptr );
   243   cl::Buffer scanLine3Buffer( ctx, CL_MEM_READ_ONLY, bufferSize, 
nullptr, 
nullptr );
   244   cl::Buffer *scanLineBuffer[3] = {&scanLine1Buffer, &scanLine2Buffer, &scanLine3Buffer};
   245   cl::Buffer resultLineBuffer( ctx, CL_MEM_WRITE_ONLY, inputSize, 
nullptr, 
nullptr );
   251   auto kernel = cl::KernelFunctor <
   257                 > ( program, 
"processNineCellWindow" );
   260   std::vector<int> rowIndex = {0, 1, 2};
   263   for ( 
int i = 0; i < ySize; ++i )
   272       feedback->
setProgress( 100.0 * static_cast< double >( i ) / ySize );
   279       for ( 
int a = 0; a < xSize + 2 ; ++a )
   283       queue.enqueueWriteBuffer( scanLine1Buffer, CL_TRUE, 0, bufferSize, scanLine.
get() );
   286       if ( GDALRasterIO( rasterBand, GF_Read, 0, i, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   288         QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   290       queue.enqueueWriteBuffer( scanLine2Buffer, CL_TRUE, 0, bufferSize, scanLine.
get() );
   293       if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   295         QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   297       queue.enqueueWriteBuffer( scanLine3Buffer, CL_TRUE, 0, bufferSize, scanLine.
get() );
   303       if ( i == ySize - 1 ) 
   305         for ( 
int a = 0; a < xSize + 2; ++a )
   309         queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.
get() ); 
   314         if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   316           QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   318         queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.
get() ); 
   322     kernel( cl::EnqueueArgs(
   326             *scanLineBuffer[rowIndex[0]],
   327             *scanLineBuffer[rowIndex[1]],
   328             *scanLineBuffer[rowIndex[2]],
   333     queue.enqueueReadBuffer( resultLineBuffer, CL_TRUE, 0, inputSize, resultLine.
get() );
   335     if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, xSize, 1, resultLine.
get(), xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   337       QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   339     std::rotate( rowIndex.begin(), rowIndex.begin() + 1, rowIndex.end() );
   354 int QgsNineCellFilter::processRasterCPU( 
QgsFeedback *feedback )
   368   GDALDriverH outputDriver = openOutputDriver();
   375   if ( !outputDataset )
   381   GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset.get(), 1 );
   388   GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset.get(), 1 );
   389   if ( !outputRasterBand )
   394   GDALSetRasterNoDataValue( outputRasterBand, -9999 );
   403   std::size_t bufferSize( 
sizeof( 
float ) * ( xSize + 2 ) );
   404   float *scanLine1 = ( 
float * ) CPLMalloc( bufferSize );
   405   float *scanLine2 = ( 
float * ) CPLMalloc( bufferSize );
   406   float *scanLine3 = ( 
float * ) CPLMalloc( bufferSize );
   408   float *resultLine = ( 
float * ) CPLMalloc( 
sizeof( 
float ) * xSize );
   411   for ( 
int yIndex = 0; yIndex < ySize; ++yIndex )
   420       feedback->
setProgress( 100.0 * static_cast< double >( yIndex ) / ySize );
   426       for ( 
int a = 0; a < xSize + 2 ; ++a )
   431       if ( GDALRasterIO( rasterBand, GF_Read, 0, 0, xSize, 1, &scanLine2[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   433         QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   439       CPLFree( scanLine1 );
   440       scanLine1 = scanLine2;
   441       scanLine2 = scanLine3;
   442       scanLine3 = ( 
float * ) CPLMalloc( bufferSize );
   446     if ( yIndex == ySize - 1 ) 
   448       for ( 
int a = 0; a < xSize + 2; ++a )
   455       if ( GDALRasterIO( rasterBand, GF_Read, 0, yIndex + 1, xSize, 1, &scanLine3[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   457         QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   468     for ( 
int xIndex = 0; xIndex < xSize ; ++xIndex )
   471       resultLine[ xIndex ] = 
processNineCellWindow( &scanLine1[ xIndex ], &scanLine1[ xIndex + 1 ], &scanLine1[ xIndex + 2 ],
   472                              &scanLine2[ xIndex ], &scanLine2[ xIndex + 1 ], &scanLine2[ xIndex + 2 ],
   473                              &scanLine3[ xIndex ], &scanLine3[ xIndex + 1 ], &scanLine3[ xIndex + 2 ] );
   477     if ( GDALRasterIO( outputRasterBand, GF_Write, 0, yIndex, xSize, 1, resultLine, xSize, 1, GDT_Float32, 0, 0 ) != CE_None )
   479       QgsDebugMsg( QStringLiteral( 
"Raster IO Error" ) );
   483   CPLFree( resultLine );
   484   CPLFree( scanLine1 );
   485   CPLFree( scanLine2 );
   486   CPLFree( scanLine3 );
 Tiny smart-pointer-like wrapper around CPLMalloc and CPLFree: this is needed because OpenCL C++ API m...
 
static QString sourceFromBaseName(const QString &baseName)
Returns the full path to a an OpenCL source file from the baseName ('.cl' extension is automatically ...
 
void setProgress(double progress)
Sets the current progress for the feedback object. 
 
static bool available()
Checks whether a suitable OpenCL platform and device is available on this system and initialize the Q...
 
int processRaster(QgsFeedback *feedback=nullptr)
Starts the calculation, reads from mInputFile and stores the result in mOutputFile. 
 
static bool supportsRasterCreate(GDALDriverH driver)
Reads whether a driver supports GDALCreate() for raster purposes. 
 
static cl::Context context()
Context factory. 
 
Base class for feedback objects to be used for cancelation of something running in a worker thread...
 
virtual float processNineCellWindow(float *x11, float *x21, float *x31, float *x12, float *x22, float *x32, float *x13, float *x23, float *x33)=0
Calculates output value from nine input values. 
 
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...
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary). 
 
static bool enabled()
Returns true if OpenCL is enabled in the user settings. 
 
Custom exception class for processing related exceptions. 
 
static QString errorText(const int errorCode)
Returns a string representation from an OpenCL errorCode. 
 
static Q_DECL_DEPRECATED cl::Program buildProgram(const cl::Context &context, const QString &source, ExceptionBehavior exceptionBehavior=Catch)
Build the program from source in the given context and depending on exceptionBehavior can throw or ca...
 
float mOutputNodataValue
The nodata value of the output layer. 
 
bool isCanceled() const
Tells whether the operation has been canceled already. 
 
static QLatin1String LOGMESSAGE_TAG
OpenCL string for message logs. 
 
QgsNineCellFilter(const QString &inputFile, const QString &outputFile, const QString &outputFormat)
Constructor that takes input file, output file and output format (GDAL string) 
 
double mZFactor
Scale factor for z-value if x-/y- units are different to z-units (111120 for degree->meters and 37040...
 
float mInputNodataValue
The nodata value of the input layer. 
 
std::unique_ptr< std::remove_pointer< GDALDatasetH >::type, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset. 
 
static cl::CommandQueue commandQueue()
Create an OpenCL command queue from the default context.