/usr/include/qgis/qgsrenderchecker.h is in libqgis-dev 2.8.6+dfsg-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | /***************************************************************************
qgsrenderchecker.h - check maprender output against an expected image
--------------------------------------
Date : 18 Jan 2008
Copyright : (C) 2008 by Tim Sutton
email : tim @ linfiniti.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSRENDERCHECKER_H
#define QGSRENDERCHECKER_H
#include <qgis.h>
#include <QDir>
#include <QString>
#include <QRegExp>
#include <QList>
#include <qgsmaprenderer.h>
#include <qgslogger.h>
#include <qgsmapsettings.h>
#include "qgsdartmeasurement.h"
class QImage;
/** \ingroup UnitTests
* This is a helper class for unit tests that need to
* write an image and compare it to an expected result
* or render time.
*/
class CORE_EXPORT QgsRenderChecker
{
public:
QgsRenderChecker();
//! Destructor
~QgsRenderChecker() {};
QString controlImagePath() const;
QString report() { return mReport; };
float matchPercent()
{
return static_cast<float>( mMismatchCount ) /
static_cast<float>( mMatchTarget ) * 100;
}
unsigned int mismatchCount() { return mMismatchCount; }
unsigned int matchTarget() { return mMatchTarget; }
//only records time for actual render part
int elapsedTime() { return mElapsedTime; }
void setElapsedTimeTarget( int theTarget ) { mElapsedTimeTarget = theTarget; };
/** Base directory name for the control image (with control image path
* suffixed) the path to the image will be constructed like this:
* controlImagePath + '/' + mControlName + '/' + mControlName + '.png'
*/
void setControlName( const QString &theName );
/** Prefix where the control images are kept.
* This will be appended to controlImagePath
*/
void setControlPathPrefix( const QString &theName ) { mControlPathPrefix = theName + QDir::separator(); }
void setControlPathSuffix( const QString& theName ) { mControlPathSuffix = theName + QDir::separator(); }
/** Get an md5 hash that uniquely identifies an image */
QString imageToHash( QString theImageFile );
void setRenderedImage( QString theImageFileName ) { mRenderedImageFile = theImageFileName; }
/**
* The path of the rendered image can be retrieved through that method.
* Will return the path set with setRenderedImage() or generated in runTest()
*
* @return The path to the rendered image
*/
const QString& renderedImage() { return mRenderedImageFile; }
//! @deprecated since 2.4 - use setMapSettings()
Q_DECL_DEPRECATED void setMapRenderer( QgsMapRenderer * thepMapRenderer );
//! @note added in 2.4
void setMapSettings( const QgsMapSettings& mapSettings );
/** Set tolerance for color components used by runTest() and compareImages().
* Default value is 0.
* @param theColorTolerance is maximum difference for each color component
* including alpha to be considered correct.
* @note added in 2.1
*/
void setColorTolerance( unsigned int theColorTolerance ) { mColorTolerance = theColorTolerance; }
/**
* Test using renderer to generate the image to be compared.
* @param theTestName - to be used as the basis for writing a file to
* e.g. /tmp/theTestName.png
* @param theMismatchCount - defaults to 0 - the number of pixels that
* are allowed to be different from the control image. In some cases
* rendering may be non-deterministic. This parameter allows you to account
* for that by providing a tolerance.
* @note make sure to call setExpectedImage and setMapRenderer first
*/
bool runTest( QString theTestName, unsigned int theMismatchCount = 0 );
/**
* Test using two arbitary images (map renderer will not be used)
* @param theTestName - to be used as the basis for writing a file to
* e.g. /tmp/theTestName.png
* @param theMismatchCount - defaults to 0 - the number of pixels that
* are allowed to be different from the control image. In some cases
* rendering may be non-deterministic. This parameter allows you to account
* for that by providing a tolerance.
* @param theRenderedImageFile to optionally override the output filename
* @note: make sure to call setExpectedImage and setRenderedImage first.
*/
bool compareImages( QString theTestName, unsigned int theMismatchCount = 0, QString theRenderedImageFile = "" );
/** Get a list of all the anomalies. An anomaly is a rendered difference
* file where there is some red pixel content (indicating a render check
* mismatch), but where the output was still acceptible. If the render
* diff matches one of these anomalies we will still consider it to be
* acceptible.
* @return a bool indicating if the diff matched one of the anomaly files
*/
bool isKnownAnomaly( QString theDiffImageFile );
/**Draws a checkboard pattern for image backgrounds, so that transparency is visible
* without requiring a transparent background for the image
*/
static void drawBackground( QImage* image );
/**
* Returns the path to the expected image file
*
* @return Path to the expected image file
*/
const QString& expectedImageFile() const { return mExpectedImageFile; }
/**
* Call this to enable internal buffering of dash messages. You may later call
* dashMessages() to get access to the buffered messages. If disabled (default)
* dash messages will be sent immediately.
*
* @param enable Enable or disable buffering
*/
void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
/**
* Get access to buffered dash messages.
* Only will return something if you call enableDashBuffering( true ); before.
*
* @return buffered dash messages
* @note not available in python bindings
*/
const QVector<QgsDartMeasurement>& dartMeasurements() const { return mDashMessages; }
protected:
QString mReport;
unsigned int mMatchTarget;
int mElapsedTime;
QString mRenderedImageFile;
QString mExpectedImageFile;
private:
void emitDashMessage( const QgsDartMeasurement& dashMessage );
void emitDashMessage( const QString& name, QgsDartMeasurement::Type type, const QString& value );
QString mControlName;
unsigned int mMismatchCount;
unsigned int mColorTolerance;
int mElapsedTimeTarget;
QgsMapSettings mMapSettings;
QString mControlPathPrefix;
QString mControlPathSuffix;
QVector<QgsDartMeasurement> mDashMessages;
bool mBufferDashMessages;
}; // class QgsRenderChecker
/** Compare two WKT strings with some tolerance
* @param a first WKT string
* @param b second WKT string
* @param tolerance tolerance to use (optional, defaults to 0.000001)
* @return bool indicating if the WKT are sufficiently equal
*/
inline bool compareWkt( QString a, QString b, double tolerance = 0.000001 )
{
QgsDebugMsg( QString( "a:%1 b:%2 tol:%3" ).arg( a ).arg( b ).arg( tolerance ) );
QRegExp re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
QString a0( a ), b0( b );
a0.replace( re, "#" );
b0.replace( re, "#" );
QgsDebugMsg( QString( "a0:%1 b0:%2" ).arg( a0 ).arg( b0 ) );
if ( a0 != b0 )
return false;
QList<double> al, bl;
int pos;
for ( pos = 0; ( pos = re.indexIn( a, pos ) ) != -1; pos += re.matchedLength() )
{
al << re.cap( 0 ).toDouble();
}
for ( pos = 0; ( pos = re.indexIn( b, pos ) ) != -1; pos += re.matchedLength() )
{
bl << re.cap( 0 ).toDouble();
}
if ( al.size() != bl.size() )
return false;
for ( int i = 0; i < al.size(); i++ )
{
if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
return false;
}
return true;
}
#endif
|