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();
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 expectedBlock;
187 delete verifiedBlock;
189 delete verifiedProvider;
190 delete expectedProvider;
194 void QgsRasterChecker::error(
const QString &message, QString &
report )
196 report += QStringLiteral(
"<font style='%1'>Error: " ).arg( mErrMsgStyle );
198 report += QLatin1String(
"</font>" );
201 double QgsRasterChecker::tolerance(
double val,
int places )
205 return 1. * std::pow( 10, std::round( std::log10( std::fabs( val ) ) - places ) );
208 QString QgsRasterChecker::compareHead()
211 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 );
215 void QgsRasterChecker::compare(
const QString ¶mName,
int verifiedVal,
int expectedVal, QString &
report,
bool &ok )
217 bool isEqual = verifiedVal == expectedVal;
218 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isEqual, QString::number( verifiedVal - expectedVal ) );
223 bool QgsRasterChecker::compare(
double verifiedVal,
double expectedVal,
double tolerance )
226 return ( std::isnan( verifiedVal ) && std::isnan( expectedVal ) ) || ( std::fabs( verifiedVal - expectedVal ) <= tolerance );
229 void QgsRasterChecker::compare(
const QString ¶mName,
double verifiedVal,
double expectedVal, QString &
report,
bool &ok,
double tolerance )
231 bool isNearEqual = compare( verifiedVal, expectedVal, tolerance );
232 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isNearEqual, QString::number( verifiedVal - expectedVal ), QString::number( tolerance ) );
237 void QgsRasterChecker::compareRow(
const QString ¶mName,
const QString &verifiedVal,
const QString &expectedVal, QString &
report,
bool ok,
const QString &difference,
const QString &tolerance )
239 report += QLatin1String(
"<tr>\n" );
240 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 );
241 report += QStringLiteral(
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, difference );
242 report += QStringLiteral(
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, tolerance );
243 report += QLatin1String(
"</tr>" );
virtual int bandCount() const =0
Gets number of bands.
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
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 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 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.