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" );
47 if ( !verifiedProvider || !verifiedProvider->
isValid() )
49 error( QStringLiteral(
"Cannot load provider %1 with URI: %2" ).arg( verifiedKey, verifiedUri ), mReport );
55 if ( !expectedProvider || !expectedProvider->
isValid() )
57 error( QStringLiteral(
"Cannot load provider %1 with URI: %2" ).arg( expectedKey, expectedUri ), mReport );
61 if ( !ok )
return false;
63 mReport += QStringLiteral(
"Verified URI: %1<br>" ).arg( verifiedUri.replace(
'&', QLatin1String(
"&" ) ) );
64 mReport += QStringLiteral(
"Expected URI: %1<br>" ).arg( expectedUri.replace(
'&', QLatin1String(
"&" ) ) );
66 mReport += QLatin1String(
"<br>" );
67 mReport += QStringLiteral(
"<table style='%1'>\n" ).arg( mTabStyle );
68 mReport += compareHead();
70 compare( QStringLiteral(
"Band count" ), verifiedProvider->
bandCount(), expectedProvider->
bandCount(), mReport, ok );
72 compare( QStringLiteral(
"Width" ), verifiedProvider->
xSize(), expectedProvider->
xSize(), mReport, ok );
73 compare( QStringLiteral(
"Height" ), verifiedProvider->
ySize(), expectedProvider->
ySize(), mReport, ok );
77 if ( verifiedProvider->
extent() != expectedProvider->
extent() ) ok =
false;
80 mReport += QLatin1String(
"</table>\n" );
82 if ( !ok )
return false;
85 for (
int band = 1; band <= expectedProvider->
bandCount(); band++ )
87 mReport += QStringLiteral(
"<h3>Band %1</h3>\n" ).arg( band );
88 mReport += QStringLiteral(
"<table style='%1'>\n" ).arg( mTabStyle );
89 mReport += compareHead();
93 compare( QStringLiteral(
"Source data type" ), verifiedProvider->
sourceDataType( band ), expectedProvider->
sourceDataType( band ), mReport, typesOk );
94 compare( QStringLiteral(
"Data type" ), verifiedProvider->
dataType( band ), expectedProvider->
dataType( band ), mReport, typesOk );
111 compare( QStringLiteral(
"Minimum value" ), verifiedStats.
minimumValue, expectedStats.
minimumValue, mReport, statsOk, tol );
113 compare( QStringLiteral(
"Maximum value" ), verifiedStats.
maximumValue, expectedStats.
maximumValue, mReport, statsOk, tol );
118 tol = tolerance( expectedStats.
mean );
119 compare( QStringLiteral(
"Mean" ), verifiedStats.
mean, expectedStats.
mean, mReport, statsOk, tol );
122 tol = tolerance( expectedStats.
stdDev, 1 );
123 compare( QStringLiteral(
"Standard deviation" ), verifiedStats.
stdDev, expectedStats.
stdDev, mReport, statsOk, tol );
125 mReport += QLatin1String(
"</table>" );
126 mReport += QLatin1String(
"<br>" );
128 if ( !statsOk || !typesOk || !noDataOk )
134 mReport += QLatin1String(
"<table><tr>" );
135 mReport += QLatin1String(
"<td>Data comparison</td>" );
136 mReport += QStringLiteral(
"<td style='%1 %2 border: 1px solid'>correct value</td>" ).arg( mCellStyle, mOkStyle );
137 mReport += QLatin1String(
"<td></td>" );
138 mReport += QStringLiteral(
"<td style='%1 %2 border: 1px solid'>wrong value<br>expected value</td></tr>" ).arg( mCellStyle, mErrStyle );
139 mReport += QLatin1String(
"</tr></table>" );
140 mReport += QLatin1String(
"<br>" );
142 int width = expectedProvider->
xSize();
143 int height = expectedProvider->
ySize();
147 if ( !expectedBlock || !expectedBlock->
isValid() ||
148 !verifiedBlock || !verifiedBlock->
isValid() )
151 mReport += QLatin1String(
"cannot read raster block" );
156 QString htmlTable = QStringLiteral(
"<table style='%1'>" ).arg( mTabStyle );
157 for (
int row = 0; row < height; row ++ )
159 htmlTable += QLatin1String(
"<tr>" );
160 for (
int col = 0; col < width; col ++ )
163 double verifiedVal = verifiedBlock->
value( row, col );
164 double expectedVal = expectedBlock->
value( row, col );
167 if ( compare( verifiedVal, expectedVal, 0 ) )
169 valStr = QStringLiteral(
"%1" ).arg( verifiedVal );
175 valStr = QStringLiteral(
"%1<br>%2" ).arg( verifiedVal ).arg( expectedVal );
177 htmlTable += QStringLiteral(
"<td style='%1 %2'>%3</td>" ).arg( mCellStyle, cellOk ? mOkStyle : mErrStyle, valStr );
179 htmlTable += QLatin1String(
"</tr>" );
181 htmlTable += QLatin1String(
"</table>" );
183 mReport += htmlTable;
185 delete expectedBlock;
186 delete verifiedBlock;
188 delete verifiedProvider;
189 delete expectedProvider;
193 void QgsRasterChecker::error(
const QString &message, QString &
report )
195 report += QStringLiteral(
"<font style='%1'>Error: " ).arg( mErrMsgStyle );
197 report += QLatin1String(
"</font>" );
200 double QgsRasterChecker::tolerance(
double val,
int places )
204 return 1. * std::pow( 10, std::round( std::log10( std::fabs( val ) ) - places ) );
207 QString QgsRasterChecker::compareHead()
210 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 );
214 void QgsRasterChecker::compare(
const QString ¶mName,
int verifiedVal,
int expectedVal, QString &
report,
bool &ok )
216 bool isEqual = verifiedVal == expectedVal;
217 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isEqual, QString::number( verifiedVal - expectedVal ) );
222 bool QgsRasterChecker::compare(
double verifiedVal,
double expectedVal,
double tolerance )
225 return ( std::isnan( verifiedVal ) && std::isnan( expectedVal ) ) || ( std::fabs( verifiedVal - expectedVal ) <= tolerance );
228 void QgsRasterChecker::compare(
const QString ¶mName,
double verifiedVal,
double expectedVal, QString &
report,
bool &ok,
double tolerance )
230 bool isNearEqual = compare( verifiedVal, expectedVal, tolerance );
231 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isNearEqual, QString::number( verifiedVal - expectedVal ), QString::number( tolerance ) );
236 void QgsRasterChecker::compareRow(
const QString ¶mName,
const QString &verifiedVal,
const QString &expectedVal, QString &
report,
bool ok,
const QString &difference,
const QString &tolerance )
238 report += QLatin1String(
"<tr>\n" );
239 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 );
240 report += QStringLiteral(
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, difference );
241 report += QStringLiteral(
"<td style='%1'>%2</td>\n" ).arg( mCellStyle, tolerance );
242 report += QLatin1String(
"</tr>" );
virtual int bandCount() const =0
Get 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.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource)
Creates a new instance of a provider.
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.
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
Return 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)
Get 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.
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
Get 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.