Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgstemporalutils.h 3 : : ------------------ 4 : : Date : March 2020 5 : : Copyright : (C) 2020 by Nyall Dawson 6 : : Email : nyall dot dawson at gmail dot com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #ifndef QGSTEMPORALUTILS_H 17 : : #define QGSTEMPORALUTILS_H 18 : : 19 : : #include "qgis_core.h" 20 : : #include "qgsrange.h" 21 : : #include "qgsinterval.h" 22 : : 23 : : class QgsProject; 24 : : class QgsMapSettings; 25 : : class QgsFeedback; 26 : : class QgsMapDecoration; 27 : : 28 : : #ifndef SIP_RUN 29 : : 30 : : /** 31 : : * \ingroup core 32 : : * \class QgsTimeDuration 33 : : * \brief Contains utility methods for working with temporal layers and projects. 34 : : * 35 : : * Designed for storage of ISO8601 duration values. 36 : : * 37 : : * \note Not available in Python bindings 38 : : * \since QGIS 3.20 39 : : */ 40 : 0 : class CORE_EXPORT QgsTimeDuration 41 : : { 42 : : public: 43 : : 44 : : //! Years 45 : 0 : int years = 0; 46 : : //! Months 47 : 0 : int months = 0; 48 : : //! Weeks 49 : 0 : int weeks = 0; 50 : : //! Days 51 : 0 : int days = 0; 52 : : //! Hours 53 : 0 : int hours = 0; 54 : : //! Minutes 55 : 0 : int minutes = 0; 56 : : //! Seconds 57 : 0 : double seconds = 0; 58 : : 59 : : /** 60 : : * Returns TRUE if the duration is null, i.e. an empty duration. 61 : : */ 62 : : bool isNull() const 63 : : { 64 : : return !years && !months && !days && 65 : : !hours && !minutes && !seconds; 66 : : } 67 : : 68 : : bool operator==( const QgsTimeDuration &other ) const 69 : : { 70 : : return years == other.years && months == other.months && 71 : : days == other.days && hours == other.hours && 72 : : minutes == other.minutes && seconds == other.seconds; 73 : : } 74 : : 75 : : bool operator!=( const QgsTimeDuration &other ) const 76 : : { 77 : : return !( *this == other ); 78 : : } 79 : : 80 : : /** 81 : : * Converts the duration to an interval value. 82 : : */ 83 : : QgsInterval toInterval() const; 84 : : 85 : : /** 86 : : * Converts the duration to an ISO8601 duration string. 87 : : */ 88 : : QString toString() const; 89 : : 90 : : /** 91 : : * Returns the total duration in seconds. 92 : : * 93 : : * \warning If the duration contains year or month intervals then the returned 94 : : * value is approximate only, due to the variable length of these intervals. 95 : : */ 96 : : long long toSeconds() const; 97 : : 98 : : /** 99 : : * Adds this duration to a starting \a dateTime value. 100 : : */ 101 : : QDateTime addToDateTime( const QDateTime &dateTime ); 102 : : 103 : : /** 104 : : * Creates a QgsTimeDuration from a \a string value. 105 : : */ 106 : : static QgsTimeDuration fromString( const QString &string, bool &ok ); 107 : : 108 : : }; 109 : : #endif 110 : : 111 : : 112 : : /** 113 : : * \ingroup core 114 : : * \class QgsTemporalUtils 115 : : * \brief Contains utility methods for working with temporal layers and projects. 116 : : * 117 : : * \since QGIS 3.14 118 : : */ 119 : : 120 : : class CORE_EXPORT QgsTemporalUtils 121 : : { 122 : : public: 123 : : 124 : : /** 125 : : * Calculates the temporal range for a \a project. 126 : : * 127 : : * This method considers the temporal range available from layers contained within the project and 128 : : * returns the maximal combined temporal extent of these layers. 129 : : */ 130 : : static QgsDateTimeRange calculateTemporalRangeForProject( QgsProject *project ); 131 : : 132 : : /** 133 : : * Calculates all temporal ranges which are in use for a \a project. 134 : : * 135 : : * This method considers the temporal range available from layers contained within the project and 136 : : * returns a list of ranges which cover only the temporal ranges which are actually in use by layers 137 : : * in the project. 138 : : * 139 : : * The returned list may be non-contiguous and have gaps in the ranges. The ranges are sorted in ascending order. 140 : : * 141 : : * \since QGIS 3.20 142 : : */ 143 : : static QList< QgsDateTimeRange > usedTemporalRangesForProject( QgsProject *project ); 144 : : 145 : : //! Contains settings relating to exporting animations 146 : : struct AnimationExportSettings 147 : : { 148 : : //! Dictates the overall temporal range of the animation. 149 : : QgsDateTimeRange animationRange; 150 : : 151 : : //! Duration of individual export frames 152 : : QgsInterval frameDuration; 153 : : 154 : : //! Destination directory for created image files. 155 : : QString outputDirectory; 156 : : 157 : : /** 158 : : * The filename template for exporting the frames. 159 : : * 160 : : * This must be in format prefix####.format, where number of 161 : : * \a # characters represents how many 0's should be left-padded to the frame number 162 : : * e.g. my###.jpg will create frames my001.jpg, my002.jpg, etc 163 : : */ 164 : : QString fileNameTemplate; 165 : : 166 : : //! List of decorations to draw onto exported frames. 167 : : QList<QgsMapDecoration *> decorations; 168 : : 169 : : }; 170 : : 171 : : /** 172 : : * Exports animation frames by rendering the map to multiple destination images. 173 : : * 174 : : * The \a mapSettings argument dictates the overall map settings such as extent 175 : : * and size, while animation and export specific settings are specified via the \a settings 176 : : * argument. 177 : : * 178 : : * An optional \a feedback argument can be used to provide progress reports and cancellation 179 : : * support. 180 : : * 181 : : * \param mapSettings settings controlling the map render 182 : : * \param settings animation and export settings 183 : : * \param error will be set to a descriptive error message if the export fails 184 : : * \param feedback optional feedback object for progress reports and cancellation checks 185 : : * 186 : : * \returns TRUE if the export was successful. 187 : : */ 188 : : static bool exportAnimation( const QgsMapSettings &mapSettings, const AnimationExportSettings &settings, QString &error SIP_OUT, QgsFeedback *feedback = nullptr ); 189 : : 190 : : /** 191 : : * Calculates the frame time for an animation. 192 : : * 193 : : * If the interval original duration is fractional or interval original unit is 194 : : * unknown (QgsUnitTypes::TemporalUnit::TemporalUnknownUnit), then QgsInterval is used 195 : : * to determine the duration of the frame. This uses average durations for months and years. 196 : : * 197 : : * Otherwise, we use QDateTime to advance by the exact duration of the current 198 : : * month or year. 199 : : * So a time step of 1.5 months will result in a duration of 45 200 : : * days, but a time step of 1 month will result in a duration that depends upon 201 : : * the number of days in the current month. 202 : : * 203 : : * \param start time of the animation 204 : : * \param frame number 205 : : * \param interval duration of the animation 206 : : * 207 : : * \returns The calculated datetime for the frame. 208 : : * 209 : : * \since QGIS 3.18 210 : : */ 211 : : static QDateTime calculateFrameTime( const QDateTime &start, const long long frame, const QgsInterval interval ); 212 : : 213 : : /** 214 : : * Calculates a complete list of datetimes between \a start and \a end, using the specified ISO8601 \a duration string (eg "PT12H"). 215 : : * \param start start date time 216 : : * \param end end date time 217 : : * \param duration ISO8601 duration string 218 : : * \param ok will be set to TRUE if \a duration was successfully parsed and date times could be calculated 219 : : * \param maxValuesExceeded will be set to TRUE if the maximum number of values to return was exceeded 220 : : * \param maxValues maximum number of values to return, or -1 to return all values 221 : : * \returns calculated list of date times 222 : : * \since QGIS 3.20 223 : : */ 224 : : static QList< QDateTime > calculateDateTimesUsingDuration( const QDateTime &start, const QDateTime &end, const QString &duration, bool &ok SIP_OUT, bool &maxValuesExceeded SIP_OUT, int maxValues = -1 ); 225 : : 226 : : #ifndef SIP_RUN 227 : : 228 : : /** 229 : : * Calculates a complete list of datetimes between \a start and \a end, using the specified ISO8601 \a duration string (eg "PT12H"). 230 : : * \param start start date time 231 : : * \param end end date time 232 : : * \param duration ISO8601 duration 233 : : * \param maxValuesExceeded will be set to TRUE if the maximum number of values to return was exceeded 234 : : * \param maxValues maximum number of values to return, or -1 to return all values 235 : : * \returns calculated list of date times 236 : : * \note Not available in Python bindings 237 : : * \since QGIS 3.20 238 : : */ 239 : : static QList< QDateTime > calculateDateTimesUsingDuration( const QDateTime &start, const QDateTime &end, const QgsTimeDuration &duration, bool &maxValuesExceeded SIP_OUT, int maxValues = -1 ); 240 : : #endif 241 : : 242 : : /** 243 : : * Calculates a complete list of datetimes from a ISO8601 \a string containing a duration (eg "2021-03-23T00:00:00Z/2021-03-24T12:00:00Z/PT12H"). 244 : : * \param string ISO8601 compatible string 245 : : * \param ok will be set to TRUE if \a string was successfully parsed and date times could be calculated 246 : : * \param maxValuesExceeded will be set to TRUE if the maximum number of values to return was exceeded 247 : : * \param maxValues maximum number of values to return, or -1 to return all values 248 : : * \returns calculated list of date times 249 : : * \since QGIS 3.20 250 : : */ 251 : : static QList< QDateTime > calculateDateTimesFromISO8601( const QString &string, bool &ok SIP_OUT, bool &maxValuesExceeded SIP_OUT, int maxValues = -1 ); 252 : : 253 : : }; 254 : : 255 : : 256 : : #endif // QGSTEMPORALUTILS_H