Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsalignraster.h
3 : : --------------------------------------
4 : : Date : June 2015
5 : : Copyright : (C) 2015 by Martin Dobias
6 : : Email : wonder dot sk at gmail dot com
7 : : ***************************************************************************
8 : : * *
9 : : * This program is free software; you can redistribute it and/or modify *
10 : : * it under the terms of the GNU General Public License as published by *
11 : : * the Free Software Foundation; either version 2 of the License, or *
12 : : * (at your option) any later version. *
13 : : * *
14 : : ***************************************************************************/
15 : :
16 : : #ifndef QGSALIGNRASTER_H
17 : : #define QGSALIGNRASTER_H
18 : :
19 : : #include <QList>
20 : : #include <QPointF>
21 : : #include <QSizeF>
22 : : #include <QString>
23 : : #include <gdal_version.h>
24 : : #include "qgis_analysis.h"
25 : : #include "qgis_sip.h"
26 : : #include "qgsogrutils.h"
27 : :
28 : : class QgsRectangle;
29 : :
30 : : typedef void *GDALDatasetH SIP_SKIP;
31 : :
32 : :
33 : : /**
34 : : * \ingroup analysis
35 : : * \brief QgsAlignRaster takes one or more raster layers and warps (resamples) them
36 : : * so they have the same:
37 : : *
38 : : * - coordinate reference system
39 : : * - cell size and raster size
40 : : * - offset of the raster grid
41 : : *
42 : : * \since QGIS 2.12
43 : : */
44 : : class ANALYSIS_EXPORT QgsAlignRaster
45 : : {
46 : : #ifdef SIP_RUN
47 : : #include <gdal_version.h>
48 : : #endif
49 : :
50 : : public:
51 : : QgsAlignRaster();
52 : :
53 : : //! Utility class for gathering information about rasters
54 : 0 : struct ANALYSIS_EXPORT RasterInfo
55 : : {
56 : : public:
57 : : //! Construct raster info with a path to a raster file
58 : : RasterInfo( const QString &layerpath );
59 : :
60 : : RasterInfo( const RasterInfo &rh ) = delete;
61 : : RasterInfo &operator=( const RasterInfo &rh ) = delete;
62 : :
63 : : //! Check whether the given path is a valid raster
64 : : bool isValid() const { return nullptr != mDataset; }
65 : :
66 : : //! Returns the CRS in WKT format
67 : 0 : QString crs() const { return mCrsWkt; }
68 : : //! Returns the size of the raster grid in pixels
69 : : QSize rasterSize() const { return QSize( mXSize, mYSize ); }
70 : : //! Returns the number of raster bands in the file
71 : : int bandCount() const { return mBandCnt; }
72 : : //! Returns the cell size in map units
73 : : QSizeF cellSize() const;
74 : : //! Returns the grid offset
75 : : QPointF gridOffset() const;
76 : : //! Returns the extent of the raster
77 : : QgsRectangle extent() const;
78 : : //! Returns the origin of the raster
79 : : QPointF origin() const;
80 : :
81 : : //! Write contents of the object to standard error stream - for debugging
82 : : void dump() const;
83 : :
84 : : //! Gets raster value at the given coordinates (from the first band)
85 : : double identify( double mx, double my );
86 : :
87 : : protected:
88 : : //! handle to open GDAL dataset
89 : : gdal::dataset_unique_ptr mDataset;
90 : : //! CRS stored in WKT format
91 : : QString mCrsWkt;
92 : : //! geotransform coefficients
93 : : double mGeoTransform[6];
94 : : //! raster grid size X
95 : : int mXSize = 0;
96 : : //! raster grid size Y
97 : : int mYSize = 0;
98 : : //! number of raster's bands
99 : : int mBandCnt = 0;
100 : :
101 : : private:
102 : : #ifdef SIP_RUN
103 : : RasterInfo( const QgsAlignRaster::RasterInfo &rh );
104 : : #endif
105 : :
106 : : friend class QgsAlignRaster;
107 : : };
108 : :
109 : :
110 : : /**
111 : : * Resampling algorithm to be used (equivalent to GDAL's enum GDALResampleAlg)
112 : : * \note RA_Max, RA_Min, RA_Median, RA_Q1 and RA_Q3 are available on GDAL >= 2.0 builds only
113 : : */
114 : : enum ResampleAlg
115 : : {
116 : : RA_NearestNeighbour = 0, //!< Nearest neighbour (select on one input pixel)
117 : : RA_Bilinear = 1, //!< Bilinear (2x2 kernel)
118 : : RA_Cubic = 2, //!< Cubic Convolution Approximation (4x4 kernel)
119 : : RA_CubicSpline = 3, //!< Cubic B-Spline Approximation (4x4 kernel)
120 : : RA_Lanczos = 4, //!< Lanczos windowed sinc interpolation (6x6 kernel)
121 : : RA_Average = 5, //!< Average (computes the average of all non-NODATA contributing pixels)
122 : : RA_Mode = 6, //!< Mode (selects the value which appears most often of all the sampled points)
123 : : RA_Max = 8, //!< Maximum (selects the maximum of all non-NODATA contributing pixels)
124 : : RA_Min = 9, //!< Minimum (selects the minimum of all non-NODATA contributing pixels)
125 : : RA_Median = 10, //!< Median (selects the median of all non-NODATA contributing pixels)
126 : : RA_Q1 = 11, //!< First quartile (selects the first quartile of all non-NODATA contributing pixels)
127 : : RA_Q3 = 12, //!< Third quartile (selects the third quartile of all non-NODATA contributing pixels)
128 : : };
129 : :
130 : : //! Definition of one raster layer for alignment
131 : 0 : struct Item
132 : : {
133 : : Item( const QString &input, const QString &output )
134 : : : inputFilename( input )
135 : : , outputFilename( output )
136 : : , resampleMethod( RA_NearestNeighbour )
137 : : , rescaleValues( false )
138 : : , srcCellSizeInDestCRS( 0.0 )
139 : : {}
140 : :
141 : : //! filename of the source raster
142 : : QString inputFilename;
143 : : //! filename of the newly created aligned raster (will be overwritten if exists already)
144 : : QString outputFilename;
145 : : //! resampling method to be used
146 : : QgsAlignRaster::ResampleAlg resampleMethod;
147 : : //! rescaling of values according to the change of pixel size
148 : : bool rescaleValues;
149 : :
150 : : // private part
151 : :
152 : : //! used for rescaling of values (if necessary)
153 : : double srcCellSizeInDestCRS;
154 : : };
155 : : typedef QList<QgsAlignRaster::Item> List;
156 : :
157 : : //! Helper struct to be sub-classed for progress reporting
158 : : struct ProgressHandler
159 : : {
160 : :
161 : : /**
162 : : * Method to be overridden for progress reporting.
163 : : * \param complete Overall progress of the alignment operation
164 : : * \returns FALSE if the execution should be canceled, TRUE otherwise
165 : : */
166 : : virtual bool progress( double complete ) = 0;
167 : :
168 : : virtual ~ProgressHandler() = default;
169 : : };
170 : :
171 : : //! Assign a progress handler instance. Does not take ownership. NULLPTR can be passed.
172 : : void setProgressHandler( ProgressHandler *progressHandler ) { mProgressHandler = progressHandler; }
173 : : //! Gets associated progress handler. May be NULLPTR (default)
174 : 0 : ProgressHandler *progressHandler() const { return mProgressHandler; }
175 : :
176 : : //! Sets list of rasters that will be aligned
177 : : void setRasters( const List &list ) { mRasters = list; }
178 : : //! Gets list of rasters that will be aligned
179 : : List rasters() const { return mRasters; }
180 : :
181 : : void setGridOffset( QPointF offset ) { mGridOffsetX = offset.x(); mGridOffsetY = offset.y(); }
182 : : QPointF gridOffset() const { return QPointF( mGridOffsetX, mGridOffsetY ); }
183 : :
184 : : //! Sets output cell size
185 : : void setCellSize( double x, double y ) { setCellSize( QSizeF( x, y ) ); }
186 : : //! Sets output cell size
187 : : void setCellSize( QSizeF size ) { mCellSizeX = size.width(); mCellSizeY = size.height(); }
188 : : //! Gets output cell size
189 : : QSizeF cellSize() const { return QSizeF( mCellSizeX, mCellSizeY ); }
190 : :
191 : : //! Sets the output CRS in WKT format
192 : : void setDestinationCrs( const QString &crsWkt ) { mCrsWkt = crsWkt; }
193 : : //! Gets the output CRS in WKT format
194 : : QString destinationCrs() const { return mCrsWkt; }
195 : :
196 : : /**
197 : : * Configure clipping extent (region of interest).
198 : : * No extra clipping is done if the rectangle is null
199 : : */
200 : : void setClipExtent( double xmin, double ymin, double xmax, double ymax );
201 : :
202 : : /**
203 : : * Configure clipping extent (region of interest).
204 : : * No extra clipping is done if the rectangle is null
205 : : */
206 : : void setClipExtent( const QgsRectangle &extent );
207 : :
208 : : /**
209 : : * Gets clipping extent (region of interest).
210 : : * No extra clipping is done if the rectangle is null
211 : : */
212 : : QgsRectangle clipExtent() const;
213 : :
214 : : /**
215 : : * Set destination CRS, cell size and grid offset from a raster file.
216 : : * The user may provide custom values for some of the parameters - in such case
217 : : * only the remaining parameters are calculated.
218 : : *
219 : : * If default CRS is used, the parameters are set according to the raster file's geo-transform.
220 : : * If a custom CRS is provided, suggested reprojection is calculated first (using GDAL) in order
221 : : * to determine suitable defaults for cell size and grid offset.
222 : : *
223 : : * \returns TRUE on success (may fail if it is not possible to reproject raster to given CRS)
224 : : */
225 : : bool setParametersFromRaster( const RasterInfo &rasterInfo, const QString &customCRSWkt = QString(), QSizeF customCellSize = QSizeF(), QPointF customGridOffset = QPointF( -1, -1 ) );
226 : :
227 : : /**
228 : : * Overridden variant for convenience, taking filename instead RasterInfo object.
229 : : * See the other variant for details.
230 : : */
231 : : bool setParametersFromRaster( const QString &filename, const QString &customCRSWkt = QString(), QSizeF customCellSize = QSizeF(), QPointF customGridOffset = QPointF( -1, -1 ) );
232 : :
233 : : /**
234 : : * Determine destination extent from the input rasters and calculate derived values
235 : : * \returns TRUE on success, sets error on error (see errorMessage())
236 : : */
237 : : bool checkInputParameters();
238 : :
239 : : /**
240 : : * Returns the expected size of the resulting aligned raster
241 : : * \note first need to run checkInputParameters() which returns with success
242 : : */
243 : : QSize alignedRasterSize() const;
244 : :
245 : : /**
246 : : * Returns the expected extent of the resulting aligned raster
247 : : * \note first need to run checkInputParameters() which returns with success
248 : : */
249 : : QgsRectangle alignedRasterExtent() const;
250 : :
251 : : /**
252 : : * Run the alignment process
253 : : * \returns TRUE on success, sets error on error (see errorMessage())
254 : : */
255 : : bool run();
256 : :
257 : : /**
258 : : * Returns the error from a previous run() call.
259 : : * Error message is empty if run() succeeded (returned TRUE)
260 : : */
261 : : QString errorMessage() const { return mErrorMessage; }
262 : :
263 : : //! write contents of the object to standard error stream - for debugging
264 : : void dump() const;
265 : :
266 : : //! Returns the index of the layer which has smallest cell size (returns -1 on error)
267 : : int suggestedReferenceLayer() const;
268 : :
269 : : protected:
270 : :
271 : : //! Internal function for processing of one raster (1. create output, 2. do the alignment)
272 : : bool createAndWarp( const Item &raster );
273 : :
274 : : //! Determine suggested output of raster warp to a different CRS. Returns TRUE on success
275 : : static bool suggestedWarpOutput( const RasterInfo &info, const QString &destWkt, QSizeF *cellSize = nullptr, QPointF *gridOffset = nullptr, QgsRectangle *rect = nullptr );
276 : :
277 : : protected:
278 : :
279 : : // set by the client
280 : :
281 : : //! Object that facilitates reporting of progress / cancellation
282 : : ProgressHandler *mProgressHandler = nullptr;
283 : :
284 : : //! Last error message from run()
285 : : QString mErrorMessage;
286 : :
287 : : //! List of rasters to be aligned (with their output files and other options)
288 : : List mRasters;
289 : :
290 : : //! Destination CRS - stored in well-known text (WKT) format
291 : : QString mCrsWkt;
292 : : //! Destination cell size
293 : : double mCellSizeX, mCellSizeY;
294 : : //! Destination grid offset - expected to be in interval <0,cellsize)
295 : : double mGridOffsetX, mGridOffsetY;
296 : :
297 : : /**
298 : : * Optional clip extent: sets "requested area" which be extended to fit the raster grid.
299 : : * Clipping not done if all coords are zeroes.
300 : : */
301 : : double mClipExtent[4];
302 : :
303 : : // derived data from other members
304 : :
305 : : //! Computed geo-transform
306 : : double mGeoTransform[6];
307 : : //! Computed raster grid width
308 : : int mXSize;
309 : :
310 : : //! Computed raster grid height
311 : : int mYSize;
312 : :
313 : : };
314 : :
315 : :
316 : : #endif // QGSALIGNRASTER_H
|