Skip to content
Permalink
Browse files

temporal match methods

  • Loading branch information
vcloarec authored and nyalldawson committed May 19, 2020
1 parent daab0ea commit 267af1e7fb06c407aa4f7b898f53191d7e4d6a72
@@ -23,22 +23,37 @@ Class for handling properties relating to a mesh data provider's temporal capabi
%End
public:

enum MatchingTemporalDatasetMethod
{
FindClosestDatasetBeforeStartRangeTime,
FindClosestDatasetFromStartRangeTime
};

QgsMeshDataProviderTemporalCapabilities();
%Docstring
Constructor for QgsMeshDataProviderTemporalCapabilities
%End

QgsMeshDatasetIndex datasetIndexFromRelativeTimeRange( int group, qint64 startTimeSinceGlobalReference, qint64 endTimeSinceGlobalReference ) const;
QgsMeshDatasetIndex datasetIndexClosestBeforeRelativeTime( int group, qint64 timeSinceGlobalReference ) const;
%Docstring
Returns the last dataset whith time less than or equal to ``timeSinceGlobalReference``

Returns invalid dataset index if ``timeSinceGlobalReference`` is outside the time extent of the dataset group

.. note::

for non temporal dataset group, ``timeSinceGlobalReference`` is not used and the unique dataset is returned
%End

QgsMeshDatasetIndex datasetIndexClosestFromRelativeTime( int group, qint64 timeSinceGlobalReference ) const;
%Docstring
Returns the first dataset that are include in the range [``startTimeSinceGlobalReference``,``endTimeSinceGlobalReference``[ (in milliseconds)
from the dataset ``group``. If no dataset is present in this range return the last dataset before this range if it not the last one
of whole the dataset group
Returns the closest dataset index from the ``timeSinceGlobalReference``

Returns invalid dataset index if there is no data set in the range
Returns invalid dataset index if ``timeSinceGlobalReference`` is outside the time extent of the dataset group

.. note::

for non temporal dataset group, the range is not used and the unique dataset is returned
for non temporal dataset group, ``timeSinceGlobalReference`` is not used and the unique dataset is returned
%End


@@ -292,6 +292,11 @@ If the temporal properties is not active, return the static dataset

:return: dataset index

.. note::

the returned dataset index depends on the matching method, see setTemporalMatchingMethod()


.. versionadded:: 3.14
%End

@@ -304,6 +309,11 @@ If the temporal properties is not active, return the static dataset

:return: dataset index

.. note::

the returned dataset index depends on the matching method, see setTemporalMatchingMethod()


.. versionadded:: 3.14
%End

@@ -329,6 +339,15 @@ Sets the reference time of the layer

:param referenceTime: the reference time

.. versionadded:: 3.14
%End

void setTemporalMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod );
%Docstring
Sets the method used to match the temporal dataset from a requested time, see activeVectorDatasetAtTime()

:param matchingMethod: the matching method

.. versionadded:: 3.14
%End

@@ -74,6 +74,18 @@ if the temporal capabilities is null, set a void time extent (reference time to

:param referenceTime: the reference time
:param capabilities: the temporal capabilities of the data provider
%End

QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod matchingMethod() const;
%Docstring
Returns the method used to match dataset from temporal capabilities
%End

void setMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod );
%Docstring
Sets the method used to match dataset from temporal capabilities

:param matchingMethod: the matching method
%End

};
@@ -0,0 +1,2 @@
# The following has been generated automatically from src/gui/qgssublayersdialog.h
QgsSublayersDialog.PromptMode.baseClass = QgsSublayersDialog
@@ -95,6 +95,11 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *
delete mOptsPage_3DView; // removes both the "3d view" list item and its page
#endif

mComboBoxTemporalDatasetMatchingMethod->addItem( tr( "Find closest dataset before requested time" ),
QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetBeforeStartRangeTime );
mComboBoxTemporalDatasetMatchingMethod->addItem( tr( "Find closest dataset from requested time (after or before)" ),
QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetFromStartRangeTime );

// update based on lyr's current state
syncToLayer();

@@ -209,6 +214,8 @@ void QgsMeshLayerProperties::syncToLayer()
mTemporalProviderTimeUnitComboBox->setCurrentIndex(
mTemporalProviderTimeUnitComboBox->findData( mMeshLayer->dataProvider()->temporalCapabilities()->temporalUnit() ) );
}
mComboBoxTemporalDatasetMatchingMethod->setCurrentIndex(
mComboBoxTemporalDatasetMatchingMethod->findData( temporalProperties->matchingMethod() ) );

