Skip to content

Commit 2fcf556

Browse files
committed
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.
1 parent 036b25e commit 2fcf556

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+919
-665
lines changed

src/app/qgsmaptoolrotatepointsymbols.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ void QgsMapToolRotatePointSymbols::createPixmapItem( QgsFeature& f )
279279
{
280280
QgsFeatureRendererV2* rv2 = mActiveLayer->rendererV2()->clone();
281281
rv2->setRotationField( "" );
282-
rv2->startRender( renderContext, mActiveLayer );
282+
rv2->startRender( renderContext, mActiveLayer->pendingFields() );
283283

284284
QgsSymbolV2* symbolV2 = rv2->symbolForFeature( f );
285285
if ( symbolV2 )

src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ SET(QGIS_CORE_SRCS
55

66
qgsmapsettings.cpp
77
qgsmaprendererjob.cpp
8+
qgsvectorlayerrenderer.cpp
89

910
gps/qgsgpsconnection.cpp
1011
gps/qgsgpsconnectionregistry.cpp

src/core/composer/qgscomposermap.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
176176
QgsMapRendererCustomPainterJob job( jobMapSettings, painter );
177177
job.start();
178178
job.waitForFinished();
179-
180179
}
181180

182181
void QgsComposerMap::cache( void )

src/core/qgsfeaturerequest.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QStringList&
119119
mFlags |= SubsetOfAttributes;
120120
mAttrs.clear();
121121

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

128129
return *this;

src/core/qgsfield.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,15 @@ QList<QgsField> QgsFields::toList() const
168168
lst.append( mFields[i].field );
169169
return lst;
170170
}
171+
172+
int QgsFields::fieldNameIndex( const QString& fieldName ) const
173+
{
174+
for ( int idx = 0; idx < count(); ++idx )
175+
{
176+
if ( QString::compare( mFields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
177+
{
178+
return idx;
179+
}
180+
}
181+
return -1;
182+
}

src/core/qgsfield.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ class CORE_EXPORT QgsFields
216216
//! Look up field's index from name. Returns -1 on error
217217
int indexFromName( const QString& name ) const { return mNameToIndex.value( name, -1 ); }
218218

219+
//! Look up field's index from name - case insensitive
220+
//! TODO: sort out case sensitive (indexFromName()) vs insensitive (fieldNameIndex()) calls
221+
//! @note added in 2.1
222+
int fieldNameIndex( const QString& fieldName ) const;
223+
219224
//! Utility function to return a list of QgsField instances
220225
QList<QgsField> toList() const;
221226

src/core/qgsgeometrycache.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
#include "qgsvectorlayereditbuffer.h"
44

5-
QgsGeometryCache::QgsGeometryCache( QgsVectorLayer* layer )
6-
: L( layer )
5+
QgsGeometryCache::QgsGeometryCache()
76
{
87
}
98

src/core/qgsgeometrycache.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
#ifndef QGSGEOMETRYCACHE_H
22
#define QGSGEOMETRYCACHE_H
33

4+
#include "qgsgeometry.h"
45
#include "qgsfeature.h"
6+
#include "qgsrectangle.h"
57

6-
#include "qgsvectorlayer.h"
8+
#include <QMap>
79

810
class CORE_EXPORT QgsGeometryCache
911
{
1012
public:
11-
QgsGeometryCache( QgsVectorLayer* layer );
13+
QgsGeometryCache();
1214
~QgsGeometryCache();
1315

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

3234
protected:
3335

34-
inline QgsVectorLayerEditBuffer* editBuffer() { return L->editBuffer(); }
35-
36-
QgsVectorLayer* L;
37-
3836
/** cache of the committed geometries retrieved *for the current display* */
3937
QgsGeometryMap mCachedGeometries;
4038

src/core/qgsmaplayer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
class QgsRenderContext;
3535
class QgsCoordinateReferenceSystem;
36+
class QgsMapLayerRenderer;
3637

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

132+
/** Return new instance of QgsMapLayerRenderer that will be used for rendering of given context
133+
* @note added in 2.1
134+
*/
135+
virtual QgsMapLayerRenderer* createMapRenderer( QgsRenderContext& rendererContext ) { Q_UNUSED( rendererContext ); return 0; }
136+
131137
/** This is the method that does the actual work of
132138
* drawing the layer onto a paint device.
133139
* @param rendererContext describes the extents,

src/core/qgsmaplayerrenderer.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef QGSMAPLAYERRENDERER_H
2+
#define QGSMAPLAYERRENDERER_H
3+
4+
#include <QList>
5+
6+
/**
7+
* Base class for utility classes that encapsulate information necessary
8+
* for rendering of map layers. The rendering is typically done in a background
9+
* thread, so it is necessary to keep all structures required for rendering away
10+
* from the original map layer because it may change any time.
11+
*
12+
* Because the data needs to be copied (to avoid the need for locking),
13+
* is is highly desirable to use copy-on-write where possible. This way,
14+
* the overhead of copying (both memory and CPU) will be kept low.
15+
* Qt containers and various Qt classes use implicit sharing.
16+
*
17+
* The scenario will be:
18+
* 1. renderer job (doing preparation in the GUI thread) calls
19+
* QgsMapLayer::createMapRenderer() and gets instance of this class.
20+
* The instance is initialized at that point and should not need
21+
* additional calls to QgsVectorLayer.
22+
* 2. renderer job (still in GUI thread) stores the renderer for later use.
23+
* 3. renderer job (in worker thread) calls QgsMapLayerRenderer::render()
24+
* 4. renderer job (again in GUI thread) will check errors() and report them
25+
*/
26+
class QgsMapLayerRenderer
27+
{
28+
public:
29+
virtual ~QgsMapLayerRenderer() {}
30+
31+
//! Do the rendering (based on data stored in the class)
32+
virtual bool render() = 0;
33+
34+
//! Container for errors (@todo instead of simple message could have error codes + custom data)
35+
struct Error
36+
{
37+
QString message;
38+
};
39+
40+
typedef QList<Error> ErrorList;
41+
42+
//! Return list of errors (problems) that happened during the rendering
43+
ErrorList errors() const { return mErrors; }
44+
45+
protected:
46+
ErrorList mErrors;
47+
};
48+
49+
#endif // QGSMAPLAYERRENDERER_H

0 commit comments

Comments
 (0)