Skip to content
Permalink
Browse files
New class QgsDateTimeStatisticalSummary
Calculates summary statistics on lists of datetime values, such
as count, count distinct, min, max and range
  • Loading branch information
nyalldawson committed May 11, 2016
1 parent 0d165e5 commit b053ad8
Show file tree
Hide file tree
Showing 7 changed files with 528 additions and 0 deletions.
@@ -39,6 +39,7 @@
%Include qgsdataitemproviderregistry.sip
%Include qgsdataprovider.sip
%Include qgsdatasourceuri.sip
%Include qgsdatetimestatisticalsummary.sip
%Include qgsdatumtransformstore.sip
%Include qgsdbfilterproxymodel.sip
%Include qgsdistancearea.sip
@@ -0,0 +1,104 @@
/** \ingroup core
* \class QgsDateTimeStatisticalSummary
* \brief Calculator for summary statistics and aggregates for a list of datetimes.
*
* Statistics are calculated by calling @link calculate @endlink and passing a list of datetimes. The
* individual statistics can then be retrieved using the associated methods. Note that not all statistics
* are calculated by default. Statistics which require slower computations are only calculated by
* specifying the statistic in the constructor or via @link setStatistics @endlink.
*
* \note Added in version 2.16
*/

class QgsDateTimeStatisticalSummary
{
%TypeHeaderCode
#include <qgsdatetimestatisticalsummary.h>
%End

public:

//! Enumeration of flags that specify statistics to be calculated
enum Statistic
{
Count, //!< Count
CountDistinct, //!< Number of distinct datetime values
CountMissing, //!< Number of missing (null) values
Min, //!< Minimum (earliest) datetime value
Max, //!< Maximum (latest) datetime value
Range, //!< Interval between earliest and latest datetime value
All, //! All statistics
};
typedef QFlags<QgsDateTimeStatisticalSummary::Statistic> Statistics;

/** Constructor for QgsDateTimeStatisticalSummary
* @param stats flags for statistics to calculate
*/
QgsDateTimeStatisticalSummary( const QgsDateTimeStatisticalSummary::Statistics& stats = All );

/** Returns flags which specify which statistics will be calculated. Some statistics
* are always calculated (eg count).
* @see setStatistics
*/
Statistics statistics() const;

/** Sets flags which specify which statistics will be calculated. Some statistics
* are always calculated (eg count).
* @param stats flags for statistics to calculate
* @see statistics
*/
void setStatistics( const Statistics& stats );

/** Resets the calculated values
*/
void reset();

/** Calculates summary statistics for a list of variants. Any non-string variants will be
* ignored.
* @param values list of variants
*/
void calculate( const QVariantList& values );

/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic
*/
QVariant statistic( Statistic stat ) const;

/** Returns the calculated count of values.
*/
int count() const;

/** Returns the number of distinct datetime values.
*/
int countDistinct() const;

/** Returns the set of distinct datetime values.
*/
QSet< QDateTime > distinctValues() const;

/** Returns the number of missing (null) datetime values.
*/
int countMissing() const;

/** Returns the minimum (earliest) non-null datetime value.
*/
QDateTime min() const;

/** Returns the maximum (latest) non-null datetime value.
*/
QDateTime max() const;

/** Returns the range (interval between earliest and latest non-null datetime values).
*/
QgsInterval range() const;

/** Returns the friendly display name for a statistic
* @param statistic statistic to return name for
*/
static QString displayName( Statistic statistic );

};

QFlags<QgsDateTimeStatisticalSummary::Statistic> operator|(QgsDateTimeStatisticalSummary::Statistic f1, QFlags<QgsDateTimeStatisticalSummary::Statistic> f2);

@@ -100,6 +100,7 @@ SET(QGIS_CORE_SRCS
qgsdataitemprovider.cpp
qgsdataitemproviderregistry.cpp
qgsdatasourceuri.cpp
qgsdatetimestatisticalsummary.cpp
qgsdatumtransformstore.cpp
qgsdbfilterproxymodel.cpp
qgsdiagramrendererv2.cpp
@@ -617,6 +618,7 @@ SET(QGIS_CORE_HDRS
qgsdataitemprovider.h
qgsdataitemproviderregistry.h
qgsdatasourceuri.h
qgsdatetimestatisticalsummary.h
qgsdatumtransformstore.h
qgsdbfilterproxymodel.h
qgsdiagramrendererv2.h
@@ -0,0 +1,144 @@
/***************************************************************************
qgsdatetimestatisticalsummary.cpp
---------------------------------
Date : May 2016
Copyright : (C) 2016 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsdatetimestatisticalsummary.h"
#include <QString>
#include <QDateTime>
#include <QStringList>
#include <QObject>
#include <QVariant>
#include <QVariantList>
#include "limits.h"

/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in test_qgsdatetimestatisticalsummary.py.
* See details in QEP #17
****************************************************************************/

QgsDateTimeStatisticalSummary::QgsDateTimeStatisticalSummary( const QgsDateTimeStatisticalSummary::Statistics& stats )
: mStatistics( stats )
{
reset();
}

void QgsDateTimeStatisticalSummary::reset()
{
mCount = 0;
mValues.clear();
mCountMissing = 0;
mMin = QDateTime();
mMax = QDateTime();
}

void QgsDateTimeStatisticalSummary::calculate( const QVariantList& values )
{
reset();

Q_FOREACH ( const QVariant& variant, values )
{
if ( variant.type() == QVariant::DateTime )
{
testDateTime( variant.toDateTime() );
}
else if ( variant.type() == QVariant::Date )
{
QDate date = variant.toDate();
testDateTime( date.isValid() ? QDateTime( date, QTime( 0, 0, 0 ) )
: QDateTime() );
}
// QTime?
}
}

void QgsDateTimeStatisticalSummary::testDateTime( const QDateTime& dateTime )
{
mCount++;

if ( !dateTime.isValid() )
mCountMissing++;

if ( mStatistics & CountDistinct )
{
mValues << dateTime;
}
if ( mStatistics & Min || mStatistics & Range )
{
if ( mMin.isValid() && dateTime.isValid() )
{
mMin = qMin( mMin, dateTime );
}
else if ( !mMin.isValid() && dateTime.isValid() )
{
mMin = dateTime;
}
}
if ( mStatistics & Max || mStatistics & Range )
{
if ( mMax.isValid() && dateTime.isValid() )
{
mMax = qMax( mMax, dateTime );
}
else if ( !mMax.isValid() && dateTime.isValid() )
{
mMax = dateTime;
}
}
}

QVariant QgsDateTimeStatisticalSummary::statistic( QgsDateTimeStatisticalSummary::Statistic stat ) const
{
switch ( stat )
{
case Count:
return mCount;
case CountDistinct:
return mValues.count();
case CountMissing:
return mCountMissing;
case Min:
return mMin;
case Max:
return mMax;
case Range:
return QVariant::fromValue( mMax - mMin );
case All:
return 0;
}
return 0;
}

QString QgsDateTimeStatisticalSummary::displayName( QgsDateTimeStatisticalSummary::Statistic statistic )
{
switch ( statistic )
{
case Count:
return QObject::tr( "Count" );
case CountDistinct:
return QObject::tr( "Count (distinct)" );
case CountMissing:
return QObject::tr( "Count (missing)" );
case Min:
return QObject::tr( "Minimum (earliest)" );
case Max:
return QObject::tr( "Maximum (latest)" );
case Range:
return QObject::tr( "Range (interval)" );
case All:
return QString();
}
return QString();
}

0 comments on commit b053ad8

Please sign in to comment.