407 changes: 207 additions & 200 deletions src/core/qgsmaprendererjob.cpp

Large diffs are not rendered by default.

21 changes: 20 additions & 1 deletion src/core/qgsmaprendererjob.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,22 @@ public slots:

#include <QtConcurrentRun>
#include <QFutureWatcher>
#include <QPainter>

class QgsMapLayerRenderer;
class QgsPalLabeling;



struct LayerRenderJob
{
QgsRenderContext context;
QImage* img; // may be null if it is not necessary to draw to separate image (e.g. sequential rendering)
QgsMapLayerRenderer* renderer; // must be deleted
QPainter::CompositionMode blendMode;
};


/** job implementation that renders everything sequentially using a custom painter.
* The returned image is always invalid (because there is none available).
*/
Expand All @@ -146,12 +159,18 @@ protected slots:

void doRender();

bool needTemporaryImage( QgsMapLayer* ml );

private:
QPainter* mPainter;
QFuture<void> mFuture;
QFutureWatcher<void> mFutureWatcher;
QgsRenderContext mRenderContext;
QgsRenderContext mRenderContext; // used just for labeling!
QgsPalLabeling* mLabelingEngine;

typedef QList<LayerRenderJob> LayerRenderJobs;

LayerRenderJobs mLayerJobs;
};


Expand Down
6 changes: 2 additions & 4 deletions src/core/qgspallabeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,10 +1499,8 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF* fm, QString t
labelY = qAbs( ptSize.y() - ptZero.y() );
}

void QgsPalLayerSettings::registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context )
void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext& context )
{
Q_UNUSED( layer );

QVariant exprVal; // value() is repeatedly nulled on data defined evaluation and replaced when successful
mCurFeat = &f;
// mCurFields = &layer->pendingFields();
Expand Down Expand Up @@ -3351,7 +3349,7 @@ int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSetti
void QgsPalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context )
{
QgsPalLayerSettings& lyr = mActiveLayers[layer];
lyr.registerFeature( layer, f, context );
lyr.registerFeature( f, context );
}

void QgsPalLabeling::registerDiagramFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context )
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgspallabeling.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ class CORE_EXPORT QgsPalLayerSettings
void calculateLabelSize( const QFontMetricsF* fm, QString text, double& labelX, double& labelY, QgsFeature* f = 0 );

// implementation of register feature hook
void registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context );
void registerFeature( QgsFeature& f, const QgsRenderContext& context );

void readFromLayer( QgsVectorLayer* layer );
void writeToLayer( QgsVectorLayer* layer );
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,7 @@ void QgsVectorFileWriter::startRender( QgsVectorLayer* vl ) const
}

QgsRenderContext ctx = renderContext();
renderer->startRender( ctx, vl );
renderer->startRender( ctx, vl->pendingFields() );
}

void QgsVectorFileWriter::stopRender( QgsVectorLayer* vl ) const
Expand Down
362 changes: 12 additions & 350 deletions src/core/qgsvectorlayer.cpp

Large diffs are not rendered by default.

30 changes: 5 additions & 25 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,16 +726,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
*/
void setRendererV2( QgsFeatureRendererV2* r );

/** Draw layer with renderer V2. QgsFeatureRenderer::startRender() needs to be called before using this method
* @note added in 1.4
*/
void drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling );

/** Draw layer with renderer V2 using symbol levels. QgsFeatureRenderer::startRender() needs to be called before using this method
* @note added in 1.4
*/
void drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling );

/** Returns point, line or polygon */
QGis::GeometryType geometryType() const;

Expand Down Expand Up @@ -1027,6 +1017,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
@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 );

/** Draws the layer
* @return false if an error occurred during drawing
*/
Expand Down Expand Up @@ -1546,24 +1541,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
QMultiMap<double, QgsSnappingResult>& snappingResults,
QgsSnapper::SnappingType snap_to ) const;

/**Reads vertex marker type from settings*/
static QgsVectorLayer::VertexMarkerType currentVertexMarkerType();

/**Reads vertex marker size from settings*/
static int currentVertexMarkerSize();

/** Add joined attributes to a feature */
//void addJoinedAttributes( QgsFeature& f, bool all = false );

/** Stop version 2 renderer and selected renderer (if required) */
void stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer );

/**Registers label and diagram layer
@param rendererContext render context
@param attributes attributes needed for labeling and diagrams will be added to the list
@param labeling out: true if there will be labeling (ng) for this layer*/
void prepareLabelingAndDiagrams( QgsRenderContext& rendererContext, QgsAttributeList& attributes, bool& labeling );

private: // Private attributes

/** Pointer to data provider derived from the abastract base class QgsDataProvider */
Expand Down
413 changes: 413 additions & 0 deletions src/core/qgsvectorlayerrenderer.cpp

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions src/core/qgsvectorlayerrenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#ifndef QGSVECTORLAYERRENDERER_H
#define QGSVECTORLAYERRENDERER_H

class QgsFeatureRendererV2;
class QgsRenderContext;
class QgsVectorLayer;

class QgsDiagramRendererV2;
class QgsDiagramLayerSettings;

class QgsGeometryCache;
class QgsFeatureIterator;
class QgsSingleSymbolRendererV2;

#include <QList>
#include <QPainter>

typedef QList<int> QgsAttributeList;

#include "qgis.h"
#include "qgsfield.h" // QgsFields
#include "qgsfeature.h" // QgsFeatureIds
#include "qgsfeatureiterator.h"

#include "qgsmaplayerrenderer.h"

class QgsVectorLayerRenderer : public QgsMapLayerRenderer
{
public:
QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRenderContext& context );
~QgsVectorLayerRenderer();

virtual bool render();

private:

/**Registers label and diagram layer
@param attributes attributes needed for labeling and diagrams will be added to the list
*/
void prepareLabelingAndDiagrams( QStringList& attributeNames );

/** Draw layer with renderer V2. QgsFeatureRenderer::startRender() needs to be called before using this method
*/
void drawRendererV2();

/** Draw layer with renderer V2 using symbol levels. QgsFeatureRenderer::startRender() needs to be called before using this method
*/
void drawRendererV2Levels();

/** Stop version 2 renderer and selected renderer (if required) */
void stopRendererV2( QgsSingleSymbolRendererV2* selRenderer );


protected:

QgsRenderContext& mContext;

This comment has been minimized.

Copy link
@m-kuhn

m-kuhn Jun 7, 2016

Member

@wonder-sk do you remember why this is a reference?

Modifications in here pollute the source object so I wonder if we could just take a working copy of it.
See discussion in 5c3aa51

This comment has been minimized.

Copy link
@wonder-sk

wonder-sk Jun 8, 2016

Author Member

If I am not wrong, having a copy instead of reference would make it impossible to cancel rendering - it is done by calling context.setRenderingStopped(true) and the QgsVectorLayerRenderer checks for the state of that flag while rendering.


QgsFields mFields;

QString mLayerID;

QgsFeatureIds mSelectedFeatureIds;

QgsFeatureIterator mFit;

QgsFeatureRendererV2 *mRendererV2;

//diagram rendering object. 0 if diagram drawing is disabled
QgsDiagramRendererV2* mDiagramRenderer;

//stores infos about diagram placement (placement type, priority, position distance)
QgsDiagramLayerSettings* mDiagramLayerSettings;

bool mCacheFeatures;
QgsGeometryCache* mCache;

bool mDrawVertexMarkers;
bool mVertexMarkerOnlyForSelection;
int mVertexMarkerStyle, mVertexMarkerSize;

QGis::GeometryType mGeometryType;

bool mLabeling;

int mLayerTransparency;
QPainter::CompositionMode mFeatureBlendMode;
};


#endif // QGSVECTORLAYERRENDERER_H
14 changes: 7 additions & 7 deletions src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,33 +358,33 @@ void QgsCategorizedSymbolRendererV2::sortByLabel( Qt::SortOrder order )
}
}

void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsFields& fields )
{
// make sure that the hash table is up to date
rebuildHash();

// find out classification attribute index from name
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
mAttrNum = fields.fieldNameIndex( mAttrName );
if ( mAttrNum == -1 )
{
mExpression = new QgsExpression( mAttrName );
mExpression->prepare( vlayer->pendingFields() );
mExpression->prepare( fields );
}

mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : fields.fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : fields.fieldNameIndex( mSizeScaleField ) );

