Skip to content
Permalink
Browse files

Tweak API for QgsTemporalUtils::exportAnimation

Make it a bit more future-proof
  • Loading branch information
nyalldawson authored and nirvn committed May 17, 2020
1 parent 8a7feed commit 09fda8d28575cd6019caa2888307083e9db3a877
@@ -31,27 +31,41 @@ This method considers the temporal range available from layers contained within
returns the maximal combined temporal extent of these layers.
%End

static bool exportAnimation( const QgsMapSettings &mapSettings,
const QgsDateTimeRange &animationRange,
QgsInterval frameDuration,
const QString &outputDirectory,
const QString &fileNameTemplate,
QString &error /Out/,
QgsFeedback *feedback );
class AnimationExportSettings
{

%TypeHeaderCode
#include "qgstemporalutils.h"
%End
public:

QgsDateTimeRange animationRange;

QgsInterval frameDuration;

QString outputDirectory;

QString fileNameTemplate;

};

static bool exportAnimation( const QgsMapSettings &mapSettings, const AnimationExportSettings &settings, QString &error /Out/, QgsFeedback *feedback = 0 );
%Docstring
Exports animation frames by rendering the map to multiple destination images.

The ``mapSettings`` argument dictates the overall map settings such as extent
and size.
and size, while animation and export specific settings are specified via the ``settings``
argument.

An optional ``feedback`` argument can be used to provide progress reports and cancelation
support.

The ``animationRange`` argument specifies the overall temporal range of the animation.
Temporal duration of individual frames is given by ``frameDuration``.
:param mapSettings: settings controlling the map render
:param settings: animation and export settings
:param feedback: optional feedback object for progress reports and cancelation checks

An ``outputDirectory`` must be set, which controls where the created image files are
stored. ``fileNameTemplate`` gives the template for exporting the frames.
This must be in format prefix####.format, where number of
# represents how many 0 should be left-padded to the frame number
e.g. my###.jpg will create frames my001.jpg, my002.jpg, etc
:return: - ``True`` if the export was successful.
- error: will be set to a descriptive error message if the export fails
%End
};

@@ -81,12 +81,15 @@ void QgsTemporalControllerDockWidget::exportAnimation()

connect( &progressDialog, &QProgressDialog::canceled, &progressFeedback, &QgsFeedback::cancel );

QgsTemporalUtils::AnimationExportSettings animationSettings;
animationSettings.frameDuration = frameDuration;
animationSettings.animationRange = animationRange;
animationSettings.outputDirectory = outputDir;
animationSettings.fileNameTemplate = fileNameExpression;

bool success = QgsTemporalUtils::exportAnimation(
s,
animationRange,
frameDuration,
outputDir,
fileNameExpression,
animationSettings,
error,
&progressFeedback );

@@ -52,31 +52,31 @@ QgsDateTimeRange QgsTemporalUtils::calculateTemporalRangeForProject( QgsProject
return QgsDateTimeRange( minDate, maxDate );
}

