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   if ( !ok ) 
return false;
    64   mReport += QStringLiteral( 
"Verified URI: %1<br>" ).arg( verifiedUri.replace( 
'&', QLatin1String( 
"&" ) ) );
    65   mReport += QStringLiteral( 
"Expected URI: %1<br>" ).arg( expectedUri.replace( 
'&', QLatin1String( 
"&" ) ) );
    67   mReport += QLatin1String( 
"<br>" );
    68   mReport += QStringLiteral( 
"<table style='%1'>\n" ).arg( mTabStyle );
    69   mReport += compareHead();
    71   compare( QStringLiteral( 
"Band count" ), verifiedProvider->
bandCount(), expectedProvider->
bandCount(), mReport, ok );
    73   compare( QStringLiteral( 
"Width" ), verifiedProvider->
xSize(), expectedProvider->
xSize(), mReport, ok );
    74   compare( QStringLiteral( 
"Height" ), verifiedProvider->
ySize(), expectedProvider->
ySize(), mReport, ok );
    78   if ( verifiedProvider->
extent() != expectedProvider->
extent() ) ok = 
false;
    81   mReport += QLatin1String( 
"</table>\n" );
    83   if ( !ok ) 
return false;
    86   for ( 
int band = 1; band <= expectedProvider->
bandCount(); band++ )
    88     mReport += QStringLiteral( 
"<h3>Band %1</h3>\n" ).arg( band );
    89     mReport += QStringLiteral( 
"<table style='%1'>\n" ).arg( mTabStyle );
    90     mReport += compareHead();
    94     compare( QStringLiteral( 
"Source data type" ), verifiedProvider->
sourceDataType( band ), expectedProvider->
sourceDataType( band ), mReport, typesOk );
    95     compare( QStringLiteral( 
"Data type" ), verifiedProvider->
dataType( band ), expectedProvider->
dataType( band ), mReport, typesOk );
   112     compare( QStringLiteral( 
"Minimum value" ), verifiedStats.
minimumValue, expectedStats.
minimumValue, mReport, statsOk, tol );
   114     compare( QStringLiteral( 
"Maximum value" ), verifiedStats.
maximumValue, expectedStats.
maximumValue, mReport, statsOk, tol );
   119     tol = tolerance( expectedStats.
mean );
   120     compare( QStringLiteral( 
"Mean" ), verifiedStats.
mean, expectedStats.
mean, mReport, statsOk, tol );
   123     tol = tolerance( expectedStats.
stdDev, 1 );
   124     compare( QStringLiteral( 
"Standard deviation" ), verifiedStats.
stdDev, expectedStats.
stdDev, mReport, statsOk, tol );
   126     mReport += QLatin1String( 
"</table>" );
   127     mReport += QLatin1String( 
"<br>" );
   129     if ( !statsOk || !typesOk || !noDataOk )
   135     mReport += QLatin1String( 
"<table><tr>" );
   136     mReport += QLatin1String( 
"<td>Data comparison</td>" );
   137     mReport += QStringLiteral( 
"<td style='%1 %2 border: 1px solid'>correct value</td>" ).arg( mCellStyle, mOkStyle );
   138     mReport += QLatin1String( 
"<td></td>" );
   139     mReport += QStringLiteral( 
"<td style='%1 %2 border: 1px solid'>wrong value<br>expected value</td></tr>" ).arg( mCellStyle, mErrStyle );
   140     mReport += QLatin1String( 
"</tr></table>" );
   141     mReport += QLatin1String( 
"<br>" );
   143     int width = expectedProvider->
xSize();
   144     int height = expectedProvider->
