Skip to content
Permalink
Browse files

Do the rendering of map layers within special classes

This is an important change: new class (QgsMapLayerRenderer) is introduced
and it keeps all information from layer which is necessary for rendering.
Thanks to that, any changes to map layer will have no impact on rendering that
may be currently underway: if the user changes renderer, rendering will
not crash because it is using a different instance.

Work in progress: only vector layers, no labeling, no diagrams, iterator
still uses some bits from QgsVectorLayer.

Another change: QgsFeatureRendererV2, QgsSymbolV2 do not get access
to QgsVectorLayer - only to fields they need. Point displacement renderer
did more extensive use of QgsVectorLayer - currently it is not functional.
  • Loading branch information
wonder-sk committed Nov 20, 2013
1 parent 036b25e commit 2fcf556c3cb9c2618753adee390bf84a5ead4775
Showing with 919 additions and 665 deletions.
  1. +1 −1 src/app/qgsmaptoolrotatepointsymbols.cpp
  2. +1 −0 src/core/CMakeLists.txt
  3. +0 −1 src/core/composer/qgscomposermap.cpp
  4. +4 −3 src/core/qgsfeaturerequest.cpp
  5. +12 −0 src/core/qgsfield.cpp
  6. +5 −0 src/core/qgsfield.h
  7. +1 −2 src/core/qgsgeometrycache.cpp
  8. +4 −6 src/core/qgsgeometrycache.h
  9. +6 −0 src/core/qgsmaplayer.h
  10. +49 −0 src/core/qgsmaplayerrenderer.h
  11. +207 −200 src/core/qgsmaprendererjob.cpp
  12. +20 −1 src/core/qgsmaprendererjob.h
  13. +2 −4 src/core/qgspallabeling.cpp
  14. +1 −1 src/core/qgspallabeling.h
  15. +1 −1 src/core/qgsvectorfilewriter.cpp
  16. +12 −350 src/core/qgsvectorlayer.cpp
  17. +5 −25 src/core/qgsvectorlayer.h
  18. +413 −0 src/core/qgsvectorlayerrenderer.cpp
  19. +90 −0 src/core/qgsvectorlayerrenderer.h
  20. +7 −7 src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
  21. +1 −1 src/core/symbology-ng/qgscategorizedsymbolrendererv2.h
  22. +1 −1 src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
  23. +4 −4 src/core/symbology-ng/qgsfillsymbollayerv2.cpp
  24. +7 −7 src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
  25. +1 −1 src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
  26. +3 −3 src/core/symbology-ng/qgslinesymbollayerv2.cpp
  27. +2 −2 src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
  28. +8 −5 src/core/symbology-ng/qgspointdisplacementrenderer.cpp
  29. +1 −1 src/core/symbology-ng/qgspointdisplacementrenderer.h
  30. +5 −0 src/core/symbology-ng/qgsrendererv2.cpp
  31. +5 −1 src/core/symbology-ng/qgsrendererv2.h
  32. +6 −6 src/core/symbology-ng/qgsrulebasedrendererv2.cpp
  33. +2 −2 src/core/symbology-ng/qgsrulebasedrendererv2.h
  34. +5 −5 src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
  35. +1 −1 src/core/symbology-ng/qgssinglesymbolrendererv2.h
  36. +3 −4 src/core/symbology-ng/qgssymbollayerv2.cpp
  37. +1 −1 src/core/symbology-ng/qgssymbollayerv2.h
  38. +4 −5 src/core/symbology-ng/qgssymbolv2.cpp
  39. +10 −5 src/core/symbology-ng/qgssymbolv2.h
  40. +4 −4 src/core/symbology-ng/qgsvectorfieldsymbollayer.cpp
  41. +1 −1 src/gui/attributetable/qgsattributetablefiltermodel.cpp
  42. +1 −1 src/gui/qgsmaptoolidentify.cpp
  43. +1 −1 src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp
  44. +1 −1 tests/src/core/testqgsrulebasedrenderer.cpp
@@ -279,7 +279,7 @@ void QgsMapToolRotatePointSymbols::createPixmapItem( QgsFeature& f )
{
QgsFeatureRendererV2* rv2 = mActiveLayer->rendererV2()->clone();
rv2->setRotationField( "" );
rv2->startRender( renderContext, mActiveLayer );
rv2->startRender( renderContext, mActiveLayer->pendingFields() );

QgsSymbolV2* symbolV2 = rv2->symbolForFeature( f );
if ( symbolV2 )
@@ -5,6 +5,7 @@ SET(QGIS_CORE_SRCS

qgsmapsettings.cpp
qgsmaprendererjob.cpp
qgsvectorlayerrenderer.cpp

gps/qgsgpsconnection.cpp
gps/qgsgpsconnectionregistry.cpp
@@ -176,7 +176,6 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
QgsMapRendererCustomPainterJob job( jobMapSettings, painter );
job.start();
job.waitForFinished();

}

void QgsComposerMap::cache( void )
@@ -119,10 +119,11 @@ QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QStringList&
mFlags |= SubsetOfAttributes;
mAttrs.clear();

for ( int idx = 0; idx < fields.count(); ++idx )
foreach ( const QString& attrName, attrNames )
{
if ( attrNames.contains( fields[idx].name() ) )
mAttrs.append( idx );
int attrNum = fields.fieldNameIndex( attrName );
if ( attrNum != -1 )
mAttrs.append( attrNum );
}

return *this;
@@ -168,3 +168,15 @@ QList<QgsField> QgsFields::toList() const
lst.append( mFields[i].field );
return lst;
}

