QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
90 QString report( bool ignoreSuccess = true ) const;
91
95 float matchPercent() const
96 {
97 return static_cast<float>( mMismatchCount ) /
98 static_cast<float>( mMatchTarget ) * 100;
99 }
100
104 unsigned int mismatchCount() const { return mMismatchCount; }
105
109 unsigned int matchTarget() const { return mMatchTarget; }
110
116 int elapsedTime() const { return mElapsedTime; }
117 void setElapsedTimeTarget( int target ) { mElapsedTimeTarget = target; }
118
126 void setControlName( const QString &name );
127
132 void setControlExtension( const QString &extension ) { mControlExtension = extension; }
133
138 void setControlPathPrefix( const QString &name ) { mControlPathPrefix = name + '/'; }
139
140 void setControlPathSuffix( const QString &name );
141
143 QString imageToHash( const QString &imageFile );
144
148 void setRenderedImage( const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
149
155 void setExpectFail( bool expectFail ) { mExpectFail = expectFail; }
156
162 QString renderedImage() const { return mRenderedImageFile; }
163
165 void setMapSettings( const QgsMapSettings &mapSettings );
166
174 void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; }
175
182 void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
183
189 enum class Flag : int
190 {
191 AvoidExportingRenderedImage = 1 << 0,
192 };
193 Q_ENUM( Flag )
194
195
200 Q_DECLARE_FLAGS( Flags, Flag )
201 Q_FLAG( Flags )
202
203
214 bool runTest( const QString &testName, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
215
228 bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString(), QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
229
235 bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
236
247 Q_DECL_DEPRECATED bool isKnownAnomaly( const QString &diffImageFile ) SIP_DEPRECATED;
248
253 static void drawBackground( QImage *image );
254
260 QString expectedImageFile() const { return mExpectedImageFile; }
261
269 void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
270
277 QVector<QgsDartMeasurement> dartMeasurements() const { return mDashMessages; }
278
279 protected:
280 QString mReport;
281 unsigned int mMatchTarget = 0;
282 int mElapsedTime = 0;
285
286 private:
287 void emitDashMessage( const QgsDartMeasurement &dashMessage );
288 void emitDashMessage( const QString &name, QgsDartMeasurement::Type type, const QString &value );
289
290#if DUMP_BASE64_IMAGES
291 void dumpRenderedImageAsBase64();
292#endif
293
294 void performPostTestActions( Flags flags );
295
296 bool mResult = false;
297 bool mExpectFail = false;
298
299 QString mBasePath;
300
301 QString mControlName;
302 unsigned int mMismatchCount = 0;
303 unsigned int mColorTolerance = 0;
304 int mMaxSizeDifferenceX = 0;
305 int mMaxSizeDifferenceY = 0;
306 int mElapsedTimeTarget = 0;
307 QgsMapSettings mMapSettings;
308 QString mControlExtension = QStringLiteral( "png" );
309 QString mControlPathPrefix;
310 QString mControlPathSuffix;
311 bool mIsCiRun = false;
312 QVector<QgsDartMeasurement> mDashMessages;
313 bool mBufferDashMessages = false;
314 QString mDiffImageFile;
315
317};
318
319Q_DECLARE_OPERATORS_FOR_FLAGS( QgsRenderChecker::Flags )
320
321
329inline bool compareWkt( const QString &a, const QString &b, double tolerance = 0.000001 )
330{
331 QgsDebugMsg( QStringLiteral( "a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ) );
332 const thread_local QRegularExpression re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
333
334 QString a0( a ), b0( b );
335 a0.replace( re, QStringLiteral( "#" ) );
336 b0.replace( re, QStringLiteral( "#" ) );
337
338 QgsDebugMsg( QStringLiteral( "a0:%1 b0:%2" ).arg( a0, b0 ) );
339
340 if ( a0 != b0 )
341 return false;
342
343 QList<double> al, bl;
344
345 int pos = 0;
346 QRegularExpressionMatch match = re.match( a );
347 while ( match.hasMatch() )
348 {
349 al << match.captured( 0 ).toDouble();
350 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
351 match = re.match( a, pos );
352 }
353 match = re.match( b );
354 while ( match.hasMatch() )
355 {
356 bl << match.captured( 0 ).toDouble();
357 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
358 match = re.match( b, pos );
359 }
360
361 if ( al.size() != bl.size() )
362 return false;
363
364 for ( int i = 0; i < al.size(); i++ )
365 {
366 if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
367 return false;
368 }
369
370 return true;
371}
372
373#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.
Flag
Render checker flags.
int elapsedTime() const
Returns the total elapsed time for the rendering test.
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().
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:2527
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsField::ConfigurationFlags) CORE_EXPORT QDataStream &operator<<(QDataStream &out
Writes the field to stream out. QGIS version compatibility is not guaranteed.
#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.