QGIS API Documentation  3.23.0-Master (eb871beae0)
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_sip.h"
21 
22 #include "qgslogger.h"
23 #include "qgsmapsettings.h"
24 #include "qgsdartmeasurement.h"
25 
26 #include <QDir>
27 #include <QString>
28 #include <QRegularExpression>
29 #include <QList>
30 
31 class QImage;
32 
39 class CORE_EXPORT QgsRenderChecker
40 {
41  public:
42 
47 
55  QString controlImagePath() const;
56 
63  void setControlImagePath( const QString &path );
64 
68  QString report() { return mReport; }
69 
73  float matchPercent() const
74  {
75  return static_cast<float>( mMismatchCount ) /
76  static_cast<float>( mMatchTarget ) * 100;
77  }
78 
82  unsigned int mismatchCount() const { return mMismatchCount; }
83 
87  unsigned int matchTarget() const { return mMatchTarget; }
88 
94  int elapsedTime() { return mElapsedTime; }
95  void setElapsedTimeTarget( int target ) { mElapsedTimeTarget = target; }
96 
104  void setControlName( const QString &name );
105 
110  void setControlExtension( const QString &extension ) { mControlExtension = extension; }
111 
116  void setControlPathPrefix( const QString &name ) { mControlPathPrefix = name + '/'; }
117 
118  void setControlPathSuffix( const QString &name );
119 
121  QString imageToHash( const QString &imageFile );
122 
126  void setRenderedImage( const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
127 
133  QString renderedImage() const { return mRenderedImageFile; }
134 
136  void setMapSettings( const QgsMapSettings &mapSettings );
137 
145  void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; }
146 
153  void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
154 
165  bool runTest( const QString &testName, unsigned int mismatchCount = 0 );
166 
178  bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString() );
179 
185  bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0 );
186 
195  bool isKnownAnomaly( const QString &diffImageFile );
196 
201  static void drawBackground( QImage *image );
202 
208  QString expectedImageFile() const { return mExpectedImageFile; }
209 
217  void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
218 
225  QVector<QgsDartMeasurement> dartMeasurements() const { return mDashMessages; }
226 
227  protected:
228  QString mReport;
229  unsigned int mMatchTarget = 0;
230  int mElapsedTime = 0;
233 
234  private:
235  void emitDashMessage( const QgsDartMeasurement &dashMessage );
236  void emitDashMessage( const QString &name, QgsDartMeasurement::Type type, const QString &value );
237 
238  QString mBasePath;
239 
240  QString mControlName;
241  unsigned int mMismatchCount = 0;
242  unsigned int mColorTolerance = 0;
243  int mMaxSizeDifferenceX = 0;
244  int mMaxSizeDifferenceY = 0;
245  int mElapsedTimeTarget = 0;
246  QgsMapSettings mMapSettings;
247  QString mControlExtension = QStringLiteral( "png" );
248  QString mControlPathPrefix;
249  QString mControlPathSuffix;
250  QVector<QgsDartMeasurement> mDashMessages;
251  bool mBufferDashMessages = false;
252 }; // class QgsRenderChecker
253 
254 
263 inline bool compareWkt( const QString &a, const QString &b, double tolerance = 0.000001 )
264 {
265  QgsDebugMsg( QStringLiteral( "a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ) );
266  const QRegularExpression re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
267 
268  QString a0( a ), b0( b );
269  a0.replace( re, QStringLiteral( "#" ) );
270  b0.replace( re, QStringLiteral( "#" ) );
271 
272  QgsDebugMsg( QStringLiteral( "a0:%1 b0:%2" ).arg( a0, b0 ) );
273 
274  if ( a0 != b0 )
275  return false;
276 
277  QList<double> al, bl;
278 
279  int pos = 0;
280  QRegularExpressionMatch match = re.match( a );
281  while ( match.hasMatch() )
282  {
283  al << match.captured( 0 ).toDouble();
284  pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
285  match = re.match( a, pos );
286  }
287  pos = 0;
288  match = re.match( b );
289  while ( match.hasMatch() )
290  {
291  bl << match.captured( 0 ).toDouble();
292  pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
293  match = re.match( b, pos );
294  }
295 
296  if ( al.size() != bl.size() )
297  return false;
298 
299  for ( int i = 0; i < al.size(); i++ )
300  {
301  if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
302  return false;
303  }
304 
305  return true;
306 }
307 
308 #endif
The QgsMapSettings class contains configuration for rendering of the map.
This is a helper class for unit tests that need to write an image and compare it to an expected resul...
void setControlExtension(const QString &extension)
Sets file extension for the control image.
int elapsedTime()
Returns the total elapsed time for the rendering test.
float matchPercent() const
Returns the percent of pixels which matched the control image.
unsigned int matchTarget() const
Returns the total number of pixels in the control image.
QString renderedImage() const
Returns the path of the rendered image generated by the test.
QVector< QgsDartMeasurement > dartMeasurements() const
Gets access to buffered dash messages.
void setElapsedTimeTarget(int target)
void setControlPathPrefix(const QString &name)
Sets the path prefix where the control images are kept.
void setRenderedImage(const QString &imageFileName)
Sets the file name of the rendered image generated by the test.
void setSizeTolerance(int xTolerance, int yTolerance)
Sets the largest allowable difference in size between the rendered and the expected image.
void enableDashBuffering(bool enable)
Call this to enable internal buffering of dash messages.
unsigned int mismatchCount() const
Returns the number of pixels which did not match the control image.
void setColorTolerance(unsigned int colorTolerance)
Set tolerance for color components used by runTest() and compareImages().
QString report()
Returns the HTML report describing the results of the test run.
QString expectedImageFile() const
Returns the path to the expected image file.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:1504
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
bool compareWkt(const QString &a, const QString &b, double tolerance=0.000001)
Compare two WKT strings with some tolerance.