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>" );
 
DataType
Raster data types.
virtual bool isValid() const =0
Returns true if this is a valid layer.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
bool runTest(const QString &verifiedKey, QString verifiedUri, const QString &expectedKey, QString expectedUri)
Test using renderer to generate the image to be compared.
Base class for raster data providers.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
Qgis::DataType sourceDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
QgsRectangle extent() const override=0
Returns the extent of the layer.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
virtual int xSize() const
Gets raster size.
virtual int bandCount() const =0
Gets number of bands.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual int ySize() const
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
Setting options for creating vector data providers.