QgsCategoryList::iterator it = mCategories.begin();
for ( ; it != mCategories.end(); ++it )
{
it->symbol()->startRender( context, vlayer );
it->symbol()->startRender( context, &fields );

if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
{
QgsSymbolV2* tempSymbol = it->symbol()->clone();
tempSymbol->setRenderHints(( mRotationFieldIdx != -1 ? QgsSymbolV2::DataDefinedRotation : 0 ) |
( mSizeScaleFieldIdx != -1 ? QgsSymbolV2::DataDefinedSizeScale : 0 ) );
tempSymbol->startRender( context, vlayer );
tempSymbol->startRender( context, &fields );
mTempSymbols[ it->value().toString()] = tempSymbol;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgscategorizedsymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2

virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature );

virtual void startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );

virtual void stopRender( QgsRenderContext& context );

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void QgsEllipseSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
mPen.setColor( mOutlineColor );
mPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ) );
mBrush.setColor( mFillColor );
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsEllipseSymbolLayerV2::stopRender( QgsSymbolV2RenderContext & )
Expand Down
8 changes: 4 additions & 4 deletions src/core/symbology-ng/qgsfillsymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void QgsSimpleFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
mSelPen = QPen( selPenColor );
mPen.setStyle( mBorderStyle );
mPen.setWidthF( mBorderWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mBorderWidthUnit ) );
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsSimpleFillSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
Expand Down Expand Up @@ -576,7 +576,7 @@ void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
mOutline->startRender( context.renderContext() );
}

prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsSVGFillSymbolLayer::stopRender( QgsSymbolV2RenderContext& context )
Expand Down Expand Up @@ -1096,7 +1096,7 @@ void QgsLinePatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& conte
mOutline->startRender( context.renderContext() );
}

prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsLinePatternFillSymbolLayer::stopRender( QgsSymbolV2RenderContext & )
Expand Down Expand Up @@ -1467,7 +1467,7 @@ void QgsPointPatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& cont
{
mOutline->startRender( context.renderContext() );
}
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsPointPatternFillSymbolLayer::stopRender( QgsSymbolV2RenderContext& context )
Expand Down
14 changes: 7 additions & 7 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,31 +236,31 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature( QgsFeature& feature
return tempSymbol;
}

void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsFields& fields )
{
// find out classification attribute index from name
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
mAttrNum = fields.fieldNameIndex( mAttrName );

if ( mAttrNum == -1 )
{
mExpression = new QgsExpression( mAttrName );
mExpression->prepare( vlayer->pendingFields() );
mExpression->prepare( fields );
}

mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : fields.fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : fields.fieldNameIndex( mSizeScaleField ) );

QgsRangeList::iterator it = mRanges.begin();
for ( ; it != mRanges.end(); ++it )
{
it->symbol()->startRender( context, vlayer );
it->symbol()->startRender( context, &fields );

if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
{
QgsSymbolV2* tempSymbol = it->symbol()->clone();
tempSymbol->setRenderHints(( mRotationFieldIdx != -1 ? QgsSymbolV2::DataDefinedRotation : 0 ) |
( mSizeScaleFieldIdx != -1 ? QgsSymbolV2::DataDefinedSizeScale : 0 ) );
tempSymbol->startRender( context, vlayer );
tempSymbol->startRender( context, &fields );
mTempSymbols[ it->symbol()] = tempSymbol;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2

virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature );

virtual void startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );

virtual void stopRender( QgsRenderContext& context );

Expand Down
6 changes: 3 additions & 3 deletions src/core/symbology-ng/qgslinesymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
mSelPen.setColor( selColor );

//prepare expressions for data defined properties
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsSimpleLineSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
Expand Down Expand Up @@ -535,10 +535,10 @@ void QgsMarkerLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
hints |= QgsSymbolV2::DataDefinedSizeScale;
mMarker->setRenderHints( hints );

mMarker->startRender( context.renderContext(), context.layer() );
mMarker->startRender( context.renderContext(), context.fields() );

//prepare expressions for data defined properties
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsMarkerLineSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
mSelCache = QImage();
}

prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}


Expand Down Expand Up @@ -868,7 +868,7 @@ void QgsSvgMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
{
mOrigSize = mSize; // save in case the size would be data defined
Q_UNUSED( context );
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
prepareExpressions( context.fields(), context.renderContext().rendererScale() );
}

void QgsSvgMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
Expand Down
13 changes: 8 additions & 5 deletions src/core/symbology-ng/qgspointdisplacementrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ QgsSymbolV2* QgsPointDisplacementRenderer::symbolForFeature( QgsFeature& feature
return 0; //not used any more
}

