41   , mLightAngle( lightAngle )
    42   , mLightAzimuth( lightAzimuth )
    43   , mMultiDirectional( false )
    65   int band = elem.attribute( QStringLiteral( 
"band" ), QStringLiteral( 
"0" ) ).toInt();
    66   double azimuth = elem.attribute( QStringLiteral( 
"azimuth" ), QStringLiteral( 
"315" ) ).toDouble();
    67   double angle = elem.attribute( QStringLiteral( 
"angle" ), QStringLiteral( 
"45" ) ).toDouble();
    68   double zFactor = elem.attribute( QStringLiteral( 
"zfactor" ), QStringLiteral( 
"1" ) ).toDouble();
    69   bool multiDirectional = elem.attribute( QStringLiteral( 
"multidirection" ), QStringLiteral( 
"0" ) ).toInt();
    80   if ( parentElem.isNull() )
    85   QDomElement rasterRendererElem = doc.createElement( QStringLiteral( 
"rasterrenderer" ) );
    88   rasterRendererElem.setAttribute( QStringLiteral( 
"band" ), mBand );
    89   rasterRendererElem.setAttribute( QStringLiteral( 
"azimuth" ), QString::number( mLightAzimuth ) );
    90   rasterRendererElem.setAttribute( QStringLiteral( 
"angle" ), QString::number( mLightAngle ) );
    91   rasterRendererElem.setAttribute( QStringLiteral( 
"zfactor" ), QString::number( mZFactor ) );
    92   rasterRendererElem.setAttribute( QStringLiteral( 
"multidirection" ), QString::number( mMultiDirectional ) );
    93   parentElem.appendChild( rasterRendererElem );
    99   std::unique_ptr< QgsRasterBlock > outputBlock( 
new QgsRasterBlock() );
   102     QgsDebugMsg( QStringLiteral( 
"No input raster!" ) );
   103     return outputBlock.release();
   106   std::shared_ptr< QgsRasterBlock > inputBlock( 
mInput->
block( mBand, extent, width, height, feedback ) );
   108   if ( !inputBlock || inputBlock->isEmpty() )
   110     QgsDebugMsg( QStringLiteral( 
"No raster data!" ) );
   111     return outputBlock.release();
   114   std::shared_ptr< QgsRasterBlock > alphaBlock;
   119     if ( !alphaBlock || alphaBlock->isEmpty() )
   122       return outputBlock.release();
   127     alphaBlock = inputBlock;
   132     return outputBlock.release();
   138   float cellXSize = 
static_cast<float>( extent.
width() ) / width;
   139   float cellYSize = 
static_cast<float>( extent.
height() ) / height;
   140   float zenithRad = 
static_cast<float>( std::max( 0.0, 90 - mLightAngle ) * M_PI / 180.0 );
   141   float azimuthRad = 
static_cast<float>( -1 * mLightAzimuth * M_PI / 180.0 );
   142   float cosZenithRad = std::cos( zenithRad );
   143   float sinZenithRad = std::sin( zenithRad );
   146   float cos_alt_mul_z = cosZenithRad * 
static_cast<float>( mZFactor );
   147   float cos_az_mul_cos_alt_mul_z = std::cos( azimuthRad ) * cos_alt_mul_z;
   148   float sin_az_mul_cos_alt_mul_z = std::sin( azimuthRad ) * cos_alt_mul_z;
   149   float cos_az_mul_cos_alt_mul_z_mul_254 = 254.0f * cos_az_mul_cos_alt_mul_z;
   150   float sin_az_mul_cos_alt_mul_z_mul_254 = 254.0f * sin_az_mul_cos_alt_mul_z;
   151   float square_z = 
