Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsrasterfilewriter.h
3 : : ---------------------
4 : : begin : July 2012
5 : : copyright : (C) 2012 by Marco Hugentobler
6 : : email : marco dot hugentobler at sourcepole dot ch
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 : : #ifndef QGSRASTERFILEWRITER_H
16 : : #define QGSRASTERFILEWRITER_H
17 : :
18 : : #include "qgis_core.h"
19 : : #include "qgscoordinatereferencesystem.h"
20 : : #include "qgscoordinatetransformcontext.h"
21 : : #include <QDomDocument>
22 : : #include <QDomElement>
23 : : #include <QString>
24 : : #include <QStringList>
25 : :
26 : : #include "qgsraster.h"
27 : :
28 : : class QgsRasterBlockFeedback;
29 : : class QgsRasterIterator;
30 : : class QgsRasterPipe;
31 : : class QgsRectangle;
32 : : class QgsRasterDataProvider;
33 : : class QgsRasterInterface;
34 : :
35 : : /**
36 : : * \ingroup core
37 : : * \brief The raster file writer which allows you to save a raster to a new file.
38 : : */
39 : 0 : class CORE_EXPORT QgsRasterFileWriter
40 : : {
41 : : public:
42 : : enum Mode
43 : : {
44 : : Raw = 0, //!< Raw data
45 : : Image = 1 //!< Rendered image
46 : : };
47 : : enum WriterError
48 : : {
49 : : NoError = 0,
50 : : SourceProviderError = 1,
51 : : DestProviderError = 2,
52 : : CreateDatasourceError = 3,
53 : : WriteError = 4,
54 : : NoDataConflict = 5, //!< Internal error if a value used for 'no data' was found in input
55 : : WriteCanceled = 6, //!< Writing was manually canceled
56 : : };
57 : :
58 : : /**
59 : : * Options for sorting and filtering raster formats.
60 : : * \since QGIS 3.0
61 : : */
62 : : enum RasterFormatOption
63 : : {
64 : : SortRecommended = 1 << 1, //!< Use recommended sort order, with extremely commonly used formats listed first
65 : : };
66 : : Q_DECLARE_FLAGS( RasterFormatOptions, RasterFormatOption )
67 : :
68 : : QgsRasterFileWriter( const QString &outputUrl );
69 : :
70 : : /**
71 : : * Create a raster file with one band without initializing the pixel data.
72 : : * Returned provider may be used to initialize the raster using writeBlock() calls.
73 : : * Ownership of the returned provider is passed to the caller.
74 : : * \returns Instance of data provider in editing mode (on success) or NULLPTR on error.
75 : : * \note Does not work with tiled mode enabled.
76 : : * \since QGIS 3.0
77 : : */
78 : : QgsRasterDataProvider *createOneBandRaster( Qgis::DataType dataType,
79 : : int width, int height,
80 : : const QgsRectangle &extent,
81 : : const QgsCoordinateReferenceSystem &crs ) SIP_FACTORY;
82 : :
83 : : /**
84 : : * Create a raster file with given number of bands without initializing the pixel data.
85 : : * Returned provider may be used to initialize the raster using writeBlock() calls.
86 : : * Ownership of the returned provider is passed to the caller.
87 : : * \returns Instance of data provider in editing mode (on success) or NULLPTR on error.
88 : : * \note Does not work with tiled mode enabled.
89 : : * \since QGIS 3.0
90 : : */
91 : : QgsRasterDataProvider *createMultiBandRaster( Qgis::DataType dataType,
92 : : int width, int height,
93 : : const QgsRectangle &extent,
94 : : const QgsCoordinateReferenceSystem &crs,
95 : : int nBands ) SIP_FACTORY;
96 : :
97 : :
98 : : /**
99 : : * Write raster file
100 : : * \param pipe raster pipe
101 : : * \param nCols number of output columns
102 : : * \param nRows number of output rows (or -1 to automatically calculate row number to have square pixels)
103 : : * \param outputExtent extent to output
104 : : * \param crs crs to reproject to
105 : : * \param feedback optional feedback object for progress reports
106 : : * \deprecated since QGIS 3.8, use version with transformContext instead
107 : : */
108 : : Q_DECL_DEPRECATED WriterError writeRaster( const QgsRasterPipe *pipe, int nCols, int nRows, const QgsRectangle &outputExtent,
109 : : const QgsCoordinateReferenceSystem &crs, QgsRasterBlockFeedback *feedback = nullptr ) SIP_DEPRECATED;
110 : :
111 : : /**
112 : : * Write raster file
113 : : * \param pipe raster pipe
114 : : * \param nCols number of output columns
115 : : * \param nRows number of output rows (or -1 to automatically calculate row number to have square pixels)
116 : : * \param outputExtent extent to output
117 : : * \param crs crs to reproject to
118 : : * \param transformContext coordinate transform context
119 : : * \param feedback optional feedback object for progress reports
120 : : * \since QGIS 3.8
121 : : */
122 : : WriterError writeRaster( const QgsRasterPipe *pipe, int nCols, int nRows, const QgsRectangle &outputExtent,
123 : : const QgsCoordinateReferenceSystem &crs,
124 : : const QgsCoordinateTransformContext &transformContext,
125 : : QgsRasterBlockFeedback *feedback = nullptr );
126 : :
127 : :
128 : : /**
129 : : * Returns the output URL for the raster.
130 : : * \since QGIS 3.0
131 : : */
132 : 0 : QString outputUrl() const { return mOutputUrl; }
133 : :
134 : 0 : void setOutputFormat( const QString &format ) { mOutputFormat = format; }
135 : : QString outputFormat() const { return mOutputFormat; }
136 : :
137 : 0 : void setOutputProviderKey( const QString &key ) { mOutputProviderKey = key; }
138 : : QString outputProviderKey() const { return mOutputProviderKey; }
139 : :
140 : : void setTiledMode( bool t ) { mTiledMode = t; }
141 : : bool tiledMode() const { return mTiledMode; }
142 : :
143 : : void setMaxTileWidth( int w ) { mMaxTileWidth = w; }
144 : : int maxTileWidth() const { return mMaxTileWidth; }
145 : :
146 : : QgsRaster::RasterBuildPyramids buildPyramidsFlag() const { return mBuildPyramidsFlag; }
147 : : void setBuildPyramidsFlag( QgsRaster::RasterBuildPyramids f ) { mBuildPyramidsFlag = f; }
148 : :
149 : : QList< int > pyramidsList() const { return mPyramidsList; }
150 : : void setPyramidsList( const QList< int > &list ) { mPyramidsList = list; }
151 : :
152 : : QString pyramidsResampling() const { return mPyramidsResampling; }
153 : : void setPyramidsResampling( const QString &str ) { mPyramidsResampling = str; }
154 : :
155 : : QgsRaster::RasterPyramidsFormat pyramidsFormat() const { return mPyramidsFormat; }
156 : : void setPyramidsFormat( QgsRaster::RasterPyramidsFormat f ) { mPyramidsFormat = f; }
157 : :
158 : : void setMaxTileHeight( int h ) { mMaxTileHeight = h; }
159 : : int maxTileHeight() const { return mMaxTileHeight; }
160 : :
161 : : void setCreateOptions( const QStringList &list ) { mCreateOptions = list; }
162 : : QStringList createOptions() const { return mCreateOptions; }
163 : :
164 : : void setPyramidsConfigOptions( const QStringList &list ) { mPyramidsConfigOptions = list; }
165 : : QStringList pyramidsConfigOptions() const { return mPyramidsConfigOptions; }
166 : :
167 : : //! Creates a filter for an GDAL driver key
168 : : static QString filterForDriver( const QString &driverName );
169 : :
170 : : /**
171 : : * Details of available filters and formats.
172 : : * \since QGIS 3.0
173 : : */
174 : 0 : struct FilterFormatDetails
175 : : {
176 : : //! Unique driver name
177 : : QString driverName;
178 : :
179 : : //! Filter string for file picker dialogs
180 : : QString filterString;
181 : : };
182 : :
183 : : /**
184 : : * Returns a list or pairs, with format filter string as first element and GDAL format key as second element.
185 : : * Relies on GDAL_DMD_EXTENSIONS metadata, if it is empty corresponding driver will be skipped even if supported.
186 : : *
187 : : * The \a options argument can be used to control the sorting and filtering of
188 : : * returned formats.
189 : : *
190 : : * \see supportedFormatExtensions()
191 : : */
192 : : static QList< QgsRasterFileWriter::FilterFormatDetails > supportedFiltersAndFormats( RasterFormatOptions options = SortRecommended );
193 : :
194 : : /**
195 : : * Returns a list of file extensions for supported formats.
196 : : *
197 : : * The \a options argument can be used to control the sorting and filtering of
198 : : * returned formats.
199 : : *
200 : : * \see supportedFiltersAndFormats()
201 : : * \since QGIS 3.0
202 : : */
203 : : static QStringList supportedFormatExtensions( RasterFormatOptions options = SortRecommended );
204 : :
205 : : /**
206 : : * Returns the GDAL driver name for a specified file \a extension. E.g. the
207 : : * driver name for the ".tif" extension is "GTiff".
208 : : * If no suitable drivers are found then an empty string is returned.
209 : : *
210 : : * Note that this method works for all GDAL drivers, including those without create support
211 : : * (and which are not supported by QgsRasterFileWriter).
212 : : *
213 : : * \since QGIS 3.0
214 : : */
215 : : static QString driverForExtension( const QString &extension );
216 : :
217 : : /**
218 : : * Returns a list of known file extensions for the given GDAL driver \a format.
219 : : * E.g. returns "tif", "tiff" for the format "GTiff".
220 : : *
221 : : * If no matching format driver is found an empty list will be returned.
222 : : *
223 : : * Note that this method works for all GDAL drivers, including those without create support
224 : : * (and which are not supported by QgsRasterFileWriter).
225 : : *
226 : : * \since QGIS 3.0
227 : : */
228 : : static QStringList extensionsForFormat( const QString &format );
229 : :
230 : : private:
231 : : QgsRasterFileWriter(); //forbidden
232 : : WriterError writeDataRaster( const QgsRasterPipe *pipe, QgsRasterIterator *iter, int nCols, int nRows, const QgsRectangle &outputExtent,
233 : : const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &transformContext,
234 : : QgsRasterBlockFeedback *feedback = nullptr );
235 : :
236 : : // Helper method used by previous one
237 : : WriterError writeDataRaster( const QgsRasterPipe *pipe,
238 : : QgsRasterIterator *iter,
239 : : int nCols, int nRows,
240 : : const QgsRectangle &outputExtent,
241 : : const QgsCoordinateReferenceSystem &crs,
242 : : Qgis::DataType destDataType,
243 : : const QList<bool> &destHasNoDataValueList,
244 : : const QList<double> &destNoDataValueList,
245 : : QgsRasterDataProvider *destProvider,
246 : : QgsRasterBlockFeedback *feedback = nullptr );
247 : :
248 : : WriterError writeImageRaster( QgsRasterIterator *iter, int nCols, int nRows, const QgsRectangle &outputExtent,
249 : : const QgsCoordinateReferenceSystem &crs,
250 : : QgsRasterBlockFeedback *feedback = nullptr );
251 : :
252 : : /**
253 : : * \brief Initialize vrt member variables
254 : : * \param xSize width of vrt
255 : : * \param ySize height of vrt
256 : : * \param crs coordinate system of vrt
257 : : * \param geoTransform optional array of transformation matrix values
258 : : * \param type datatype of vrt
259 : : * \param destHasNoDataValueList TRUE if destination has no data value, indexed from 0
260 : : * \param destNoDataValueList no data value, indexed from 0
261 : : */
262 : : void createVRT( int xSize, int ySize, const QgsCoordinateReferenceSystem &crs, double *geoTransform, Qgis::DataType type, const QList<bool> &destHasNoDataValueList, const QList<double> &destNoDataValueList );
263 : : //write vrt document to disk
264 : : bool writeVRT( const QString &file );
265 : : //add file entry to vrt
266 : : void addToVRT( const QString &filename, int band, int xSize, int ySize, int xOffset, int yOffset );
267 : : void buildPyramids( const QString &filename, QgsRasterDataProvider *destProviderIn = nullptr );
268 : :
269 : : //! Create provider and datasource for a part image (vrt mode)
270 : : QgsRasterDataProvider *createPartProvider( const QgsRectangle &extent, int nCols, int iterCols, int iterRows,
271 : : int iterLeft, int iterTop,
272 : : const QString &outputUrl, int fileIndex, int nBands, Qgis::DataType type,
273 : : const QgsCoordinateReferenceSystem &crs );
274 : :
275 : : /**
276 : : * \brief Init VRT (for tiled mode) or create global output provider (single-file mode)
277 : : * \param nCols number of tile columns
278 : : * \param nRows number of tile rows
279 : : * \param crs coordinate system of vrt
280 : : * \param geoTransform optional array of transformation matrix values
281 : : * \param nBands number of bands
282 : : * \param type datatype of vrt
283 : : * \param destHasNoDataValueList TRUE if destination has no data value, indexed from 0
284 : : * \param destNoDataValueList no data value, indexed from 0
285 : : */
286 : : QgsRasterDataProvider *initOutput( int nCols, int nRows,
287 : : const QgsCoordinateReferenceSystem &crs, double *geoTransform, int nBands,
288 : : Qgis::DataType type,
289 : : const QList<bool> &destHasNoDataValueList = QList<bool>(), const QList<double> &destNoDataValueList = QList<double>() );
290 : :
291 : : //! Calculate nRows, geotransform and pixel size for output
292 : : void globalOutputParameters( const QgsRectangle &extent, int nCols, int &nRows, double *geoTransform, double &pixelSize );
293 : :
294 : : QString partFileName( int fileIndex );
295 : : QString vrtFileName();
296 : :
297 : : Mode mMode = Raw;
298 : : QString mOutputUrl;
299 : 0 : QString mOutputProviderKey = QStringLiteral( "gdal" );
300 : 0 : QString mOutputFormat = QStringLiteral( "GTiff" );
301 : : QStringList mCreateOptions;
302 : : QgsCoordinateReferenceSystem mOutputCRS;
303 : :
304 : : //! False: Write one file, TRUE: create a directory and add the files numbered
305 : : bool mTiledMode = false;
306 : : int mMaxTileWidth = 500;
307 : : int mMaxTileHeight = 500;
308 : :
309 : : QList< int > mPyramidsList;
310 : 0 : QString mPyramidsResampling = QStringLiteral( "AVERAGE" );
311 : : QgsRaster::RasterBuildPyramids mBuildPyramidsFlag = QgsRaster::PyramidsFlagNo;
312 : : QgsRaster::RasterPyramidsFormat mPyramidsFormat = QgsRaster::PyramidsGTiff;
313 : : QStringList mPyramidsConfigOptions;
314 : :
315 : : QDomDocument mVRTDocument;
316 : : QList<QDomElement> mVRTBands;
317 : :
318 : : QgsRasterBlockFeedback *mFeedback = nullptr;
319 : :
320 : : const QgsRasterPipe *mPipe = nullptr;
321 : : const QgsRasterInterface *mInput = nullptr;
322 : : };
323 : :
324 : : #endif // QGSRASTERFILEWRITER_H
|