int QgsFields::fieldNameIndex( const QString& fieldName ) const
{
for ( int idx = 0; idx < count(); ++idx )
{
if ( QString::compare( mFields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
{
return idx;
}
}
return -1;
}
@@ -216,6 +216,11 @@ class CORE_EXPORT QgsFields
//! Look up field's index from name. Returns -1 on error
int indexFromName( const QString& name ) const { return mNameToIndex.value( name, -1 ); }

//! Look up field's index from name - case insensitive
//! TODO: sort out case sensitive (indexFromName()) vs insensitive (fieldNameIndex()) calls
//! @note added in 2.1
int fieldNameIndex( const QString& fieldName ) const;

//! Utility function to return a list of QgsField instances
QList<QgsField> toList() const;

@@ -2,8 +2,7 @@

#include "qgsvectorlayereditbuffer.h"

QgsGeometryCache::QgsGeometryCache( QgsVectorLayer* layer )
: L( layer )
QgsGeometryCache::QgsGeometryCache()
{
}

@@ -1,14 +1,16 @@
#ifndef QGSGEOMETRYCACHE_H
#define QGSGEOMETRYCACHE_H

#include "qgsgeometry.h"
#include "qgsfeature.h"
#include "qgsrectangle.h"

#include "qgsvectorlayer.h"
#include <QMap>

class CORE_EXPORT QgsGeometryCache
{
public:
QgsGeometryCache( QgsVectorLayer* layer );
QgsGeometryCache();
~QgsGeometryCache();

inline QgsGeometryMap& cachedGeometries() { return mCachedGeometries; }
@@ -31,10 +33,6 @@ class CORE_EXPORT QgsGeometryCache

protected:

inline QgsVectorLayerEditBuffer* editBuffer() { return L->editBuffer(); }

QgsVectorLayer* L;

/** cache of the committed geometries retrieved *for the current display* */
QgsGeometryMap mCachedGeometries;

@@ -33,6 +33,7 @@

class QgsRenderContext;
class QgsCoordinateReferenceSystem;
class QgsMapLayerRenderer;

class QDomDocument;
class QKeyEvent;
@@ -128,6 +129,11 @@ class CORE_EXPORT QgsMapLayer : public QObject
@note added in version 1.6*/
virtual void reload() {}

/** Return new instance of QgsMapLayerRenderer that will be used for rendering of given context
* @note added in 2.1
*/
virtual QgsMapLayerRenderer* createMapRenderer( QgsRenderContext& rendererContext ) { Q_UNUSED( rendererContext ); return 0; }

/** This is the method that does the actual work of
* drawing the layer onto a paint device.
* @param rendererContext describes the extents,
@@ -0,0 +1,49 @@
#ifndef QGSMAPLAYERRENDERER_H
#define QGSMAPLAYERRENDERER_H

#include <QList>

/**
* Base class for utility classes that encapsulate information necessary
* for rendering of map layers. The rendering is typically done in a background
* thread, so it is necessary to keep all structures required for rendering away
* from the original map layer because it may change any time.
*
* Because the data needs to be copied (to avoid the need for locking),
* is is highly desirable to use copy-on-write where possible. This way,
* the overhead of copying (both memory and CPU) will be kept low.
* Qt containers and various Qt classes use implicit sharing.
*
* The scenario will be:
* 1. renderer job (doing preparation in the GUI thread) calls
* QgsMapLayer::createMapRenderer() and gets instance of this class.
* The instance is initialized at that point and should not need
* additional calls to QgsVectorLayer.
* 2. renderer job (still in GUI thread) stores the renderer for later use.
* 3. renderer job (in worker thread) calls QgsMapLayerRenderer::render()
* 4. renderer job (again in GUI thread) will check errors() and report them
*/
class QgsMapLayerRenderer
{
public:
virtual ~QgsMapLayerRenderer() {}

//! Do the rendering (based on data stored in the class)
virtual bool render() = 0;

//! Container for errors (@todo instead of simple message could have error codes + custom data)
struct Error
{
QString message;
};

typedef QList<Error> ErrorList;

//! Return list of errors (problems) that happened during the rendering
ErrorList errors() const { return mErrors; }

protected:
ErrorList mErrors;
};

#endif // QGSMAPLAYERRENDERER_H

0 comments on commit 2fcf556

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