Skip to content
Permalink
Browse files

If a wms-t layer is the first temporal layer loaded into a project,

use the wms-t capabilities to set a sensible default time step
for the temporal controller (just like we do for mesh layers)
  • Loading branch information
nyalldawson committed Mar 25, 2021
1 parent 89491b5 commit 929b7086b1bf294bc45b6342434c49d0b4d128ed
@@ -120,6 +120,26 @@ extent of datetime values available for reference temporal ranges from the provi
%Docstring
Returns the requested temporal range.
Intended to be used by the provider in fetching data.
%End

QgsInterval defaultInterval() const;
%Docstring
Returns the default time step interval corresponding to the available
datetime values for the provider.

.. seealso:: :py:func:`setDefaultInterval`

.. versionadded:: 3.20
%End

void setDefaultInterval( const QgsInterval &interval );
%Docstring
Sets the default time step ``interval`` corresponding to the available
datetime values for the provider.

.. seealso:: :py:func:`defaultInterval`

.. versionadded:: 3.20
%End

};
@@ -278,6 +278,11 @@ QList<QDateTime> QgsTemporalUtils::calculateDateTimesFromISO8601( const QString
// QgsTimeDuration
//

QgsInterval QgsTimeDuration::toInterval() const
{
return QgsInterval( years, months, weeks, days, hours, minutes, seconds );
}

QString QgsTimeDuration::toString() const
{
QString text( "P" );
@@ -77,6 +77,11 @@ class CORE_EXPORT QgsTimeDuration
return !( *this == other );
}

/**
* Converts the duration to an interval value.
*/
QgsInterval toInterval() const;

/**
* Converts the duration to an ISO8601 duration string.
*/
@@ -63,6 +63,16 @@ void QgsRasterDataProviderTemporalCapabilities::setRequestedTemporalRange( const
mRequestedRange = dateTimeRange;
}

QgsInterval QgsRasterDataProviderTemporalCapabilities::defaultInterval() const
{
return mDefaultInterval;
}

void QgsRasterDataProviderTemporalCapabilities::setDefaultInterval( const QgsInterval &defaultInterval )
{
mDefaultInterval = defaultInterval;
}

const QgsDateTimeRange &QgsRasterDataProviderTemporalCapabilities::requestedTemporalRange() const
{
return mRequestedRange;
@@ -21,6 +21,7 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsrange.h"
#include "qgsinterval.h"
#include "qgsdataprovidertemporalcapabilities.h"

/**
@@ -134,6 +135,24 @@ class CORE_EXPORT QgsRasterDataProviderTemporalCapabilities : public QgsDataProv
*/
const QgsDateTimeRange &requestedTemporalRange() const;

/**
* Returns the default time step interval corresponding to the available
* datetime values for the provider.
*
* \see setDefaultInterval()
* \since QGIS 3.20
*/
QgsInterval defaultInterval() const;

/**
* Sets the default time step \a interval corresponding to the available
* datetime values for the provider.
*
* \see defaultInterval()
* \since QGIS 3.20
*/
void setDefaultInterval( const QgsInterval &interval );

private:

/**
@@ -172,6 +191,8 @@ class CORE_EXPORT QgsRasterDataProviderTemporalCapabilities : public QgsDataProv
*/
QgsDateTimeRange mAvailableReferenceRange;

QgsInterval mDefaultInterval;

//! Interval handling method
IntervalHandlingMethod mIntervalMatchMethod = MatchUsingWholeRange;

@@ -25,6 +25,9 @@
#include "qgstemporalutils.h"
#include "qgsmaplayertemporalproperties.h"
#include "qgsmeshlayer.h"
#include "qgsrasterlayer.h"
#include "qgsrasterdataprovider.h"
#include "qgsrasterdataprovidertemporalcapabilities.h"

#include <QAction>
#include <QMenu>
@@ -443,14 +446,23 @@ void QgsTemporalControllerWidget::firstTemporalLayerLoaded( QgsMapLayer *layer )
{
setDatesToProjectTime();

QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
if ( meshLayer )
if ( QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer ) )
{
mBlockFrameDurationUpdates++;
setTimeStep( meshLayer->firstValidTimeStep() );
mBlockFrameDurationUpdates--;
updateFrameDuration();
}
else if ( QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer ) )
{
if ( rasterLayer->dataProvider() && rasterLayer->dataProvider()->temporalCapabilities() )
{
mBlockFrameDurationUpdates++;
setTimeStep( rasterLayer->dataProvider()->temporalCapabilities()->defaultInterval() );
mBlockFrameDurationUpdates--;
updateFrameDuration();
}
}
}

