QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
31class QImage;
32
33#define DUMP_BASE64_IMAGES 0
34
41class CORE_EXPORT QgsRenderChecker
42{
43 Q_GADGET
44
45 public:
46
51
57 static QDir testReportDir();
58
65 static bool shouldGenerateReport();
66
74 QString controlImagePath() const;
75
82 void setControlImagePath( const QString &path );
83
92 QString report( bool ignoreSuccess = true ) const;
93
103 QString markdownReport( bool ignoreSuccess = true ) const;
104
108 float matchPercent() const
109 {
110 return static_cast<float>( mMismatchCount ) /
111 static_cast<float>( mMatchTarget ) * 100;
112 }
113
117 unsigned int mismatchCount() const { return mMismatchCount; }
118
122 unsigned int matchTarget() const { return mMatchTarget; }
123
129 int elapsedTime() const { return mElapsedTime; }
130 void setElapsedTimeTarget( int target ) { mElapsedTimeTarget = target; }
131
139 void setControlName( const QString &name );
140
145 void setControlExtension( const QString &extension ) { mControlExtension = extension; }
146
151 void setControlPathPrefix( const QString &name ) { mControlPathPrefix = name + '/'; }
152
153 void setControlPathSuffix( const QString &name );
154
156 QString imageToHash( const QString &imageFile );
157
161 void setRenderedImage( const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
162
168 void setExpectFail( bool expectFail ) { mExpectFail = expectFail; }
169
175 QString renderedImage() const { return mRenderedImageFile; }
176
177 void setMapSettings( const QgsMapSettings &mapSettings );
178
185 void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; }
186
192 void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
193
199 enum class Flag : int SIP_ENUM_BASETYPE( IntFlag )
200 {
201 AvoidExportingRenderedImage = 1 << 0,
202 };
203 Q_ENUM( Flag )
204
205
210 Q_DECLARE_FLAGS( Flags, Flag )
211 Q_FLAG( Flags )
212
224 bool runTest( const QString &testName, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
225
238 bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString(), QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
239
245 bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
246
257 Q_DECL_DEPRECATED bool isKnownAnomaly( const QString &diffImageFile ) SIP_DEPRECATED;
258
263 static void drawBackground( QImage *image );
264
270 QString expectedImageFile() const { return mExpectedImageFile; }
271
279 void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
280
287 QVector<QgsDartMeasurement> dartMeasurements() const { return mDashMessages; }
288
294 static QString sourcePath();
295
296 protected:
298 QString mReport;
301 unsigned int mMatchTarget = 0;
302 int mElapsedTime = 0;
305
306 private:
307 void emitDashMessage( const QgsDartMeasurement &dashMessage );
308 void emitDashMessage( const QString &name, QgsDartMeasurement::Type type, const QString &value );
309
310#if DUMP_BASE64_IMAGES
311 void dumpRenderedImageAsBase64();
312#endif
313
314 void performPostTestActions( Flags flags );
315
316 bool mResult = false;
317 bool mExpectFail = false;
318
319 QString mBasePath;
320
321 QString mControlName;
322 unsigned int mMismatchCount = 0;
323 unsigned int mColorTolerance = 0;
324 int mMaxSizeDifferenceX = 0;
325 int mMaxSizeDifferenceY = 0;
326 int mElapsedTimeTarget = 0;
327 QgsMapSettings mMapSettings;
328 QString mControlExtension = QStringLiteral( "png" );
329 QString mControlPathPrefix;
330 QString mControlPathSuffix;
331 bool mIsCiRun = false;
332 QVector<QgsDartMeasurement> mDashMessages;
333 bool mBufferDashMessages = false;
334 QString mDiffImageFile;
335
337};
338
340
341
349inline bool compareWkt( const QString &a, const QString &b, double tolerance = 0.000001 )
350{
351 QgsDebugMsgLevel( QStringLiteral( "a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ), 2 );
352 const thread_local QRegularExpression re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
353
354 QString a0( a ), b0( b );
355 a0.replace( re, QStringLiteral( "#" ) );
356 b0.replace( re, QStringLiteral( "#" ) );
357
358 QgsDebugMsgLevel( QStringLiteral( "a0:%1 b0:%2" ).arg( a0, b0 ), 2 );
359
360 if ( a0 != b0 )
361 return false;
362
363 QList<double> al, bl;
364
365 int pos = 0;
366 QRegularExpressionMatch match = re.match( a );
367 while ( match.hasMatch() )
368 {
369 al << match.captured( 0 ).toDouble();
370 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
371 match = re.match( a, pos );
372 }
373 match = re.match( b );
374 while ( match.hasMatch() )
375 {
376 bl << match.captured( 0 ).toDouble();
377 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
378 match = re.match( b, pos );
379 }
380
381 if ( al.size() != bl.size() )
382 return false;
383
384 for ( int i = 0; i < al.size(); i++ )
385 {
386 if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
387 return false;
388 }
389
390 return true;
391}
392
393#endif
The QgsMapSettings class contains configuration for rendering of the map.
This class allows checking rendered images against comparison images.
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.
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 mReport
HTML format report.
QFlags< Flag > Flags
Render checker flags.
Flag
Render checker flags.
int elapsedTime() const
Returns the total elapsed time for the rendering test.
QString mMarkdownReport
Markdown report.
QString renderedImage() const
Returns the path of the rendered image generated by the test.
void setElapsedTimeTarget(int target)
QVector< QgsDartMeasurement > dartMeasurements() const
Gets access to buffered dash messages.
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 setExpectFail(bool expectFail)
Sets whether the comparison is expected to fail.
void setColorTolerance(unsigned int colorTolerance)
Set tolerance for color components used by runTest() and compareImages().
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5207
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_ENUM_BASETYPE(type)
Definition: qgis_sip.h:278
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
bool compareWkt(const QString &a, const QString &b, double tolerance=0.000001)
Compare two WKT strings with some tolerance.
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsTextRendererUtils::CurvedTextFlags)