1 /*************************************************************************** 2 qgshillshaderenderer.cpp 3 --------------------------------- 4 begin : May 2016 5 copyright : (C) 2016 by Nathan Woodrow 6 email : woodrow dot nathan at gmail dot com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef QGSHILLSHADERENDERER_H 19 #define QGSHILLSHADERENDERER_H 20 21 22 #include "qgis_core.h" 23 #include "qgis_sip.h" 24 #include "qgsrasterrenderer.h" 25 26 class QgsRasterBlock; 27 class QgsRectangle; 28 class QgsRasterInterface; 29 30 31 /** 32 * \ingroup core 33 * \brief A renderer for generating live hillshade models. 34 * \since QGIS 2.16 35 */ 36 class CORE_EXPORT QgsHillshadeRenderer : public QgsRasterRenderer 37 { 38 public: 39 40 /** 41 * \brief A renderer for generating live hillshade models. 42 * \param input The input raster interface 43 * \param band The band in the raster to use 44 * \param lightAzimuth The azimuth of the light source 45 * \param lightAltitude The altitude of the light source 46 */ 47 QgsHillshadeRenderer( QgsRasterInterface *input, int band, double lightAzimuth, double lightAltitude ); 48 49 QgsHillshadeRenderer *clone() const override SIP_FACTORY; 50 51 /** 52 * \brief Factory method to create a new renderer 53 * \param elem A DOM element to create the renderer from. 54 * \param input The raster input interface. 55 * \returns A new QgsHillshadeRenderer. 56 */ 57 static QgsRasterRenderer *create( const QDomElement &elem, QgsRasterInterface *input ) SIP_FACTORY; 58 59 void writeXml( QDomDocument &doc, QDomElement &parentElem ) const override; 60 61 QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback = nullptr ) override SIP_FACTORY; 62 63 QList<int> usesBands() const override; 64 65 void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props = QVariantMap() ) const override; 66 67 /** 68 * Returns the band used by the renderer 69 */ band()70 int band() const { return mBand; } 71 72 /** 73 * Sets the band used by the renderer. 74 * \see band 75 */ 76 void setBand( int bandNo ); 77 78 /** 79 * Returns the direction of the light over the raster between 0-360. 80 * \see setAzimuth() 81 */ azimuth()82 double azimuth() const { return mLightAzimuth; } 83 84 /** 85 * Returns the angle of the light source over the raster. 86 * \see setAltitude() 87 */ altitude()88 double altitude() const { return mLightAngle; } 89 90 /** 91 * Returns the Z scaling factor. 92 * \see setZFactor() 93 */ zFactor()94 double zFactor() const { return mZFactor; } 95 96 /** 97 * Returns TRUE if the renderer is using multi-directional hillshading. 98 * \see setMultiDirectional() 99 */ multiDirectional()100 bool multiDirectional() const { return mMultiDirectional; } 101 102 /** 103 * \brief Set the azimuth of the light source. 104 * \param azimuth The azimuth of the light source, between 0 and 360.0 105 * \see azimuth() 106 */ setAzimuth(double azimuth)107 void setAzimuth( double azimuth ) { mLightAzimuth = azimuth; } 108 109 /** 110 * \brief Set the altitude of the light source 111 * \param altitude the altitude 112 * \see altitude() 113 */ setAltitude(double altitude)114 void setAltitude( double altitude ) { mLightAngle = altitude; } 115 116 /** 117 * \brief Set the Z scaling factor of the result image. 118 * \param zfactor The z factor 119 * \see zFactor() 120 */ setZFactor(double zfactor)121 void setZFactor( double zfactor ) { mZFactor = zfactor; } 122 123 /** 124 * Sets whether to render using a multi-directional hillshade algorithm. 125 * \param isMultiDirectional set to TRUE to use multi directional rendering 126 * \see multiDirectional() 127 */ setMultiDirectional(bool isMultiDirectional)128 void setMultiDirectional( bool isMultiDirectional ) { mMultiDirectional = isMultiDirectional; } 129 130 private: 131 int mBand; 132 double mZFactor; 133 double mLightAngle; 134 double mLightAzimuth; 135 bool mMultiDirectional; 136 137 //! Calculates the first order derivative in x-direction according to Horn (1981) 138 double calcFirstDerX( double x11, double x21, double x31, double x12, double x22, double x32, double x13, double x23, double x33, double cellsize ); 139 140 //! Calculates the first order derivative in y-direction according to Horn (1981) 141 double calcFirstDerY( double x11, double x21, double x31, double x12, double x22, double x32, double x13, double x23, double x33, double cellsize ); 142 }; 143 144 #endif // QGSHILLSHADERENDERER_H 145