From fe39578eaef4aba911f9da7739d0db0924225d1d Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Fri, 28 Mar 2014 15:35:43 +0100 Subject: [PATCH] Added python bindings for QgsMapRendererJob + subclasses and QgsMapRendererCache --- python/core/core.sip | 2 + python/core/qgsmaprenderercache.sip | 39 +++++++ python/core/qgsmaprendererjob.sip | 156 ++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 python/core/qgsmaprenderercache.sip create mode 100644 python/core/qgsmaprendererjob.sip diff --git a/python/core/core.sip b/python/core/core.sip index 43c3a758b75..b9180a98747 100644 --- a/python/core/core.sip +++ b/python/core/core.sip @@ -48,6 +48,8 @@ %Include qgsmaplayerregistry.sip %Include qgsmaplayerrenderer.sip %Include qgsmaprenderer.sip +%Include qgsmaprenderercache.sip +%Include qgsmaprendererjob.sip %Include qgsmapsettings.sip %Include qgsmaptopixel.sip %Include qgsmessagelog.sip diff --git a/python/core/qgsmaprenderercache.sip b/python/core/qgsmaprenderercache.sip new file mode 100644 index 00000000000..38ee9a47558 --- /dev/null +++ b/python/core/qgsmaprenderercache.sip @@ -0,0 +1,39 @@ + +/** + * This class is responsible for keeping cache of rendered images of individual layers. + * + * Once a layer has rendered image stored in the cache (using setCacheImage(...)), + * the cache listens to repaintRequested() signals from layer. If triggered, the cache + * removes the rendered image (and disconnects from the layer). + * + * The class is thread-safe (multiple classes can access the same instance safely). + * + * @note added in 2.4 + */ +class QgsMapRendererCache : QObject +{ +%TypeHeaderCode +#include +%End + + public: + + QgsMapRendererCache(); + + //! invalidate the cache contents + void clear(); + + //! initialize cache: set new parameters and erase cache if parameters have changed + //! @return flag whether the parameters are the same as last time + bool init( QgsRectangle extent, double scale ); + + //! set cached image for the specified layer ID + void setCacheImage( QString layerId, const QImage& img ); + + //! get cached image for the specified layer ID. Returns null image if it is not cached. + QImage cacheImage( QString layerId ); + + //! remove layer from the cache + void clearCacheImage( QString layerId ); + +}; diff --git a/python/core/qgsmaprendererjob.sip b/python/core/qgsmaprendererjob.sip new file mode 100644 index 00000000000..9d10b3aecc9 --- /dev/null +++ b/python/core/qgsmaprendererjob.sip @@ -0,0 +1,156 @@ + +/** abstract base class renderer jobs that asynchronously start map rendering */ +class QgsMapRendererJob : QObject +{ +%TypeHeaderCode +#include +%End + + public: + + QgsMapRendererJob( const QgsMapSettings& settings ); + + virtual ~QgsMapRendererJob(); + + //! Start the rendering job and immediately return. + //! Does nothing if the rendering is already in progress. + virtual void start() = 0; + + //! Stop the rendering job - does not return until the job has terminated. + //! Does nothing if the rendering is not active. + virtual void cancel() = 0; + + //! Block until the job has finished. + virtual void waitForFinished() = 0; + + //! Tell whether the rendering job is currently running in background. + virtual bool isActive() const = 0; + + //! Get pointer to internal labeling engine (in order to get access to the results) + virtual QgsLabelingResults* takeLabelingResults() = 0 /Transfer/; + + struct Error + { + Error( const QString& lid, const QString& msg ); + + QString layerID; + QString message; + }; + + typedef QList Errors; + + //! List of errors that happened during the rendering job - available when the rendering has been finished + Errors errors() const; + + + //! Assign a cache to be used for reading and storing rendered images of individual layers. + //! Does not take ownership of the object. + void setCache( QgsMapRendererCache* cache ); + + //! Set which vector layers should be cached while rendering + //! @note The way how geometries are cached is really suboptimal - this method may be removed in future releases + void setRequestedGeometryCacheForLayers( const QStringList& layerIds ); + + //! Find out how log it took to finish the job (in miliseconds) + int renderingTime() const; + + signals: + + //! emitted when asynchronous rendering is finished (or canceled). + void finished(); + +}; + + +/** Intermediate base class adding functionality that allows client to query the rendered image. + * The image can be queried even while the rendering is still in progress to get intermediate result + */ +class QgsMapRendererQImageJob : QgsMapRendererJob +{ +%TypeHeaderCode +#include +%End + + public: + QgsMapRendererQImageJob( const QgsMapSettings& settings ); + + //! Get a preview/resulting image + virtual QImage renderedImage() = 0; +}; + + + +/** job implementation that renders everything sequentially in one thread */ +class QgsMapRendererSequentialJob : QgsMapRendererQImageJob +{ +%TypeHeaderCode +#include +%End + + public: + QgsMapRendererSequentialJob( const QgsMapSettings& settings ); + ~QgsMapRendererSequentialJob(); + + virtual void start(); + virtual void cancel(); + virtual void waitForFinished(); + virtual bool isActive() const; + + virtual QgsLabelingResults* takeLabelingResults() /Transfer/; + + // from QgsMapRendererJobWithPreview + virtual QImage renderedImage(); + + public slots: + + void internalFinished(); +}; + + + + +/** job implementation that renders all layers in parallel */ +class QgsMapRendererParallelJob : QgsMapRendererQImageJob +{ +%TypeHeaderCode +#include +%End + + public: + QgsMapRendererParallelJob( const QgsMapSettings& settings ); + ~QgsMapRendererParallelJob(); + + virtual void start(); + virtual void cancel(); + virtual void waitForFinished(); + virtual bool isActive() const; + + virtual QgsLabelingResults* takeLabelingResults() /Transfer/; + + // from QgsMapRendererJobWithPreview + virtual QImage renderedImage(); +}; + + + +/** job implementation that renders everything sequentially using a custom painter. + * The returned image is always invalid (because there is none available). + */ +class QgsMapRendererCustomPainterJob : QgsMapRendererJob +{ +%TypeHeaderCode +#include +%End + + public: + QgsMapRendererCustomPainterJob( const QgsMapSettings& settings, QPainter* painter ); + ~QgsMapRendererCustomPainterJob(); + + virtual void start(); + virtual void cancel(); + virtual void waitForFinished(); + virtual bool isActive() const; + virtual QgsLabelingResults* takeLabelingResults() /Transfer/; + + // TODO wrap??? const LayerRenderJobs& jobs() const; +};