1 /***************************************************************************
2 qgsrasterlayertemporalproperties.cpp
3 ---------------
4 begin : February 2020
5 copyright : (C) 2020 by Samweli Mwakisambwe
6 email : samweli at kartoza dot com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "qgsrasterlayertemporalproperties.h"
19 #include "qgsrasterdataprovidertemporalcapabilities.h"
20 #include "qgsrasterlayer.h"
21
QgsRasterLayerTemporalProperties(QObject * parent,bool enabled)22 QgsRasterLayerTemporalProperties::QgsRasterLayerTemporalProperties( QObject *parent, bool enabled )
23 : QgsMapLayerTemporalProperties( parent, enabled )
24 {
25 }
26
isVisibleInTemporalRange(const QgsDateTimeRange & range) const27 bool QgsRasterLayerTemporalProperties::isVisibleInTemporalRange( const QgsDateTimeRange &range ) const
28 {
29 if ( !isActive() )
30 return true;
31
32 switch ( mMode )
33 {
34 case Qgis::RasterTemporalMode::FixedTemporalRange:
35 return range.isInfinite() || mFixedRange.isInfinite() || mFixedRange.overlaps( range );
36
37 case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider:
38 case Qgis::RasterTemporalMode::RedrawLayerOnly:
39 return true;
40 }
41 return true;
42 }
43
calculateTemporalExtent(QgsMapLayer * layer) const44 QgsDateTimeRange QgsRasterLayerTemporalProperties::calculateTemporalExtent( QgsMapLayer *layer ) const
45 {
46 QgsRasterLayer *rasterLayer = qobject_cast< QgsRasterLayer *>( layer );
47 if ( !rasterLayer )
48 return QgsDateTimeRange();
49
50 switch ( mMode )
51 {
52 case Qgis::RasterTemporalMode::FixedTemporalRange:
53 return mFixedRange;
54
55 case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider:
56 return rasterLayer->dataProvider()->temporalCapabilities()->availableTemporalRange();
57
58 case Qgis::RasterTemporalMode::RedrawLayerOnly:
59 break;
60 }
61
62 return QgsDateTimeRange();
63 }
64
allTemporalRanges(QgsMapLayer * layer) const65 QList<QgsDateTimeRange> QgsRasterLayerTemporalProperties::allTemporalRanges( QgsMapLayer *layer ) const
66 {
67 QgsRasterLayer *rasterLayer = qobject_cast< QgsRasterLayer *>( layer );
68 if ( !rasterLayer )
69 return {};
70
71 switch ( mMode )
72 {
73 case Qgis::RasterTemporalMode::FixedTemporalRange:
74 return { mFixedRange };
75
76 case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider:
77 {
78 const QList< QgsDateTimeRange > ranges = rasterLayer->dataProvider()->temporalCapabilities()->allAvailableTemporalRanges();
79 return ranges.empty() ? QList< QgsDateTimeRange > { rasterLayer->dataProvider()->temporalCapabilities()->availableTemporalRange() } : ranges;
80 }
81
82 case Qgis::RasterTemporalMode::RedrawLayerOnly:
83 break;
84 }
85
86 return {};
87 }
88
mode() const89 Qgis::RasterTemporalMode QgsRasterLayerTemporalProperties::mode() const
90 {
91 return mMode;
92 }
93
setMode(Qgis::RasterTemporalMode mode)94 void QgsRasterLayerTemporalProperties::setMode( Qgis::RasterTemporalMode mode )
95 {
96 if ( mMode == mode )
97 return;
98 mMode = mode;
99 }
100
flags() const101 QgsTemporalProperty::Flags QgsRasterLayerTemporalProperties::flags() const
102 {
103 return mode() == Qgis::RasterTemporalMode::FixedTemporalRange ? QgsTemporalProperty::FlagDontInvalidateCachedRendersWhenRangeChanges : QgsTemporalProperty::Flags();
104 }
105
intervalHandlingMethod() const106 Qgis::TemporalIntervalMatchMethod QgsRasterLayerTemporalProperties::intervalHandlingMethod() const
107 {
108 return mIntervalHandlingMethod;
109 }
110
setIntervalHandlingMethod(Qgis::TemporalIntervalMatchMethod method)111 void QgsRasterLayerTemporalProperties::setIntervalHandlingMethod( Qgis::TemporalIntervalMatchMethod method )
112 {
113 if ( mIntervalHandlingMethod == method )
114 return;
115 mIntervalHandlingMethod = method;
116 }
117
setFixedTemporalRange(const QgsDateTimeRange & range)118 void QgsRasterLayerTemporalProperties::setFixedTemporalRange( const QgsDateTimeRange &range )
119 {
120 mFixedRange = range;
121 }
122
fixedTemporalRange() const123 const QgsDateTimeRange &QgsRasterLayerTemporalProperties::fixedTemporalRange() const
124 {
125 return mFixedRange;
126 }
127
readXml(const QDomElement & element,const QgsReadWriteContext & context)128 bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context )
129 {
130 Q_UNUSED( context )
131 // TODO add support for raster layers with multi-temporal properties.
132
133 const QDomElement temporalNode = element.firstChildElement( QStringLiteral( "temporal" ) );
134
135 setIsActive( temporalNode.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt() );
136
137 mMode = static_cast< Qgis::RasterTemporalMode >( temporalNode.attribute( QStringLiteral( "mode" ), QStringLiteral( "0" ) ). toInt() );
138 mIntervalHandlingMethod = static_cast< Qgis::TemporalIntervalMatchMethod >( temporalNode.attribute( QStringLiteral( "fetchMode" ), QStringLiteral( "0" ) ). toInt() );
139
140 const QDomNode rangeElement = temporalNode.namedItem( QStringLiteral( "fixedRange" ) );
141
142 const QDomNode begin = rangeElement.namedItem( QStringLiteral( "start" ) );
143 const QDomNode end = rangeElement.namedItem( QStringLiteral( "end" ) );
144
145 const QDateTime beginDate = QDateTime::fromString( begin.toElement().text(), Qt::ISODate );
146 const QDateTime endDate = QDateTime::fromString( end.toElement().text(), Qt::ISODate );
147
148 const QgsDateTimeRange range = QgsDateTimeRange( beginDate, endDate );
149 setFixedTemporalRange( range );
150
151 return true;
152 }
153
writeXml(QDomElement & element,QDomDocument & document,const QgsReadWriteContext & context)154 QDomElement QgsRasterLayerTemporalProperties::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context )
155 {
156 Q_UNUSED( context )
157 if ( element.isNull() )
158 return QDomElement();
159
160 QDomElement temporalElement = document.createElement( QStringLiteral( "temporal" ) );
161 temporalElement.setAttribute( QStringLiteral( "enabled" ), isActive() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
162 temporalElement.setAttribute( QStringLiteral( "mode" ), QString::number( static_cast< int >( mMode ) ) );
163 temporalElement.setAttribute( QStringLiteral( "fetchMode" ), QString::number( static_cast< int >( mIntervalHandlingMethod ) ) );
164
165 QDomElement rangeElement = document.createElement( QStringLiteral( "fixedRange" ) );
166
167 QDomElement startElement = document.createElement( QStringLiteral( "start" ) );
168 QDomElement endElement = document.createElement( QStringLiteral( "end" ) );
169
170 const QDomText startText = document.createTextNode( mFixedRange.begin().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
171 const QDomText endText = document.createTextNode( mFixedRange.end().toTimeSpec( Qt::OffsetFromUTC ).toString( Qt::ISODate ) );
172 startElement.appendChild( startText );
173 endElement.appendChild( endText );
174 rangeElement.appendChild( startElement );
175 rangeElement.appendChild( endElement );
176
177 temporalElement.appendChild( rangeElement );
178
179 element.appendChild( temporalElement );
180
181 return element;
182 }
183
setDefaultsFromDataProviderTemporalCapabilities(const QgsDataProviderTemporalCapabilities * capabilities)184 void QgsRasterLayerTemporalProperties::setDefaultsFromDataProviderTemporalCapabilities( const QgsDataProviderTemporalCapabilities *capabilities )
185 {
186 if ( const QgsRasterDataProviderTemporalCapabilities *rasterCaps = dynamic_cast< const QgsRasterDataProviderTemporalCapabilities *>( capabilities ) )
187 {
188 setIsActive( rasterCaps->hasTemporalCapabilities() );
189 setFixedTemporalRange( rasterCaps->availableTemporalRange() );
190
191 if ( rasterCaps->hasTemporalCapabilities() )
192 {
193 setMode( Qgis::RasterTemporalMode::TemporalRangeFromDataProvider );
194 }
195
196 mIntervalHandlingMethod = rasterCaps->intervalHandlingMethod();
197 }
198 }
199