QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsrasterlayerelevationproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterlayerelevationproperties.cpp
3 ---------------
4 begin : February 2022
5 copyright : (C) 2022 by Nyall Dawson
6 email : nyall dot dawson 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 "qgsapplication.h"
23#include "qgsfillsymbol.h"
24#include "qgsfillsymbollayer.h"
25#include "qgslinesymbol.h"
26#include "qgslinesymbollayer.h"
27#include "qgsrasterlayer.h"
28#include "qgssymbollayerutils.h"
29
30#include <QString>
31
32#include "moc_qgsrasterlayerelevationproperties.cpp"
33
34using namespace Qt::StringLiterals;
35
38{
40 setDefaultProfileLineSymbol( color );
41 setDefaultProfileFillSymbol( color );
42}
43
45
47{
48 return mEnabled;
49}
50
51QDomElement QgsRasterLayerElevationProperties::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context )
52{
53 QDomElement element = document.createElement( u"elevation"_s );
54 element.setAttribute( u"enabled"_s, mEnabled ? u"1"_s : u"0"_s );
55 element.setAttribute( u"mode"_s, qgsEnumValueToKey( mMode ) );
56 element.setAttribute( u"symbology"_s, qgsEnumValueToKey( mSymbology ) );
57 if ( !std::isnan( mElevationLimit ) )
58 element.setAttribute( u"elevationLimit"_s, qgsDoubleToString( mElevationLimit ) );
59
60 writeCommonProperties( element, document, context );
61
62 switch ( mMode )
63 {
65 element.setAttribute( u"lower"_s, qgsDoubleToString( mFixedRange.lower() ) );
66 element.setAttribute( u"upper"_s, qgsDoubleToString( mFixedRange.upper() ) );
67 element.setAttribute( u"includeLower"_s, mFixedRange.includeLower() ? "1" : "0" );
68 element.setAttribute( u"includeUpper"_s, mFixedRange.includeUpper() ? "1" : "0" );
69 break;
70
72 {
73 QDomElement ranges = document.createElement( u"ranges"_s );
74 for ( auto it = mRangePerBand.constBegin(); it != mRangePerBand.constEnd(); ++it )
75 {
76 QDomElement range = document.createElement( u"range"_s );
77 range.setAttribute( u"band"_s, it.key() );
78 range.setAttribute( u"lower"_s, qgsDoubleToString( it.value().lower() ) );
79 range.setAttribute( u"upper"_s, qgsDoubleToString( it.value().upper() ) );
80 range.setAttribute( u"includeLower"_s, it.value().includeLower() ? "1" : "0" );
81 range.setAttribute( u"includeUpper"_s, it.value().includeUpper() ? "1" : "0" );
82 ranges.appendChild( range );
83 }
84 element.appendChild( ranges );
85 break;
86 }
87
89 break;
90
92 element.setAttribute( u"band"_s, mBandNumber );
93 break;
94 }
95
96 QDomElement profileLineSymbolElement = document.createElement( u"profileLineSymbol"_s );
97 profileLineSymbolElement.appendChild( QgsSymbolLayerUtils::saveSymbol( QString(), mProfileLineSymbol.get(), document, context ) );
98 element.appendChild( profileLineSymbolElement );
99
100 QDomElement profileFillSymbolElement = document.createElement( u"profileFillSymbol"_s );
101 profileFillSymbolElement.appendChild( QgsSymbolLayerUtils::saveSymbol( QString(), mProfileFillSymbol.get(), document, context ) );
102 element.appendChild( profileFillSymbolElement );
103
104 parentElement.appendChild( element );
105 return element;
106}
107
108bool QgsRasterLayerElevationProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context )
109{
110 const QDomElement elevationElement = element.firstChildElement( u"elevation"_s ).toElement();
111 mEnabled = elevationElement.attribute( u"enabled"_s, u"0"_s ).toInt();
112 mMode = qgsEnumKeyToValue( elevationElement.attribute( u"mode"_s ), Qgis::RasterElevationMode::RepresentsElevationSurface );
113 mSymbology = qgsEnumKeyToValue( elevationElement.attribute( u"symbology"_s ), Qgis::ProfileSurfaceSymbology::Line );
114 if ( elevationElement.hasAttribute( u"elevationLimit"_s ) )
115 mElevationLimit = elevationElement.attribute( u"elevationLimit"_s ).toDouble();
116 else
117 mElevationLimit = std::numeric_limits< double >::quiet_NaN();
118
119 readCommonProperties( elevationElement, context );
120
121 switch ( mMode )
122 {
124 {
125 const double lower = elevationElement.attribute( u"lower"_s ).toDouble();
126 const double upper = elevationElement.attribute( u"upper"_s ).toDouble();
127 const bool includeLower = elevationElement.attribute( u"includeLower"_s ).toInt();
128 const bool includeUpper = elevationElement.attribute( u"includeUpper"_s ).toInt();
129 mFixedRange = QgsDoubleRange( lower, upper, includeLower, includeUpper );
130 break;
131 }
132
134 {
135 mRangePerBand.clear();
136
137 const QDomNodeList ranges = elevationElement.firstChildElement( u"ranges"_s ).childNodes();
138 for ( int i = 0; i < ranges.size(); ++i )
139 {
140 const QDomElement rangeElement = ranges.at( i ).toElement();
141 const int band = rangeElement.attribute( u"band"_s ).toInt();
142 const double lower = rangeElement.attribute( u"lower"_s ).toDouble();
143 const double upper = rangeElement.attribute( u"upper"_s ).toDouble();
144 const bool includeLower = rangeElement.attribute( u"includeLower"_s ).toInt();
145 const bool includeUpper = rangeElement.attribute( u"includeUpper"_s ).toInt();
146 mRangePerBand.insert( band, QgsDoubleRange( lower, upper, includeLower, includeUpper ) );
147 }
148 break;
149 }
150
152 break;
153
155 mBandNumber = elevationElement.attribute( u"band"_s, u"1"_s ).toInt();
156 break;
157 }
158
159 const QColor defaultColor = QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor();
160
161 const QDomElement profileLineSymbolElement = elevationElement.firstChildElement( u"profileLineSymbol"_s ).firstChildElement( u"symbol"_s );
162 mProfileLineSymbol = QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( profileLineSymbolElement, context );
163 if ( !mProfileLineSymbol )
164 setDefaultProfileLineSymbol( defaultColor );
165
166 const QDomElement profileFillSymbolElement = elevationElement.firstChildElement( u"profileFillSymbol"_s ).firstChildElement( u"symbol"_s );
167 mProfileFillSymbol = QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( profileFillSymbolElement, context );
168 if ( !mProfileFillSymbol )
169 setDefaultProfileFillSymbol( defaultColor );
170
171 return true;
172}
173
175{
176 auto res = std::make_unique< QgsRasterLayerElevationProperties >( nullptr );
177 res->setEnabled( mEnabled );
178 res->setMode( mMode );
179 res->setProfileLineSymbol( mProfileLineSymbol->clone() );
180 res->setProfileFillSymbol( mProfileFillSymbol->clone() );
181 res->setProfileSymbology( mSymbology );
182 res->setElevationLimit( mElevationLimit );
183 res->setBandNumber( mBandNumber );
184 res->setFixedRange( mFixedRange );
185 res->setFixedRangePerBand( mRangePerBand );
186 res->copyCommonProperties( this );
187 return res.release();
188}
189
191{
192 QStringList properties;
193 switch ( mMode )
194 {
196 properties << tr( "Elevation range: %1 to %2" ).arg( mFixedRange.lower() ).arg( mFixedRange.upper() );
197 break;
198
200 {
201 for ( auto it = mRangePerBand.constBegin(); it != mRangePerBand.constEnd(); ++it )
202 {
203 properties << tr( "Elevation for band %1: %2 to %3" ).arg( it.key() ).arg( it.value().lower() ).arg( it.value().upper() );
204 }
205 break;
206 }
207
209 break;
210
212 properties << tr( "Elevation band: %1" ).arg( mBandNumber );
213 properties << tr( "Scale: %1" ).arg( mZScale );
214 properties << tr( "Offset: %1" ).arg( mZOffset );
215 break;
216 }
217
218 return u"<li>%1</li>"_s.arg( properties.join( "</li><li>"_L1 ) );
219}
220
222{
223 switch ( mMode )
224 {
226 return mFixedRange.overlaps( range );
227
229 {
230 for ( auto it = mRangePerBand.constBegin(); it != mRangePerBand.constEnd(); ++it )
231 {
232 if ( it.value().overlaps( range ) )
233 return true;
234 }
235 return false;
236 }
237
239 {
240 if ( QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer ) )
241 {
242 QgsExpressionContext context;
245 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band"_s, 1, true, false, tr( "Band number" ) ) );
246 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_name"_s, rl->dataProvider()->displayBandName( 1 ), true, false, tr( "Band name" ) ) );
247 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_description"_s, rl->dataProvider()->bandDescription( 1 ), true, false, tr( "Band description" ) ) );
248 context.appendScope( bandScope );
249
252 lowerProperty.prepare( context );
253 upperProperty.prepare( context );
254 for ( int band = 1; band <= rl->bandCount(); ++band )
255 {
256 bandScope->setVariable( u"band"_s, band );
257 bandScope->setVariable( u"band_name"_s, rl->dataProvider()->displayBandName( band ) );
258 bandScope->setVariable( u"band_description"_s, rl->dataProvider()->bandDescription( band ) );
259
260 bool ok = false;
261 const double lower = lowerProperty.valueAsDouble( context, 0, &ok );
262 if ( !ok )
263 continue;
264 const double upper = upperProperty.valueAsDouble( context, 0, &ok );
265 if ( !ok )
266 continue;
267
268 if ( QgsDoubleRange( lower, upper ).overlaps( range ) )
269 return true;
270 }
271 }
272 return false;
273 }
274
276 // TODO -- test actual raster z range
277 return true;
278 }
280}
281
283{
284 switch ( mMode )
285 {
287 return mFixedRange;
288
290 {
291 double lower = std::numeric_limits< double >::max();
292 double upper = std::numeric_limits< double >::min();
293 bool includeLower = true;
294 bool includeUpper = true;
295 for ( auto it = mRangePerBand.constBegin(); it != mRangePerBand.constEnd(); ++it )
296 {
297 if ( it.value().lower() < lower )
298 {
299 lower = it.value().lower();
300 includeLower = it.value().includeLower();
301 }
302 else if ( !includeLower && it.value().lower() == lower && it.value().includeLower() )
303 {
304 includeLower = true;
305 }
306 if ( it.value().upper() > upper )
307 {
308 upper = it.value().upper();
309 includeUpper = it.value().includeUpper();
310 }
311 else if ( !includeUpper && it.value().upper() == upper && it.value().includeUpper() )
312 {
313 includeUpper = true;
314 }
315 }
316 return QgsDoubleRange( lower, upper, includeLower, includeUpper );
317 }
318
320 {
321 if ( QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer ) )
322 {
323 QgsExpressionContext context;
326 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band"_s, 1, true, false, tr( "Band number" ) ) );
327 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_name"_s, rl->dataProvider()->displayBandName( 1 ), true, false, tr( "Band name" ) ) );
328 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_description"_s, rl->dataProvider()->bandDescription( 1 ), true, false, tr( "Band description" ) ) );
329 context.appendScope( bandScope );
330
333 lowerProperty.prepare( context );
334 upperProperty.prepare( context );
335 double minLower = std::numeric_limits<double>::max();
336 double maxUpper = std::numeric_limits<double>::lowest();
337 for ( int band = 1; band <= rl->bandCount(); ++band )
338 {
339 bandScope->setVariable( u"band"_s, band );
340 bandScope->setVariable( u"band_name"_s, rl->dataProvider()->displayBandName( band ) );
341 bandScope->setVariable( u"band_description"_s, rl->dataProvider()->bandDescription( band ) );
342
343 bool ok = false;
344 const double lower = lowerProperty.valueAsDouble( context, 0, &ok );
345 if ( !ok )
346 continue;
347 const double upper = upperProperty.valueAsDouble( context, 0, &ok );
348 if ( !ok )
349 continue;
350
351 minLower = std::min( minLower, lower );
352 maxUpper = std::max( maxUpper, upper );
353 }
354 return ( minLower == std::numeric_limits<double>::max() && maxUpper == std::numeric_limits<double>::lowest() ) ? QgsDoubleRange() : QgsDoubleRange( minLower, maxUpper );
355 }
356 return QgsDoubleRange();
357 }
358
360 // TODO -- determine actual z range from raster statistics
361 return QgsDoubleRange();
362 }
364}
365
367{
368 switch ( mMode )
369 {
371 {
372 if ( !mFixedRange.isInfinite() && mFixedRange.lower() != mFixedRange.upper() )
373 return { mFixedRange.lower(), mFixedRange.upper() };
374 else if ( !mFixedRange.isInfinite() )
375 return { mFixedRange.lower() };
376
377 return {};
378 }
379
381 {
382 QList< double > res;
383 for ( auto it = mRangePerBand.constBegin(); it != mRangePerBand.constEnd(); ++it )
384 {
385 if ( it.value().isInfinite() )
386 continue;
387
388 if ( !res.contains( it.value().lower( ) ) )
389 res.append( it.value().lower() );
390 if ( !res.contains( it.value().upper( ) ) )
391 res.append( it.value().upper() );
392 }
393 std::sort( res.begin(), res.end() );
394 return res;
395 }
396
398 {
399 QList< double > res;
400 if ( QgsRasterLayer *rl = qobject_cast< QgsRasterLayer * >( layer ) )
401 {
402 QgsExpressionContext context;
405 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band"_s, 1, true, false, tr( "Band number" ) ) );
406 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_name"_s, rl->dataProvider()->displayBandName( 1 ), true, false, tr( "Band name" ) ) );
407 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_description"_s, rl->dataProvider()->bandDescription( 1 ), true, false, tr( "Band description" ) ) );
408 context.appendScope( bandScope );
409
412 lowerProperty.prepare( context );
413 upperProperty.prepare( context );
414 for ( int band = 1; band <= rl->bandCount(); ++band )
415 {
416 bandScope->setVariable( u"band"_s, band );
417 bandScope->setVariable( u"band_name"_s, rl->dataProvider()->displayBandName( band ) );
418 bandScope->setVariable( u"band_description"_s, rl->dataProvider()->bandDescription( band ) );
419
420 bool ok = false;
421 const double lower = lowerProperty.valueAsDouble( context, 0, &ok );
422 if ( ok && !res.contains( lower ) )
423 res.append( lower );
424 const double upper = upperProperty.valueAsDouble( context, 0, &ok );
425 if ( ok && !res.contains( upper ) )
426 res.append( upper );
427 }
428 }
429 return res;
430 }
431
433 return {};
434 }
436}
437
442
460
462{
463 if ( enabled == mEnabled )
464 return;
465
466 mEnabled = enabled;
467 emit changed();
469}
470
475
477{
478 if ( mMode == mode )
479 return;
480
481 mMode = mode;
482 emit changed();
483}
484
486{
487 if ( mBandNumber == band )
488 return;
489
490 mBandNumber = band;
491 emit changed();
493}
494
496{
497 if ( !mEnabled || std::isnan( pixelValue ) )
498 return QgsDoubleRange();
499
500 switch ( mMode )
501 {
503 return mFixedRange;
504
506 {
507 auto it = mRangePerBand.constFind( band );
508 if ( it != mRangePerBand.constEnd() )
509 return it.value();
510 return QgsDoubleRange();
511 }
512
514 {
515 if ( layer && band > 0 && band <= layer->bandCount() )
516 {
517 QgsExpressionContext context;
520 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band"_s, band, true, false, tr( "Band number" ) ) );
521 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_name"_s, layer->dataProvider()->displayBandName( band ), true, false, tr( "Band name" ) ) );
522 bandScope->addVariable( QgsExpressionContextScope::StaticVariable( u"band_description"_s, layer->dataProvider()->bandDescription( band ), true, false, tr( "Band description" ) ) );
523 context.appendScope( bandScope );
524
527 lowerProperty.prepare( context );
528 upperProperty.prepare( context );
529
530 bool ok = false;
531 const double lower = lowerProperty.valueAsDouble( context, 0, &ok );
532 if ( !ok )
533 return QgsDoubleRange();
534 const double upper = upperProperty.valueAsDouble( context, 0, &ok );
535 if ( !ok )
536 return QgsDoubleRange();
537
538 return QgsDoubleRange( lower, upper );
539 }
540
541 return QgsDoubleRange();
542 }
543
545 {
546 if ( band != mBandNumber )
547 return QgsDoubleRange();
548
549 const double z = pixelValue * mZScale + mZOffset;
550 return QgsDoubleRange( z, z );
551 }
552 }
554}
555
557{
558 switch ( mMode )
559 {
562 return -1;
563
565 {
566 // find the top-most band which matches the map range
567 int currentMatchingBand = -1;
568 QgsDoubleRange currentMatchingRange;
569 for ( auto it = mRangePerBand.constBegin(); it != mRangePerBand.constEnd(); ++it )
570 {
571 if ( it.value().overlaps( range ) )
572 {
573 if ( currentMatchingRange.isInfinite()
574 || ( it.value().includeUpper() && it.value().upper() >= currentMatchingRange.upper() )
575 || ( !currentMatchingRange.includeUpper() && it.value().upper() >= currentMatchingRange.upper() ) )
576 {
577 currentMatchingBand = it.key();
578 currentMatchingRange = it.value();
579 }
580 }
581 }
582 return currentMatchingBand;
583 }
584
586 {
587 if ( layer )
588 {
589 QgsExpressionContext context;
592 context.appendScope( bandScope );
593
596 lowerProperty.prepare( context );
597 upperProperty.prepare( context );
598
599 int currentMatchingBand = -1;
600 QgsDoubleRange currentMatchingRange;
601
602 for ( int band = 1; band <= layer->bandCount(); ++band )
603 {
604 bandScope->setVariable( u"band"_s, band );
605 bandScope->setVariable( u"band_name"_s, layer->dataProvider()->displayBandName( band ) );
606 bandScope->setVariable( u"band_description"_s, layer->dataProvider()->bandDescription( band ) );
607
608 bool ok = false;
609 const double lower = lowerProperty.valueAsDouble( context, 0, &ok );
610 if ( !ok )
611 continue;
612 const double upper = upperProperty.valueAsDouble( context, 0, &ok );
613 if ( !ok )
614 continue;
615
616 const QgsDoubleRange bandRange = QgsDoubleRange( lower, upper );
617 if ( bandRange.overlaps( range ) )
618 {
619 if ( currentMatchingRange.isInfinite()
620 || ( bandRange.includeUpper() && bandRange.upper() >= currentMatchingRange.upper() )
621 || ( !currentMatchingRange.includeUpper() && bandRange.upper() >= currentMatchingRange.upper() ) )
622 {
623 currentMatchingBand = band;
624 currentMatchingRange = bandRange;
625 }
626 }
627 }
628 return currentMatchingBand;
629 }
630 return -1;
631 }
632 }
634}
635
637{
638 return mProfileLineSymbol.get();
639}
640
642{
643 mProfileLineSymbol.reset( symbol );
644 emit changed();
646}
647
649{
650 return mProfileFillSymbol.get();
651}
652
654{
655 mProfileFillSymbol.reset( symbol );
656 emit changed();
658}
659
661{
662 if ( mSymbology == symbology )
663 return;
664
665 mSymbology = symbology;
666 emit changed();
668}
669
671{
672 return mElevationLimit;
673}
674
676{
677 if ( qgsDoubleNear( mElevationLimit, limit ) )
678 return;
679
680 mElevationLimit = limit;
681 emit changed();
683}
684
686{
687 // multiple bands => unlikely to be a DEM
688 if ( layer->bandCount() > 1 )
689 return false;
690
691 // raster attribute table => unlikely to be a DEM
692 if ( layer->attributeTable( 1 ) )
693 return false;
694
695 if ( QgsRasterDataProvider *dataProvider = layer->dataProvider() )
696 {
697 // filter out data types which aren't likely to be DEMs
698 switch ( dataProvider->dataType( 1 ) )
699 {
708 return false;
709
717 break;
718 }
719 }
720
721 // Check the layer's name for DEM-ish hints.
722 // See discussion at https://github.com/qgis/QGIS/pull/30245 - this list must NOT be translated,
723 // but adding hardcoded localized variants of the strings is encouraged.
724 static const QStringList sPartialCandidates{ u"dem"_s,
725 u"dtm"_s,
726 u"dsm"_s,
727 u"height"_s,
728 u"elev"_s,
729 u"srtm"_s,
730 u"dted"_s,
731 // French hints
732 u"mne"_s,
733 u"mnt"_s,
734 u"mns"_s,
735 u"rge"_s,
736 u"alti"_s,
737 // German hints
738 u"dhm"_s,
739 u"dgm"_s,
740 u"dom"_s,
741 u"Höhe"_s,
742 u"Hoehe"_s };
743 const QString layerName = layer->name();
744 for ( const QString &candidate : sPartialCandidates )
745 {
746 if ( layerName.contains( candidate, Qt::CaseInsensitive ) )
747 return true;
748 }
749
750 // these candidates must occur with word boundaries (we don't want to find "aster" in "raster"!)
751 static const QStringList sWordCandidates{ u"aster"_s };
752 for ( const QString &candidate : sWordCandidates )
753 {
754 const thread_local QRegularExpression re( u"\\b%1\\b"_s.arg( candidate ) );
755 if ( re.match( layerName, Qt::CaseInsensitive ).hasMatch() )
756 return true;
757 }
758
759 return false;
760}
761
762void QgsRasterLayerElevationProperties::setDefaultProfileLineSymbol( const QColor &color )
763{
764 auto profileLineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( color, 0.6 );
765 mProfileLineSymbol = std::make_unique< QgsLineSymbol>( QgsSymbolLayerList( { profileLineLayer.release() } ) );
766}
767
768void QgsRasterLayerElevationProperties::setDefaultProfileFillSymbol( const QColor &color )
769{
770 auto profileFillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( color );
771 profileFillLayer->setStrokeStyle( Qt::NoPen );
772 mProfileFillSymbol = std::make_unique< QgsFillSymbol>( QgsSymbolLayerList( { profileFillLayer.release() } ) );
773}
774
776{
777 return mRangePerBand;
778}
779
780void QgsRasterLayerElevationProperties::setFixedRangePerBand( const QMap<int, QgsDoubleRange> &ranges )
781{
782 if ( ranges == mRangePerBand )
783 return;
784
785 mRangePerBand = ranges;
786 emit changed();
787}
788
790{
791 return mFixedRange;
792}
793
795{
796 if ( range == mFixedRange )
797 return;
798
799 mFixedRange = range;
800 emit changed();
801}
RasterElevationMode
Raster layer elevation modes.
Definition qgis.h:4080
@ FixedRangePerBand
Layer has a fixed (manually specified) elevation range per band.
Definition qgis.h:4083
@ FixedElevationRange
Layer has a fixed elevation range.
Definition qgis.h:4081
@ RepresentsElevationSurface
Pixel values represent an elevation surface.
Definition qgis.h:4082
@ DynamicRangePerBand
Layer has a elevation range per band, calculated dynamically from an expression.
Definition qgis.h:4084
@ CInt32
Complex Int32.
Definition qgis.h:390
@ Float32
Thirty two bit floating point (float).
Definition qgis.h:387
@ CFloat64
Complex Float64.
Definition qgis.h:392
@ Int16
Sixteen bit signed integer (qint16).
Definition qgis.h:384
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:394
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30).
Definition qgis.h:382
@ UInt16
Sixteen bit unsigned integer (quint16).
Definition qgis.h:383
@ Byte
Eight bit unsigned integer (quint8).
Definition qgis.h:381
@ UnknownDataType
Unknown or unspecified type.
Definition qgis.h:380
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition qgis.h:393
@ Int32
Thirty two bit signed integer (qint32).
Definition qgis.h:386
@ Float64
Sixty four bit floating point (double).
Definition qgis.h:388
@ CFloat32
Complex Float32.
Definition qgis.h:391
@ CInt16
Complex Int16.
Definition qgis.h:389
@ UInt32
Thirty two bit unsigned integer (quint32).
Definition qgis.h:385
ProfileSurfaceSymbology
Surface symbology type for elevation profile plots.
Definition qgis.h:4252
@ Line
The elevation surface will be rendered using a line symbol.
Definition qgis.h:4253
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
QColor fetchRandomStyleColor() const
Returns a random color for use with a new symbol style (e.g.
QgsRange which stores a range of double values.
Definition qgsrange.h:236
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:290
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
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.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
A line symbol type, for rendering LineString and MultiLineString geometries.
QgsPropertyCollection mDataDefinedProperties
Property collection for data defined elevation settings.
void writeCommonProperties(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context)
Writes common class properties to a DOM element, to be used later with readXml().
void profileGenerationPropertyChanged()
Emitted when any of the elevation properties which relate solely to generation of elevation profiles ...
QgsMapLayerElevationProperties(QObject *parent)
Constructor for QgsMapLayerElevationProperties, with the specified parent object.
void readCommonProperties(const QDomElement &element, const QgsReadWriteContext &context)
Reads common class properties from a DOM element previously written by writeXml().
void changed()
Emitted when any of the elevation properties have changed.
void profileRenderingPropertyChanged()
Emitted when any of the elevation properties which relate solely to presentation of elevation results...
@ RasterPerBandUpperElevation
Upper elevation for each raster band.
@ RasterPerBandLowerElevation
Lower elevation for each raster band.
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when z range context is modified.
Base class for all map layer types.
Definition qgsmaplayer.h:83
QString name
Definition qgsmaplayer.h:87
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:104
bool overlaps(const QgsRange< T > &other) const
Returns true if this range overlaps another range.
Definition qgsrange.h:179
T upper() const
Returns the upper bound of the range.
Definition qgsrange.h:88
Base class for raster data providers.
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.
QgsDoubleRange fixedRange() const
Returns the fixed elevation range for the raster.
void setProfileFillSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to render the raster profile in elevation profile plots.
void setFixedRange(const QgsDoubleRange &range)
Sets the fixed elevation range for the raster.
QgsDoubleRange elevationRangeForPixelValue(QgsRasterLayer *layer, int band, double pixelValue) const
Returns the elevation range corresponding to a raw pixel value from the specified band.
QList< double > significantZValues(QgsMapLayer *layer) const override
Returns a list of significant elevation/z-values for the specified layer, using the settings defined ...
Qgis::RasterElevationMode mode() const
Returns the elevation mode.
QgsLineSymbol * profileLineSymbol() const
Returns the line symbol used to render the raster profile in elevation profile plots.
bool hasElevation() const override
Returns true if the layer has an elevation or z component.
QgsRasterLayerElevationProperties * clone() const override
Creates a clone of the properties.
QgsDoubleRange calculateZRange(QgsMapLayer *layer) const override
Attempts to calculate the overall elevation or z range for the specified layer, using the settings de...
QgsMapLayerElevationProperties::Flags flags() const override
Returns flags associated to the elevation properties.
void setBandNumber(int band)
Sets the band number from which the elevation should be taken.
int bandForElevationRange(QgsRasterLayer *layer, const QgsDoubleRange &range) const
Returns the band corresponding to the specified range.
QString htmlSummary() const override
Returns a HTML formatted summary of the properties.
void setElevationLimit(double limit)
Sets the elevation limit, which is used when profileSymbology() is Qgis::ProfileSurfaceSymbology::Fil...
void setFixedRangePerBand(const QMap< int, QgsDoubleRange > &ranges)
Sets the fixed elevation range for each band.
bool isVisibleInZRange(const QgsDoubleRange &range, QgsMapLayer *layer=nullptr) const override
Returns true if the layer should be visible and rendered for the specified z range.
void setProfileSymbology(Qgis::ProfileSurfaceSymbology symbology)
Sets the symbology option used to render the raster profile in elevation profile plots.
QMap< int, QgsDoubleRange > fixedRangePerBand() const
Returns the fixed elevation range for each band.
static bool layerLooksLikeDem(QgsRasterLayer *layer)
Returns true if a raster layer looks like a DEM.
QDomElement writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) override
Writes the properties to a DOM element, to be used later with readXml().
QgsFillSymbol * profileFillSymbol() const
Returns the fill symbol used to render the raster profile in elevation profile plots.
double elevationLimit() const
Returns the elevation limit, which is used when profileSymbology() is Qgis::ProfileSurfaceSymbology::...
void setProfileLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the raster profile in elevation profile plots.
void setMode(Qgis::RasterElevationMode mode)
Sets the elevation mode.
void setEnabled(bool enabled)
Sets whether the elevation properties are enabled, i.e.
QgsRasterLayerElevationProperties(QObject *parent)
Constructor for QgsRasterLayerElevationProperties, with the specified parent object.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the elevation properties from a DOM element previously written by writeXml().
bool showByDefaultInElevationProfilePlots() const override
Returns true if the layer should be visible by default in newly created elevation profile plots.
Represents a raster layer.
QgsRasterAttributeTable * attributeTable(int bandNumber) const
Returns the (possibly NULL) raster attribute table for the given band bandNumber.
int bandCount() const
Returns the number of bands in this layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
A container for the context for various read/write operations on objects.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
Definition qgis.h:7110
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:6817
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:7091
#define BUILTIN_UNREACHABLE
Definition qgis.h:7489
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6900
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30
Single variable definition for use within a QgsExpressionContextScope.