mStaticScalarWidget->syncToLayer();
mStaticScalarWidget->setVisible( !mMeshLayer->temporalProperties()->isActive() );
@@ -371,6 +378,8 @@ void QgsMeshLayerProperties::apply()
mStaticScalarWidget->apply();
bool needEmitRendererChanged = mMeshLayer->temporalProperties()->isActive() == mTemporalStaticDatasetCheckBox->isChecked();
mMeshLayer->temporalProperties()->setIsActive( !mTemporalStaticDatasetCheckBox->isChecked() );
mMeshLayer->setTemporalMatchingMethod( static_cast<QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod>(
mComboBoxTemporalDatasetMatchingMethod->currentData().toInt() ) );

if ( needMeshUpdating )
mMeshLayer->reload();
@@ -21,38 +21,58 @@
QgsMeshDataProviderTemporalCapabilities::QgsMeshDataProviderTemporalCapabilities(): QgsDataProviderTemporalCapabilities()
{}

QgsMeshDatasetIndex QgsMeshDataProviderTemporalCapabilities::datasetIndexFromRelativeTimeRange( int group, qint64 startTimeSinceGlobalReference, qint64 endTimeSinceGlobalReference ) const
QgsMeshDatasetIndex QgsMeshDataProviderTemporalCapabilities::datasetIndexClosestFromRelativeTime( int group, qint64 timeSinceGlobalReference ) const
{
// No time --> non temporal dataset, so return the dataset that has to be the only one
const QList<qint64> &datasetTimes = mDatasetTimeSinceGroupReference[group];
if ( datasetTimes.isEmpty() )
return QgsMeshDatasetIndex( group, 0 );
const QDateTime groupReference = mGroupsReferenceDateTime[group];
const qint64 startTimeSinceGroupReference =
startTimeSinceGlobalReference - mGlobalReferenceDateTime.msecsTo( groupReference );
const qint64 endTimeSinceGroupReference =
endTimeSinceGlobalReference - mGlobalReferenceDateTime.msecsTo( groupReference );
const qint64 timeSinceGroupReference =
timeSinceGlobalReference - mGlobalReferenceDateTime.msecsTo( groupReference );

if ( startTimeSinceGroupReference > datasetTimes.last() )
if ( timeSinceGroupReference > datasetTimes.last() // after last time
|| timeSinceGroupReference < datasetTimes.first() ) // before first time
return QgsMeshDatasetIndex();

if ( endTimeSinceGroupReference < datasetTimes.first() )
return QgsMeshDatasetIndex();

for ( int i = 0; i < datasetTimes.count(); ++i )
for ( int i = 1 ; i < datasetTimes.count(); ++i )
{
qint64 time = datasetTimes.at( i );
if ( startTimeSinceGroupReference <= time )
qint64 time1 = datasetTimes.at( i - 1 );
qint64 time2 = datasetTimes.at( i );
if ( time1 <= timeSinceGroupReference && timeSinceGroupReference <= time2 )
{
if ( endTimeSinceGroupReference < time ) // Start and end of range are before the current time step
return QgsMeshDatasetIndex( group, i - 1 ); // --> return the previous time step, invalid if i=0
if ( abs( timeSinceGroupReference - time2 ) < abs( timeSinceGroupReference - time1 ) )
return QgsMeshDatasetIndex( group, i );
else
return QgsMeshDatasetIndex( group, i ); // current time step are included in [start,end] --> return current
return QgsMeshDatasetIndex( group, i - 1 );
}
}

// if we are here (normally, this could no happen), return invalid dataset index
return QgsMeshDatasetIndex();
return QgsMeshDatasetIndex( QgsMeshDatasetIndex( group, datasetTimes.count() - 1 ) );
}

QgsMeshDatasetIndex QgsMeshDataProviderTemporalCapabilities::datasetIndexClosestBeforeRelativeTime( int group, qint64 timeSinceGlobalReference ) const
{
// No time --> non temporal dataset, so return the dataset that has to be the only one
const QList<qint64> &datasetTimes = mDatasetTimeSinceGroupReference[group];
if ( datasetTimes.isEmpty() )
return QgsMeshDatasetIndex( group, 0 );
const QDateTime groupReference = mGroupsReferenceDateTime[group];
const qint64 timeSinceGroupReference =
timeSinceGlobalReference - mGlobalReferenceDateTime.msecsTo( groupReference );

if ( timeSinceGroupReference > datasetTimes.last() // after last time
|| timeSinceGroupReference < datasetTimes.first() ) // before first time
return QgsMeshDatasetIndex();

for ( int i = 1; i < datasetTimes.count(); ++i )
{
qint64 time = datasetTimes.at( i );
if ( timeSinceGroupReference < time )
return QgsMeshDatasetIndex( group, i - 1 );
}

return QgsMeshDatasetIndex( QgsMeshDatasetIndex( group, datasetTimes.count() - 1 ) );
}

