Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgshillshadefilter.h - description
3 : : --------------------------------
4 : : begin : September 26th, 2011
5 : : copyright : (C) 2011 by Marco Hugentobler
6 : : email : marco dot hugentobler at sourcepole dot ch
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 : : #include "qgshillshadefilter.h"
19 : : #include <cmath>
20 : :
21 : 0 : QgsHillshadeFilter::QgsHillshadeFilter( const QString &inputFile, const QString &outputFile, const QString &outputFormat, double lightAzimuth,
22 : : double lightAngle )
23 : 0 : : QgsDerivativeFilter( inputFile, outputFile, outputFormat )
24 : 0 : , mLightAzimuth( static_cast<float>( lightAzimuth ) )
25 : 0 : , mLightAngle( static_cast<float>( lightAngle ) )
26 : 0 : , mCosZenithRad( std::cos( static_cast<float>( lightAngle * M_PI ) / 180.0f ) )
27 : 0 : , mSinZenithRad( std::sin( static_cast<float>( lightAngle * M_PI ) / 180.0f ) )
28 : 0 : , mAzimuthRad( static_cast<float>( lightAzimuth * M_PI ) / 180.0f )
29 : 0 : {
30 : 0 : }
31 : :
32 : 0 : float QgsHillshadeFilter::processNineCellWindow( float *x11, float *x21, float *x31,
33 : : float *x12, float *x22, float *x32,
34 : : float *x13, float *x23, float *x33 )
35 : : {
36 : :
37 : 0 : float derX = calcFirstDerX( x11, x21, x31, x12, x22, x32, x13, x23, x33 );
38 : 0 : float derY = calcFirstDerY( x11, x21, x31, x12, x22, x32, x13, x23, x33 );
39 : :
40 : 0 : if ( derX == mOutputNodataValue || derY == mOutputNodataValue )
41 : : {
42 : 0 : return mOutputNodataValue;
43 : : }
44 : :
45 : 0 : float slope_rad = std::atan( std::sqrt( derX * derX + derY * derY ) );
46 : 0 : float aspect_rad = 0;
47 : 0 : if ( derX == 0 && derY == 0 ) //aspect undefined, take a neutral value. Better solutions?
48 : : {
49 : 0 : aspect_rad = mAzimuthRad / 2.0f;
50 : 0 : }
51 : : else
52 : : {
53 : 0 : aspect_rad = M_PI + std::atan2( derX, derY );
54 : : }
55 : 0 : return std::max( 0.0f, 255.0f * ( ( mCosZenithRad * std::cos( slope_rad ) ) +
56 : 0 : ( mSinZenithRad * std::sin( slope_rad ) *
57 : 0 : std::cos( mAzimuthRad - aspect_rad ) ) ) );
58 : 0 : }
59 : :
60 : 0 : void QgsHillshadeFilter::setLightAzimuth( float azimuth )
61 : : {
62 : 0 : mLightAzimuth = azimuth;
63 : 0 : mAzimuthRad = azimuth * static_cast<float>( M_PI ) / 180.0f;
64 : 0 : }
65 : :
66 : 0 : void QgsHillshadeFilter::setLightAngle( float angle )
67 : : {
68 : 0 : mLightAngle = angle;
69 : 0 : mCosZenithRad = std::cos( angle * static_cast<float>( M_PI ) / 180.0f );
70 : 0 : mSinZenithRad = std::sin( angle * static_cast<float>( M_PI ) / 180.0f );
71 : 0 : }
72 : :
73 : : #ifdef HAVE_OPENCL
74 : :
75 : : void QgsHillshadeFilter::addExtraRasterParams( std::vector<float> ¶ms )
76 : : {
77 : :
78 : : params.push_back( mCosZenithRad ); // cos_zenith_rad 5
79 : : params.push_back( mSinZenithRad ); // sin_zenith_rad 6
80 : : params.push_back( mAzimuthRad ); // azimuth_rad 7
81 : :
82 : : }
83 : :
84 : : #endif
|