ySize();
   145     std::unique_ptr< QgsRasterBlock > expectedBlock( expectedProvider->
block( band, expectedProvider->
extent(), width, height ) );
   146     std::unique_ptr< QgsRasterBlock > verifiedBlock( verifiedProvider->
block( band, expectedProvider->
extent(), width, height ) );
   148     if ( !expectedBlock || !expectedBlock->isValid() ||
   149          !verifiedBlock || !verifiedBlock->isValid() )
   152       mReport += QLatin1String( 
"cannot read raster block" );
   157     QString htmlTable = QStringLiteral( 
"<table style='%1'>" ).arg( mTabStyle );
   158     for ( 
int row = 0; row < height; row ++ )
   160       htmlTable += QLatin1String( 
"<tr>" );
   161       for ( 
int col = 0; col < width; col ++ )
   164         double verifiedVal = verifiedBlock->value( row, col );
   165         double expectedVal = expectedBlock->value( row, col );
   168         if ( compare( verifiedVal, expectedVal, 0 ) )
   170           valStr = QStringLiteral( 
"%1" ).arg( verifiedVal );
   176           valStr = QStringLiteral( 
"%1<br>%2" ).arg( verifiedVal ).arg( expectedVal );
   178         htmlTable += QStringLiteral( 
"<td style='%1 %2'>%3</td>" ).arg( mCellStyle, cellOk ? mOkStyle : mErrStyle, valStr );
   180       htmlTable += QLatin1String( 
"</tr>" );
   182     htmlTable += QLatin1String( 
"</table>" );
   184     mReport += htmlTable;
   186   delete verifiedProvider;
   187   delete expectedProvider;
   191 void QgsRasterChecker::error( 
const QString &message, QString &
report )
   193   report += QStringLiteral( 
"<font style='%1'>Error: " ).arg( mErrMsgStyle );
   195   report += QLatin1String( 
"</font>" );
   198 double QgsRasterChecker::tolerance( 
double val, 
int places )
   202   return 1. * std::pow( 10, std::round( std::log10( std::fabs( val ) ) - places ) );
   205 QString QgsRasterChecker::compareHead()
   208   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 );
   212 void QgsRasterChecker::compare( 
const QString ¶mName, 
int verifiedVal, 
int expectedVal, QString &
report, 
bool &ok )
   214   bool isEqual = verifiedVal == expectedVal;
   215   compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ), 
report, isEqual, QString::number( verifiedVal - expectedVal ) );
   220 bool QgsRasterChecker::compare( 
double verifiedVal, 
double expectedVal, 
double tolerance )
   223   return ( std::isnan( verifiedVal ) && std::isnan( expectedVal ) ) || ( std::fabs( verifiedVal - expectedVal ) <= tolerance );
   226 void QgsRasterChecker::compare( 
const QString ¶mName, 
double verifiedVal, 
double expectedVal, QString &
report, 
bool &ok, 
double tolerance )
   228   bool isNearEqual = compare( verifiedVal, expectedVal, tolerance );
   229   compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ), 
report, isNearEqual, QString::number( verifiedVal - expectedVal ), QString::number( tolerance ) );
   234 void QgsRasterChecker::compareRow( 
const QString ¶mName, 
const QString &verifiedVal, 
const QString &expectedVal, QString &
report, 
bool ok, 
const QString &difference, 
const QString &tolerance )
   236   report += QLatin1String( 
"<tr>\n" );
   237   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 );
   238   report += QStringLiteral( 
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, difference );
   239   report += QStringLiteral( 
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, tolerance );
   240   report += QLatin1String( 
"</tr>" );
 virtual int bandCount() const =0
Gets number of bands. 
 
double maximumValue
The maximum cell value in the raster band. 
 
virtual int ySize() const
 
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. 
 
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions())
Creates a new instance of a provider. 
 
double stdDev
The standard deviation of the cell values. 
 
The RasterBandStats struct is a container for statistics about a single raster band. 
 
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance. 
 
double mean
The mean cell value for the band. NO_DATA values are excluded. 
 
QgsRectangle extent() const override=0
Returns the extent of the layer. 
 
virtual bool isValid() const =0
Returns true if this is a valid layer. 
 
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
 
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value. 
 
bool runTest(const QString &verifiedKey, QString verifiedUri, const QString &expectedKey, QString expectedUri)
Test using renderer to generate the image to be compared. 
 
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics. 
 
QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size. 
 
Setting options for creating vector data providers. 
 
double minimumValue
The minimum cell value in the raster band. 
 
virtual int xSize() const
Gets raster size. 
 
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number. 
 
Base class for raster data providers.