26 #include <QCryptographicHash> 34 mTabStyle =
"border-spacing: 0px; border-width: 1px 1px 0 0; border-style: solid;";
35 mCellStyle =
"border-width: 0 0 1px 1px; border-style: solid; font-size: smaller; text-align: center;";
36 mOkStyle =
"background: #00ff00;";
37 mErrStyle =
"background: #ff0000;";
38 mErrMsgStyle =
"color: #ff0000;";
49 if ( !verifiedProvider || !verifiedProvider->
isValid() )
51 error(
QString(
"Cannot load provider %1 with URI: %2" ).arg( theVerifiedKey, theVerifiedUri ), mReport );
57 if ( !expectedProvider || !expectedProvider->
isValid() )
59 error(
QString(
"Cannot load provider %1 with URI: %2" ).arg( theExpectedKey, theExpectedUri ), mReport );
63 if ( !ok )
return false;
65 mReport +=
QString(
"Verified URI: %1<br>" ).
arg( theVerifiedUri.
replace(
'&',
"&" ) );
66 mReport +=
QString(
"Expected URI: %1<br>" ).
arg( theExpectedUri.
replace(
'&',
"&" ) );
69 mReport +=
QString(
"<table style='%1'>\n" ).
arg( mTabStyle );
70 mReport += compareHead();
72 compare(
"Band count", verifiedProvider->
bandCount(), expectedProvider->
bandCount(), mReport, ok );
74 compare(
"Width", verifiedProvider->
xSize(), expectedProvider->
xSize(), mReport, ok );
75 compare(
"Height", verifiedProvider->
ySize(), expectedProvider->
ySize(), mReport, ok );
79 if ( verifiedProvider->
extent() != expectedProvider->
extent() ) ok =
false;
82 mReport +=
"</table>\n";
84 if ( !ok )
return false;
87 for (
int band = 1; band <= expectedProvider->
bandCount(); band++ )
89 mReport +=
QString(
"<h3>Band %1</h3>\n" ).
arg( band );
90 mReport +=
QString(
"<table style='%1'>\n" ).
arg( mTabStyle );
91 mReport += compareHead();
95 compare(
"Source data type", verifiedProvider->
srcDataType( band ), expectedProvider->
srcDataType( band ), mReport, typesOk );
96 compare(
"Data type", verifiedProvider->
dataType( band ), expectedProvider->
dataType( band ), mReport, typesOk );
103 compare(
"No data (NULL) value", verifiedProvider->
srcNoDataValue( band ), expectedProvider->
srcNoDataValue( band ), mReport, noDataOk );
120 tol = tolerance( expectedStats.
mean );
121 compare(
"Mean", verifiedStats.
mean, expectedStats.
mean, mReport, statsOk, tol );
124 tol = tolerance( expectedStats.
stdDev, 1 );
125 compare(
"Standard deviation", verifiedStats.
stdDev, expectedStats.
stdDev, mReport, statsOk, tol );
127 mReport +=
"</table>";
130 if ( !statsOk || !typesOk || !noDataOk )
136 mReport +=
"<table><tr>";
137 mReport +=
"<td>Data comparison</td>";
138 mReport +=
QString(
"<td style='%1 %2 border: 1px solid'>correct value</td>" ).
arg( mCellStyle, mOkStyle );
139 mReport +=
"<td></td>";
140 mReport +=
QString(
"<td style='%1 %2 border: 1px solid'>wrong value<br>expected value</td></tr>" ).
arg( mCellStyle, mErrStyle );
141 mReport +=
"</tr></table>";
144 int width = expectedProvider->
xSize();
145 int height = expectedProvider->
ySize();
149 if ( !expectedBlock || !expectedBlock->
isValid() ||
150 !verifiedBlock || !verifiedBlock->
isValid() )
153 mReport +=
"cannot read raster block";
159 for (
int row = 0; row < height; row ++ )
162 for (
int col = 0; col < width; col ++ )
165 double verifiedVal = verifiedBlock->
value( row, col );
166 double expectedVal = expectedBlock->
value( row, col );
169 if ( compare( verifiedVal, expectedVal, 0 ) )
177 valStr =
QString(
"%1<br>%2" ).
arg( verifiedVal ).
arg( expectedVal );
179 htmlTable +=
QString(
"<td style='%1 %2'>%3</td>" ).
arg( mCellStyle, cellOk ? mOkStyle : mErrStyle, valStr );
181 htmlTable +=
"</tr>";
183 htmlTable +=
"</table>";
185 mReport += htmlTable;
187 delete expectedBlock;
188 delete verifiedBlock;
190 delete verifiedProvider;
191 delete expectedProvider;
195 void QgsRasterChecker::error(
const QString& theMessage,
QString &theReport )
197 theReport +=
QString(
"<font style='%1'>Error: " ).
arg( mErrMsgStyle );
198 theReport += theMessage;
199 theReport +=
"</font>";
202 double QgsRasterChecker::tolerance(
double val,
int places )
206 return 1. * qPow( 10, qRound( log10( qAbs( val ) ) - places ) );
209 QString QgsRasterChecker::compareHead()
212 html +=
QString(
"<tr><th style='%1'>Param name</th><th style='%1'>Verified value</th><th style='%1'>Expected value</th><th style='%1'>Difference</th><th style='%1'>Tolerance</th></tr>" ).
arg( mCellStyle );
216 void QgsRasterChecker::compare(
const QString& theParamName,
int verifiedVal,
int expectedVal,
QString &theReport,
bool &theOk )
218 bool ok = verifiedVal == expectedVal;
220 if ( !ok ) theOk =
false;
223 bool QgsRasterChecker::compare(
double verifiedVal,
double expectedVal,
double theTolerance )
226 return ( qIsNaN( verifiedVal ) && qIsNaN( expectedVal ) ) || ( qAbs( verifiedVal - expectedVal ) <= theTolerance );
229 void QgsRasterChecker::compare(
const QString& theParamName,
double verifiedVal,
double expectedVal,
QString &theReport,
bool &theOk,
double theTolerance )
231 bool ok = compare( verifiedVal, expectedVal, theTolerance );
233 if ( !ok ) theOk =
false;
236 void QgsRasterChecker::compareRow(
const QString& theParamName,
const QString& verifiedVal,
const QString& expectedVal,
QString &theReport,
bool theOk,
const QString& theDifference,
const QString& theTolerance )
238 theReport +=
"<tr>\n";
239 theReport +=
QString(
"<td style='%1'>%2</td><td style='%1 %3'>%4</td><td style='%1'>%5</td>\n" ).
arg( mCellStyle, theParamName, theOk ? mOkStyle : mErrStyle, verifiedVal, expectedVal );
240 theReport +=
QString(
"<td style='%1'>%2</td>\n" ).
arg( mCellStyle, theDifference );
241 theReport +=
QString(
"<td style='%1'>%2</td>\n" ).
arg( mCellStyle, theTolerance );
242 theReport +=
"</tr>";
virtual int bandCount() const =0
Get number of bands.
static QgsProviderRegistry * instance(const QString &pluginPath=QString::null)
Means of accessing canonical single instance.
bool isValid() const
Returns true if the block is valid (correctly filled with data).
double maximumValue
The maximum cell value in the raster band.
virtual int ySize() const
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
virtual QgsRasterBandStats bandStatistics(int theBandNo, int theStats=QgsRasterBandStats::All, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Get band statistics.
double stdDev
The standard deviation of the cell values.
QString number(int n, int base)
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band.
QgsDataProvider * provider(const QString &providerKey, const QString &dataSource)
Create an instance of the provider.
virtual QGis::DataType srcDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual QgsRasterBlock * block(int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight) override
Read block of data using given extent and size.
virtual QgsRectangle extent() override=0
Get the extent of the data source.
virtual QGis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
QString & replace(int position, int n, QChar after)
bool runTest(const QString &theVerifiedKey, QString theVerifiedUri, const QString &theExpectedKey, QString theExpectedUri)
Test using renderer to generate the image to be compared.
virtual bool isValid()=0
Returns true if this is a valid layer.
double value(int row, int column) const
Read a single value if type of block is numeric.
double minimumValue
The minimum cell value in the raster band.
virtual bool srcHasNoDataValue(int bandNo) const
Return true if source band has no data value.
virtual double srcNoDataValue(int bandNo) const
Value representing no data value.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
virtual int xSize() const
Get raster size.
Base class for raster data providers.