void QgsPointDisplacementRenderer::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
void QgsPointDisplacementRenderer::startRender( QgsRenderContext& context, const QgsFields& fields )
{
mRenderer->startRender( context, vlayer );
mRenderer->startRender( context, fields );

//create groups with features that have the same position
createDisplacementGroups( const_cast<QgsVectorLayer*>( vlayer ), context.extent() );
createDisplacementGroups( 0, context.extent() );
printInfoDisplacementGroups(); //just for debugging

if ( mLabelAttributeName.isEmpty() )
Expand All @@ -213,7 +213,7 @@ void QgsPointDisplacementRenderer::startRender( QgsRenderContext& context, const
}
else
{
mLabelIndex = vlayer->fieldNameIndex( mLabelAttributeName );
mLabelIndex = fields.fieldNameIndex( mLabelAttributeName );
}

if ( mMaxLabelScaleDenominator > 0 && context.rendererScale() > mMaxLabelScaleDenominator )
Expand All @@ -227,7 +227,7 @@ void QgsPointDisplacementRenderer::startRender( QgsRenderContext& context, const

if ( mCenterSymbol )
{
mCenterSymbol->startRender( context, vlayer );
mCenterSymbol->startRender( context, &fields );
}
}

Expand Down Expand Up @@ -341,6 +341,9 @@ QgsLegendSymbolList QgsPointDisplacementRenderer::legendSymbolItems( double scal

void QgsPointDisplacementRenderer::createDisplacementGroups( QgsVectorLayer* vlayer, const QgsRectangle& viewExtent )
{
Q_ASSERT( 0 && "Point Displacement Renderer is currently not working - it is now illegal to interact with QgsVectorLayer"
" in any way. The renderer should build groups in the renderFeature() calls and then do all rendering in stopRender()");

if ( !vlayer || ( vlayer->wkbType() != QGis::WKBPoint && vlayer->wkbType() != QGis::WKBPoint25D ) )
{
return;
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgspointdisplacementrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsFeatureRendererV2

QgsSymbolV2* symbolForFeature( QgsFeature& feature );

void startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
void startRender( QgsRenderContext& context, const QgsFields& fields );

void stopRender( QgsRenderContext& context );

Expand Down
5 changes: 5 additions & 0 deletions src/core/symbology-ng/qgsrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::defaultRenderer( QGis::GeometryType
return new QgsSingleSymbolRendererV2( QgsSymbolV2::defaultSymbol( geomType ) );
}

void QgsFeatureRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer* vlayer )
{
startRender( context, vlayer->pendingFields() );
}


bool QgsFeatureRendererV2::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker )
{
Expand Down
6 changes: 5 additions & 1 deletion src/core/symbology-ng/qgsrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
class QgsSymbolV2;
class QgsRenderContext;
class QgsFeature;
class QgsFields;
class QgsVectorLayer;

typedef QMap<QString, QString> QgsStringMap;
Expand Down Expand Up @@ -81,7 +82,10 @@ class CORE_EXPORT QgsFeatureRendererV2
*/
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature ) = 0;

virtual void startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer ) = 0;
virtual void startRender( QgsRenderContext& context, const QgsFields& fields ) = 0;

//! @deprecated since 2.1 - not using QgsVectorLayer directly anymore
Q_DECL_DEPRECATED virtual void startRender( QgsRenderContext& context, const QgsVectorLayer* vlayer );

virtual void stopRender( QgsRenderContext& context ) = 0;

Expand Down
12 changes: 6 additions & 6 deletions src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ void QgsRuleBasedRendererV2::Rule::toSld( QDomDocument& doc, QDomElement &elemen
}
}

bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const QgsFields& fields )
{
mActiveChildren.clear();

Expand All @@ -355,16 +355,16 @@ bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const

// init this rule
if ( mFilter )
mFilter->prepare( vlayer->pendingFields() );
mFilter->prepare( fields );
if ( mSymbol )
mSymbol->startRender( context, vlayer );
mSymbol->startRender( context, &fields );

// init children
// build temporary list of active rules (usable with this scale)
for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
{
Rule* rule = *it;
if ( rule->startRender( context, vlayer ) )
if ( rule->startRender( context, fields ) )
{
// only add those which are active with current scale
mActiveChildren.append( rule );
Expand Down Expand Up @@ -726,10 +726,10 @@ bool QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
}


void QgsRuleBasedRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
void QgsRuleBasedRendererV2::startRender( QgsRenderContext& context, const QgsFields& fields )
{
// prepare active children
mRootRule->startRender( context, vlayer );
mRootRule->startRender( context, fields );

QSet<int> symbolZLevelsSet = mRootRule->collectZLevels();
QList<int> symbolZLevels = symbolZLevelsSet.toList();
Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgsrulebasedrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
QDomElement save( QDomDocument& doc, QgsSymbolV2Map& symbolMap );

//! prepare the rule for rendering and its children (build active children array)
bool startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
bool startRender( QgsRenderContext& context, const QgsFields& fields );
//! get all used z-levels from this rule and children
QSet<int> collectZLevels();
//! assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering
Expand Down Expand Up @@ -203,7 +203,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2

virtual bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );

virtual void startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );

virtual void stopRender( QgsRenderContext& context );

Expand Down
10 changes: 5 additions & 5 deletions src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature( QgsFeature& feature )
return mTempSymbol;
}

void QgsSingleSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
void QgsSingleSymbolRendererV2::startRender( QgsRenderContext& context, const QgsFields& fields )
{
if ( !mSymbol )
{
return;
}
mRotationFieldIdx = mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField );
mSizeScaleFieldIdx = mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField );
mRotationFieldIdx = mRotationField.isEmpty() ? -1 : fields.fieldNameIndex( mRotationField );
mSizeScaleFieldIdx = mSizeScaleField.isEmpty() ? -1 : fields.fieldNameIndex( mSizeScaleField );

mSymbol->startRender( context, vlayer );
mSymbol->startRender( context, &fields );

if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
{
Expand All @@ -103,7 +103,7 @@ void QgsSingleSymbolRendererV2::startRender( QgsRenderContext& context, const Qg
hints |= QgsSymbolV2::DataDefinedSizeScale;
mTempSymbol->setRenderHints( hints );

mTempSymbol->startRender( context, vlayer );
mTempSymbol->startRender( context, &fields );

if ( mSymbol->type() == QgsSymbolV2::Marker )
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgssinglesymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2

virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature );

virtual void startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );

virtual void stopRender( QgsRenderContext& context );

Expand Down
7 changes: 3 additions & 4 deletions src/core/symbology-ng/qgssymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,19 @@ void QgsSymbolLayerV2::removeDataDefinedProperties()
mDataDefinedProperties.clear();
}

void QgsSymbolLayerV2::prepareExpressions( const QgsVectorLayer* vl, double scale )
void QgsSymbolLayerV2::prepareExpressions( const QgsFields* fields, double scale )
{
if ( !vl )
if ( !fields )
{
return;
}

const QgsFields& fields = vl->pendingFields();
QMap< QString, QgsExpression* >::iterator it = mDataDefinedProperties.begin();
for ( ; it != mDataDefinedProperties.end(); ++it )
{
if ( it.value() )
{
it.value()->prepare( fields );
it.value()->prepare( *fields );
if ( scale > 0 )
{
it.value()->setScale( scale );
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgssymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class CORE_EXPORT QgsSymbolLayerV2
static const bool selectFillBorder = false; // Fill symbol layer also selects border symbology
static const bool selectFillStyle = false; // Fill symbol uses symbol layer style..

virtual void prepareExpressions( const QgsVectorLayer* vl, double scale = -1 );
virtual void prepareExpressions( const QgsFields* fields, double scale = -1 );
virtual QgsExpression* expression( const QString& property );
/**Saves data defined properties to string map*/
void saveDataDefinedProperties( QgsStringMap& stringMap ) const;
Expand Down
9 changes: 4 additions & 5 deletions src/core/symbology-ng/qgssymbolv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,9 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
}


void QgsSymbolV2::startRender( QgsRenderContext& context, const QgsVectorLayer* layer )
void QgsSymbolV2::startRender( QgsRenderContext& context, const QgsFields* fields )
{
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints );
symbolContext.setLayer( layer );
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, 0, fields );
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
( *it )->startRender( symbolContext );
}
Expand Down Expand Up @@ -375,8 +374,8 @@ QSet<QString> QgsSymbolV2::usedAttributes() const
////////////////////


QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints, const QgsFeature* f )
: mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints ), mFeature( f ), mLayer( 0 )
QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints, const QgsFeature* f, const QgsFields* fields )
: mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints ), mFeature( f ), mFields( fields )
{

}
Expand Down
15 changes: 10 additions & 5 deletions src/core/symbology-ng/qgssymbolv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class QDomElement;
//class