void QgsTemporalControllerWidget::onProjectCleared()
@@ -560,38 +572,46 @@ void QgsTemporalControllerWidget::setTimeStep( const QgsInterval &timeStep )
if ( ! timeStep.isValid() || timeStep.seconds() <= 0 )
return;

// Search the time unit the most appropriate :
// the one that gives the smallest time step value for double spin box with round value (if possible) and/or the less signifiant digits

int selectedUnit = -1;
int stringSize = std::numeric_limits<int>::max();
int precision = mStepSpinBox->decimals();
double selectedValue = std::numeric_limits<double>::max();
for ( int i = 0; i < mTimeStepsComboBox->count(); ++i )
if ( timeStep.originalUnit() != QgsUnitTypes::TemporalIrregularStep )
{
QgsUnitTypes::TemporalUnit unit = static_cast<QgsUnitTypes::TemporalUnit>( mTimeStepsComboBox->itemData( i ).toInt() );
double value = timeStep.seconds() * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalSeconds, unit );
QString string = QString::number( value, 'f', precision );
string.remove( QRegExp( "0+$" ) ); //remove trailing zero
string.remove( QRegExp( "[.]+$" ) ); //remove last point if present
// Search the time unit the most appropriate :
// the one that gives the smallest time step value for double spin box with round value (if possible) and/or the less signifiant digits

if ( value >= 1
&& string.size() <= stringSize // less significant digit than currently selected
&& value < selectedValue ) // less than currently selected
{
selectedUnit = i;
selectedValue = value;
stringSize = string.size();
}
else if ( string != '0'
&& string.size() < precision + 2 //round value (ex: 0.xx with precision=3)
&& string.size() < stringSize ) //less significant digit than currently selected
int stringSize = std::numeric_limits<int>::max();
int precision = mStepSpinBox->decimals();
for ( int i = 0; i < mTimeStepsComboBox->count(); ++i )
{
selectedUnit = i ;
selectedValue = value ;
stringSize = string.size();
QgsUnitTypes::TemporalUnit unit = static_cast<QgsUnitTypes::TemporalUnit>( mTimeStepsComboBox->itemData( i ).toInt() );
double value = timeStep.seconds() * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::TemporalSeconds, unit );
QString string = QString::number( value, 'f', precision );
string.remove( QRegExp( "0+$" ) ); //remove trailing zero
string.remove( QRegExp( "[.]+$" ) ); //remove last point if present

if ( value >= 1
&& string.size() <= stringSize // less significant digit than currently selected
&& value < selectedValue ) // less than currently selected
{
selectedUnit = i;
selectedValue = value;
stringSize = string.size();
}
else if ( string != '0'
&& string.size() < precision + 2 //round value (ex: 0.xx with precision=3)
&& string.size() < stringSize ) //less significant digit than currently selected
{
selectedUnit = i ;
selectedValue = value ;
stringSize = string.size();
}
}
}
else
{
selectedUnit = mTimeStepsComboBox->findData( static_cast< int >( timeStep.originalUnit() ) );
selectedValue = 1;
}

if ( selectedUnit >= 0 )
{
@@ -124,10 +124,13 @@ bool QgsWmsSettings::parseUri( const QString &uriString )
{
mAllRanges.append( QgsDateTimeRange( begin, end ) );
}

mDefaultInterval = extent.resolution.toInterval();
}
else
{
mAllRanges.append( QgsDateTimeRange( begin, end ) );
mDefaultInterval = QgsInterval( 1, QgsUnitTypes::TemporalIrregularStep );
}
}

@@ -786,6 +786,8 @@ class QgsWmsSettings
//! All available temporal ranges
QList< QgsDateTimeRange > mAllRanges;

QgsInterval mDefaultInterval;

//! Fixed reference temporal range for the data provider
QgsDateTimeRange mFixedReferenceRange;

@@ -173,6 +173,7 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri, const ProviderOptions &optio
temporalCapabilities()->setHasTemporalCapabilities( true );
temporalCapabilities()->setAvailableTemporalRange( mSettings.mFixedRange );
temporalCapabilities()->setAllAvailableTemporalRanges( mSettings.mAllRanges );
temporalCapabilities()->setDefaultInterval( mSettings.mDefaultInterval );

temporalCapabilities()->setIntervalHandlingMethod(
QgsRasterDataProviderTemporalCapabilities::MatchExactUsingStartOfRange );

0 comments on commit 929b708

Please sign in to comment.