QGIS API Documentation 3.29.0-Master (006c3c0232)
qgsdatetimestatisticalsummary.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdatetimestatisticalsummary.cpp
3 ---------------------------------
4 Date : May 2016
5 Copyright : (C) 2016 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
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
17#include "qgsvariantutils.h"
18#include <QString>
19#include <QDateTime>
20#include <QStringList>
21#include <QObject>
22#include <QVariant>
23#include <QVariantList>
24#include <limits>
25
26/***************************************************************************
27 * This class is considered CRITICAL and any change MUST be accompanied with
28 * full unit tests in test_qgsdatetimestatisticalsummary.py.
29 * See details in QEP #17
30 ****************************************************************************/
31
32QgsDateTimeStatisticalSummary::QgsDateTimeStatisticalSummary( QgsDateTimeStatisticalSummary::Statistics stats )
33 : mStatistics( stats )
34{
35 reset();
36}
37
39{
40 mCount = 0;
41 mValues.clear();
42 mCountMissing = 0;
43 mMin = QDateTime();
44 mMax = QDateTime();
45 mIsTimes = false;
46}
47
48void QgsDateTimeStatisticalSummary::calculate( const QVariantList &values )
49{
50 reset();
51
52 const auto constValues = values;
53 for ( const QVariant &variant : constValues )
54 {
55 addValue( variant );
56 }
57 finalize();
58}
59
60void QgsDateTimeStatisticalSummary::addValue( const QVariant &value )
61{
62
63 if ( value.type() == QVariant::DateTime )
64 {
65 testDateTime( value.toDateTime(), QgsVariantUtils::isNull( value ) );
66 }
67 else if ( value.type() == QVariant::Date )
68 {
69 const QDate date = value.toDate();
70 testDateTime( date.isValid() ? QDateTime( date, QTime( 0, 0, 0 ) )
71 : QDateTime(), QgsVariantUtils::isNull( value ) );
72 }
73 else if ( value.type() == QVariant::Time )
74 {
75 mIsTimes = true;
76 const QTime time = value.toTime();
77 testDateTime( time.isValid() ? QDateTime( QDate::fromJulianDay( 0 ), time )
78 : QDateTime(), QgsVariantUtils::isNull( value ) );
79 }
80 else //not a date
81 {
82 mCountMissing++;
83 mCount++;
84 }
85
86 // QTime?
87}
88
90{
91 //nothing to do for now - this method has been added for forward compatibility
92 //if statistics are implemented which require a post-calculation step
93}
94
95void QgsDateTimeStatisticalSummary::testDateTime( const QDateTime &dateTime, bool isNull )
96{
97 mCount++;
98
99 if ( !dateTime.isValid() || isNull )
100 mCountMissing++;
101
102 if ( mStatistics & CountDistinct )
103 {
104 mValues << dateTime;
105 }
106 if ( mStatistics & Min || mStatistics & Range )
107 {
108 if ( mMin.isValid() && dateTime.isValid() )
109 {
110 mMin = std::min( mMin, dateTime );
111 }
112 else if ( !mMin.isValid() && dateTime.isValid() )
113 {
114 mMin = dateTime;
115 }
116 }
117 if ( mStatistics & Max || mStatistics & Range )
118 {
119 if ( mMax.isValid() && dateTime.isValid() )
120 {
121 mMax = std::max( mMax, dateTime );
122 }
123 else if ( !mMax.isValid() && dateTime.isValid() )
124 {
125 mMax = dateTime;
126 }
127 }
128}
129
131{
132 switch ( stat )
133 {
134 case Count:
135 return mCount;
136 case CountDistinct:
137 return mValues.count();
138 case CountMissing:
139 return mCountMissing;
140 case Min:
141 return mIsTimes ? QVariant( mMin.time() ) : QVariant( mMin );
142 case Max:
143 return mIsTimes ? QVariant( mMax.time() ) : QVariant( mMax );
144 case Range:
145 return mIsTimes ? QVariant::fromValue( mMax.time() - mMin.time() ) : QVariant::fromValue( mMax - mMin );
146 case All:
147 return 0;
148 }
149 return 0;
150}
151
153{
154 switch ( statistic )
155 {
156 case Count:
157 return QObject::tr( "Count" );
158 case CountDistinct:
159 return QObject::tr( "Count (distinct)" );
160 case CountMissing:
161 return QObject::tr( "Count (missing)" );
162 case Min:
163 return QObject::tr( "Minimum (earliest)" );
164 case Max:
165 return QObject::tr( "Maximum (latest)" );
166 case Range:
167 return QObject::tr( "Range (interval)" );
168 case All:
169 return QString();
170 }
171 return QString();
172}
173
void calculate(const QVariantList &values)
Calculates summary statistics for a list of variants.
QgsDateTimeStatisticalSummary(QgsDateTimeStatisticalSummary::Statistics stats=All)
Constructor for QgsDateTimeStatisticalSummary.
void addValue(const QVariant &value)
Adds a single datetime to the statistics calculation.
QVariant statistic(QgsDateTimeStatisticalSummary::Statistic stat) const
Returns the value of a specified statistic.
void finalize()
Must be called after adding all datetimes with addValue() and before retrieving any calculated dateti...
void reset()
Resets the calculated values.
Statistic
Enumeration of flags that specify statistics to be calculated.
@ Min
Minimum (earliest) datetime value.
@ Max
Maximum (latest) datetime value.
@ CountDistinct
Number of distinct datetime values.
@ Range
Interval between earliest and latest datetime value.
@ CountMissing
Number of missing (null) values.
static QString displayName(QgsDateTimeStatisticalSummary::Statistic statistic)
Returns the friendly display name for a statistic.
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.