25#include <QCryptographicHash>
32using namespace Qt::StringLiterals;
36 mTabStyle = u
"border-spacing: 0px; border-width: 1px 1px 0 0; border-style: solid;"_s;
37 mCellStyle = u
"border-width: 0 0 1px 1px; border-style: solid; font-size: smaller; text-align: center;"_s;
38 mOkStyle = u
"background: #00ff00;"_s;
39 mErrStyle = u
"background: #ff0000;"_s;
40 mErrMsgStyle = u
"color: #ff0000;"_s;
44 const QString &expectedKey, QString expectedUri )
52 if ( !verifiedProvider || !verifiedProvider->
isValid() )
54 error( u
"Cannot load provider %1 with URI: %2"_s.arg( verifiedKey, verifiedUri ), mReport );
60 if ( !expectedProvider || !expectedProvider->
isValid() )
62 error( u
"Cannot load provider %1 with URI: %2"_s.arg( expectedKey, expectedUri ), mReport );
66 mReport += u
"Verified URI: %1<br>"_s.arg( verifiedUri.replace(
'&',
"&"_L1 ) );
67 mReport += u
"Expected URI: %1<br>"_s.arg( expectedUri.replace(
'&',
"&"_L1 ) );
70 mReport += u
"<table style='%1'>\n"_s.arg( mTabStyle );
71 mReport += compareHead();
73 compare( u
"Band count"_s, verifiedProvider->
bandCount(), expectedProvider->
bandCount(), mReport, ok );
75 compare( u
"Width"_s, verifiedProvider->
xSize(), expectedProvider->
xSize(), mReport, ok );
76 compare( u
"Height"_s, verifiedProvider->
ySize(), expectedProvider->
ySize(), mReport, ok );
80 if ( verifiedProvider->
extent() != expectedProvider->
extent() ) ok =
false;
83 mReport +=
"</table>\n"_L1;
85 if ( !ok )
return false;
88 for (
int band = 1; band <= expectedProvider->
bandCount(); band++ )
90 mReport += u
"<h3>Band %1</h3>\n"_s.arg( band );
91 mReport += u
"<table style='%1'>\n"_s.arg( mTabStyle );
92 mReport += compareHead();
97 compare( u
"Data type"_s, verifiedProvider->
dataType( band ), expectedProvider->
dataType( band ), mReport, typesOk );
100 bool noDataOk =
true;
121 tol = tolerance( expectedStats.
mean );
122 compare( u
"Mean"_s, verifiedStats.
mean, expectedStats.
mean, mReport, statsOk, tol );
125 tol = tolerance( expectedStats.
stdDev, 1 );
126 compare( u
"Standard deviation"_s, verifiedStats.
stdDev, expectedStats.
stdDev, mReport, statsOk, tol );
128 mReport +=
"</table>"_L1;
129 mReport +=
"<br>"_L1;
131 if ( !statsOk || !typesOk || !noDataOk )
137 mReport +=
"<table><tr>"_L1;
138 mReport +=
"<td>Data comparison</td>"_L1;
139 mReport += u
"<td style='%1 %2 border: 1px solid'>correct value</td>"_s.arg( mCellStyle, mOkStyle );
140 mReport +=
"<td></td>"_L1;
141 mReport += u
"<td style='%1 %2 border: 1px solid'>wrong value<br>expected value</td></tr>"_s.arg( mCellStyle, mErrStyle );
142 mReport +=
"</tr></table>"_L1;
143 mReport +=
"<br>"_L1;
145 const int width = expectedProvider->
xSize();
146 const int height = expectedProvider->
ySize();
147 std::unique_ptr< QgsRasterBlock > expectedBlock( expectedProvider->
block( band, expectedProvider->
extent(), width, height ) );
148 std::unique_ptr< QgsRasterBlock > verifiedBlock( verifiedProvider->
block( band, expectedProvider->
extent(), width, height ) );
150 if ( !expectedBlock || !expectedBlock->isValid() ||
151 !verifiedBlock || !verifiedBlock->isValid() )
154 mReport +=
"cannot read raster block"_L1;
159 QString htmlTable = u
"<table style='%1'>"_s.arg( mTabStyle );
160 for (
int row = 0; row < height; row ++ )
162 htmlTable +=
"<tr>"_L1;
163 for (
int col = 0; col < width; col ++ )
166 const double verifiedVal = verifiedBlock->value( row, col );
167 const double expectedVal = expectedBlock->value( row, col );
170 if ( compare( verifiedVal, expectedVal, 0 ) )
172 valStr = QString::number( verifiedVal );
178 valStr = u
"%1<br>%2"_s.arg( verifiedVal ).arg( expectedVal );
180 htmlTable += u
"<td style='%1 %2'>%3</td>"_s.arg( mCellStyle, cellOk ? mOkStyle : mErrStyle, valStr );
182 htmlTable +=
"</tr>"_L1;
184 htmlTable +=
"</table>"_L1;
186 mReport += htmlTable;
188 delete verifiedProvider;
189 delete expectedProvider;
193void QgsRasterChecker::error(
const QString &message, QString &report )
195 report += u
"<font style='%1'>Error: "_s.arg( mErrMsgStyle );
200double QgsRasterChecker::tolerance(
double val,
int places )
204 return 1. * std::pow( 10, std::round( std::log10( std::fabs( val ) ) - places ) );
207QString QgsRasterChecker::compareHead()
210 html += u
"<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>"_s.arg( mCellStyle );
214void QgsRasterChecker::compare(
const QString ¶mName,
int verifiedVal,
int expectedVal, QString &report,
bool &ok )
216 const bool isEqual = verifiedVal == expectedVal;
217 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isEqual, QString::number( verifiedVal - expectedVal ) );
222void QgsRasterChecker::compare(
const QString ¶mName,
Qgis::DataType verifiedVal,
Qgis::DataType expectedVal, QString &report,
bool &ok )
224 const bool isEqual = verifiedVal == expectedVal;
225 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 ) ) );
230bool QgsRasterChecker::compare(
double verifiedVal,
double expectedVal,
double tolerance )
233 return ( std::isnan( verifiedVal ) && std::isnan( expectedVal ) ) || ( std::fabs( verifiedVal - expectedVal ) <= tolerance );
236void QgsRasterChecker::compare(
const QString ¶mName,
double verifiedVal,
double expectedVal, QString &report,
bool &ok,
double tolerance )
238 const bool isNearEqual = compare( verifiedVal, expectedVal, tolerance );
239 compareRow( paramName, QString::number( verifiedVal ), QString::number( expectedVal ),
report, isNearEqual, QString::number( verifiedVal - expectedVal ), QString::number( tolerance ) );
244void QgsRasterChecker::compareRow(
const QString ¶mName,
const QString &verifiedVal,
const QString &expectedVal, QString &report,
bool ok,
const QString &difference,
const QString &tolerance )
247 report += u
"<td style='%1'>%2</td><td style='%1 %3'>%4</td><td style='%1'>%5</td>\n"_s.arg( mCellStyle, paramName, ok ? mOkStyle : mErrStyle, verifiedVal, expectedVal );
248 report += u
"<td style='%1'>%2</td>\n"_s.arg( mCellStyle, difference );
249 report += u
"<td style='%1'>%2</td>\n"_s.arg( mCellStyle, tolerance );
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.
Q_DECL_DEPRECATED QgsRasterBandStats bandStatistics(int bandNo, int stats, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual int bandCount() const =0
Gets number of bands.
virtual int ySize() const
Q_INVOKABLE 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.