Skip to content

Commit 059f343

Browse files
committed
Add missing files
1 parent dafa384 commit 059f343

File tree

2 files changed

+217
-0
lines changed

2 files changed

+217
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/***************************************************************************
2+
qgsreclassifyutils.cpp
3+
---------------------
4+
begin : June, 2018
5+
copyright : (C) 2018 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsreclassifyutils.h"
19+
#include "qgsrasterinterface.h"
20+
#include "qgsrasteriterator.h"
21+
#include "qgsrasterblock.h"
22+
#include "qgsprocessingfeedback.h"
23+
#include "qgsrasterdataprovider.h"
24+
25+
#include "qgis.h"
26+
27+
///@cond PRIVATE
28+
29+
void QgsReclassifyUtils::reclassify(const QVector<QgsReclassifyUtils::RasterClass> &classes, QgsRasterInterface *sourceRaster, int band,
30+
const QgsRectangle &extent, int sourceWidthPixels, int sourceHeightPixels,
31+
QgsRasterDataProvider *destinationRaster, double destNoDataValue, bool useNoDataForMissingValues,
32+
QgsProcessingFeedback *feedback )
33+
{
34+
int maxWidth = 4000;
35+
int maxHeight = 4000;
36+
37+
QgsRasterIterator iter( sourceRaster );
38+
iter.setMaximumTileWidth( maxWidth );
39+
iter.setMaximumTileHeight( maxHeight );
40+
iter.startRasterRead( band, sourceWidthPixels, sourceHeightPixels, extent );
41+
42+
int nbBlocksWidth = std::ceil( 1.0 * sourceWidthPixels / maxWidth );
43+
int nbBlocksHeight = std::ceil( 1.0 * sourceHeightPixels / maxHeight );
44+
int nbBlocks = nbBlocksWidth * nbBlocksHeight;
45+
46+
int iterLeft = 0;
47+
int iterTop = 0;
48+
int iterCols = 0;
49+
int iterRows = 0;
50+
destinationRaster->setEditable( true );
51+
QgsRasterBlock *rasterBlock = nullptr;
52+
bool reclassed = false;
53+
while ( iter.readNextRasterPart( band, iterCols, iterRows, &rasterBlock, iterLeft, iterTop ) )
54+
{
55+
if ( feedback )
56+
feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
57+
std::unique_ptr< QgsRasterBlock > reclassifiedBlock = qgis::make_unique< QgsRasterBlock >( Qgis::Float32, iterCols, iterRows );
58+
59+
for ( int row = 0; row < iterRows; row++ )
60+
{
61+
if ( feedback && feedback->isCanceled() )
62+
break;
63+
for ( int column = 0; column < iterCols; column++ )
64+
{
65+
if ( rasterBlock->isNoData( row, column ) )
66+
reclassifiedBlock->setValue( row, column, destNoDataValue );
67+
else
68+
{
69+
double value = rasterBlock->value( row, column );
70+
double newValue = reclassifyValue( classes, value, reclassed );
71+
if ( reclassed )
72+
reclassifiedBlock->setValue( row, column, newValue );
73+
else
74+
reclassifiedBlock->setValue( row, column, useNoDataForMissingValues ? destNoDataValue : value );
75+
}
76+
}
77+
}
78+
destinationRaster->writeBlock( reclassifiedBlock.get(), 1, iterLeft, iterTop );
79+
80+
delete rasterBlock;
81+
}
82+
destinationRaster->setEditable( false );
83+
}
84+
85+
double QgsReclassifyUtils::reclassifyValue(const QVector<QgsReclassifyUtils::RasterClass> &classes, double input, bool &reclassified)
86+
{
87+
reclassified = false;
88+
for ( const QgsReclassifyUtils::RasterClass &c : classes )
89+
{
90+
if ( c.contains( input ) )
91+
{
92+
reclassified = true;
93+
return c.value;
94+
}
95+
}
96+
return input;
97+
}
98+
99+
///@endcond
100+
101+
102+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/***************************************************************************
2+
qgsreclassifyutils.h
3+
---------------------
4+
begin : June, 2018
5+
copyright : (C) 2018 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSRECLASSIFYUTILS
19+
#define QGSRECLASSIFYUTILS
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis.h"
24+
#include "qgis_analysis.h"
25+
#include "qgsrasterrange.h"
26+
27+
class QgsRasterInterface;
28+
class QgsProcessingFeedback;
29+
class QgsRasterDataProvider;
30+
class QgsRectangle;
31+
32+
///@cond PRIVATE
33+
34+
/**
35+
* Utility functions for reclassifying raster layers.
36+
* \ingroup analysis
37+
* \since QGIS 3.4
38+
*/
39+
class ANALYSIS_EXPORT QgsReclassifyUtils
40+
{
41+
42+
public:
43+
44+
/**
45+
* Represents a single class for a reclassification operation.
46+
*/
47+
class RasterClass : public QgsRasterRange
48+
{
49+
public:
50+
51+
//! Default constructor for an empty class
52+
RasterClass() = default;
53+
54+
/**
55+
* Constructor for RasterClass, with the specified range of min to max values.
56+
* The \a value argument gives the desired output value for this raster class.
57+
*/
58+
RasterClass( double minValue, double maxValue, QgsRasterRange::BoundsType type, double value )
59+
: QgsRasterRange( minValue, maxValue, type )
60+
, value( value )
61+
{}
62+
63+
//! Desired output value for class
64+
double value = 0;
65+
};
66+
67+
/**
68+
* Performs a reclassification operation on a raster source \a sourceRaster, reclassifying to the given
69+
* list of \a classes.
70+
*
71+
* Parameters of the raster must be given by the \a band, \a extent, \a sourceWidthPixels and
72+
* \a sourceHeightPixels values.
73+
*
74+
* The raster data provider \a destinationRaster will be used to save the result of the
75+
* reclassification operation. The caller is responsible for ensuring that this data provider
76+
* has been created with the same extent, pixel dimensions and CRS as the input raster.
77+
*
78+
* The nodata value for the destination should be specified via \a destNoDataValue. This
79+
* will be used wherever the source raster has a no data value or a source pixel value
80+
* does not have a matching class.
81+
*
82+
* If \a useNoDataForMissingValues is true, then any raster values which do not match to
83+
* a class will be changed to the no data value. Otherwise they are saved unchanged.
84+
*
85+
* The \a feedback argument gives an optional processing feedback, for progress reports
86+
* and cancelation.
87+
*/
88+
static void reclassify(const QVector< RasterClass > &classes,
89+
QgsRasterInterface *sourceRaster,
90+
int band,
91+
const QgsRectangle& extent,
92+
int sourceWidthPixels,
93+
int sourceHeightPixels,
94+
QgsRasterDataProvider *destinationRaster,
95+
double destNoDataValue, bool useNoDataForMissingValues,
96+
QgsProcessingFeedback *feedback = nullptr );
97+
98+
/**
99+
* Reclassifies a single \a input value, using the specified list of \a classes.
100+
*
101+
* If a matching class was found, then \a reclassified will be set to true and the
102+
* class output value returned.
103+
*
104+
* If no matching class was found then \a reclassified will be set to false, and the
105+
* original \a input value returned unchanged.
106+
*/
107+
static double reclassifyValue( const QVector< RasterClass > &classes, double input, bool& reclassified );
108+
109+
};
110+
111+
///@endcond PRIVATE
112+
113+
#endif // QGSRECLASSIFYUTILS
114+
115+

0 commit comments

Comments
 (0)