static_cast<float>( mZFactor * mZFactor );
   152   float sin_altRadians_mul_254 = 254.0f * sinZenithRad;
   155   float sin_altRadians_mul_127 = 127.0f * sinZenithRad;
   157   float cos225_az_mul_cos_alt_mul_z_mul_127 = -32.87001872802012f * cos_alt_mul_z;
   158   float cos_alt_mul_z_mul_127 = 127.0f * cos_alt_mul_z;
   170                   && inputBlock->dataTypeSize() <= 4 );
   176     if ( source.isEmpty() )
   184   std::chrono::time_point<std::chrono::system_clock> startTime( std::chrono::system_clock::now() );
   192       std::size_t inputDataTypeSize = inputBlock->dataTypeSize();
   193       std::size_t outputDataTypeSize = outputBlock->dataTypeSize();
   196       switch ( inputBlock->dataType() )
   198         case Qgis::DataType::Byte:
   199           typeName = QStringLiteral( 
"unsigned char" );
   201         case Qgis::DataType::UInt16:
   202           typeName = QStringLiteral( 
"unsigned int" );
   204         case Qgis::DataType::Int16:
   205           typeName = QStringLiteral( 
"short" );
   207         case Qgis::DataType::UInt32:
   208           typeName = QStringLiteral( 
"unsigned int" );
   210         case Qgis::DataType::Int32:
   211           typeName = QStringLiteral( 
"int" );
   213         case Qgis::DataType::Float32:
   214           typeName = QStringLiteral( 
"float" );
   217           throw QgsException( QStringLiteral( 
"Unsupported data type for OpenCL processing." ) );
   220       if ( inputBlock->dataType() != Qgis::DataType::Float32 )
   222         source.replace( QStringLiteral( 
"__global float *scanLine" ), QStringLiteral( 
"__global %1 *scanLine" ).arg( typeName ) );
   226       std::size_t scanLineWidth( inputBlock->width() + 2 );
   227       std::size_t inputSize( inputDataTypeSize * inputBlock->width() );
   230       std::size_t bufferWidth( width + 2 );
   231       std::size_t bufferSize( inputDataTypeSize * bufferWidth );
   236       std::unique_ptr<QgsRasterBlock> scanLine = qgis::make_unique<QgsRasterBlock>( inputBlock->dataType(), scanLineWidth, 1 );
   243       std::vector<float> rasterParams;
   244       rasterParams.push_back( inputBlock->noDataValue() );
   245       rasterParams.push_back( outputBlock->noDataValue() );
   246       rasterParams.push_back( mZFactor );
   247       rasterParams.push_back( cellXSize );
   248       rasterParams.push_back( cellYSize );
   249       rasterParams.push_back( static_cast<float>( 
mOpacity ) ); 
   252       rasterParams.push_back( cos_az_mul_cos_alt_mul_z_mul_254 ); 
   253       rasterParams.push_back( sin_az_mul_cos_alt_mul_z_mul_254 ); 
   254       rasterParams.push_back( square_z ); 
   255       rasterParams.push_back( sin_altRadians_mul_254 ); 
   258       rasterParams.push_back( sin_altRadians_mul_127 ); 
   259       rasterParams.push_back( cos225_az_mul_cos_alt_mul_z_mul_127 ); 
   260       rasterParams.push_back( cos_alt_mul_z_mul_127 ); 
   263       rasterParams.push_back( static_cast<float>( qBlue( defaultNodataColor ) ) ); 
   264       rasterParams.push_back( static_cast<float>( qGreen( defaultNodataColor ) ) ); 
   265       rasterParams.push_back( static_cast<float>( qRed( defaultNodataColor ) ) ); 
   266       rasterParams.push_back( static_cast<float>( qAlpha( defaultNodataColor ) ) / 255.0f ); 
   269       rasterParams.push_back( static_cast<float>( mMultiDirectional ) ); 
   271       cl::Buffer rasterParamsBuffer( queue, rasterParams.begin(), rasterParams.end(), 
true, 
false, nullptr );
   272       cl::Buffer scanLine1Buffer( ctx, CL_MEM_READ_ONLY, bufferSize, 
nullptr, 
nullptr );
   273       cl::Buffer scanLine2Buffer( ctx, CL_MEM_READ_ONLY, bufferSize, 
nullptr, 
nullptr );
   274       cl::Buffer scanLine3Buffer( ctx, CL_MEM_READ_ONLY, bufferSize, 
nullptr, 
nullptr );
   275       cl::Buffer *scanLineBuffer[3] = {&scanLine1Buffer, &scanLine2Buffer, &scanLine3Buffer};
   277       cl::Buffer resultLineBuffer( ctx, CL_MEM_WRITE_ONLY, outputDataTypeSize * width, 
nullptr, 
nullptr );
   279       static std::map<Qgis::DataType, cl::Program> programCache;
   280       cl::Program program = programCache[inputBlock->dataType()];
   281       if ( ! program.get() )
   285         program = programCache[inputBlock->dataType()];
   292       auto kernel =  cl::KernelFunctor <
   298                      > ( program, 
"processNineCellWindow" );
   302       std::vector<int> rowIndex = {0, 1, 2};
   304       for ( 
int i = 0; i < height; i++ )
   313           feedback->
