QGIS API Documentation 3.41.0-Master (d2aaa9c6e02)
Loading...
Searching...
No Matches
qgsrange.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsrange.h
3 ----------
4 begin : April 2017
5 copyright : (C) 2017 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#ifndef QGSRANGE_H
19#define QGSRANGE_H
20
21#include "qgis_sip.h"
22#include "qgis_core.h"
23#include "qgis.h"
24
25#include <QDate>
26#include <QDateTime>
27
44template <typename T>
46{
47 public:
48
53 QgsRange( T lower, T upper, bool includeLower = true, bool includeUpper = true )
54 : mLower( lower )
55 , mUpper( upper )
58 {}
59
67 : mLower( lower )
68 , mUpper( upper )
69 , mIncludeLower( limits == Qgis::RangeLimits::IncludeLowerExcludeUpper || limits == Qgis::RangeLimits::IncludeBoth )
70 , mIncludeUpper( limits == Qgis::RangeLimits::ExcludeLowerIncludeUpper || limits == Qgis::RangeLimits::IncludeBoth )
71 {}
72
78 T lower() const { return mLower; }
79
85 T upper() const { return mUpper; }
86
93 bool includeLower() const { return mIncludeLower; }
94
101 bool includeUpper() const { return mIncludeUpper; }
102
119
125 bool isEmpty() const { return mLower > mUpper || ( mUpper == mLower && !( mIncludeLower || mIncludeUpper ) ); }
126
131 bool isSingleton() const { return mLower == mUpper && ( mIncludeLower || mIncludeUpper ); }
132
137 bool contains( const QgsRange<T> &other ) const
138 {
139 const bool lowerOk = ( mIncludeLower && mLower <= other.mLower )
140 || ( !mIncludeLower && mLower < other.mLower )
141 || ( !mIncludeLower && !other.mIncludeLower && mLower <= other.mLower );
142 if ( !lowerOk )
143 return false;
144
145 const bool upperOk = ( mIncludeUpper && mUpper >= other.mUpper )
146 || ( !mIncludeUpper && mUpper > other.mUpper )
147 || ( !mIncludeUpper && !other.mIncludeUpper && mUpper >= other.mUpper );
148 if ( !upperOk )
149 return false;
150
151 return true;
152 }
153
157 bool contains( T element ) const
158 {
159 const bool lowerOk = ( mIncludeLower && mLower <= element )
160 || ( !mIncludeLower && mLower < element );
161 if ( !lowerOk )
162 return false;
163
164 const bool upperOk = ( mIncludeUpper && mUpper >= element )
165 || ( !mIncludeUpper && mUpper > element );
166 if ( !upperOk )
167 return false;
168
169 return true;
170 }
171
176 bool overlaps( const QgsRange<T> &other ) const
177 {
178 if ( ( ( mIncludeLower && mLower <= other.mLower ) || ( !mIncludeLower && mLower < other.mLower ) )
179 && ( ( mIncludeUpper && mUpper >= other.mUpper ) || ( !mIncludeUpper && mUpper > other.mUpper ) ) )
180 return true;
181
182 if ( ( ( mIncludeLower && mLower <= other.mLower ) || ( !mIncludeLower && mLower < other.mLower ) )
183 && ( ( mIncludeUpper && mUpper >= other.mLower ) || ( !mIncludeUpper && mUpper > other.mLower ) ) )
184 return true;
185
186 if ( ( ( mIncludeLower && mLower <= other.mUpper ) || ( !mIncludeLower && mLower < other.mUpper ) )
187 && ( ( mIncludeUpper && mUpper >= other.mUpper ) || ( !mIncludeUpper && mUpper > other.mUpper ) ) )
188 return true;
189
190 if ( ( ( mIncludeLower && mLower >= other.mLower ) || ( !mIncludeLower && mLower > other.mLower ) )
191 && ( ( mIncludeLower && mLower <= other.mUpper ) || ( !mIncludeLower && mLower < other.mUpper ) ) )
192 return true;
193
194 if ( mLower == other.mLower && mUpper == other.mUpper )
195 return true;
196
197 return false;
198 }
199
200 bool operator==( const QgsRange<T> &other ) const
201 {
202 return mLower == other.mLower &&
203 mUpper == other.mUpper &&
204 mIncludeLower == other.includeLower() &&
205 mIncludeUpper == other.includeUpper();
206 }
207
208 bool operator!=( const QgsRange<T> &other ) const
209 {
210 return ( ! operator==( other ) );
211 }
212
213 protected:
214
217 bool mIncludeLower = true;
218 bool mIncludeUpper = true;
219
220};
221
222// These typedefs are in place to work around a SIP bug:
223// https://github.com/Python-SIP/sip/issues/66
224#ifndef SIP_RUN
227#endif
228
236class CORE_EXPORT QgsDoubleRange : public QgsRange< double >
237{
238 public:
239
246 QgsDoubleRange( double lower, double upper, Qgis::RangeLimits limits )
247 : QgsRange( lower, upper, limits )
248 {}
249
250#ifndef SIP_RUN
251
260 QgsDoubleRange( double lower = std::numeric_limits< double >::lowest(),
261 double upper = std::numeric_limits< double >::max(),
262 bool includeLower = true, bool includeUpper = true )
263 : QgsRange( lower, upper, includeLower, includeUpper )
264 {}
265#else
266
271 QgsDoubleRange( double lower,
272 double upper,
273 bool includeLower = true, bool includeUpper = true )
274 : QgsRange( lower, upper, includeLower, includeUpper )
275 {}
276
283 : QgsRange( std::numeric_limits< double >::lowest(), std::numeric_limits< double >::max(), true, true )
284 {}
285#endif
286
291 bool isInfinite() const
292 {
293 return lower() == std::numeric_limits< double >::lowest() && upper() == std::numeric_limits< double >::max();
294 }
295
296#ifdef SIP_RUN
297 SIP_PYOBJECT __repr__();
298 % MethodCode
299 QString str = QStringLiteral( "<QgsDoubleRange: %1%2, %3%4>" ).arg( sipCpp->includeLower() ? QStringLiteral( "[" ) : QStringLiteral( "(" ) )
300 .arg( sipCpp->lower() )
301 .arg( sipCpp->upper() )
302 .arg( sipCpp->includeUpper() ? QStringLiteral( "]" ) : QStringLiteral( ")" ) );
303 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
304 % End
305#endif
306
307 bool operator==( const QgsDoubleRange &other ) const
308 {
309 return qgsDoubleNear( mLower, other.mLower ) &&
310 qgsDoubleNear( mUpper, other.mUpper ) &&
311 mIncludeLower == other.includeLower() &&
312 mIncludeUpper == other.includeUpper();
313 }
314
315 bool operator!=( const QgsDoubleRange &other ) const
316 {
317 return ( ! operator==( other ) );
318 }
319
320};
321
323
324
325
332class CORE_EXPORT QgsIntRange : public QgsRange< int >
333{
334 public:
335
342 QgsIntRange( int lower, int upper, Qgis::RangeLimits limits )
343 : QgsRange( lower, upper, limits )
344 {}
345
346#ifndef SIP_RUN
347
356 QgsIntRange( int lower = std::numeric_limits< int >::lowest(),
357 int upper = std::numeric_limits< int >::max(),
358 bool includeLower = true, bool includeUpper = true )
359 : QgsRange( lower, upper, includeLower, includeUpper )
360 {}
361#else
362
367 QgsIntRange( int lower,
368 int upper,
369 bool includeLower = true, bool includeUpper = true )
370 : QgsRange( lower, upper, includeLower, includeUpper )
371 {}
372
379 : QgsRange( std::numeric_limits< int >::lowest(), std::numeric_limits< int >::max(), true, true )
380 {}
381#endif
382
387 bool isInfinite() const
388 {
389 return lower() == std::numeric_limits< int >::lowest() && upper() == std::numeric_limits< int >::max();
390 }
391
392#ifdef SIP_RUN
393 SIP_PYOBJECT __repr__();
394 % MethodCode
395 QString str = QStringLiteral( "<QgsIntRange: %1%2, %3%4>" ).arg( sipCpp->includeLower() ? QStringLiteral( "[" ) : QStringLiteral( "(" ) )
396 .arg( sipCpp->lower() )
397 .arg( sipCpp->upper() )
398 .arg( sipCpp->includeUpper() ? QStringLiteral( "]" ) : QStringLiteral( ")" ) );
399 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
400 % End
401#endif
402
403};
404
406
407
408
423template <typename T>
425{
426 public:
427
433#ifndef SIP_RUN
434 QgsTemporalRange( const T &begin = T(), const T &end = T(), bool includeBeginning = true, bool includeEnd = true )
435 : mLower( begin )
436 , mUpper( end )
437 , mIncludeLower( includeBeginning )
438 , mIncludeUpper( includeEnd )
439 {}
440#else
441 QgsTemporalRange( const T &begin, const T &end, bool includeBeginning = true, bool includeEnd = true );
442 // default constructor as default value for templates is not handled in SIP
443#endif
444
450 T begin() const { return mLower; }
451
457 T end() const { return mUpper; }
458
465 bool includeBeginning() const { return mIncludeLower; }
466
472 bool includeEnd() const { return mIncludeUpper; }
473
479 bool isInstant() const { return mLower.isValid() && mUpper.isValid() && mLower == mUpper && ( mIncludeLower || mIncludeUpper ); }
480
486 bool isInfinite() const
487 {
488 return !mLower.isValid() && !mUpper.isValid();
489 }
490
496 bool isEmpty() const
497 {
498 if ( !mLower.isValid() && !mUpper.isValid() )
499 return false;
500
501 if ( mLower.isValid() != mUpper.isValid() )
502 return false;
503
504 if ( mLower > mUpper )
505 return true;
506
507 if ( mLower == mUpper && !( mIncludeLower || mIncludeUpper ) )
508 return true;
509
510 return false;
511 }
512
516 bool contains( const QgsTemporalRange<T> &other ) const
517 {
518 if ( !other.mLower.isValid() && mLower.isValid() )
519 return false;
520
521 if ( mLower.isValid() )
522 {
523 const bool lowerOk = ( mIncludeLower && mLower <= other.mLower )
524 || ( !mIncludeLower && mLower < other.mLower )
525 || ( !mIncludeLower && !other.mIncludeLower && mLower <= other.mLower );
526 if ( !lowerOk )
527 return false;
528 }
529
530 if ( !other.mUpper.isValid() && mUpper.isValid() )
531 return false;
532
533 if ( mUpper.isValid() )
534 {
535 const bool upperOk = ( mIncludeUpper && mUpper >= other.mUpper )
536 || ( !mIncludeUpper && mUpper > other.mUpper )
537 || ( !mIncludeUpper && !other.mIncludeUpper && mUpper >= other.mUpper );
538 if ( !upperOk )
539 return false;
540 }
541
542 return true;
543 }
544
548 bool contains( const T &element ) const
549 {
550 if ( !element.isValid() )
551 return false;
552
553 if ( mLower.isValid() )
554 {
555 const bool lowerOk = ( mIncludeLower && mLower <= element )
556 || ( !mIncludeLower && mLower < element );
557 if ( !lowerOk )
558 return false;
559 }
560
561 if ( mUpper.isValid() )
562 {
563 const bool upperOk = ( mIncludeUpper && mUpper >= element )
564 || ( !mIncludeUpper && mUpper > element );
565 if ( !upperOk )
566 return false;
567 }
568
569 return true;
570 }
571
575 bool overlaps( const QgsTemporalRange<T> &other ) const
576 {
577 if ( !mUpper.isValid() && ( ( mIncludeLower && mLower <= other.mUpper ) || ( !mIncludeLower && mLower < other.mUpper ) ) )
578 return true;
579
580 if ( ( ( mIncludeLower && mLower <= other.mLower ) || ( !mIncludeLower && mLower < other.mLower ) )
581 && ( ( mIncludeUpper && mUpper >= other.mUpper ) || ( !mIncludeUpper && mUpper > other.mUpper ) ) )
582 return true;
583
584 if ( ( ( mIncludeLower && mLower <= other.mLower ) || ( !mIncludeLower && mLower < other.mLower ) )
585 && ( ( mIncludeUpper && mUpper >= other.mLower ) || ( !mIncludeUpper && mUpper > other.mLower ) ) )
586 return true;
587
588 if ( ( ( mIncludeLower && mLower <= other.mUpper ) || ( !mIncludeLower && mLower < other.mUpper ) )
589 && ( ( mIncludeUpper && mUpper >= other.mUpper ) || ( !mIncludeUpper && mUpper > other.mUpper ) ) )
590 return true;
591
592 if ( ( ( mIncludeLower && mLower >= other.mLower ) || ( !mIncludeLower && mLower > other.mLower ) )
593 && ( ( mIncludeLower && mLower <= other.mUpper ) || ( !mIncludeLower && mLower < other.mUpper ) ) )
594 return true;
595
596 if ( mLower == other.mLower && mUpper == other.mUpper )
597 return true;
598
599 return false;
600 }
601
610 bool extend( const QgsTemporalRange<T> &other )
611 {
612 if ( other.isEmpty() )
613 {
614 return false;
615 }
616 else if ( isEmpty() )
617 {
618 mLower = other.begin();
619 mUpper = other.end();
620 mIncludeLower = other.includeBeginning();
621 mIncludeUpper = other.includeEnd();
622 return true;
623 }
624
625 // Both not empty, do some math
626 bool changed { false };
627
628 // Lower
629 if ( ! other.begin().isValid()
630 || ( begin().isValid() && other.begin() < mLower ) )
631 {
632 mLower = other.begin();
633 mIncludeLower = other.includeBeginning();
634 changed = true;
635 }
636 else if ( other.begin() == mLower && other.includeBeginning() && ! mIncludeLower )
637 {
638 mIncludeLower = true;
639 changed = true;
640 }
641
642 // Upper
643 if ( ! other.end().isValid()
644 || ( end().isValid() && other.end() > mUpper ) )
645 {
646 mUpper = other.end();
647 mIncludeUpper = other.includeEnd();
648 changed = true;
649 }
650 else if ( other.end() == mUpper && other.includeEnd() && ! mIncludeUpper )
651 {
652 mIncludeUpper = true;
653 changed = true;
654 }
655 return changed;
656 }
657
658#ifndef SIP_RUN
659
673 static QList< QgsTemporalRange<T> > mergeRanges( const QList< QgsTemporalRange<T> > &ranges )
674 {
675 if ( ranges.empty() )
676 return {};
677
678 QList< QgsTemporalRange<T > > sortedRanges = ranges;
679 // cppcheck-suppress mismatchingContainerExpression
680 std::sort( sortedRanges.begin(), sortedRanges.end(), []( const QgsTemporalRange< T > &a, const QgsTemporalRange< T > &b ) -> bool { return a.begin() < b.begin(); } );
681 QList< QgsTemporalRange<T>> res;
682 res.reserve( sortedRanges.size() );
683
684 QgsTemporalRange<T> prevRange;
685 auto it = sortedRanges.constBegin();
686 prevRange = *it++;
687 for ( ; it != sortedRanges.constEnd(); ++it )
688 {
689 if ( prevRange.overlaps( *it ) )
690 {
691 prevRange.extend( *it );
692 }
693 else
694 {
695 res << prevRange;
696 prevRange = *it;
697 }
698 }
699 res << prevRange;
700 return res;
701 }
702#endif
703
704 bool operator==( const QgsTemporalRange<T> &other ) const
705 {
706 return mLower == other.mLower &&
707 mUpper == other.mUpper &&
708 mIncludeLower == other.includeBeginning() &&
709 mIncludeUpper == other.includeEnd();
710 }
711
712 bool operator!=( const QgsTemporalRange<T> &other ) const
713 {
714 return ( ! operator==( other ) );
715 }
716
717 private:
718
719 T mLower;
720 T mUpper;
721 bool mIncludeLower = true;
722 bool mIncludeUpper = true;
723};
724
725
736
738
739
749
751
752#endif // QGSRANGE_H
The Qgis class provides global constants for use throughout the application.
Definition qgis.h:54
RangeLimits
Describes how the limits of a range are handled.
Definition qgis.h:3787
@ ExcludeLowerIncludeUpper
Lower value is excluded from the range, upper value in inccluded.
@ IncludeBoth
Both lower and upper values are included in the range.
@ ExcludeBoth
Both lower and upper values are excluded from the range.
@ IncludeLowerExcludeUpper
Lower value is included in the range, upper value is excluded.
QgsRange which stores a range of double values.
Definition qgsrange.h:237
QgsDoubleRange(double lower, double upper, Qgis::RangeLimits limits)
Constructor for QgsDoubleRange.
Definition qgsrange.h:246
QgsDoubleRange(double lower=std::numeric_limits< double >::lowest(), double upper=std::numeric_limits< double >::max(), bool includeLower=true, bool includeUpper=true)
Constructor for QgsDoubleRange.
Definition qgsrange.h:260
bool operator==(const QgsDoubleRange &other) const
Definition qgsrange.h:307
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:291
bool operator!=(const QgsDoubleRange &other) const
Definition qgsrange.h:315
QgsRange which stores a range of integer values.
Definition qgsrange.h:333
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:387
QgsIntRange(int lower, int upper, Qgis::RangeLimits limits)
Constructor for QgsIntRange.
Definition qgsrange.h:342
QgsIntRange(int lower=std::numeric_limits< int >::lowest(), int upper=std::numeric_limits< int >::max(), bool includeLower=true, bool includeUpper=true)
Constructor for QgsIntRange.
Definition qgsrange.h:356
A template based class for storing ranges (lower to upper values).
Definition qgsrange.h:46
bool mIncludeLower
Definition qgsrange.h:217
QgsRange(T lower, T upper, Qgis::RangeLimits limits)
Constructor for QgsRange.
Definition qgsrange.h:66
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
Qgis::RangeLimits rangeLimits() const
Returns the limit handling of the range.
Definition qgsrange.h:108
QgsRange(T lower, T upper, bool includeLower=true, bool includeUpper=true)
Constructor for QgsRange.
Definition qgsrange.h:53
bool contains(const QgsRange< T > &other) const
Returns true if this range contains another range.
Definition qgsrange.h:137
T lower() const
Returns the lower bound of the range.
Definition qgsrange.h:78
bool includeLower() const
Returns true if the lower bound is inclusive, or false if the lower bound is exclusive.
Definition qgsrange.h:93
bool mIncludeUpper
Definition qgsrange.h:218
T upper() const
Returns the upper bound of the range.
Definition qgsrange.h:85
bool isSingleton() const
Returns true if the range consists only of a single value or instant.
Definition qgsrange.h:131
bool operator!=(const QgsRange< T > &other) const
Definition qgsrange.h:208
bool contains(T element) const
Returns true if this range contains a specified element.
Definition qgsrange.h:157
bool operator==(const QgsRange< T > &other) const
Definition qgsrange.h:200
bool isEmpty() const
Returns true if the range is empty, ie the lower bound equals (or exceeds) the upper bound and either...
Definition qgsrange.h:125
A template based class for storing temporal ranges (beginning to end values).
Definition qgsrange.h:425
bool contains(const T &element) const
Returns true if this range contains a specified element.
Definition qgsrange.h:548
T begin() const
Returns the beginning of the range.
Definition qgsrange.h:450
bool contains(const QgsTemporalRange< T > &other) const
Returns true if this range contains another range.
Definition qgsrange.h:516
bool extend(const QgsTemporalRange< T > &other)
Extends the range in place by extending this range out to include an other range.
Definition qgsrange.h:610
T end() const
Returns the upper bound of the range.
Definition qgsrange.h:457
bool isInstant() const
Returns true if the range consists only of a single instant.
Definition qgsrange.h:479
bool operator!=(const QgsTemporalRange< T > &other) const
Definition qgsrange.h:712
QgsTemporalRange(const T &begin=T(), const T &end=T(), bool includeBeginning=true, bool includeEnd=true)
Constructor for QgsTemporalRange.
Definition qgsrange.h:434
bool operator==(const QgsTemporalRange< T > &other) const
Definition qgsrange.h:704
bool overlaps(const QgsTemporalRange< T > &other) const
Returns true if this range overlaps another range.
Definition qgsrange.h:575
bool includeEnd() const
Returns true if the end is inclusive, or false if the end is exclusive.
Definition qgsrange.h:472
bool includeBeginning() const
Returns true if the beginning is inclusive, or false if the beginning is exclusive.
Definition qgsrange.h:465
bool isEmpty() const
Returns true if the range is empty, ie the beginning equals (or exceeds) the end and either of the bo...
Definition qgsrange.h:496
static QList< QgsTemporalRange< T > > mergeRanges(const QList< QgsTemporalRange< T > > &ranges)
Merges a list of temporal ranges.
Definition qgsrange.h:673
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:486
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:6091
#define SIP_DOC_TEMPLATE
Definition qgis_sip.h:224
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
QgsTemporalRange< QDate > QgsDateRange
QgsRange which stores a range of dates.
Definition qgsrange.h:735
QgsRange< double > QgsRangedoubleBase
Definition qgsrange.h:225
QgsRange< int > QgsRangeintBase
Definition qgsrange.h:226