Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsmaplayerrenderer.h 3 : : -------------------------------------- 4 : : Date : December 2013 5 : : Copyright : (C) 2013 by Martin Dobias 6 : : Email : wonder dot sk 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 QGSMAPLAYERRENDERER_H 17 : : #define QGSMAPLAYERRENDERER_H 18 : : 19 : : #include <QStringList> 20 : : 21 : : #include "qgis_core.h" 22 : : #include "qgis_sip.h" 23 : : 24 : : class QgsFeedback; 25 : : class QgsRenderContext; 26 : : 27 : : /** 28 : : * \ingroup core 29 : : * \brief Base class for utility classes that encapsulate information necessary 30 : : * for rendering of map layers. 31 : : * 32 : : * The rendering is typically done in a background 33 : : * thread, so it is necessary to keep all structures required for rendering away 34 : : * from the original map layer because it may change any time. 35 : : * 36 : : * Because the data needs to be copied (to avoid the need for locking), 37 : : * it is highly desirable to use copy-on-write where possible. This way, 38 : : * the overhead of copying (both memory and CPU) will be kept low. 39 : : * Qt containers and various Qt classes use implicit sharing. 40 : : * 41 : : * The scenario will be: 42 : : * 43 : : * # renderer job (doing preparation in the GUI thread) calls 44 : : * QgsMapLayer::createMapRenderer() and gets instance of this class. 45 : : * The instance is initialized at that point and should not need 46 : : * additional calls to QgsVectorLayer. 47 : : * # renderer job (still in GUI thread) stores the renderer for later use. 48 : : * # renderer job (in worker thread) calls QgsMapLayerRenderer::render() 49 : : * # renderer job (again in GUI thread) will check errors() and report them 50 : : * 51 : : * \since QGIS 2.4 52 : : */ 53 : : class CORE_EXPORT QgsMapLayerRenderer 54 : : { 55 : : public: 56 : : 57 : : /** 58 : : * Constructor for QgsMapLayerRenderer, with the associated \a layerID and render \a context. 59 : : */ 60 : 0 : QgsMapLayerRenderer( const QString &layerID, QgsRenderContext *context = nullptr ) 61 : 0 : : mLayerID( layerID ) 62 : 0 : , mContext( context ) 63 : 0 : {} 64 : : 65 : 0 : virtual ~QgsMapLayerRenderer() = default; 66 : : 67 : : /** 68 : : * Do the rendering (based on data stored in the class). 69 : : * 70 : : * Returns TRUE if the layer was completely rendered successfully (i.e. the render 71 : : * was not canceled early). 72 : : */ 73 : : virtual bool render() = 0; 74 : : 75 : : /** 76 : : * Returns TRUE if the renderer must be rendered to a raster paint device (e.g. QImage). 77 : : * 78 : : * Some layer settings require layers to be effectively "flattened" while rendering maps, 79 : : * which is achieved by first rendering the layer onto a raster paint device and then compositing 80 : : * the resultant image onto the final map render. 81 : : * 82 : : * E.g. if a layer contains features with transparency or alternative blending modes, and 83 : : * the effects of these opacity or blending modes should be restricted to only affect other 84 : : * features within the SAME layer, then a flattened raster based render is required. 85 : : * 86 : : * Subclasses should return TRUE whenever their corresponding layer settings require the 87 : : * layer to always be rendered using a raster paint device. 88 : : * 89 : : * \since QGIS 3.18 90 : : */ 91 : 0 : virtual bool forceRasterRender() const { return false; } 92 : : 93 : : /** 94 : : * Access to feedback object of the layer renderer (may be NULLPTR) 95 : : * \since QGIS 3.0 96 : : */ 97 : 0 : virtual QgsFeedback *feedback() const { return nullptr; } 98 : : 99 : : //! Returns list of errors (problems) that happened during the rendering 100 : 0 : QStringList errors() const { return mErrors; } 101 : : 102 : : //! Gets access to the ID of the layer rendered by this class 103 : 0 : QString layerId() const { return mLayerID; } 104 : : 105 : : /** 106 : : * Returns the render context associated with the renderer. 107 : : * 108 : : * \since QGIS 3.10 109 : : */ 110 : 0 : QgsRenderContext *renderContext() { return mContext; } 111 : : 112 : : /** 113 : : * Returns the render context associated with the renderer. 114 : : * 115 : : * \note Not available in Python bindings 116 : : * \since QGIS 3.18 117 : : */ 118 : 0 : const QgsRenderContext *renderContext() const SIP_SKIP { return mContext; } 119 : : 120 : : /** 121 : : * Returns whether the renderer has already drawn (at 122 : : * least partially) some data 123 : : * 124 : : * \since QGIS 3.18 125 : : */ 126 : 0 : bool isReadyToCompose() const { return mReadyToCompose; } 127 : : 128 : : /** 129 : : * Sets approximate render \a time (in ms) for the layer to render. 130 : : * 131 : : * This can be used to specifies a hint at the expected render times for the layer, so that 132 : : * the individual layer renderer subclasses can apply heuristics and determine appropriate update 133 : : * intervals during the render operation. 134 : : * 135 : : * \note Not available in Python bindings. 136 : : * \since QGIS 3.18 137 : : */ 138 : 0 : virtual void setLayerRenderingTimeHint( int time ) SIP_SKIP { Q_UNUSED( time ) } 139 : : 140 : : protected: 141 : : QStringList mErrors; 142 : : QString mLayerID; 143 : : 144 : : // TODO QGIS 4.0 - make false as default 145 : : 146 : : /** 147 : : * The flag must be set to false in renderer's constructor 148 : : * if wants to use the smarter map redraws functionality 149 : : * https://github.com/qgis/QGIS-Enhancement-Proposals/issues/181 150 : : * 151 : : * The flag must be set to true by renderer when 152 : : * the data is fetched and the renderer actually 153 : : * started to update the destination image. 154 : : * 155 : : * When the flag is set to false, the image from 156 : : * QgsMapRendererCache is used instead to avoid flickering. 157 : : * 158 : : * \since QGIS 3.18 159 : : */ 160 : 0 : bool mReadyToCompose = true; 161 : : 162 : : /** 163 : : * Maximum time (in ms) to allow display of a previously cached 164 : : * preview image while rendering layers, before switching to 165 : : * a progressive rendering display. 166 : : * 167 : : * \note Not available in Python bindings 168 : : * \since QGIS 3.18 169 : : */ 170 : : static constexpr int MAX_TIME_TO_USE_CACHED_PREVIEW_IMAGE = 3000 SIP_SKIP; 171 : : 172 : : private: 173 : : 174 : : // TODO QGIS 4.0 - make reference instead of pointer! 175 : : 176 : : /** 177 : : * Associated render context. 178 : : * 179 : : * \since QGIS 3.10 180 : : */ 181 : : QgsRenderContext *mContext = nullptr; 182 : : }; 183 : : 184 : : #endif // QGSMAPLAYERRENDERER_H