25 #include <QCryptographicHash>
32 mTabStyle = QStringLiteral(
"border-spacing: 0px; border-width: 1px 1px 0 0; border-style: solid;" );
33 mCellStyle = QStringLiteral(
"border-width: 0 0 1px 1px; border-style: solid; font-size: smaller; text-align: center;" );
34 mOkStyle = QStringLiteral(
"background: #00ff00;" );
35 mErrStyle = QStringLiteral(
"background: #ff0000;" );
36 mErrMsgStyle = QStringLiteral(
"color: #ff0000;" );
40 const QString &expectedKey, QString expectedUri )
43 mReport += QLatin1String(
"\n\n" );
48 if ( !verifiedProvider || !verifiedProvider->
isValid() )
50 error( QStringLiteral(
"Cannot load provider %1 with URI: %2" ).arg( verifiedKey, verifiedUri ), mReport );
56 if ( !expectedProvider || !expectedProvider->
isValid() )
58 error( QStringLiteral(
"Cannot load provider %1 with URI: %2" ).arg( expectedKey, expectedUri ), mReport );
62 mReport += QStringLiteral(
"Verified URI: %1<br>" ).arg( verifiedUri.replace(
'&', QLatin1String(
"&" ) ) );
63 mReport += QStringLiteral(
"Expected URI: %1<br>" ).arg( expectedUri.replace(
'&', QLatin1String(
"&" ) ) );
65 mReport += QLatin1String(
"<br>" );
66 mReport += QStringLiteral(
"<table style='%1'>\n" ).arg( mTabStyle );
67 mReport += compareHead();
69 compare( QStringLiteral(
"Band count" ), verifiedProvider->
bandCount(), expectedProvider->
bandCount(), mReport, ok );
71 compare( QStringLiteral(
"Width" ), verifiedProvider->
xSize(), expectedProvider->
xSize(), mReport, ok );
72 compare( QStringLiteral(
"Height" ), verifiedProvider->
ySize(), expectedProvider->
ySize(), mReport, ok );
76 if ( verifiedProvider->
extent() != expectedProvider->
extent() ) ok =
false;
79 mReport += QLatin1String(
"</table>\n" );
81 if ( !ok )
return false;
84 for (
int band = 1; band <= expectedProvider->
bandCount(); band++ )
86 mReport += QStringLiteral(
"<h3>Band %1</h3>\n" ).arg( band );
87 mReport += QStringLiteral(
"<table style='%1'>\n" ).arg( mTabStyle );
88 mReport += compareHead();
92 compare( QStringLiteral(
"Source data type" ), verifiedProvider->
sourceDataType( band ), expectedProvider->
sourceDataType( band ), mReport, typesOk );
93 compare( QStringLiteral(
"Data type" ), verifiedProvider->
dataType( band ), expectedProvider->
dataType( band ), mReport, typesOk );
110 compare( QStringLiteral(
"Minimum value" ), verifiedStats.
minimumValue, expectedStats.
minimumValue, mReport, statsOk, tol );
112 compare( QStringLiteral(
"Maximum value" ), verifiedStats.
maximumValue, expectedStats.
maximumValue, mReport, statsOk, tol );
117 tol = tolerance( expectedStats.
mean );
118 compare( QStringLiteral(
"Mean" ), verifiedStats.
mean, expectedStats.
mean, mReport, statsOk, tol );
121 tol = tolerance( expectedStats.
stdDev, 1 );
122 compare( QStringLiteral(
"Standard deviation" ), verifiedStats.
stdDev, expectedStats.
stdDev, mReport, statsOk, tol );
124 mReport += QLatin1String(
"</table>" );
125 mReport += QLatin1String(
"<br>" );
127 if ( !statsOk || !typesOk || !noDataOk )
133 mReport += QLatin1String(
"<table><tr>" );
134 mReport += QLatin1String(
"<td>Data comparison</td>" );
135 mReport += QStringLiteral(
"<td style='%1 %2 border: 1px solid'>correct value</td>" ).arg( mCellStyle, mOkStyle );
136 mReport += QLatin1String(
"<td></td>" );
137 mReport += QStringLiteral(
"<td style='%1 %2 border: 1px solid'>wrong value<br>expected value</td></tr>" ).arg( mCellStyle, mErrStyle );
138 mReport += QLatin1String(
"</tr></table>" );
139 mReport += QLatin1String(
"<br>" );
141 const int width = expectedProvider->
xSize();
142 const int height = expectedProvider->
ySize();
143 std::unique_ptr< QgsRasterBlock > expectedBlock( expectedProvider->
block( band, expectedProvider->
extent(), width, height ) );
144 std::unique_ptr< QgsRasterBlock > verifiedBlock( verifiedProvider->
block( band, expectedProvider->
extent(), width, height ) );
146 if ( !expectedBlock || !expectedBlock->isValid() ||
147 !verifiedBlock || !verifiedBlock->isValid() )
150 mReport += QLatin1String(
"cannot read raster block" );
155 QString htmlTable = QStringLiteral(
"<table style='%1'>" ).arg( mTabStyle );
156 for (
int row = 0; row < height; row ++ )
158 htmlTable += QLatin1String(
"<tr>" );
159 for (
int col = 0; col < width; col ++ )
162 const double verifiedVal = verifiedBlock->value( row, col );
163 const double expectedVal = expectedBlock->value( row, col );
166 if ( compare( verifiedVal, expectedVal, 0 ) )
168 valStr = QString::number( verifiedVal );
174 valStr = QStringLiteral(
"%1<br>%2" ).arg( verifiedVal ).arg( expectedVal );
176 htmlTable += QStringLiteral(
"<td style='%1 %2'>%3</td>" ).arg( mCellStyle, cellOk ? mOkStyle : mErrStyle, valStr );
178 htmlTable += QLatin1String(
"</tr>" );
180 htmlTable += QLatin1String(
"</table>" );
182 mReport += htmlTable;
184 delete verifiedProvider;
185 delete expectedProvider;
189 void QgsRasterChecker::error(
const QString &message, QString &report )
191 report += QStringLiteral(
"<font style='%1'>Error: " ).arg( mErrMsgStyle );
193 report += QLatin1String(
"</font>" );
196 double QgsRasterChecker::tolerance(
double val,
int places )
200 return 1. * std::pow( 10, std::round( std::log10( std::fabs( val ) ) - places ) );
203 QString QgsRasterChecker::compareHead()
206 html += QStringLiteral(
"<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 );
210 void QgsRasterChecker::compare(
const QString ¶mName,
int verifiedVal,
int expectedVal, QString &report,
bool &ok )
212 const bool isEqual = verifiedVal == expectedVal;
213 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isEqual, QString::number( verifiedVal - expectedVal ) );
218 void QgsRasterChecker::compare(
const QString ¶mName,
Qgis::DataType verifiedVal,
Qgis::DataType expectedVal, QString &report,
bool &ok )
220 const bool isEqual = verifiedVal == expectedVal;
221 compareRow( paramName, QString::number(
static_cast< int>( verifiedVal ) ), QString::number(
static_cast< int >( expectedVal ) ),
report, isEqual, QString::number(
static_cast< int >( verifiedVal ) -
static_cast< int>( expectedVal ) ) );
226 bool QgsRasterChecker::compare(
double verifiedVal,
double expectedVal,
double tolerance )
229 return ( std::isnan( verifiedVal ) && std::isnan( expectedVal ) ) || ( std::fabs( verifiedVal - expectedVal ) <= tolerance );
232 void QgsRasterChecker::compare(
const QString ¶mName,
double verifiedVal,
double expectedVal, QString &report,
bool &ok,
double tolerance )
234 const bool isNearEqual = compare( verifiedVal, expectedVal, tolerance );
235 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isNearEqual, QString::number( verifiedVal - expectedVal ), QString::number( tolerance ) );
240 void QgsRasterChecker::compareRow(
const QString ¶mName,
const QString &verifiedVal,
const QString &expectedVal, QString &report,
bool ok,
const QString &difference,
const QString &tolerance )
242 report += QLatin1String(
"<tr>\n" );
243 report += QStringLiteral(
"<td style='%1'>%2</td><td style='%1 %3'>%4</td><td style='%1'>%5</td>\n" ).arg( mCellStyle, paramName, ok ? mOkStyle : mErrStyle, verifiedVal, expectedVal );
244 report += QStringLiteral(
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, difference );
245 report += QStringLiteral(
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, tolerance );
246 report += QLatin1String(
"</tr>" );