QGIS API Documentation 3.99.0-Master (752b475928d)
Loading...
Searching...
No Matches
qgsrasterlayerutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterlayerutils.cpp
3 -------------------------
4 begin : March 2024
5 copyright : (C) 2024 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 "qgsrasterlayerutils.h"
19
22#include "qgsrasterlayer.h"
25
27 QgsRasterLayer *layer,
28 const QgsDateTimeRange &temporalRange,
29 const QgsDoubleRange &elevationRange,
30 bool &matched )
31{
32 if ( !layer )
33 {
34 matched = false;
35 return -1;
36 }
37
38 matched = true;
39 const QgsRasterLayerElevationProperties *elevationProperties = qobject_cast< QgsRasterLayerElevationProperties * >( layer->elevationProperties() );
40 const QgsRasterLayerTemporalProperties *temporalProperties = qobject_cast< QgsRasterLayerTemporalProperties *>( layer->temporalProperties() );
41
42 // neither active
43 if ( ( !temporalProperties->isActive() || temporalRange.isInfinite() )
44 && ( !elevationProperties->hasElevation() || elevationRange.isInfinite() ) )
45 {
46 return -1;
47 }
48
49 // only elevation properties enabled
50 if ( !temporalProperties->isActive() || temporalRange.isInfinite() )
51 {
52 const int band = elevationProperties->bandForElevationRange( layer, elevationRange );
53 matched = band > 0;
54 return band;
55 }
56
57 // only temporal properties enabled
58 if ( !elevationProperties->hasElevation() || elevationRange.isInfinite() )
59 {
60 const int band = temporalProperties->bandForTemporalRange( layer, temporalRange );
61 matched = band > 0;
62 return band;
63 }
64
65 // both elevation and temporal properties enabled
66
67 // first find bands matching the temporal range
68 QList< int > temporalBands;
69 switch ( temporalProperties->mode() )
70 {
76 {
77 temporalBands << temporalProperties->filteredBandsForTemporalRange( layer, temporalRange );
78 break;
79 }
80
82 {
83 temporalBands << temporalProperties->bandNumber();
84 break;
85 }
86 }
87
88 if ( temporalBands.empty() )
89 {
90 matched = false;
91 return -1;
92 }
93
94 switch ( elevationProperties->mode() )
95 {
98 return temporalBands.at( 0 );
99
101 {
102 // find the top-most band which matches the map range
103 int currentMatchingBand = -1;
104 matched = false;
105 QgsDoubleRange currentMatchingRange;
106 const QMap<int, QgsDoubleRange> rangePerBand = elevationProperties->fixedRangePerBand();
107 for ( int band : temporalBands )
108 {
109 const QgsDoubleRange rangeForBand = rangePerBand.value( band );
110 if ( rangeForBand.overlaps( elevationRange ) )
111 {
112 if ( currentMatchingRange.isInfinite()
113 || ( rangeForBand.includeUpper() && rangeForBand.upper() >= currentMatchingRange.upper() )
114 || ( !currentMatchingRange.includeUpper() && rangeForBand.upper() >= currentMatchingRange.upper() ) )
115 {
116 matched = true;
117 currentMatchingBand = band;
118 currentMatchingRange = rangeForBand;
119 }
120 }
121 }
122 return currentMatchingBand;
123 }
124
126 {
127 QgsExpressionContext context;
130 context.appendScope( bandScope );
131
134 lowerProperty.prepare( context );
135 upperProperty.prepare( context );
136
137 int currentMatchingBand = -1;
138 matched = false;
139 QgsDoubleRange currentMatchingRange;
140
141 for ( int band : temporalBands )
142 {
143 bandScope->setVariable( QStringLiteral( "band" ), band );
144 bandScope->setVariable( QStringLiteral( "band_name" ), layer->dataProvider()->displayBandName( band ) );
145 bandScope->setVariable( QStringLiteral( "band_description" ), layer->dataProvider()->bandDescription( band ) );
146
147 bool ok = false;
148 const double lower = lowerProperty.valueAsDouble( context, 0, &ok );
149 if ( !ok )
150 continue;
151 const double upper = upperProperty.valueAsDouble( context, 0, &ok );
152 if ( !ok )
153 continue;
154
155 const QgsDoubleRange bandRange = QgsDoubleRange( lower, upper );
156 if ( bandRange.overlaps( elevationRange ) )
157 {
158 if ( currentMatchingRange.isInfinite()
159 || ( bandRange.includeUpper() && bandRange.upper() >= currentMatchingRange.upper() )
160 || ( !currentMatchingRange.includeUpper() && bandRange.upper() >= currentMatchingRange.upper() ) )
161 {
162 currentMatchingBand = band;
163 currentMatchingRange = bandRange;
164 matched = true;
165 }
166 }
167 }
168 return currentMatchingBand;
169 }
170 }
172}
@ FixedRangePerBand
Layer has a fixed (manually specified) elevation range per band.
Definition qgis.h:4024
@ FixedElevationRange
Layer has a fixed elevation range.
Definition qgis.h:4022
@ RepresentsElevationSurface
Pixel values represent an elevation surface.
Definition qgis.h:4023
@ DynamicRangePerBand
Layer has a elevation range per band, calculated dynamically from an expression.
Definition qgis.h:4025
@ RepresentsTemporalValues
Pixel values represent an datetime.
Definition qgis.h:2626
@ RedrawLayerOnly
Redraw the layer when temporal range changes, but don't apply any filtering. Useful when raster symbo...
Definition qgis.h:2624
@ FixedRangePerBand
Layer has a fixed temporal range per band.
Definition qgis.h:2625
@ TemporalRangeFromDataProvider
Mode when raster layer delegates temporal range handling to the dataprovider.
Definition qgis.h:2623
@ FixedTemporalRange
Mode when temporal properties have fixed start and end datetimes.
Definition qgis.h:2622
@ FixedDateTime
Layer has a fixed date time instant.
Definition qgis.h:2627
QgsRange which stores a range of double values.
Definition qgsrange.h:233
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:287
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the object's property collection, used for data defined overrides.
@ RasterPerBandUpperElevation
Upper elevation for each raster band.
@ RasterPerBandLowerElevation
Lower elevation for each raster band.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
A store for object properties.
double valueAsDouble(const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property and interprets it as a double.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const
Prepares the property against a specified expression context.
bool includeUpper() const
Returns true if the upper bound is inclusive, or false if the upper bound is exclusive.
Definition qgsrange.h:101
bool overlaps(const QgsRange< T > &other) const
Returns true if this range overlaps another range.
Definition qgsrange.h:176
T upper() const
Returns the upper bound of the range.
Definition qgsrange.h:85
virtual QString bandDescription(int bandNumber)
Returns the description for band bandNumber, or an empty string if the band is not valid or has not d...
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
Raster layer specific subclass of QgsMapLayerElevationProperties.
Qgis::RasterElevationMode mode() const
Returns the elevation mode.
bool hasElevation() const override
Returns true if the layer has an elevation or z component.
int bandForElevationRange(QgsRasterLayer *layer, const QgsDoubleRange &range) const
Returns the band corresponding to the specified range.
QMap< int, QgsDoubleRange > fixedRangePerBand() const
Returns the fixed elevation range for each band.
Implementation of map layer temporal properties for raster layers.
QList< int > filteredBandsForTemporalRange(QgsRasterLayer *layer, const QgsDateTimeRange &range) const
Returns a filtered list of bands which match the specified range.
Qgis::RasterTemporalMode mode() const
Returns the temporal properties mode.
int bandForTemporalRange(QgsRasterLayer *layer, const QgsDateTimeRange &range) const
Returns the band corresponding to the specified range.
int bandNumber() const
Returns the band number from which temporal values should be taken.
static int renderedBandForElevationAndTemporalRange(QgsRasterLayer *layer, const QgsDateTimeRange &temporalRange, const QgsDoubleRange &elevationRange, bool &matched)
Given a raster layer, returns the band which should be used for rendering the layer for a specified t...
Represents a raster layer.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
QgsMapLayerElevationProperties * elevationProperties() override
Returns the layer's elevation properties.
bool isActive() const
Returns true if the temporal property is active.
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:482
#define BUILTIN_UNREACHABLE
Definition qgis.h:7208
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
Definition qgsrange.h:761