Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsrasterlayer.h - description
3 : : -------------------
4 : : begin : Fri Jun 28 2002
5 : : copyright : (C) 2004 by T.Sutton, Gary E.Sherman, Steve Halasz
6 : : email : tim@linfiniti.com
7 : : ***************************************************************************/
8 : : /*
9 : : * Peter J. Ersts - contributed to the refactoring and maintenance of this class
10 : : * B. Morley - added functions to convert this class to a data provider interface
11 : : * Frank Warmerdam - contributed bug fixes and migrated class to use all GDAL_C_API calls
12 : : */
13 : : /***************************************************************************
14 : : * *
15 : : * This program is free software; you can redistribute it and/or modify *
16 : : * it under the terms of the GNU General Public License as published by *
17 : : * the Free Software Foundation; either version 2 of the License, or *
18 : : * (at your option) any later version. *
19 : : * *
20 : : ***************************************************************************/
21 : : #ifndef QGSRASTERLAYER_H
22 : : #define QGSRASTERLAYER_H
23 : :
24 : : #include "qgis_core.h"
25 : : #include "qgis_sip.h"
26 : : #include <QColor>
27 : : #include <QDateTime>
28 : : #include <QList>
29 : : #include <QMap>
30 : : #include <QPair>
31 : : #include <QVector>
32 : :
33 : : #include "qgis_sip.h"
34 : : #include "qgsmaplayer.h"
35 : : #include "qgsraster.h"
36 : : #include "qgsrasterdataprovider.h"
37 : : #include "qgsrasterpipe.h"
38 : : #include "qgsrasterviewport.h"
39 : : #include "qgsrasterminmaxorigin.h"
40 : : #include "qgscontrastenhancement.h"
41 : :
42 : : class QgsMapToPixel;
43 : : class QgsRasterRenderer;
44 : : class QgsRectangle;
45 : : class QgsRasterLayerTemporalProperties;
46 : :
47 : : class QImage;
48 : : class QPixmap;
49 : : class QSlider;
50 : :
51 : : typedef QList < QPair< QString, QColor > > QgsLegendColorList;
52 : :
53 : : /**
54 : : * \ingroup core
55 : : *
56 : : * \brief Represents a raster layer.
57 : : *
58 : : * A QgsRasterLayer is instantiated by specifying the name of a data provider,
59 : : * such as "gdal" or "wms", and a url defining the specific data set to connect to.
60 : : * The raster layer constructor in turn instantiates a QgsRasterDataProvider subclass
61 : : * corresponding to the provider type, and passes it the url. The data provider
62 : : * connects to the data source.
63 : : *
64 : : * Sample usage of the QgsRasterLayer class:
65 : : *
66 : : * \code{.py}
67 : : * my_raster_layer = QgsRasterLayer("/path/to/file.tif", "my layer")
68 : : * \endcode
69 : : */
70 : : class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
71 : : {
72 : 0 : Q_OBJECT
73 : : public:
74 : :
75 : : //! \brief Default sample size (number of pixels) for estimated statistics/histogram calculation
76 : : static const double SAMPLE_SIZE;
77 : :
78 : : //! \brief Default enhancement algorithm for single band raster
79 : : static const QgsContrastEnhancement::ContrastEnhancementAlgorithm SINGLE_BAND_ENHANCEMENT_ALGORITHM;
80 : :
81 : : //! \brief Default enhancement algorithm for multiple band raster of type Byte
82 : : static const QgsContrastEnhancement::ContrastEnhancementAlgorithm MULTIPLE_BAND_SINGLE_BYTE_ENHANCEMENT_ALGORITHM;
83 : :
84 : : //! \brief Default enhancement algorithm for multiple band raster of type different from Byte
85 : : static const QgsContrastEnhancement::ContrastEnhancementAlgorithm MULTIPLE_BAND_MULTI_BYTE_ENHANCEMENT_ALGORITHM;
86 : :
87 : : //! \brief Default enhancement limits for single band raster
88 : : static const QgsRasterMinMaxOrigin::Limits SINGLE_BAND_MIN_MAX_LIMITS;
89 : :
90 : : //! \brief Default enhancement limits for multiple band raster of type Byte
91 : : static const QgsRasterMinMaxOrigin::Limits MULTIPLE_BAND_SINGLE_BYTE_MIN_MAX_LIMITS;
92 : :
93 : : //! \brief Default enhancement limits for multiple band raster of type different from Byte
94 : : static const QgsRasterMinMaxOrigin::Limits MULTIPLE_BAND_MULTI_BYTE_MIN_MAX_LIMITS;
95 : :
96 : : //! \brief Constructor. Provider is not set.
97 : : QgsRasterLayer();
98 : :
99 : : /**
100 : : * Setting options for loading raster layers.
101 : : * \since QGIS 3.0
102 : : */
103 : 0 : struct LayerOptions
104 : : {
105 : :
106 : : /**
107 : : * Constructor for LayerOptions.
108 : : */
109 : 0 : explicit LayerOptions( bool loadDefaultStyle = true,
110 : : const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext() )
111 : 0 : : loadDefaultStyle( loadDefaultStyle )
112 : 0 : , transformContext( transformContext )
113 : 0 : {}
114 : :
115 : : //! Sets to TRUE if the default layer style should be loaded
116 : : bool loadDefaultStyle = true;
117 : :
118 : : /**
119 : : * Coordinate transform context
120 : : * \since QGIS 3.8
121 : : */
122 : : QgsCoordinateTransformContext transformContext = QgsCoordinateTransformContext();
123 : :
124 : : /**
125 : : * Controls whether the layer is allowed to have an invalid/unknown CRS.
126 : : *
127 : : * If TRUE, then no validation will be performed on the layer's CRS and the layer
128 : : * layer's crs() may be invalid() (i.e. the layer will have no georeferencing available
129 : : * and will be treated as having purely numerical coordinates).
130 : : *
131 : : * If FALSE (the default), the layer's CRS will be validated using QgsCoordinateReferenceSystem::validate(),
132 : : * which may cause a blocking, user-facing dialog asking users to manually select the correct CRS for the
133 : : * layer.
134 : : *
135 : : * \since QGIS 3.10
136 : : */
137 : 0 : bool skipCrsValidation = false;
138 : :
139 : : };
140 : :
141 : : /**
142 : : * \brief This is the constructor for the RasterLayer class.
143 : : *
144 : : * The main tasks carried out by the constructor are:
145 : : *
146 : : * - Load the rasters default style (.qml) file if it exists
147 : : * - Populate the RasterStatsVector with initial values for each band.
148 : : * - Calculate the layer extents
149 : : * - Determine whether the layer is gray, paletted or multiband.
150 : : * - Assign sensible defaults for the red, green, blue and gray bands.
151 : : *
152 : : */
153 : : explicit QgsRasterLayer( const QString &uri,
154 : : const QString &baseName = QString(),
155 : : const QString &providerType = "gdal",
156 : : const QgsRasterLayer::LayerOptions &options = QgsRasterLayer::LayerOptions() );
157 : :
158 : : ~QgsRasterLayer() override;
159 : :
160 : : #ifdef SIP_RUN
161 : : SIP_PYOBJECT __repr__();
162 : : % MethodCode
163 : : QString str = QStringLiteral( "<QgsRasterLayer: '%1' (%2)>" ).arg( sipCpp->name(), sipCpp->dataProvider() ? sipCpp->dataProvider()->name() : QStringLiteral( "Invalid" ) );
164 : : sipRes = PyUnicode_FromString( str.toUtf8().constData() );
165 : : % End
166 : : #endif
167 : :
168 : : /**
169 : : * Returns a new instance equivalent to this one. A new provider is
170 : : * created for the same data source and renderer is cloned too.
171 : : * \returns a new layer instance
172 : : * \since QGIS 3.0
173 : : */
174 : : QgsRasterLayer *clone() const override SIP_FACTORY;
175 : :
176 : : //! \brief This enumerator describes the types of shading that can be used
177 : : enum ColorShadingAlgorithm
178 : : {
179 : : UndefinedShader,
180 : : PseudoColorShader,
181 : : FreakOutShader,
182 : : ColorRampShader,
183 : : UserDefinedShader
184 : : };
185 : :
186 : : //! \brief This enumerator describes the type of raster layer
187 : : enum LayerType
188 : : {
189 : : GrayOrUndefined,
190 : : Palette,
191 : : Multiband,
192 : : ColorLayer
193 : : };
194 : :
195 : : /**
196 : : * This helper checks to see whether the file name appears to be a valid
197 : : * raster file name. If the file name looks like it could be valid,
198 : : * but some sort of error occurs in processing the file, the error is
199 : : * returned in \a retError.
200 : : */
201 : : static bool isValidRasterFileName( const QString &fileNameQString, QString &retError );
202 : : // TODO QGIS 4.0 - rename fileNameQString to fileName
203 : :
204 : : static bool isValidRasterFileName( const QString &fileNameQString );
205 : :
206 : : //! Returns time stamp for given file name
207 : : static QDateTime lastModified( const QString &name );
208 : :
209 : : /**
210 : : * Set the data provider.
211 : : * \deprecated Use the version with ProviderOptions instead.
212 : : */
213 : : Q_DECL_DEPRECATED void setDataProvider( const QString &provider ) SIP_DEPRECATED;
214 : :
215 : : /**
216 : : * Set the data provider.
217 : : * \param provider provider key string, must match a valid QgsRasterDataProvider key. E.g. "gdal", "wms", etc.
218 : : * \param options provider options
219 : : * \param flags provider flags since QGIS 3.16
220 : : * \since QGIS 3.2
221 : : */
222 : : void setDataProvider( const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
223 : :
224 : : /**
225 : : * Updates the data source of the layer. The layer's renderer and legend will be preserved only
226 : : * if the geometry type of the new data source matches the current geometry type of the layer.
227 : : * \param dataSource new layer data source
228 : : * \param baseName base name of the layer
229 : : * \param provider provider string
230 : : * \param options provider options
231 : : * \param loadDefaultStyleFlag set to TRUE to reset the layer's style to the default for the
232 : : * data source
233 : : * \see dataSourceChanged()
234 : : * \since QGIS 3.6
235 : : */
236 : : void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false ) override;
237 : :
238 : : /**
239 : : * Returns the raster layer type (which is a read only property).
240 : : */
241 : : LayerType rasterType() { return mRasterType; }
242 : :
243 : : /**
244 : : * Sets the raster's \a renderer. Takes ownership of the renderer object.
245 : : * \see renderer()
246 : : */
247 : : void setRenderer( QgsRasterRenderer *renderer SIP_TRANSFER );
248 : :
249 : : /**
250 : : * Returns the raster's renderer.
251 : : *
252 : : * \see setRenderer()
253 : : */
254 : 0 : QgsRasterRenderer *renderer() const { return mPipe.renderer(); }
255 : :
256 : : /**
257 : : * Returns the raster's resample filter.
258 : : *
259 : : * \see brightnessFilter()
260 : : * \see hueSaturationFilter()
261 : : */
262 : : QgsRasterResampleFilter *resampleFilter() const { return mPipe.resampleFilter(); }
263 : :
264 : : /**
265 : : * Returns the raster's brightness/contrast filter.
266 : : *
267 : : * \see resampleFilter()
268 : : * \see hueSaturationFilter()
269 : : */
270 : 0 : QgsBrightnessContrastFilter *brightnessFilter() const { return mPipe.brightnessFilter(); }
271 : :
272 : : /**
273 : : * Returns the raster's hue/saturation filter.
274 : : *
275 : : * \see resampleFilter()
276 : : * \see brightnessFilter()
277 : : */
278 : 0 : QgsHueSaturationFilter *hueSaturationFilter() const { return mPipe.hueSaturationFilter(); }
279 : :
280 : : /**
281 : : * Select which stage of the pipe should apply resampling.
282 : : *
283 : : * \see QgsRasterPipe::setResamplingStage()
284 : : *
285 : : * \since QGIS 3.16
286 : : */
287 : : void setResamplingStage( QgsRasterPipe::ResamplingStage stage );
288 : :
289 : : /**
290 : : * Returns which stage of the pipe should apply resampling.
291 : : *
292 : : * \see QgsRasterPipe::resamplingStage()
293 : : *
294 : : * \since QGIS 3.16
295 : : */
296 : 0 : QgsRasterPipe::ResamplingStage resamplingStage() const { return mPipe.resamplingStage(); }
297 : :
298 : : /**
299 : : * Returns the raster pipe.
300 : : */
301 : 0 : QgsRasterPipe *pipe() { return &mPipe; }
302 : :
303 : : /**
304 : : * Returns the width of the (unclipped) raster.
305 : : * \see height()
306 : : */
307 : : int width() const;
308 : :
309 : : /**
310 : : * Returns the height of the (unclipped) raster.
311 : : * \see width()
312 : : */
313 : : int height() const;
314 : :
315 : : /**
316 : : * Returns the number of bands in this layer.
317 : : */
318 : : int bandCount() const;
319 : :
320 : : /**
321 : : * Returns the name of a band given its number.
322 : : */
323 : : QString bandName( int bandNoInt ) const;
324 : :
325 : : /**
326 : : * Returns the source data provider.
327 : : *
328 : : * This will be NULLPTR if the layer is invalid.
329 : : */
330 : : QgsRasterDataProvider *dataProvider() override;
331 : :
332 : : /**
333 : : * Returns the source data provider.
334 : : *
335 : : * This will be NULLPTR if the layer is invalid.
336 : : */
337 : : const QgsRasterDataProvider *dataProvider() const SIP_PYNAME( constDataProvider ) override;
338 : :
339 : : void reload() override;
340 : : QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
341 : :
342 : : //! \brief This is an overloaded version of the draw() function that is called by both draw() and thumbnailAsPixmap
343 : : void draw( QPainter *theQPainter,
344 : : QgsRasterViewPort *myRasterViewPort,
345 : : const QgsMapToPixel *qgsMapToPixel = nullptr );
346 : :
347 : : /**
348 : : * Returns a list with classification items (Text and color).
349 : : *
350 : : * \deprecated use QgsRasterRenderer::createLegendNodes() instead.
351 : : */
352 : : Q_DECL_DEPRECATED QgsLegendColorList legendSymbologyItems() const SIP_DEPRECATED;
353 : :
354 : : bool isSpatial() const override { return true; }
355 : :
356 : : QString htmlMetadata() const override;
357 : :
358 : : /**
359 : : * Returns a 100x100 pixmap of the color palette. If the layer has no palette a white pixmap will be returned
360 : : * \param bandNumber the number of the band to use for generating a pixmap of the associated palette
361 : : */
362 : : QPixmap paletteAsPixmap( int bandNumber = 1 );
363 : :
364 : : //! \brief [ data provider interface ] Which provider is being used for this Raster Layer?
365 : : QString providerType() const;
366 : :
367 : : /**
368 : : * Returns the number of raster units per each raster pixel in X axis.
369 : : *
370 : : * In a world file, this is normally the first row (without the sign). (E.g.
371 : : * the value reported by the GDAL geotransform[1]).
372 : : *
373 : : * \see rasterUnitsPerPixelY()
374 : : */
375 : : double rasterUnitsPerPixelX() const;
376 : :
377 : : /**
378 : : * Returns the number of raster units per each raster pixel in Y axis.
379 : : *
380 : : * In a world file, this is normally the first row (without the sign).
381 : : *
382 : : * \see rasterUnitsPerPixelX()
383 : : */
384 : : double rasterUnitsPerPixelY() const;
385 : :
386 : : void setOpacity( double opacity ) FINAL;
387 : : double opacity() const FINAL;
388 : :
389 : : /**
390 : : * \brief Set contrast enhancement algorithm
391 : : * \param algorithm Contrast enhancement algorithm
392 : : * \param limits Limits
393 : : * \param extent Extent used to calculate limits, if empty, use full layer extent
394 : : * \param sampleSize Size of data sample to calculate limits, if 0, use full resolution
395 : : * \param generateLookupTableFlag Generate lookup table.
396 : : */
397 : : void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm algorithm,
398 : : QgsRasterMinMaxOrigin::Limits limits = QgsRasterMinMaxOrigin::MinMax,
399 : : const QgsRectangle &extent = QgsRectangle(),
400 : : int sampleSize = QgsRasterLayer::SAMPLE_SIZE,
401 : : bool generateLookupTableFlag = true );
402 : :
403 : : /**
404 : : * \brief Refresh contrast enhancement with new extent.
405 : : * \note not available in Python bindings
406 : : */
407 : : void refreshContrastEnhancement( const QgsRectangle &extent ) SIP_SKIP;
408 : :
409 : : /**
410 : : * \brief Refresh renderer with new extent, if needed
411 : : * \note not available in Python bindings
412 : : */
413 : : void refreshRendererIfNeeded( QgsRasterRenderer *rasterRenderer, const QgsRectangle &extent ) SIP_SKIP;
414 : :
415 : : /**
416 : : * Returns the string (typically sql) used to define a subset of the layer.
417 : : * \returns The subset string or null QString if not implemented by the provider
418 : : * \since QGIS 3.12
419 : : */
420 : : virtual QString subsetString() const;
421 : :
422 : : /**
423 : : * Sets the string (typically sql) used to define a subset of the layer
424 : : * \param subset The subset string. This may be the where clause of a sql statement
425 : : * or other definition string specific to the underlying dataprovider
426 : : * and data store.
427 : : * \returns TRUE, when setting the subset string was successful, FALSE otherwise
428 : : * \since QGIS 3.12
429 : : */
430 : : virtual bool setSubsetString( const QString &subset );
431 : :
432 : : /**
433 : : * Returns default contrast enhancement settings for that type of raster.
434 : : * \note not available in Python bindings
435 : : */
436 : : bool defaultContrastEnhancementSettings(
437 : : QgsContrastEnhancement::ContrastEnhancementAlgorithm &myAlgorithm,
438 : : QgsRasterMinMaxOrigin::Limits &myLimits ) const SIP_SKIP;
439 : :
440 : : //! Sets the default contrast enhancement
441 : : void setDefaultContrastEnhancement();
442 : :
443 : : QStringList subLayers() const override;
444 : :
445 : : /**
446 : : * \brief Draws a preview of the rasterlayer into a QImage
447 : : * \since QGIS 2.4
448 : : */
449 : : QImage previewAsImage( QSize size, const QColor &bgColor = Qt::white,
450 : : QImage::Format format = QImage::Format_ARGB32_Premultiplied );
451 : :
452 : : void setLayerOrder( const QStringList &layers ) override;
453 : : void setSubLayerVisibility( const QString &name, bool vis ) override;
454 : : QDateTime timestamp() const override;
455 : : bool accept( QgsStyleEntityVisitorInterface *visitor ) const override;
456 : :
457 : : /**
458 : : * Writes the symbology of the layer into the document provided in SLD 1.0.0 format
459 : : * \param node the node that will have the style element added to it.
460 : : * \param doc the document that will have the QDomNode added.
461 : : * \param errorMessage reference to string that will be updated with any error messages
462 : : * \param props a open ended set of properties that can drive/inform the SLD encoding
463 : : * \returns TRUE in case of success
464 : : * \since QGIS 3.6
465 : : */
466 : : bool writeSld( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QVariantMap &props = QVariantMap() ) const;
467 : :
468 : : /**
469 : : * If the ignoreExtent flag is set, the layer will also render outside the
470 : : * bounding box reported by the data provider.
471 : : * To be used for example for WMS layers with labels or symbology that happens
472 : : * to be drawn outside the data extent.
473 : : *
474 : : * \since QGIS 3.10
475 : : */
476 : : bool ignoreExtents() const;
477 : :
478 : : QgsMapLayerTemporalProperties *temporalProperties() override;
479 : :
480 : : public slots:
481 : : void showStatusMessage( const QString &message );
482 : :
483 : : /**
484 : : * Sets the coordinate transform context to \a transformContext
485 : : *
486 : : * \since QGIS 3.8
487 : : */
488 : : virtual void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
489 : :
490 : : signals:
491 : :
492 : : /**
493 : : * Emitted when the layer's subset string has changed.
494 : : * \since QGIS 3.12
495 : : */
496 : : void subsetStringChanged();
497 : :
498 : :
499 : : protected:
500 : : bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
501 : : bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
502 : : bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) override;
503 : : bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage,
504 : : const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
505 : : bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
506 : : const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
507 : : bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
508 : : QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
509 : : QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;
510 : :
511 : : private:
512 : : //! \brief Initialize default values
513 : : void init();
514 : :
515 : : //! \brief Close data provider and clear related members
516 : : void closeDataProvider();
517 : :
518 : : //! \brief Update the layer if it is outdated
519 : : bool update();
520 : :
521 : : //! Sets corresponding renderer for style
522 : : void setRendererForDrawingStyle( QgsRaster::DrawingStyle drawingStyle );
523 : :
524 : : void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm algorithm,
525 : : QgsRasterMinMaxOrigin::Limits limits,
526 : : const QgsRectangle &extent,
527 : : int sampleSize,
528 : : bool generateLookupTableFlag,
529 : : QgsRasterRenderer *rasterRenderer );
530 : :
531 : : //! Refresh renderer
532 : : void refreshRenderer( QgsRasterRenderer *rasterRenderer, const QgsRectangle &extent );
533 : :
534 : : void computeMinMax( int band,
535 : : const QgsRasterMinMaxOrigin &mmo,
536 : : QgsRasterMinMaxOrigin::Limits limits,
537 : : const QgsRectangle &extent,
538 : : int sampleSize,
539 : : double &min, double &max );
540 : :
541 : : //! \brief Constant defining flag for XML and a constant that signals property not used
542 : : const QString QSTRING_NOT_SET;
543 : : const QString TRSTRING_NOT_SET;
544 : :
545 : : //! Pointer to data provider
546 : : QgsRasterDataProvider *mDataProvider = nullptr;
547 : :
548 : : //! Pointer to temporal properties
549 : : QgsRasterLayerTemporalProperties *mTemporalProperties = nullptr;
550 : :
551 : : //! [ data provider interface ] Timestamp, the last modified time of the data source when the layer was created
552 : : QDateTime mLastModified;
553 : :
554 : : QgsRasterViewPort mLastViewPort;
555 : :
556 : : LayerType mRasterType;
557 : :
558 : : QgsRasterPipe mPipe;
559 : :
560 : : //! To save computations and possible infinite cycle of notifications
561 : : QgsRectangle mLastRectangleUsedByRefreshContrastEnhancementIfNeeded;
562 : :
563 : : QDomDocument mOriginalStyleDocument;
564 : : QDomElement mOriginalStyleElement;
565 : : };
566 : :
567 : : // clazy:excludeall=qstring-allocations
568 : :
569 : : #endif
|