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>" );