diff --git a/src/core/qgsmaprendererjob.cpp b/src/core/qgsmaprendererjob.cpp index 4a2fbb8619a..6d583974a21 100644 --- a/src/core/qgsmaprendererjob.cpp +++ b/src/core/qgsmaprendererjob.cpp @@ -14,6 +14,7 @@ #include "qgsmaplayerrenderer.h" #include "qgsmaprenderercache.h" #include "qgspallabeling.h" +#include "qgsvectorlayerrenderer.h" QgsMapRendererJob::QgsMapRendererJob( const QgsMapSettings& settings ) @@ -438,6 +439,17 @@ void QgsMapRendererJob::drawNewLabeling( const QgsMapSettings& settings, QgsRend } } +void QgsMapRendererJob::updateLayerGeometryCaches() +{ + foreach ( QString id, mGeometryCaches.keys() ) + { + const QgsGeometryCache& cache = mGeometryCaches[id]; + if ( QgsVectorLayer* vl = qobject_cast( QgsMapLayerRegistry::instance()->mapLayer( id ) ) ) + *vl->cache() = cache; + } + mGeometryCaches.clear(); +} + bool QgsMapRendererJob::needTemporaryImage( QgsMapLayer* ml ) { @@ -525,6 +537,8 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter* painter, QgsPalLabelin qDebug("CACHE VALID: %d", cacheValid); } + mGeometryCaches.clear(); + while ( li.hasPrevious() ) { QString layerId = li.previous(); @@ -629,6 +643,14 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter* painter, QgsPalLabelin job.renderer = ml->createMapRenderer( job.context ); + if ( mRequestedGeomCacheForLayers.contains( ml->id() ) ) + { + if ( QgsVectorLayerRenderer* vlr = dynamic_cast( job.renderer ) ) + { + vlr->setGeometryCachePointer( &mGeometryCaches[ ml->id() ] ); + } + } + /* // TODO: split extent if ( split ) @@ -675,6 +697,8 @@ void QgsMapRendererJob::cleanupJobs( LayerRenderJobs& jobs ) } jobs.clear(); + + updateLayerGeometryCaches(); } ///////////// diff --git a/src/core/qgsmaprendererjob.h b/src/core/qgsmaprendererjob.h index 4201aefda85..474d505b7ea 100644 --- a/src/core/qgsmaprendererjob.h +++ b/src/core/qgsmaprendererjob.h @@ -12,6 +12,7 @@ #include "qgsmapsettings.h" +#include "qgsgeometrycache.h" class QgsLabelingResults; class QgsMapLayerRenderer; @@ -77,6 +78,9 @@ public: //! 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 ) { mRequestedGeomCacheForLayers = layerIds; } //! Find out how log it took to finish the job (in miliseconds) int renderingTime() const { return mRenderingTime; } @@ -108,11 +112,19 @@ protected: static void drawOldLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext ); static void drawNewLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine ); + //! called when rendering has finished to update all layers' geometry caches + void updateLayerGeometryCaches(); + QgsMapSettings mSettings; Errors mErrors; QgsMapRendererCache* mCache; + //! list of layer IDs for which the geometry cache should be updated + QStringList mRequestedGeomCacheForLayers; + //! map of geometry caches + QMap mGeometryCaches; + QTime mRenderingStart; int mRenderingTime; }; diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp index 74fb0314866..a9ce1bf8e57 100644 --- a/src/core/qgsvectorlayerrenderer.cpp +++ b/src/core/qgsvectorlayerrenderer.cpp @@ -35,11 +35,6 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender mSelectedFeatureIds = layer->selectedFeaturesIds(); mDrawVertexMarkers = ( layer->editBuffer() != 0 ); - mCacheFeatures = ( layer->editBuffer() != 0 ); - if ( mCacheFeatures ) - { - mCache = new QgsGeometryCache(); - } mGeometryType = layer->geometryType(); @@ -70,11 +65,8 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender QgsDebugMsg( "rendering v2:\n" + mRendererV2->dump() ); - if ( mCacheFeatures ) + if ( mDrawVertexMarkers ) { - // Destroy all cached geometries and clear the references to them - mCache->setCachedGeometriesRect( mContext.extent() ); - // set editing vertex markers style mRendererV2->setVertexMarkerAppearance( mVertexMarkerStyle, mVertexMarkerSize ); } @@ -91,7 +83,6 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender QgsVectorLayerRenderer::~QgsVectorLayerRenderer() { delete mRendererV2; - delete mCache; delete mSource; } @@ -142,6 +133,17 @@ bool QgsVectorLayerRenderer::render() return true; } +void QgsVectorLayerRenderer::setGeometryCachePointer( QgsGeometryCache* cache ) +{ + mCache = cache; + + if ( mCache ) + { + // Destroy all cached geometries and clear the references to them + mCache->setCachedGeometriesRect( mContext.extent() ); + } +} + void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit ) @@ -166,7 +168,7 @@ void QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit ) // render feature bool rendered = mRendererV2->renderFeature( fet, mContext, -1, sel, drawMarker ); - if ( mCacheFeatures ) + if ( mCache ) { // Cache this for the use of (e.g.) modifying the feature's uncommitted geometry. mCache->cacheGeometry( fet.id(), *fet.geometry() ); @@ -236,7 +238,7 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit ) } features[sym].append( fet ); - if ( mCacheFeatures ) + if ( mCache ) { // Cache this for the use of (e.g.) modifying the feature's uncommitted geometry. mCache->cacheGeometry( fet.id(), *fet.geometry() ); diff --git a/src/core/qgsvectorlayerrenderer.h b/src/core/qgsvectorlayerrenderer.h index bbdb78cb1a1..c6d661c4501 100644 --- a/src/core/qgsvectorlayerrenderer.h +++ b/src/core/qgsvectorlayerrenderer.h @@ -34,6 +34,10 @@ public: virtual bool render(); + //! where to save the cached geometries + //! @note The way how geometries are cached is really suboptimal - this method may be removed in future releases + void setGeometryCachePointer( QgsGeometryCache* cache ); + private: /**Registers label and diagram layer diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp index 57560de6fa5..2fffa5dd681 100644 --- a/src/gui/qgsmapcanvas.cpp +++ b/src/gui/qgsmapcanvas.cpp @@ -652,6 +652,18 @@ void QgsMapCanvas::refreshMap() mJob = new QgsMapRendererSequentialJob( mSettings ); connect(mJob, SIGNAL( finished() ), SLOT( rendererJobFinished() ) ); mJob->setCache( mCache ); + + QStringList layersForGeometryCache; + foreach ( QString id, mSettings.layers() ) + { + if ( QgsVectorLayer* vl = qobject_cast( QgsMapLayerRegistry::instance()->mapLayer( id ) ) ) + { + if ( vl->isEditable() ) + layersForGeometryCache << id; + } + } + mJob->setRequestedGeometryCacheForLayers( layersForGeometryCache ); + mJob->start(); mMapUpdateTimer.start();