setProgress( 100.0 * static_cast< double >( i ) / height );
   319           scanLine->resetNoDataValue();
   320           queue.enqueueWriteBuffer( scanLine1Buffer, CL_TRUE, 0, bufferSize, scanLine->bits( ) );
   322           memcpy( scanLine->bits( 0, 1 ), inputBlock->bits( i, 0 ), inputSize );
   323           queue.enqueueWriteBuffer( scanLine2Buffer, CL_TRUE, 0, bufferSize, scanLine->bits( ) ); 
   325           memcpy( scanLine->bits( 0, 1 ), inputBlock->bits( i + 1, 0 ), inputSize );
   326           queue.enqueueWriteBuffer( scanLine3Buffer, CL_TRUE, 0, bufferSize, scanLine->bits( ) ); 
   332           if ( i == inputBlock->height() - 1 )
   334             scanLine->resetNoDataValue();
   335             queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine->bits( ) );
   339             queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, inputDataTypeSize * 1 , inputSize, inputBlock->bits( i + 1, 0 ) );
   343         kernel( cl::EnqueueArgs(
   347                 *scanLineBuffer[rowIndex[0]],
   348                 *scanLineBuffer[rowIndex[1]],
   349                 *scanLineBuffer[rowIndex[2]],
   354         queue.enqueueReadBuffer( resultLineBuffer, CL_TRUE, 0, outputDataTypeSize * outputBlock->width( ), outputBlock->bits( i, 0 ) );
   355         std::rotate( rowIndex.begin(), rowIndex.begin() + 1, rowIndex.end() );
   358     catch ( cl::Error &e )
   373     for ( 
qgssize i = 0; i < static_cast<qgssize>( height ); i++ )
   376       for ( 
qgssize j = 0; j < static_cast<qgssize>( width ); j++ )
   379         if ( inputBlock->isNoData( i,  j ) )
   381           outputBlock->setColor( static_cast<int>( i ), static_cast<int>( j ), defaultNodataColor );
   385         qgssize iUp, iDown, jLeft, jRight;
   391         else if ( i < static_cast<qgssize>( height ) - 1 )
   407         else if ( j <  static_cast<qgssize>( width ) - 1 )
   429         x22 = inputBlock->value( i, j );
   431         x11 = inputBlock->isNoData( iUp, jLeft )  ? x22 : inputBlock->value( iUp, jLeft );
   432         x21 = inputBlock->isNoData( i, jLeft )     ? x22 : inputBlock->value( i, jLeft );
   433         x31 = inputBlock->isNoData( iDown, jLeft ) ? x22 : inputBlock->value( iDown, jLeft );
   435         x12 = inputBlock->isNoData( iUp, j )       ? x22 : inputBlock->value( iUp, j );
   437         x32 = inputBlock->isNoData( iDown, j )     ? x22 : inputBlock->value( iDown, j );
   439         x13 = inputBlock->isNoData( iUp, jRight )   ? x22 : inputBlock->value( iUp, jRight );
   440         x23 = inputBlock->isNoData( i, jRight )     ? x22 : inputBlock->value( i, jRight );
   441         x33 = inputBlock->isNoData( iDown, jRight ) ? x22 : inputBlock->value( iDown, jRight );
   443         double derX = calcFirstDerX( x11, x21, x31, x12, x22, x32, x13, x23, x33, cellXSize );
   444         double derY = calcFirstDerY( x11, x21, x31, x12, x22, x32, x13, x23, x33, cellYSize );
   449         if ( !mMultiDirectional )
   452           grayValue = qBound( 0.0, ( sin_altRadians_mul_254 -
   453                                      ( derY * cos_az_mul_cos_alt_mul_z_mul_254 -
   454                                        derX * sin_az_mul_cos_alt_mul_z_mul_254 ) ) /
   455                               std::sqrt( 1 + square_z * ( derX * derX + derY * derY ) )
   462           const float xx = derX * derX;
   463           const float yy = derY * derY;
   464           const float xx_plus_yy = xx + yy;
   466           if ( xx_plus_yy == 0.0 )
   468             grayValue = qBound( 0.0f, static_cast<float>( 1.0 + sin_altRadians_mul_254 ), 255.0f );
   473             float val225_mul_127 = sin_altRadians_mul_127 +
   474                                    ( derX - derY ) * cos225_az_mul_cos_alt_mul_z_mul_127;
   475             val225_mul_127 = ( val225_mul_127 <= 0.0 ) ? 0.0 : val225_mul_127;
   476             float val270_mul_127 = sin_altRadians_mul_127 -
   477                                    derX * cos_alt_mul_z_mul_127;
   478             val270_mul_127 = ( val270_mul_127 <= 0.0 ) ? 0.0 : val270_mul_127;
   479             float val315_mul_127 = sin_altRadians_mul_127 +
   480                                    ( derX + derY ) * cos225_az_mul_cos_alt_mul_z_mul_127;
   481             val315_mul_127 = ( val315_mul_127 <= 0.0 ) ? 0.0 : val315_mul_127;
   482             float val360_mul_127 = sin_altRadians_mul_127 -
   483                                    derY * cos_alt_mul_z_mul_127;
   484             val360_mul_127 = ( val360_mul_127 <= 0.0 ) ? 0.0 : val360_mul_127;
   487             const float weight_225 = 0.5 * xx_plus_yy - derX * derY;
   488             const float weight_270 = xx;
   489             const float weight_315 = xx_plus_yy - weight_225;
   490             const float weight_360 = yy;
   491             const float cang_mul_127 = (
   492                                          ( weight_225 * val225_mul_127 +
   493                                            weight_270 * val270_mul_127 +
   494                                            weight_315 * val315_mul_127 +
   495                                            weight_360 * val360_mul_127 ) / xx_plus_yy ) /
   496                                        ( 1 + square_z * xx_plus_yy );
   498             grayValue = qBound( 0.0f, 1.0f + cang_mul_127, 255.0f );
   509           currentAlpha *= alphaBlock->value( i ) / 255.0;
   514           outputBlock->setColor( i, j, qRgba( grayValue, grayValue, grayValue, 255 ) );
   518           outputBlock->setColor( i, j, qRgba( currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * 255 ) );
   527   if ( 
QgsSettings().value( QStringLiteral( 
"Map/logCanvasRefreshEvent" ), 
false ).toBool() )
   530                                .arg( useOpenCL ? QStringLiteral( 
"OpenCL" ) : QStringLiteral( 
"CPU" ) )
   533                                .arg( std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now() - startTime ).count() ),
   539   return outputBlock.release();
   562 double QgsHillshadeRenderer::calcFirstDerX( 
double x11, 
double x21, 
double x31, 
double x12, 
double x22, 
double x32, 
double x13, 
double x23, 
double x33, 
double cellsize )
   567   return ( ( x13 + x23 + x23 + x33 ) - ( x11 + x21 + x21 + x31 ) ) / ( 8 * cellsize );
   570 double QgsHillshadeRenderer::calcFirstDerY( 
double x11, 
double x21, 
double x31, 
double x12, 
double x22, 
double x32, 
double x13, 
double x23, 
double x33, 
double cellsize )
   575   return ( ( x31 + x32 + x32 + x33 ) - ( x11 + x12 + x12 + x13 ) ) / ( 8 * -cellsize );
   586   QDomNodeList elements = element.elementsByTagName( QStringLiteral( 
"sld:RasterSymbolizer" ) );
   587   if ( elements.size() == 0 )
   591   QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
   598     QDomElement channelSelectionElem = doc.createElement( QStringLiteral( 
"sld:ChannelSelection" ) );
   599     elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( 
"sld:Opacity" ) );
   600     if ( elements.size() != 0 )
   602       rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
   606       elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( 
"sld:Geometry" ) );
   607       if ( elements.size() != 0 )
   609         rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
   613         rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
   618     QDomElement channelElem = doc.createElement( QStringLiteral( 
"sld:GrayChannel" ) );
   619     channelSelectionElem.appendChild( channelElem );
   622     QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( 
"sld:SourceChannelName" ) );
   623     sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( 
band() ) ) );
   624     channelElem.appendChild( sourceChannelNameElem );
   628   QDomElement shadedReliefElem = doc.createElement( QStringLiteral( 
"sld:ShadedRelief" ) );
   629   rasterSymbolizerElem.appendChild( shadedReliefElem );
   632   QDomElement brightnessOnlyElem = doc.createElement( QStringLiteral( 
"sld:BrightnessOnly" ) );
   633   brightnessOnlyElem.appendChild( doc.createTextNode( QStringLiteral( 
"true" ) ) );
   634   shadedReliefElem.appendChild( brightnessOnlyElem );
   637   QDomElement reliefFactorElem = doc.createElement( QStringLiteral( 
"sld:ReliefFactor" ) );
   638   reliefFactorElem.appendChild( doc.createTextNode( QString::number( 
zFactor() ) ) );
   639   shadedReliefElem.appendChild( reliefFactorElem );
   642   QDomElement altitudeVendorOptionElem = doc.createElement( QStringLiteral( 
"sld:VendorOption" ) );
   643   altitudeVendorOptionElem.setAttribute( QStringLiteral( 
"name" ), QStringLiteral( 
"altitude" ) );
   644   altitudeVendorOptionElem.appendChild( doc.createTextNode( QString::number( 
altitude() ) ) );
   645   shadedReliefElem.appendChild( altitudeVendorOptionElem );
   648   QDomElement azimutVendorOptionElem = doc.createElement( QStringLiteral( 
"sld:VendorOption" ) );
   649   azimutVendorOptionElem.setAttribute( QStringLiteral( 
"name" ), QStringLiteral( 
"azimuth" ) );
   650   azimutVendorOptionElem.appendChild( doc.createTextNode( QString::number( 
azimuth() ) ) );
   651   shadedReliefElem.appendChild( azimutVendorOptionElem );
   654   QDomElement multidirectionalVendorOptionElem = doc.createElement( QStringLiteral( 
"sld:VendorOption" ) );
   655   multidirectionalVendorOptionElem.setAttribute( QStringLiteral( 
"name" ), QStringLiteral( 
"multidirectional" ) );
   656   multidirectionalVendorOptionElem.appendChild( doc.createTextNode( QString::number( 
multiDirectional() ) ) );
   657   shadedReliefElem.appendChild( multidirectionalVendorOptionElem );
 virtual int bandCount() const =0
