QGIS API Documentation  2.99.0-Master (19b062c)
qgsrenderchecker.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrenderchecker.h - check maprender output against an expected image
3  --------------------------------------
4  Date : 18 Jan 2008
5  Copyright : (C) 2008 by Tim Sutton
6  email : tim @ linfiniti.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 
16 #ifndef QGSRENDERCHECKER_H
17 #define QGSRENDERCHECKER_H
18 
19 #include "qgis_core.h"
20 #include "qgis.h"
21 #include <QDir>
22 #include <QString>
23 #include <QRegExp>
24 #include <QList>
25 
26 #include "qgslogger.h"
27 #include "qgsmapsettings.h"
28 #include "qgsdartmeasurement.h"
29 
30 class QImage;
31 
38 class CORE_EXPORT QgsRenderChecker
39 {
40  public:
41 
45  QgsRenderChecker() = default;
46 
47  QString controlImagePath() const;
48 
49  QString report() { return mReport; }
50 
51  float matchPercent()
52  {
53  return static_cast<float>( mMismatchCount ) /
54  static_cast<float>( mMatchTarget ) * 100;
55  }
56  unsigned int mismatchCount() { return mMismatchCount; }
57  unsigned int matchTarget() { return mMatchTarget; }
58  //only records time for actual render part
59  int elapsedTime() { return mElapsedTime; }
60  void setElapsedTimeTarget( int target ) { mElapsedTimeTarget = target; }
61 
67  void setControlName( const QString &name );
68 
73  void setControlPathPrefix( const QString &name ) { mControlPathPrefix = name + '/'; }
74 
75  void setControlPathSuffix( const QString &name );
76 
78  QString imageToHash( const QString &imageFile );
79 
80  void setRenderedImage( const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
81 
88  QString renderedImage() { return mRenderedImageFile; }
89 
91  void setMapSettings( const QgsMapSettings &mapSettings );
92 
100  void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; }
101 
108  void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
109 
120  bool runTest( const QString &testName, unsigned int mismatchCount = 0 );
121 
133  bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString() );
134 
143  bool isKnownAnomaly( const QString &diffImageFile );
144 
149  static void drawBackground( QImage *image );
150 
156  QString expectedImageFile() const { return mExpectedImageFile; }
157 
165  void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
166 
174  QVector<QgsDartMeasurement> dartMeasurements() const { return mDashMessages; }
175 
176  protected:
177  QString mReport;
178  unsigned int mMatchTarget = 0;
179  int mElapsedTime = 0;
182 
183  private:
184  void emitDashMessage( const QgsDartMeasurement &dashMessage );
185  void emitDashMessage( const QString &name, QgsDartMeasurement::Type type, const QString &value );
186 
187  QString mControlName;
188  unsigned int mMismatchCount = 0;
189  unsigned int mColorTolerance = 0;
190  int mMaxSizeDifferenceX = 0;
191  int mMaxSizeDifferenceY = 0;
192  int mElapsedTimeTarget = 0;
193  QgsMapSettings mMapSettings;
194  QString mControlPathPrefix;
195  QString mControlPathSuffix;
196  QVector<QgsDartMeasurement> mDashMessages;
197  bool mBufferDashMessages = false;
198 }; // class QgsRenderChecker
199 
200 
209 inline bool compareWkt( const QString &a, const QString &b, double tolerance = 0.000001 )
210 {
211  QgsDebugMsg( QString( "a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ) );
212  QRegExp re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
213 
214  QString a0( a ), b0( b );
215  a0.replace( re, QStringLiteral( "#" ) );
216  b0.replace( re, QStringLiteral( "#" ) );
217 
218  QgsDebugMsg( QString( "a0:%1 b0:%2" ).arg( a0, b0 ) );
219 
220  if ( a0 != b0 )
221  return false;
222 
223  QList<double> al, bl;
224 
225  int pos;
226  for ( pos = 0; ( pos = re.indexIn( a, pos ) ) != -1; pos += re.matchedLength() )
227  {
228  al << re.cap( 0 ).toDouble();
229  }
230  for ( pos = 0; ( pos = re.indexIn( b, pos ) ) != -1; pos += re.matchedLength() )
231  {
232  bl << re.cap( 0 ).toDouble();
233  }
234 
235  if ( al.size() != bl.size() )
236  return false;
237 
238  for ( int i = 0; i < al.size(); i++ )
239  {
240  if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
241  return false;
242  }
243 
244  return true;
245 }
246 
247 #endif
void enableDashBuffering(bool enable)
Call this to enable internal buffering of dash messages.
QString expectedImageFile() const
Returns the path to the expected image file.
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
void setRenderedImage(const QString &imageFileName)
QString renderedImage()
The path of the rendered image can be retrieved through that method.
This is a helper class for unit tests that need to write an image and compare it to an expected resul...
void setSizeTolerance(int xTolerance, int yTolerance)
Sets the largest allowable difference in size between the rendered and the expected image...
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:227
The QgsMapSettings class contains configuration for rendering of the map.
void setControlPathPrefix(const QString &name)
Prefix where the control images are kept.
bool compareWkt(const QString &a, const QString &b, double tolerance=0.000001)
Compare two WKT strings with some tolerance.
unsigned int matchTarget()
QVector< QgsDartMeasurement > dartMeasurements() const
Get access to buffered dash messages.
void setColorTolerance(unsigned int colorTolerance)
Set tolerance for color components used by runTest() and compareImages().
void setElapsedTimeTarget(int target)
unsigned int mismatchCount()