void QgsMeshDataProviderTemporalCapabilities::addGroupReferenceDateTime( int group, const QDateTime &reference )
@@ -34,21 +34,37 @@ class CORE_EXPORT QgsMeshDataProviderTemporalCapabilities: public QgsDataProvide
{
public:

/**
* Method to use when requesting a tempral dataset from a time
**/
enum MatchingTemporalDatasetMethod
{
FindClosestDatasetBeforeStartRangeTime, //! Find the closest dataset which have its time before the requested start range time
FindClosestDatasetFromStartRangeTime //! Find the closest dataset before or after the requested start range time
};

/**
* Constructor for QgsMeshDataProviderTemporalCapabilities
*/
QgsMeshDataProviderTemporalCapabilities();

/**
* Returns the first dataset that are include in the range [\a startTimeSinceGlobalReference,\a endTimeSinceGlobalReference[ (in milliseconds)
* from the dataset \a group. If no dataset is present in this range return the last dataset before this range if it not the last one
* of whole the dataset group
* Returns the last dataset whith time less than or equal to \a timeSinceGlobalReference
*
* Returns invalid dataset index if \a timeSinceGlobalReference is outside the time extent of the dataset group
*
* \note for non temporal dataset group, \a timeSinceGlobalReference is not used and the unique dataset is returned
*/
QgsMeshDatasetIndex datasetIndexClosestBeforeRelativeTime( int group, qint64 timeSinceGlobalReference ) const;

/**
* Returns the closest dataset index from the \a timeSinceGlobalReference
*
* Returns invalid dataset index if there is no data set in the range
*Returns invalid dataset index if \a timeSinceGlobalReference is outside the time extent of the dataset group
*
* \note for non temporal dataset group, the range is not used and the unique dataset is returned
* \note for non temporal dataset group, \a timeSinceGlobalReference is not used and the unique dataset is returned
*/
QgsMeshDatasetIndex datasetIndexFromRelativeTimeRange( int group, qint64 startTimeSinceGlobalReference, qint64 endTimeSinceGlobalReference ) const;
QgsMeshDatasetIndex datasetIndexClosestFromRelativeTime( int group, qint64 timeSinceGlobalReference ) const;

/**
* Adds a \a reference date/time from a dataset \a group
@@ -82,9 +82,7 @@ void QgsMeshLayer::setDefaultRendererSettings()
meta.minimum() == std::numeric_limits<double>::quiet_NaN() )
meshSettings.setEnabled( true );

// If the mesh is non temporal, set the static scalar dataset
if ( !mDataProvider->temporalCapabilities()->hasTemporalCapabilities() )
setStaticScalarDatasetIndex( QgsMeshDatasetIndex( 0, 0 ) );
setStaticScalarDatasetIndex( QgsMeshDatasetIndex( 0, 0 ) );
}
else
{
@@ -435,12 +433,17 @@ QgsMeshDatasetIndex QgsMeshLayer::datasetIndexAtTime( const QgsDateTimeRange &ti
{
const QDateTime layerReferenceTime = mTemporalProperties->referenceTime();
qint64 startTime = layerReferenceTime.msecsTo( timeRange.begin() );
qint64 endTime = layerReferenceTime.msecsTo( timeRange.end() );

if ( dataProvider() )
return dataProvider()->temporalCapabilities()->datasetIndexFromRelativeTimeRange( datasetGroupIndex, startTime, endTime );
else
return QgsMeshDatasetIndex();
switch ( mTemporalProperties->matchingMethod() )
{
case QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetBeforeStartRangeTime:
return dataProvider()->temporalCapabilities()->datasetIndexClosestBeforeRelativeTime( datasetGroupIndex, startTime );
case QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetFromStartRangeTime:
return dataProvider()->temporalCapabilities()->datasetIndexClosestFromRelativeTime( datasetGroupIndex, startTime );
}

return QgsMeshDatasetIndex();
}

void QgsMeshLayer::applyClassificationOnScalarSettings( const QgsMeshDatasetGroupMetadata &meta, QgsMeshRendererScalarSettings &scalarSettings ) const
@@ -637,6 +640,11 @@ void QgsMeshLayer::setReferenceTime( const QDateTime &referenceTime )
mTemporalProperties->setReferenceTime( referenceTime, nullptr );
}

void QgsMeshLayer::setTemporalMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod )
{
mTemporalProperties->setMatchingMethod( matchingMethod );
}

QgsPointXY QgsMeshLayer::snapOnVertex( const QgsPointXY &point, double searchRadius )
{
const QgsTriangularMesh *mesh = triangularMesh();
@@ -332,6 +332,8 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
* \param timeRange the time range
* \returns dataset index
*
* \note the returned dataset index depends on the matching method, see setTemporalMatchingMethod()
*
* \since QGIS 3.14
*/
QgsMeshDatasetIndex activeScalarDatasetAtTime( const QgsDateTimeRange &timeRange ) const;
@@ -343,6 +345,8 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
* \param timeRange the time range
* \returns dataset index
*
* \note the returned dataset index depends on the matching method, see setTemporalMatchingMethod()
*
* \since QGIS 3.14
*/
QgsMeshDatasetIndex activeVectorDatasetAtTime( const QgsDateTimeRange &timeRange ) const;
@@ -388,6 +392,15 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
*/
void setReferenceTime( const QDateTime &referenceTime );

/**
* Sets the method used to match the temporal dataset from a requested time, see activeVectorDatasetAtTime()
*
* \param matchingMethod the matching method
*
* \since QGIS 3.14
*/
void setTemporalMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod );

/**
* Returns the position of the snapped point on the mesh element closest to \a point intersecting with
* the searching area defined by \a point and \a searchRadius
@@ -33,6 +33,7 @@ QDomElement QgsMeshLayerTemporalProperties::writeXml( QDomElement &element, QDom
temporalElement.setAttribute( QStringLiteral( "reference-time" ), mReferenceTime.toTimeSpec( Qt::UTC ).toString( Qt::ISODate ) );
temporalElement.setAttribute( QStringLiteral( "start-time-extent" ), mTimeExtent.begin().toTimeSpec( Qt::UTC ).toString( Qt::ISODate ) );
temporalElement.setAttribute( QStringLiteral( "end-time-extent" ), mTimeExtent.end().toTimeSpec( Qt::UTC ).toString( Qt::ISODate ) );
temporalElement.setAttribute( QStringLiteral( "matching-method" ), mMatchingMethod );

element.appendChild( temporalElement );

@@ -57,6 +58,9 @@ bool QgsMeshLayerTemporalProperties::readXml( const QDomElement &element, const
mTimeExtent = QgsDateTimeRange( start, end );
}

mMatchingMethod = static_cast<QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod>(
temporalElement.attribute( QStringLiteral( "matching-method" ) ).toInt() );

return true;
}

@@ -98,3 +102,13 @@ void QgsMeshLayerTemporalProperties::setReferenceTime( const QDateTime &referenc
else
mTimeExtent = QgsDateTimeRange( referenceTime, referenceTime );
}

QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod QgsMeshLayerTemporalProperties::matchingMethod() const
{
return mMatchingMethod;
}

void QgsMeshLayerTemporalProperties::setMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod )
{
mMatchingMethod = matchingMethod;
}
@@ -19,6 +19,7 @@
#define QGSMESHLAYERTEMPORALPROPERTIES_H

#include "qgsmaplayertemporalproperties.h"
#include "qgsmeshdataprovidertemporalcapabilities.h"


/**
@@ -86,9 +87,23 @@ class CORE_EXPORT QgsMeshLayerTemporalProperties : public QgsMapLayerTemporalPro
*/
void setReferenceTime( const QDateTime &referenceTime, const QgsDataProviderTemporalCapabilities *capabilities );

/**
* Returns the method used to match dataset from temporal capabilities
*/
QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod matchingMethod() const;

/**
* Sets the method used to match dataset from temporal capabilities
*
* \param matchingMethod the matching method
*/
void setMatchingMethod( const QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod &matchingMethod );

private:
QDateTime mReferenceTime;
QgsDateTimeRange mTimeExtent;
QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod mMatchingMethod =
QgsMeshDataProviderTemporalCapabilities::FindClosestDatasetBeforeStartRangeTime;
};

#endif // QGSMESHLAYERTEMPORALPROPERTIES_H

0 comments on commit 267af1e

Please sign in to comment.
You can’t perform that action at this time.