class QgsFeature;
class QgsFields;
class QgsSymbolLayerV2;
class QgsRenderContext;
class QgsVectorLayer;
Expand Down Expand Up @@ -97,7 +98,7 @@ class CORE_EXPORT QgsSymbolV2
//! delete layer at specified index and set a new one
bool changeSymbolLayer( int index, QgsSymbolLayerV2* layer );

void startRender( QgsRenderContext& context, const QgsVectorLayer* layer = 0 );
void startRender( QgsRenderContext& context, const QgsFields* fields = 0 );
void stopRender( QgsRenderContext& context );

void setColor( const QColor& color );
Expand Down Expand Up @@ -152,7 +153,7 @@ class CORE_EXPORT QgsSymbolV2
class CORE_EXPORT QgsSymbolV2RenderContext
{
public:
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false, int renderHints = 0, const QgsFeature* f = 0 );
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false, int renderHints = 0, const QgsFeature* f = 0, const QgsFields* = 0 );
~QgsSymbolV2RenderContext();

QgsRenderContext& renderContext() { return mRenderContext; }
Expand All @@ -176,10 +177,14 @@ class CORE_EXPORT QgsSymbolV2RenderContext
void setRenderHints( int hints ) { mRenderHints = hints; }

void setFeature( const QgsFeature* f ) { mFeature = f; }
//! Current feature being rendered - may be null
const QgsFeature* feature() const { return mFeature; }

void setLayer( const QgsVectorLayer* layer ) { mLayer = layer; }
const QgsVectorLayer* layer() const { return mLayer; }
//! Fields of the layer. Currently only available in startRender() calls
//! to allow symbols with data-defined properties prepare the expressions
//! (other times fields() returns null)
//! @note added in 2.1
const QgsFields* fields() const { return mFields; }

double outputLineWidth( double width ) const;
double outputPixelSize( double size ) const;
Expand All @@ -194,7 +199,7 @@ class CORE_EXPORT QgsSymbolV2RenderContext
bool mSelected;
int mRenderHints;
const QgsFeature* mFeature; //current feature
const QgsVectorLayer* mLayer; //current vectorlayer
const QgsFields* mFields;
};


Expand Down
8 changes: 4 additions & 4 deletions src/core/symbology-ng/qgsvectorfieldsymbollayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ void QgsVectorFieldSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
mLineSymbol->startRender( context.renderContext() );
}

const QgsVectorLayer* layer = context.layer();
if ( layer )
const QgsFields* fields = context.fields();
if ( fields )
{
mXIndex = layer->fieldNameIndex( mXAttribute );
mYIndex = layer->fieldNameIndex( mYAttribute );
mXIndex = fields->fieldNameIndex( mXAttribute );
mYIndex = fields->fieldNameIndex( mYAttribute );
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/gui/attributetable/qgsattributetablefiltermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ void QgsAttributeTableFilterModel::generateListOfVisibleFeatures()
filter = renderer && renderer->capabilities() & QgsFeatureRendererV2::Filter;
}

renderer->startRender( renderContext, layer() );
renderer->startRender( renderContext, layer()->pendingFields() );

QgsFeatureIterator features = masterModel()->layerCache()->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setFilterRect( rect ) );

Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsmaptoolidentify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QList<IdentifyResult> *results, Qg
if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent )
{
// setup scale for scale dependent visibility (rule based)
renderer->startRender( context, layer );
renderer->startRender( context, layer->pendingFields() );
filter = renderer->capabilities() & QgsFeatureRendererV2::Filter;
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ void QgsRuleBasedRendererV2Widget::countFeatures()

QgsRenderContext renderContext;
renderContext.setRendererScale( 0 ); // ignore scale
mRenderer->startRender( renderContext, mLayer );
mRenderer->startRender( renderContext, mLayer->pendingFields() );

int nFeatures = mLayer->pendingFeatureCount();
QProgressDialog p( tr( "Calculating feature count." ), tr( "Abort" ), 0, nFeatures );
Expand Down
2 changes: 1 addition & 1 deletion tests/src/core/testqgsrulebasedrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class TestQgsRuleBasedRenderer: public QObject
QVERIFY( r.capabilities() & QgsFeatureRendererV2::MoreSymbolsPerFeature );

QgsRenderContext ctx; // dummy render context
r.startRender( ctx, layer );
r.startRender( ctx, layer->pendingFields() );

// test willRenderFeature
QVERIFY( r.willRenderFeature( f1 ) == true );
Expand Down