31 , mLightAngle( lightAngle )
32 , mLightAzimuth( lightAzimuth )
33 , mMultiDirectional( false )
88 return block2( bandNo, extent, width, height );
103 if ( !inputBlock || inputBlock->
isEmpty() )
116 if ( !alphaBlock || alphaBlock->
isEmpty() )
126 alphaBlock = inputBlock;
138 double cellXSize = extent.
width() / double( width );
139 double cellYSize = extent.
height() / double( height );
140 double zenithRad = qMax( 0.0, 90 - mLightAngle ) *
M_PI / 180.0;
141 double azimuthRad = -1 * mLightAzimuth *
M_PI / 180.0;
142 double cosZenithRad = cos( zenithRad );
143 double sinZenithRad = sin( zenithRad );
146 double angle0Rad = ( -1 * mLightAzimuth - 45 - 45 * 0.5 ) *
M_PI / 180.0;
147 double angle1Rad = ( -1 * mLightAzimuth - 45 * 0.5 ) *
M_PI / 180.0;
148 double angle2Rad = ( -1 * mLightAzimuth + 45 * 0.5 ) *
M_PI / 180.0;
149 double angle3Rad = ( -1 * mLightAzimuth + 45 + 45 * 0.5 ) *
M_PI / 180.0;
161 outputBlock->
setColor( i, j, myDefaultColor );
165 qgssize iUp, iDown, jLeft, jRight;
171 else if ( i < (
qgssize )height - 1 )
187 else if ( j < (
qgssize )width - 1 )
209 x22 = inputBlock->
value( i, j );
211 x11 = inputBlock->
isNoData( iUp, jLeft ) ? x22 : inputBlock->
value( iUp, jLeft );
212 x21 = inputBlock->
isNoData( i, jLeft ) ? x22 : inputBlock->
value( i, jLeft );
213 x31 = inputBlock->
isNoData( iDown, jLeft ) ? x22 : inputBlock->
value( iDown, jLeft );
215 x12 = inputBlock->
isNoData( iUp, j ) ? x22 : inputBlock->
value( iUp, j );
217 x32 = inputBlock->
isNoData( iDown, j ) ? x22 : inputBlock->
value( iDown, j );
219 x13 = inputBlock->
isNoData( iUp, jRight ) ? x22 : inputBlock->
value( iUp, jRight );
220 x23 = inputBlock->
isNoData( i, jRight ) ? x22 : inputBlock->
value( i, jRight );
221 x33 = inputBlock->
isNoData( iDown, jRight ) ? x22 : inputBlock->
value( iDown, jRight );
223 double derX = calcFirstDerX( x11, x21, x31, x12, x22, x32, x13, x23, x33, cellXSize );
224 double derY = calcFirstDerY( x11, x21, x31, x12, x22, x32, x13, x23, x33, cellYSize );
226 double slopeRad = atan( mZFactor * sqrt( derX * derX + derY * derY ) );
227 double aspectRad = atan2( derX, -derY );
231 if ( !mMultiDirectional )
234 grayValue = qBound( 0.0, 255.0 * ( cosZenithRad * cos( slopeRad )
235 + sinZenithRad * sin( slopeRad )
236 * cos( azimuthRad - aspectRad ) ) , 255.0 );
241 double weight0 = sin( aspectRad - angle0Rad );
242 double weight1 = sin( aspectRad - angle1Rad );
243 double weight2 = sin( aspectRad - angle2Rad );
244 double weight3 = sin( aspectRad - angle3Rad );
245 weight0 = weight0 * weight0;
246 weight1 = weight1 * weight1;
247 weight2 = weight2 * weight2;
248 weight3 = weight3 * weight3;
250 double cosSlope = cosZenithRad * cos( slopeRad );
251 double sinSlope = sinZenithRad * sin( slopeRad );
252 double color0 = cosSlope + sinSlope * cos( angle0Rad - aspectRad ) ;
253 double color1 = cosSlope + sinSlope * cos( angle1Rad - aspectRad ) ;
254 double color2 = cosSlope + sinSlope * cos( angle2Rad - aspectRad ) ;
255 double color3 = cosSlope + sinSlope * cos( angle3Rad - aspectRad ) ;
256 grayValue = qBound( 0.0, 255 * ( weight0 * color0 + weight1 * color1 + weight2 * color2 + weight3 * color3 ) * 0.5, 255.0 );
266 currentAlpha *= alphaBlock->
value( i ) / 255.0;
271 outputBlock->
setColor( i, j, qRgba( grayValue, grayValue, grayValue, 255 ) );
275 outputBlock->
setColor( i, j, qRgba( currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * 255 ) );
308 double QgsHillshadeRenderer::calcFirstDerX(
double x11,
double x21,
double x31,
double x12,
double x22,
double x32,
double x13,
double x23,
double x33,
double cellsize )
313 return (( x13 + x23 + x23 + x33 ) - ( x11 + x21 + x21 + x31 ) ) / ( 8 * cellsize );
316 double QgsHillshadeRenderer::calcFirstDerY(
double x11,
double x21,
double x31,
double x12,
double x22,
double x32,
double x13,
double x23,
double x33,
double cellsize )
321 return (( x31 + x32 + x32 + x33 ) - ( x11 + x12 + x12 + x13 ) ) / ( 8 * -cellsize );
virtual int bandCount() const =0
Get number of bands.
void writeXML(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
A rectangle specified with double values.
QgsRasterBlock * block2(int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
QDomNode appendChild(const QDomNode &newChild)
void setMultiDirectional(bool isMultiDirectional)
Sets whether to render using a multi-directional hillshade algorithm.
QString attribute(const QString &name, const QString &defValue) const
int alphaValue(double, int theGlobalTransparency=255) const
Returns the transparency value for a single value Pixel.
virtual QgsRasterInterface * input() const
Current input.
void copyCommonProperties(const QgsRasterRenderer *other)
Copies common properties like opacity / transparency data from other renderer.
double toDouble(bool *ok) const
bool isNoData(int row, int column)
Check if value at position is no data.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
void readXML(const QDomElement &rendererElem) override
Sets base class members from xml.
virtual QgsRasterBlock * block2(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)
Read block of data using given extent and size.
void setBand(int bandNo)
Sets the band used by the renderer.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value.
void setZFactor(double zfactor)
Set the Z scaling factor of the result image.
int band() const
Returns the band used by the renderer.
bool setColor(int row, int column, QRgb color)
Set color on position.
static const QRgb NODATA_COLOR
QString number(int n, int base)
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
bool multiDirectional() const
Returns true if the renderer is using multi-directional hillshading.
void setAttribute(const QString &name, const QString &value)
double width() const
Width of the rectangle.
int toInt(bool *ok, int base) const
A renderer for generating live hillshade models.
bool isEmpty() const
Returns true if block is empty, i.e.
void _writeXML(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXML method of subclasses) ...
QgsHillshadeRenderer(QgsRasterInterface *input, int band, double lightAzimuth, double lightAltitude)
A renderer for generating live hillshade models.
int mAlphaBand
Read alpha value from band.
Base class for processing filters like renderers, reprojector, resampler etc.
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...
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
QgsHillshadeRenderer * clone() const override
Clone itself, create deep copy.
bool reset(QGis::DataType theDataType, int theWidth, int theHeight)
Reset block.
virtual QgsRectangle extent()
Get the extent of the interface.
double value(int row, int column) const
Read a single value if type of block is numeric.
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.
QDomElement createElement(const QString &tagName)
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Factory method to create a new renderer.
QgsRasterInterface * mInput
Feedback object tailored for raster block reading.
QgsRasterBlock * block(int bandNo, QgsRectangle const &extent, int width, int height) override
Read block of data using given extent and size.
Raster renderer pipe that applies colors to a raster.
double height() const
Height of the rectangle.