38       return range.isInfinite() || mFixedRange.isInfinite() || mFixedRange.overlaps( range );
 
   52   QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
 
   54     return QgsDateTimeRange();
 
   64       if ( fieldIndex >= 0 )
 
   66         const QDateTime min = vectorLayer->
minimumValue( fieldIndex ).toDateTime();
 
   67         const QDateTime maxStartTime = vectorLayer->
maximumValue( fieldIndex ).toDateTime();
 
   69         return QgsDateTimeRange( min, maxStartTime + eventDuration );
 
   77       const int durationFieldIndex = vectorLayer->
fields().
lookupField( mDurationFieldName );
 
   78       if ( fieldIndex >= 0 && durationFieldIndex >= 0 )
 
   80         const QDateTime minTime = vectorLayer->
minimumValue( fieldIndex ).toDateTime();
 
   88           const QDateTime start = f.
attribute( fieldIndex ).toDateTime();
 
   89           if ( start.isValid() )
 
   91             const QVariant durationValue = f.
attribute( durationFieldIndex );
 
   92             if ( durationValue.isValid() )
 
   94               const double duration = durationValue.toDouble();
 
   95               const QDateTime end = start.addMSecs( 
QgsInterval( duration, mDurationUnit ).seconds() * 1000.0 );
 
   97                 maxTime = maxTime.isValid() ? std::max( maxTime, end ) : end;
 
  101         return QgsDateTimeRange( minTime, maxTime );
 
  108       const int startFieldIndex = vectorLayer->
fields().
lookupField( mStartFieldName );
 
  110       if ( startFieldIndex >= 0 && endFieldIndex >= 0 )
 
  112         return QgsDateTimeRange( std::min( vectorLayer->
minimumValue( startFieldIndex ).toDateTime(),
 
  113                                            vectorLayer->
minimumValue( endFieldIndex ).toDateTime() ),
 
  114                                  std::max( vectorLayer->
maximumValue( startFieldIndex ).toDateTime(),
 
  115                                            vectorLayer->
maximumValue( endFieldIndex ).toDateTime() ) );
 
  117       else if ( startFieldIndex >= 0 )
 
  119         return QgsDateTimeRange( vectorLayer->
minimumValue( startFieldIndex ).toDateTime(),
 
  120                                  vectorLayer->
maximumValue( startFieldIndex ).toDateTime() );
 
  122       else if ( endFieldIndex >= 0 )
 
  124         return QgsDateTimeRange( vectorLayer->
minimumValue( endFieldIndex ).toDateTime(),
 
  125                                  vectorLayer->
maximumValue( endFieldIndex ).toDateTime() );
 
  132       bool hasStartExpression = !mStartExpression.isEmpty();
 
  133       bool hasEndExpression = !mEndExpression.isEmpty();
 
  134       if ( !hasStartExpression && !hasEndExpression )
 
  135         return QgsDateTimeRange();
 
  145       if ( hasStartExpression )
 
  152       if ( hasEndExpression )
 
  158       QSet< QString > fields;
 
  159       if ( hasStartExpression )
 
  161       if ( hasEndExpression )
 
  177         const QDateTime start = hasStartExpression ? 
startExpression.evaluate( &context ).toDateTime() : QDateTime();
 
  178         const QDateTime end = hasEndExpression ? 
endExpression.evaluate( &context ).toDateTime() : QDateTime();
 
  180         if ( start.isValid() )
 
  182           minTime = minTime.isValid() ? std::min( minTime, start ) : start;
 
  183           if ( !hasEndExpression )
 
  184             maxTime = maxTime.isValid() ? std::max( maxTime, start ) : start;
 
  188           maxTime = maxTime.isValid() ? std::max( maxTime, end ) : end;
 
  189           if ( !hasStartExpression )
 
  190             minTime = minTime.isValid() ? std::min( minTime, end ) : end;
 
  193       return QgsDateTimeRange( minTime, maxTime );
 
  200   return QgsDateTimeRange();
 
  234   QDomElement temporalNode = element.firstChildElement( QStringLiteral( 
"temporal" ) );
 
  236   setIsActive( temporalNode.attribute( QStringLiteral( 
"enabled" ), QStringLiteral( 
"0" ) ).toInt() );
 
  238   mMode = 