Gets number of bands. 
 
static QString sourcePath()
Returns the base path to OpenCL program directory. 
 
A rectangle specified with double values. 
 
bool isEmpty() const
True if there are no entries in the pixel lists except the nodata value. 
 
static void setEnabled(bool enabled)
Set the OpenCL user setting to enabled. 
 
static QString sourceFromBaseName(const QString &baseName)
Returns the full path to a an OpenCL source file from the baseName ('.cl' extension is automatically ...
 
virtual void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs. 
 
void setMultiDirectional(bool isMultiDirectional)
Sets whether to render using a multi-directional hillshade algorithm. 
 
This class is a composition of two QSettings instances: 
 
virtual QgsRectangle extent() const
Gets the extent of the interface. 
 
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size. 
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference) 
 
void setProgress(double progress)
Sets the current progress for the feedback object. 
 
virtual QgsRasterInterface * input() const
Current input. 
 
static bool available()
Checks whether a suitable OpenCL platform and device is available on this system and initialize the Q...
 
QMap< QString, QString > QgsStringMap
 
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored) 
 
static cl::Context context()
Context factory. 
 
void setBand(int bandNo)
Sets the band used by the renderer. 
 
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value. 
 
void setZFactor(double zfactor)
Set the Z scaling factor of the result image. 
 
