1 /***************************************************************************
2      testziplayer.cpp
3      --------------------------------------
4     Date                 : Mon Jul 16 15:50:29 BRT 2012
5     Copyright            : (C) 2012 Etienne Tourigny
6     Email                : etourigny.dev@gmail.com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 #include "qgstest.h"
16 #include <QObject>
17 #include <QString>
18 #include <QApplication>
19 #include <QFileInfo>
20 
21 #include <qwt_global.h>
22 
23 //qgis includes...
24 #include <qgsapplication.h>
25 #include <qgsproviderregistry.h>
26 #include <qgsrasterlayer.h>
27 #include <qgsconfig.h>
28 #include "qgssinglebandgrayrendererwidget.h"
29 #include "qgsmultibandcolorrendererwidget.h"
30 #include "qgssinglebandpseudocolorrendererwidget.h"
31 #include "qgsrasterhistogramwidget.h"
32 
33 //qgis unit test includes
34 #include <qgsrenderchecker.h>
35 
36 
37 /**
38  * \ingroup UnitTests
39  * This is a unit test to verify that raster histogram works
40  */
41 class TestRasterHistogram : public QObject
42 {
43     Q_OBJECT
44 
TestRasterHistogram()45     TestRasterHistogram() {}
46 
47   private:
48 
49     QString mDataDir;
50     QString mTestPrefix;
51     int mWidth, mHeight, mImageQuality;
52     QgsRasterLayer *mRasterLayer = nullptr;
53     QgsSingleBandGrayRendererWidget *mGrayRendererWidget = nullptr;
54     QgsMultiBandColorRendererWidget *mRGBRendererWidget = nullptr;
55     QgsSingleBandPseudoColorRendererWidget *mPseudoRendererWidget = nullptr;
56     QgsRasterHistogramWidget *mHistogramWidget = nullptr;
57     QString mReport;
58 
59     bool openLayer( const QString &fileName );
60     void closeLayer();
61     bool saveImage( const QString &fileName );
62     int testFile( QString testName,
63                   QString rendererName,
64                   QgsRasterRendererWidget *rendererWidget,
65                   QStringList actionsList = QStringList(),
66                   int selectedBand = -1 );
67 
68   private slots:
69 
70     // init / cleanup
71     void initTestCase();// will be called before the first testfunction is executed.
72     void cleanupTestCase();// will be called after the last testfunction was executed.
init()73     void init() {};// will be called before each testfunction is executed.
cleanup()74     void cleanup() {};// will be called after every testfunction.
75 
76     // tests
77     void testGray1();
78     void testGray2();
79     void testRGB1();
80     void testRGB2();
81     void testRGB3();
82     void testRGB4();
83     void testPseudo1();
84 };
85 
86 
87 // slots
88 
initTestCase()89 void TestRasterHistogram::initTestCase()
90 {
91   QgsApplication::init();
92   QgsApplication::initQgis();
93   QString mySettings = QgsApplication::showSettings();
94   mySettings = mySettings.replace( "\n", "<br />" );
95 
96   // output test environment
97   QgsApplication::showSettings();
98   qDebug() << "QWT version:   " << QWT_VERSION_STR;
99   mTestPrefix = "histogram_qwt6";
100 
101   // save data dir
102   mDataDir = QString( TEST_DATA_DIR ) + "/";
103   mWidth = mHeight = 400;
104   mImageQuality = -1;
105   // Set up the QgsSettings environment
106   QCoreApplication::setOrganizationName( "QGIS" );
107   QCoreApplication::setOrganizationDomain( "qgis.org" );
108   QCoreApplication::setApplicationName( "QGIS-TEST" );
109 
110   // setup objects
111   mRasterLayer = 0;
112   mGrayRendererWidget = 0;
113   mRGBRendererWidget = 0;
114   mPseudoRendererWidget = 0;
115   mHistogramWidget = 0;
116 
117   mReport += "<h1>Raster Histogram Tests</h1>\n";
118   mReport += "<p>" + mySettings + "</p>";
119 
120   // remove .aux.xml file to make sure histogram computation is fresh
121   QFile::remove( mDataDir + "/landsat.tif.aux.xml" );
122   QVERIFY( openLayer( "landsat.tif" ) );
123 }
124 
cleanupTestCase()125 void TestRasterHistogram::cleanupTestCase()
126 {
127   closeLayer();
128   // remove .aux.xml file to make sure histogram computation is fresh
129   QFile::remove( mDataDir + "/landsat.tif.aux.xml" );
130   QString myReportFile = QDir::tempPath() + "/qgishistotest.html";
131   QFile myFile( myReportFile );
132   if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
133   {
134     QTextStream myQTextStream( &myFile );
135     myQTextStream << mReport;
136     myFile.close();
137     //QDesktopServices::openUrl( "file:///" + myReportFile );
138   }
139 }
140 
141 // grayscale, all bands
testGray1()142 void TestRasterHistogram::testGray1()
143 {
144   QStringList actionsList;
145   QVERIFY( testFile( "gray1", "singlebandgray", mGrayRendererWidget, actionsList ) >= 0 );
146 }
147 
148 // grayscale, gray band
testGray2()149 void TestRasterHistogram::testGray2()
150 {
151   QStringList actionsList( "Show RGB" );
152   QVERIFY( testFile( "gray2", "singlebandgray", mGrayRendererWidget, actionsList ) >= 0 );
153 }
154 
155 // RGB, all bands
testRGB1()156 void TestRasterHistogram::testRGB1()
157 {
158   QStringList actionsList;
159   QVERIFY( testFile( "rgb1", "multibandcolor", mRGBRendererWidget, actionsList ) >= 0 );
160 }
161 
162 // RGB, RGB bands
testRGB2()163 void TestRasterHistogram::testRGB2()
164 {
165   QStringList actionsList( "Show RGB" );
166   QVERIFY( testFile( "rgb2", "multibandcolor", mRGBRendererWidget, actionsList ) >= 0 );
167 }
168 
169 // RGB, band 5
testRGB3()170 void TestRasterHistogram::testRGB3()
171 {
172   QStringList actionsList( "Show selected" );
173   QVERIFY( testFile( "rgb3", "multibandcolor", mRGBRendererWidget, actionsList, 5 ) >= 0 );
174 }
175 
176 // RGB, all bands + markers, load 1 stddev
testRGB4()177 void TestRasterHistogram::testRGB4()
178 {
179   QStringList actionsList;
180   actionsList << "Show selected" << "Show markers" << "Load 1 stddev";
181   QVERIFY( testFile( "rgb4", "multibandcolor", mRGBRendererWidget, actionsList ) >= 0 );
182 }
183 
184 // pseudocolor, all bands
testPseudo1()185 void TestRasterHistogram::testPseudo1()
186 {
187   QStringList actionsList;
188   QVERIFY( testFile( "pseudo1", "singlebandpseudocolor", mPseudoRendererWidget, actionsList ) >= 0 );
189 }
190 
191 // helper methods
192 
openLayer(const QString & fileName)193 bool TestRasterHistogram::openLayer( const QString &fileName )
194 {
195   mRasterLayer = new QgsRasterLayer( mDataDir + "/" + fileName, fileName );
196   if ( ! mRasterLayer )
197     return false;
198   mGrayRendererWidget = new QgsSingleBandGrayRendererWidget( mRasterLayer );
199   mRGBRendererWidget = new QgsMultiBandColorRendererWidget( mRasterLayer );
200   mPseudoRendererWidget = new QgsSingleBandPseudoColorRendererWidget( mRasterLayer );
201   mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, 0 );
202   mHistogramWidget->computeHistogram( true );
203   return true;
204 }
205 
closeLayer()206 void TestRasterHistogram::closeLayer()
207 {
208   if ( mHistogramWidget )
209   {
210     delete mHistogramWidget;
211     mHistogramWidget = 0;
212   }
213   if ( mGrayRendererWidget )
214   {
215     delete mGrayRendererWidget;
216     mGrayRendererWidget = 0;
217   }
218   if ( mRGBRendererWidget )
219   {
220     delete mRGBRendererWidget;
221     mRGBRendererWidget = 0;
222   }
223   if ( mPseudoRendererWidget )
224   {
225     delete mPseudoRendererWidget;
226     mPseudoRendererWidget = 0;
227   }
228   if ( mRasterLayer )
229   {
230     delete mRasterLayer;
231     mRasterLayer = 0;
232   }
233 }
234 
saveImage(const QString & fileName)235 bool TestRasterHistogram::saveImage( const QString &fileName )
236 {
237   return mHistogramWidget->histoSaveAsImage( fileName, mWidth, mHeight, mImageQuality );
238 }
239 
240 // test resulting image file - relax this test because there are too many possible outputs depending on machine
241 // 1 means pass, 0 means warning (different images), -1 means fail (no image output)
testFile(QString testType,QString rendererName,QgsRasterRendererWidget * rendererWidget,QStringList actionsList,int selectedBand)242 int TestRasterHistogram::testFile( QString testType,
243                                    QString rendererName, QgsRasterRendererWidget *rendererWidget,
244                                    QStringList actionsList, int selectedBand )
245 {
246   if ( mRasterLayer == 0 )
247   {
248     QWARN( QString( "Invalid raster layer" ).toLocal8Bit().data() );
249     return false;
250   }
251 
252   // reset histogram widget to clear previous state
253   if ( mHistogramWidget )
254     delete mHistogramWidget;
255   mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, 0 );
256 
257   // setup histogram widget
258   mHistogramWidget->setRendererWidget( rendererName, rendererWidget );
259   foreach ( QString actionName, actionsList )
260   {
261     mHistogramWidget->histoAction( actionName );
262   }
263   if ( selectedBand != -1 )
264   {
265     mHistogramWidget->setSelectedBand( selectedBand );
266   }
267   QString fileName = QDir::tempPath() + "/" +
268                      testType + "_result.png";
269   if ( ! saveImage( fileName ) )
270   {
271     QWARN( QString( "Did not save image file " + fileName ).toLocal8Bit().data() );
272     return -1;
273   }
274   mReport += "<h2>" + testType + "</h2>\n";
275 
276   QgsRenderChecker myChecker;
277   myChecker.setControlPathPrefix( mTestPrefix );
278   myChecker.setControlName( "expected_histo_" + testType );
279   //  myChecker.setMapRenderer( mpMapRenderer );
280   bool myResultFlag = myChecker.compareImages( testType, 0, fileName );
281   mReport += "\n\n\n" + myChecker.report();
282 
283   // return myResultFlag;
284   if ( ! myResultFlag )
285   {
286     QWARN( QString( "Test %1 failed with file %2 " ).arg( testType ).arg( fileName ).toLocal8Bit().data() );
287     return 0;
288   }
289   return 1;
290 }
291 
292 
293 QGSTEST_MAIN( TestRasterHistogram )
294 #include "testqgsrasterhistogram.moc"
295