static_cast< TemporalMode >( temporalNode.attribute( QStringLiteral( 
"mode" ), QStringLiteral( 
"0" ) ). toInt() );
 
  240   mStartFieldName = temporalNode.attribute( QStringLiteral( 
"startField" ) );
 
  241   mEndFieldName = temporalNode.attribute( QStringLiteral( 
"endField" ) );
 
  242   mStartExpression = temporalNode.attribute( QStringLiteral( 
"startExpression" ) );
 
  243   mEndExpression = temporalNode.attribute( QStringLiteral( 
"endExpression" ) );
 
  244   mDurationFieldName = temporalNode.attribute( QStringLiteral( 
"durationField" ) );
 
  246   mFixedDuration = temporalNode.attribute( QStringLiteral( 
"fixedDuration" ) ).toDouble();
 
  247   mAccumulateFeatures = temporalNode.attribute( QStringLiteral( 
"accumulate" ), QStringLiteral( 
"0" ) ).toInt();
 
  249   QDomNode rangeElement = temporalNode.namedItem( QStringLiteral( 
"fixedRange" ) );
 
  251   QDomNode begin = rangeElement.namedItem( QStringLiteral( 
"start" ) );
 
  252   QDomNode end = rangeElement.namedItem( QStringLiteral( 
"end" ) );
 
  254   QDateTime beginDate = QDateTime::fromString( begin.toElement().text(), Qt::ISODate );
 
  255   QDateTime endDate = QDateTime::fromString( end.toElement().text(), Qt::ISODate );
 
  257   QgsDateTimeRange range = QgsDateTimeRange( beginDate, endDate );
 
  266   if ( element.isNull() )
 
  267     return QDomElement();
 
  269   QDomElement temporalElement = document.createElement( QStringLiteral( 
"temporal" ) );
 
  270   temporalElement.setAttribute( QStringLiteral( 
"enabled" ), 
isActive() ? QStringLiteral( 
"1" ) : QStringLiteral( 
"0" ) );
 
  271   temporalElement.setAttribute( QStringLiteral( 
"mode" ), QString::number( mMode ) );
 
  273   temporalElement.setAttribute( QStringLiteral( 
"startField" ), mStartFieldName );
 
  274   temporalElement.setAttribute( QStringLiteral( 
"endField" ), mEndFieldName );
 
  275   temporalElement.setAttribute( QStringLiteral( 
"startExpression" ), mStartExpression );
 
  276   temporalElement.setAttribute( QStringLiteral( 
"endExpression" ), mEndExpression );
 
  277   temporalElement.setAttribute( QStringLiteral( 
"durationField" ), mDurationFieldName );
 
  279   temporalElement.setAttribute( QStringLiteral( 
"fixedDuration" ), 
qgsDoubleToString( mFixedDuration ) );
 
  280   temporalElement.setAttribute( QStringLiteral( 
"accumulate" ), mAccumulateFeatures ? QStringLiteral( 
"1" ) : QStringLiteral( 
"0" ) );
 
  282   QDomElement rangeElement = document.createElement( QStringLiteral( 
"fixedRange" ) );
 
  284   QDomElement startElement = document.createElement( QStringLiteral( 
"start" ) );
 
  285   QDomElement endElement = document.createElement( QStringLiteral( 
"end" ) );
 
  287   QDomText startText = document.createTextNode( mFixedRange.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
 
  288   QDomText endText = document.createTextNode( mFixedRange.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
 
  289   startElement.appendChild( startText );
 
  290   endElement.appendChild( endText );
 
  291   rangeElement.appendChild( startElement );
 
  292   rangeElement.appendChild( endElement );
 
  294   temporalElement.appendChild( rangeElement );
 
  296   element.appendChild( temporalElement );
 
  305     setIsActive( vectorCaps->hasTemporalCapabilities() );
 
  309     switch ( vectorCaps->mode() )
 
  326   return mStartExpression;
 
  336   return mEndExpression;
 
  346   return mAccumulateFeatures;
 
  356   return mFixedDuration;
 
  366   return mStartFieldName;
 
  371   mStartFieldName = startFieldName;
 
  376   return mEndFieldName;
 
  381   mEndFieldName = 
field;
 
  386   return mDurationFieldName;
 
  391   mDurationFieldName = 
field;
 
  396   return mDurationUnit;
 
  401   mDurationUnit = units;
 
  406   return QStringLiteral( 
"make_datetime(%1,%2,%3,%4,%5,%6)" ).arg( datetime.date().year() )
 
  407          .arg( datetime.date().month() )
 
  408          .arg( datetime.date().day() )
 
  409          .arg( datetime.time().hour() )
 
  410          .arg( datetime.time().minute() )
 
  411          .arg( datetime.time().second() + datetime.time().msec() / 1000.0 );
 
  427       if ( mAccumulateFeatures )
 
  430                range.includeEnd() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  436                range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  438                range.includeEnd() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  444                range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  446                range.includeEnd() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  453       QString intervalExpression;
 
  454       switch ( mDurationUnit )
 
  500              range.includeEnd() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  503              range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  511       if ( !mStartFieldName.isEmpty() && !mEndFieldName.isEmpty() )
 
  514                range.includeEnd() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  517                range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  520       else if ( !mStartFieldName.isEmpty() )
 
  523                range.includeBeginning() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  526       else if ( !mEndFieldName.isEmpty() )
 
  529                range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  537       if ( !mStartExpression.isEmpty() && !mEndExpression.isEmpty() )
 
  539         return QStringLiteral( 
"((%1) %2 %3) AND ((%4) %5 %6)" ).arg( mStartExpression,
 
  540                range.includeEnd() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  543                range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  546       else if ( !mStartExpression.isEmpty() )
 
  548         return QStringLiteral( 
"(%1) %2 %3" ).arg( mStartExpression,
 
  549                range.includeBeginning() ? QStringLiteral( 
"<=" ) : QStringLiteral( 
"<" ),
 
  552       else if ( !mEndExpression.isEmpty() )
 
  554         return QStringLiteral( 
"(%1) %2 %3" ).arg( mEndExpression,
 
  555                range.includeBeginning() ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
  574   static QStringList sStartCandidates{ QStringLiteral( 
"start" ),
 
  575                                        QStringLiteral( 
"begin" ),
 
  576                                        QStringLiteral( 
"from" )};
 
  578   static QStringList sEndCandidates{ QStringLiteral( 
"end" ),
 
  579                                      QStringLiteral( 
"last" ),
 
  580                                      QStringLiteral( 
"to" )};
 
  582   static QStringList sSingleFieldCandidates{ QStringLiteral( 
"event" ) };
 
  585   bool foundStart = 
false;
 
  586   bool foundEnd = 
false;
 
  595       for ( 
const QString &candidate : sStartCandidates )
 
  598         if ( fldName.indexOf( candidate, 0, Qt::CaseInsensitive ) > -1 )
 
  600           mStartFieldName = fldName;
 
  608       for ( 
const QString &candidate : sEndCandidates )
 
  611         if ( fldName.indexOf( candidate, 0, Qt::CaseInsensitive ) > -1 )
 
  613           mEndFieldName = fldName;
 
  619     if ( foundStart && foundEnd )
 
  631       for ( 
const QString &candidate : sSingleFieldCandidates )
 
  634         if ( fldName.indexOf( candidate, 0, Qt::CaseInsensitive ) > -1 )
 
  636           mStartFieldName = fldName;
 
  646   if ( foundStart && foundEnd )
 
  648   else if ( foundStart )