bool QgsTemporalUtils::exportAnimation( const QgsMapSettings &mapSettings, const QgsDateTimeRange &animationRange, QgsInterval frameDuration, const QString &outputDirectory, const QString &fileNameTemplate, QString &error, QgsFeedback *feedback )
bool QgsTemporalUtils::exportAnimation( const QgsMapSettings &mapSettings, const QgsTemporalUtils::AnimationExportSettings &settings, QString &error, QgsFeedback *feedback )
{
if ( fileNameTemplate.isEmpty() )
if ( settings.fileNameTemplate.isEmpty() )
{
error = QObject::tr( "Filename template is empty" );
return false;
}
int numberOfDigits = fileNameTemplate.count( QLatin1Char( '#' ) );
int numberOfDigits = settings.fileNameTemplate.count( QLatin1Char( '#' ) );
if ( numberOfDigits < 0 )
{
error = QObject::tr( "Wrong filename template format (must contain #)" );
return false;
}
const QString token( numberOfDigits, QLatin1Char( '#' ) );
if ( !fileNameTemplate.contains( token ) )
if ( !settings.fileNameTemplate.contains( token ) )
{
error = QObject::tr( "Filename template must contain all # placeholders in one continuous group." );
return false;
}

QgsTemporalNavigationObject navigator;
navigator.setTemporalExtents( animationRange );
navigator.setFrameDuration( frameDuration );
QgsMapSettings settings = mapSettings;
const QgsExpressionContext context = settings.expressionContext();
navigator.setTemporalExtents( settings.animationRange );
navigator.setFrameDuration( settings.frameDuration );
QgsMapSettings ms = mapSettings;
const QgsExpressionContext context = ms.expressionContext();

const long long totalFrames = navigator.totalFrameCount();
long long currentFrame = 0;
@@ -96,26 +96,26 @@ bool QgsTemporalUtils::exportAnimation( const QgsMapSettings &mapSettings, const

navigator.setCurrentFrameNumber( currentFrame );

settings.setIsTemporal( true );
settings.setTemporalRange( navigator.dateTimeRangeForFrameNumber( currentFrame ) );
ms.setIsTemporal( true );
ms.setTemporalRange( navigator.dateTimeRangeForFrameNumber( currentFrame ) );

QgsExpressionContext frameContext = context;
frameContext.appendScope( navigator.createExpressionContextScope() );
frameContext.appendScope( QgsExpressionContextUtils::mapSettingsScope( settings ) );
settings.setExpressionContext( frameContext );
frameContext.appendScope( QgsExpressionContextUtils::mapSettingsScope( ms ) );
ms.setExpressionContext( frameContext );

QString fileName( fileNameTemplate );
QString fileName( settings.fileNameTemplate );
const QString frameNoPaddedLeft( QStringLiteral( "%1" ).arg( currentFrame, numberOfDigits, 10, QChar( '0' ) ) ); // e.g. 0001
fileName.replace( token, frameNoPaddedLeft );
const QString path = QDir( outputDirectory ).filePath( fileName );
const QString path = QDir( settings.outputDirectory ).filePath( fileName );

QImage img = QImage( settings.outputSize(), settings.outputImageFormat() );
img.setDotsPerMeterX( 1000 * settings.outputDpi() / 25.4 );
img.setDotsPerMeterY( 1000 * settings.outputDpi() / 25.4 );
img.fill( settings.backgroundColor().rgb() );
QImage img = QImage( ms.outputSize(), ms.outputImageFormat() );
img.setDotsPerMeterX( 1000 * ms.outputDpi() / 25.4 );
img.setDotsPerMeterY( 1000 * ms.outputDpi() / 25.4 );
img.fill( ms.backgroundColor().rgb() );

QPainter p( &img );
QgsMapRendererCustomPainterJob job( settings, &p );
QgsMapRendererCustomPainterJob job( ms, &p );
job.start();
job.waitForFinished();
p.end();
@@ -44,28 +44,48 @@ class CORE_EXPORT QgsTemporalUtils
*/
static QgsDateTimeRange calculateTemporalRangeForProject( QgsProject *project );

class AnimationExportSettings
{
public:

//! Dictates the overall temporal range of the animation.
QgsDateTimeRange animationRange;

//! Duration of individual export frames
QgsInterval frameDuration;

//! Destination directory for created image files.
QString outputDirectory;

/**
* The filename template for exporting the frames.
*
* This must be in format prefix####.format, where number of
* \a # characters represents how many 0's should be left-padded to the frame number
* e.g. my###.jpg will create frames my001.jpg, my002.jpg, etc
*/
QString fileNameTemplate;

};

/**
* Exports animation frames by rendering the map to multiple destination images.
*
* The \a mapSettings argument dictates the overall map settings such as extent
* and size.
* and size, while animation and export specific settings are specified via the \a settings
* argument.
*
* An optional \a feedback argument can be used to provide progress reports and cancelation
* support.
*
* The \a animationRange argument specifies the overall temporal range of the animation.
* Temporal duration of individual frames is given by \a frameDuration.
* \param mapSettings settings controlling the map render
* \param settings animation and export settings
* \param error will be set to a descriptive error message if the export fails
* \param feedback optional feedback object for progress reports and cancelation checks
*
* An \a outputDirectory must be set, which controls where the created image files are
* stored. \a fileNameTemplate gives the template for exporting the frames.
* This must be in format prefix####.format, where number of
* # represents how many 0 should be left-padded to the frame number
* e.g. my###.jpg will create frames my001.jpg, my002.jpg, etc
* \returns TRUE if the export was successful.
*/
static bool exportAnimation( const QgsMapSettings &mapSettings,
const QgsDateTimeRange &animationRange,
QgsInterval frameDuration,
const QString &outputDirectory,
const QString &fileNameTemplate,
QString &error SIP_OUT,
QgsFeedback *feedback );
static bool exportAnimation( const QgsMapSettings &mapSettings, const AnimationExportSettings &settings, QString &error SIP_OUT, QgsFeedback *feedback = nullptr );
};


0 comments on commit 09fda8d

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