int band() const
Returns the band used by the renderer. 
 
static const QRgb NODATA_COLOR
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied. 
 
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer. 
 
bool multiDirectional() const
Returns true if the renderer is using multi-directional hillshading. 
 
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size. 
 
double width() const
Returns the width of the rectangle. 
 
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
 
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). 
 
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer. 
 
static bool enabled()
Returns true if OpenCL is enabled in the user settings. 
 
A renderer for generating live hillshade models. 
 
QgsHillshadeRenderer(QgsRasterInterface *input, int band, double lightAzimuth, double lightAltitude)
A renderer for generating live hillshade models. 
 
int mAlphaBand
Read alpha value from band. 
 
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses. 
 
Base class for processing filters like renderers, reprojector, resampler etc. 
 
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel. 
 
static QString errorText(const int errorCode)
Returns a string representation from an OpenCL errorCode. 
 
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
 
QgsHillshadeRenderer * clone() const override
Clone itself, create deep copy. 
 
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...
 
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs. 
 
bool isCanceled() const
Tells whether the operation has been canceled already. 
 
static QLatin1String LOGMESSAGE_TAG
OpenCL string for message logs. 
 
double altitude() const
Returns the angle of the light source over the raster. 
 
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml. 
 
double mOpacity
Global alpha value (0-1) 
 
double zFactor() const
Returns the Z scaling factor. 
 
double azimuth() const
Returns the direction of the light over the raster between 0-360. 
 
static cl::CommandQueue commandQueue()
Create an OpenCL command queue from the default context. 
 
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Factory method to create a new renderer. 
 
QgsRasterInterface * mInput
 
Feedback object tailored for raster block reading. 
 
Defines a QGIS exception class. 
 
Raster renderer pipe that applies colors to a raster. 
 
double height() const
Returns the height of the rectangle.