QGIS API Documentation 4.3.0-Master (ffcfc20b9b4)
Loading...
Searching...
No Matches
qgsalgorithmalignrasters.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmalignrasters.cpp
3 ---------------------
4 begin : July 2023
5 copyright : (C) 2023 by Alexander Bruy
6 email : alexander dot bruy 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
19
20#include "qgsalignraster.h"
21#include "qgsalignrasterdata.h"
23
24#include <QString>
25
26using namespace Qt::StringLiterals;
27
29
30Qgis::ProcessingAlgorithmFlags QgsAlignRastersAlgorithm::flags() const
31{
33}
34
35QString QgsAlignRastersAlgorithm::name() const
36{
37 return u"alignrasters"_s;
38}
39
40QString QgsAlignRastersAlgorithm::displayName() const
41{
42 return QObject::tr( "Align rasters" );
43}
44
45QStringList QgsAlignRastersAlgorithm::tags() const
46{
47 return QObject::tr( "raster,align,resample,rescale" ).split( ',' );
48}
49
50QString QgsAlignRastersAlgorithm::group() const
51{
52 return QObject::tr( "Raster tools" );
53}
54
55QString QgsAlignRastersAlgorithm::groupId() const
56{
57 return u"rastertools"_s;
58}
59
60QString QgsAlignRastersAlgorithm::shortHelpString() const
61{
62 return QObject::tr( "This algorithm aligns rasters by resampling them to the same cell size and reprojecting to the same CRS." );
63}
64
65QString QgsAlignRastersAlgorithm::shortDescription() const
66{
67 return QObject::tr( "Aligns rasters by resampling them to the same cell size and reprojecting to the same CRS." );
68}
69
70QgsAlignRastersAlgorithm *QgsAlignRastersAlgorithm::createInstance() const
71{
72 return new QgsAlignRastersAlgorithm();
73}
74
75bool QgsAlignRastersAlgorithm::checkParameterValues( const QVariantMap &parameters, QgsProcessingContext &context, QString *message ) const
76{
77 const QVariant layersVariant = parameters.value( parameterDefinition( u"LAYERS"_s )->name() );
78 const QList<QgsAlignRasterData::RasterItem> items = QgsProcessingParameterAlignRasterLayers::parameterAsItems( layersVariant, context );
79 bool unconfiguredLayers = false;
80 for ( const QgsAlignRasterData::RasterItem &item : items )
81 {
82 if ( item.outputFilename.isEmpty() )
83 {
84 unconfiguredLayers = true;
85 break;
86 }
87 }
88 if ( unconfiguredLayers )
89 {
90 *message = QObject::tr( "An output file is not configured for one or more input layers. Configure output files via 'Configure Raster…' under Input layers parameter." );
91 return false;
92 }
93 return QgsProcessingAlgorithm::checkParameterValues( parameters, context );
94}
95
96void QgsAlignRastersAlgorithm::initAlgorithm( const QVariantMap & )
97{
98 addParameter( new QgsProcessingParameterAlignRasterLayers( u"LAYERS"_s, QObject::tr( "Input layers" ) ) );
99 addParameter( new QgsProcessingParameterRasterLayer( u"REFERENCE_LAYER"_s, QObject::tr( "Reference layer" ) ) );
100
101 addParameter( new QgsProcessingParameterCrs( u"CRS"_s, QObject::tr( "Override reference CRS" ), QVariant(), true ) );
102 addParameter( new QgsProcessingParameterNumber( u"CELL_SIZE_X"_s, QObject::tr( "Override reference cell size X" ), Qgis::ProcessingNumberParameterType::Double, QVariant(), true, 1e-9 ) );
103 addParameter( new QgsProcessingParameterNumber( u"CELL_SIZE_Y"_s, QObject::tr( "Override reference cell size Y" ), Qgis::ProcessingNumberParameterType::Double, QVariant(), true, 1e-9 ) );
104 addParameter( new QgsProcessingParameterNumber( u"GRID_OFFSET_X"_s, QObject::tr( "Override reference grid offset X" ), Qgis::ProcessingNumberParameterType::Double, QVariant(), true, 1e-9 ) );
105 addParameter( new QgsProcessingParameterNumber( u"GRID_OFFSET_Y"_s, QObject::tr( "Override reference grid offset Y" ), Qgis::ProcessingNumberParameterType::Double, QVariant(), true, 1e-9 ) );
106 addParameter( new QgsProcessingParameterExtent( u"EXTENT"_s, QObject::tr( "Clip to extent" ), QVariant(), true ) );
107
108 addOutput( new QgsProcessingOutputMultipleLayers( u"OUTPUT_LAYERS"_s, QObject::tr( "Aligned rasters" ) ) );
109}
110
111QVariantMap QgsAlignRastersAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
112{
113 QGS_MARK_ALGORITHM_SOURCE
114
115 QgsRasterLayer *referenceLayer = parameterAsRasterLayer( parameters, u"REFERENCE_LAYER"_s, context );
116 if ( !referenceLayer )
117 throw QgsProcessingException( invalidRasterError( parameters, u"REFERENCE_LAYER"_s ) );
118
119 const QVariant layersVariant = parameters.value( parameterDefinition( u"LAYERS"_s )->name() );
120 const QList<QgsAlignRasterData::RasterItem> items = QgsProcessingParameterAlignRasterLayers::parameterAsItems( layersVariant, context );
121 QStringList outputLayers;
122 outputLayers.reserve( items.size() );
123 for ( const QgsAlignRasterData::RasterItem &item : items )
124 {
125 outputLayers << item.outputFilename;
126 }
127
128 QgsAlignRaster rasterAlign;
129 rasterAlign.setRasters( items );
130
131 QString customCRSWkt;
132 QSizeF customCellSize;
133 QPointF customGridOffset( -1, -1 );
134
135 if ( parameters.value( u"CRS"_s ).isValid() )
136 {
137 QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, u"CRS"_s, context );
138 customCRSWkt = crs.toWkt( Qgis::CrsWktVariant::PreferredGdal );
139 }
140
141 bool hasXValue = parameters.value( u"CELL_SIZE_X"_s ).isValid();
142 bool hasYValue = parameters.value( u"CELL_SIZE_Y"_s ).isValid();
143 if ( ( hasXValue && !hasYValue ) || ( !hasXValue && hasYValue ) )
144 {
145 throw QgsProcessingException( QObject::tr( "Either set both X and Y cell size values or keep both as 'Not set'." ) );
146 }
147 else if ( hasXValue && hasYValue )
148 {
149 double xSize = parameterAsDouble( parameters, u"CELL_SIZE_X"_s, context );
150 double ySize = parameterAsDouble( parameters, u"CELL_SIZE_Y"_s, context );
151 customCellSize = QSizeF( xSize, ySize );
152 }
153
154 hasXValue = parameters.value( u"GRID_OFFSET_X"_s ).isValid();
155 hasYValue = parameters.value( u"GRID_OFFSET_Y"_s ).isValid();
156 if ( ( hasXValue && !hasYValue ) || ( !hasXValue && hasYValue ) )
157 {
158 throw QgsProcessingException( QObject::tr( "Either set both X and Y grid offset values or keep both as 'Not set'." ) );
159 }
160 else if ( hasXValue && hasYValue )
161 {
162 double xSize = parameterAsDouble( parameters, u"GRID_OFFSET_X"_s, context );
163 double ySize = parameterAsDouble( parameters, u"GRID_OFFSET_Y"_s, context );
164 customGridOffset = QPointF( xSize, ySize );
165 }
166
167 if ( parameters.value( u"EXTENT"_s ).isValid() )
168 {
169 QgsRectangle extent = parameterAsExtent( parameters, u"EXTENT"_s, context );
170 rasterAlign.setClipExtent( extent );
171 }
172
173 struct QgsAlignRasterProgress : public QgsAlignRaster::ProgressHandler
174 {
175 explicit QgsAlignRasterProgress( QgsFeedback *feedback )
176 : mFeedback( feedback )
177 {}
178 bool progress( double complete ) override
179 {
180 mFeedback->setProgress( complete * 100 );
181 return true;
182 }
183
184 protected:
185 QgsFeedback *mFeedback = nullptr;
186 };
187
188 rasterAlign.setProgressHandler( new QgsAlignRasterProgress( feedback ) );
189
190 bool result = rasterAlign.setParametersFromRaster( referenceLayer->source(), customCRSWkt, customCellSize, customGridOffset );
191 if ( !result )
192 {
193 throw QgsProcessingException( QObject::tr( "It is not possible to reproject reference raster to target CRS." ) );
194 }
195
196 result = rasterAlign.run();
197 if ( !result )
198 {
199 throw QgsProcessingException( QObject::tr( "Failed to align rasters: %1" ).arg( rasterAlign.errorMessage() ) );
200 }
201
202 QVariantMap outputs;
203 outputs.insert( u"OUTPUT_LAYERS"_s, outputLayers );
204 return outputs;
205}
206
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition qgis.h:3826
@ PreferredGdal
Preferred format for conversion of CRS to WKT for use with the GDAL library.
Definition qgis.h:2614
@ HideFromModeler
Algorithm should be hidden from the modeler.
Definition qgis.h:3801
@ Double
Double/float values.
Definition qgis.h:4023
Takes one or more raster layers and warps (resamples) them to a common grid.
bool setParametersFromRaster(const RasterInfo &rasterInfo, const QString &customCRSWkt=QString(), QSizeF customCellSize=QSizeF(), QPointF customGridOffset=QPointF(-1, -1))
Set destination CRS, cell size and grid offset from a raster file.
bool run()
Run the alignment process.
void setClipExtent(double xmin, double ymin, double xmax, double ymax)
Configure clipping extent (region of interest).
void setProgressHandler(ProgressHandler *progressHandler)
Assign a progress handler instance. Does not take ownership. nullptr can be passed.
QString errorMessage() const
Returns the error from a previous run() call.
void setRasters(const List &list)
Sets list of rasters that will be aligned.
Represents a coordinate reference system (CRS).
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
virtual Qgis::ProcessingAlgorithmFlags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
virtual bool checkParameterValues(const QVariantMap &parameters, QgsProcessingContext &context, QString *message=nullptr) const
Checks the supplied parameter values to verify that they satisfy the requirements of this algorithm i...
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
A multi-layer output for processing algorithms which create map layers, when the number and nature of...
A parameter for Processing algorithms specifying how rasters should be aligned.
static QList< QgsAlignRasterData::RasterItem > parameterAsItems(const QVariant &layersVariant, QgsProcessingContext &context)
Converts a QVariant value (a QVariantList) to a list of input layers.
A coordinate reference system parameter for processing algorithms.
A rectangular map extent parameter for processing algorithms.
A numeric parameter for processing algorithms.
A raster layer parameter for processing algorithms.
Represents a raster layer.
A rectangle specified with double values.
Definition of one raster layer for alignment.
Helper struct to be sub-classed for progress reporting.
virtual bool progress(double complete)=0
Method to be overridden for progress reporting.