Skip to content
Permalink
Browse files

Port renderers to expression contexts

  • Loading branch information
nyalldawson committed Aug 22, 2015
1 parent d6d6827 commit 0cab6b337662f54ea6a17a80ee4fcd64b3e08d3b
@@ -110,6 +110,8 @@ void QgsMapToolRotatePointSymbols::canvasPressEvent( QMouseEvent *e )
if ( !renderer )
return;
QgsRenderContext context = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() );
context.expressionContext() << QgsExpressionContextUtils::layerScope( mActiveLayer );
context.expressionContext().setFeature( pointFeature );
renderer->startRender( context, mActiveLayer->fields() );

//find all rotation fields used by renderer for feature
@@ -137,6 +137,7 @@ void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) );

QgsRenderContext context = QgsRenderContext::fromMapSettings( canvas->mapSettings() );
context.expressionContext() << QgsExpressionContextUtils::layerScope( vlayer );
QgsFeatureRendererV2* r = vlayer->rendererV2();
if ( r )
r->startRender( context, vlayer->fields() );
@@ -158,6 +159,7 @@ void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
double closestFeatureDist = std::numeric_limits<double>::max();
while ( fit.nextFeature( f ) )
{
context.expressionContext().setFeature( f );
// make sure to only use features that are visible
if ( r && !r->willRenderFeature( f, context ) )
continue;
@@ -934,6 +934,7 @@ void QgsDxfExport::writeEntities()
QgsFeature fet;
while ( featureIt.nextFeature( fet ) )
{
ctx.expressionContext().setFeature( fet );
QString layerName( dxfLayerName( layerIt->second == -1 ? vl->name() : fet.attribute( layerIt->second ).toString() ) );

sctx.setFeature( &fet );
@@ -1002,6 +1003,9 @@ void QgsDxfExport::writeEntitiesSymbolLevels( QgsVectorLayer* layer )
QHash< QgsSymbolV2*, QList<QgsFeature> > features;

QgsRenderContext ctx = renderContext();
ctx.expressionContext() << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( layer );
QgsSymbolV2RenderContext sctx( ctx, QgsSymbolV2::MM, 1.0, false, 0, 0 );
renderer->startRender( ctx, layer->fields() );

@@ -1023,6 +1027,7 @@ void QgsDxfExport::writeEntitiesSymbolLevels( QgsVectorLayer* layer )
QgsSymbolV2* featureSymbol = 0;
while ( fit.nextFeature( fet ) )
{
ctx.expressionContext().setFeature( fet );
featureSymbol = renderer->symbolForFeature( fet, ctx );
if ( !featureSymbol )
{
@@ -42,6 +42,7 @@ void QgsMapHitTest::run()
context.setExtent( mSettings.outputExtentToLayerExtent( vl, mSettings.visibleExtent() ) );
}

context.expressionContext() << QgsExpressionContextUtils::layerScope( vl );
SymbolV2Set& usedSymbols = mHitTest[vl];
runHitTestLayer( vl, usedSymbols, context );
}
@@ -61,6 +62,7 @@ void QgsMapHitTest::runHitTestLayer( QgsVectorLayer* vl, SymbolV2Set& usedSymbol
QgsFeatureIterator fi = vl->getFeatures( request );
while ( fi.nextFeature( f ) )
{
context.expressionContext().setFeature( f );
if ( moreSymbolsPerFeature )
{
foreach ( QgsSymbolV2* s, r->originalSymbolsForFeature( f, context ) )
@@ -1573,6 +1573,7 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2*
//add OGR feature style type
if ( mSymbologyExport != NoSymbology && renderer )
{
mRenderContext.expressionContext().setFeature( feature );
//SymbolLayerSymbology: concatenate ogr styles of all symbollayers
QgsSymbolV2List symbols = renderer->symbolsForFeature( feature, mRenderContext );
QString styleString;
@@ -2500,6 +2501,11 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
if ( !layer )
return ErrInvalidLayer;

mRenderContext.expressionContext() = QgsExpressionContext();
mRenderContext.expressionContext() << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( layer );

QgsFeatureRendererV2 *renderer = layer->rendererV2();
if ( !renderer )
return ErrInvalidLayer;
@@ -2540,6 +2546,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels
return ErrProjection;
}
}
mRenderContext.expressionContext().setFeature( fet );

featureSymbol = renderer->symbolForFeature( fet, mRenderContext );
if ( !featureSymbol )
@@ -718,11 +718,16 @@ bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
// Renderer (rule based) may depend on context scale, with scale is ignored if 0
QgsRenderContext renderContext;
renderContext.setRendererScale( 0 );
renderContext.expressionContext() << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( this );

mRendererV2->startRender( renderContext, fields() );

QgsFeature f;
while ( fit.nextFeature( f ) )
{
renderContext.expressionContext().setFeature( f );
QgsSymbolV2List featureSymbolList = mRendererV2->originalSymbolsForFeature( f, renderContext );
for ( QgsSymbolV2List::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
{
@@ -348,6 +348,7 @@ void QgsVectorLayerRenderer::drawRendererV2Levels( QgsFeatureIterator& fit )
return;
}

mContext.expressionContext().setFeature( fet );
QgsSymbolV2* sym = mRendererV2->symbolForFeature( fet, mContext );
if ( !sym )
{
@@ -211,8 +211,8 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& featu
return symbol; // no data-defined rotation/scaling - just return the symbol

// find out rotation, size scale
const double rotation = mRotation.data() ? mRotation->evaluate( feature ).toDouble() : 0;
const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( feature ).toDouble() : 1.;
const double rotation = mRotation.data() ? mRotation->evaluate( &context.expressionContext() ).toDouble() : 0;
const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( &context.expressionContext() ).toDouble() : 1.;

// take a temporary symbol (or create it if doesn't exist)
QgsSymbolV2* tempSymbol = mTempSymbols[symbol];
@@ -243,7 +243,7 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::originalSymbolForFeature( QgsFeatur
if ( mAttrNum == -1 )
{
Q_ASSERT( mExpression.data() );
value = mExpression->evaluate( &feature );
value = mExpression->evaluate( &context.expressionContext() );
}
else
{
@@ -409,7 +409,7 @@ void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, con
if ( mAttrNum == -1 )
{
mExpression.reset( new QgsExpression( mAttrName ) );
mExpression->prepare( fields );
mExpression->prepare( &context.expressionContext() );
}

QgsCategoryList::iterator it = mCategories.begin();
@@ -326,8 +326,8 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature( QgsFeature& feature
return symbol; // no data-defined rotation/scaling - just return the symbol

// find out rotation, size scale
const double rotation = mRotation.data() ? mRotation->evaluate( feature ).toDouble() : 0;
const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( feature ).toDouble() : 1.;
const double rotation = mRotation.data() ? mRotation->evaluate( &context.expressionContext() ).toDouble() : 0;
const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( &context.expressionContext() ).toDouble() : 1.;

// take a temporary symbol (or create it if doesn't exist)
QgsSymbolV2* tempSymbol = mTempSymbols[symbol];
@@ -355,7 +355,7 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::originalSymbolForFeature( QgsFeature&
QVariant value;
if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
{
value = mExpression->evaluate( &feature );
value = mExpression->evaluate( &context.expressionContext() );
}
else
{
@@ -380,7 +380,7 @@ void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const
if ( mAttrNum == -1 )
{
mExpression.reset( new QgsExpression( mAttrName ) );
mExpression->prepare( fields );
mExpression->prepare( &context.expressionContext() );
}

QgsRangeList::iterator it = mRanges.begin();
@@ -76,7 +76,7 @@ void QgsHeatmapRenderer::startRender( QgsRenderContext& context, const QgsFields
if ( mWeightAttrNum == -1 )
{
mWeightExpression.reset( new QgsExpression( mWeightExpressionString ) );
mWeightExpression->prepare( fields );
mWeightExpression->prepare( &context.expressionContext() );
}

initializeValues( context );
@@ -122,7 +122,7 @@ bool QgsHeatmapRenderer::renderFeature( QgsFeature& feature, QgsRenderContext& c
if ( mWeightAttrNum == -1 )
{
Q_ASSERT( mWeightExpression.data() );
value = mWeightExpression->evaluate( &feature );
value = mWeightExpression->evaluate( &context.expressionContext() );
}
else
{
@@ -234,6 +234,7 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::defaultRenderer( QGis::GeometryType
QgsSymbolV2* QgsFeatureRendererV2::symbolForFeature( QgsFeature& feature )
{
QgsRenderContext context;
context.setExpressionContext( QgsExpressionContextUtils::createFeatureBasedContext( feature, QgsFields() ) );
return symbolForFeature( feature, context );
}

@@ -233,12 +233,13 @@ QgsLegendSymbolListV2 QgsRuleBasedRendererV2::Rule::legendSymbolItemsV2( int cur
}


bool QgsRuleBasedRendererV2::Rule::isFilterOK( QgsFeature& f, QgsRenderContext * ) const
bool QgsRuleBasedRendererV2::Rule::isFilterOK( QgsFeature& f, QgsRenderContext* context ) const
{
if ( ! mFilter || mElseRule )
return true;

QVariant res = mFilter->evaluate( &f );
context->expressionContext().setFeature( f );
QVariant res = mFilter->evaluate( context ? &context->expressionContext() : 0 );
return res.toInt() != 0;
}

@@ -409,7 +410,7 @@ bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const

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

@@ -47,11 +47,11 @@ QgsSingleSymbolRendererV2::~QgsSingleSymbolRendererV2()

QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature( QgsFeature& feature, QgsRenderContext &context )
{
Q_UNUSED( context );
context.expressionContext().setFeature( feature );
if ( !mRotation.data() && !mSizeScale.data() ) return mSymbol.data();

const double rotation = mRotation.data() ? mRotation->evaluate( feature ).toDouble() : 0;
const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( feature ).toDouble() : 1.;
const double rotation = mRotation.data() ? mRotation->evaluate( &context.expressionContext() ).toDouble() : 0;
const double sizeScale = mSizeScale.data() ? mSizeScale->evaluate( &context.expressionContext() ).toDouble() : 1.;

if ( mTempSymbol->type() == QgsSymbolV2::Marker )
{
@@ -230,6 +230,9 @@ void QgsAttributeTableFilterModel::generateListOfVisibleFeatures()
bool filter = false;
QgsRectangle rect = mCanvas->mapSettings().mapToLayerCoordinates( layer(), mCanvas->extent() );
QgsRenderContext renderContext;
renderContext.expressionContext() << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( layer() );
QgsFeatureRendererV2* renderer = layer()->rendererV2();

mFilteredFeatures.clear();
@@ -280,6 +283,7 @@ void QgsAttributeTableFilterModel::generateListOfVisibleFeatures()

while ( features.nextFeature( f ) )
{
renderContext.expressionContext().setFeature( f );
if ( !filter || renderer->willRenderFeature( f, renderContext ) )
{
mFilteredFeatures << f.id();
@@ -244,6 +244,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QList<IdentifyResult> *results, Qg
bool filter = false;

QgsRenderContext context( QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ) );
context.expressionContext() << QgsExpressionContextUtils::layerScope( layer );
QgsFeatureRendererV2* renderer = layer->rendererV2();
if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent )
{
@@ -257,6 +258,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QList<IdentifyResult> *results, Qg
QMap< QString, QString > derivedAttributes = commonDerivedAttributes;

QgsFeatureId fid = f_it->id();
context.expressionContext().setFeature( *f_it );

if ( filter && !renderer->willRenderFeature( *f_it, context ) )
continue;
@@ -646,12 +646,18 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
{
// Lets assume it's an expression
QgsExpression* expression = new QgsExpression( attrName );
expression->prepare( mLayer->fields() );
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( mLayer );

expression->prepare( &context );
QgsFeatureIterator fit = mLayer->getFeatures();
QgsFeature feature;
while ( fit.nextFeature( feature ) )
{
QVariant value = expression->evaluate( feature );
context.setFeature( feature );
QVariant value = expression->evaluate( &context );
if ( unique_vals.contains( value ) )
continue;
unique_vals << value;
@@ -504,6 +504,14 @@ void QgsRuleBasedRendererV2Widget::countFeatures()

QgsRenderContext renderContext;
renderContext.setRendererScale( 0 ); // ignore scale

QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( mLayer );

renderContext.setExpressionContext( context );

mRenderer->startRender( renderContext, mLayer->fields() );

int nFeatures = mLayer->featureCount();
@@ -514,6 +522,7 @@ void QgsRuleBasedRendererV2Widget::countFeatures()
QgsFeature f;
while ( fit.nextFeature( f ) )
{
renderContext.expressionContext().setFeature( f );
QgsRuleBasedRendererV2::RuleList featureRuleList = mRenderer->rootRule()->rulesForFeature( f, &renderContext );

foreach ( QgsRuleBasedRendererV2::Rule* rule, featureRuleList )
@@ -633,9 +642,12 @@ void QgsRendererRulePropsDialog::testFilter()
return;
}

const QgsFields& fields = mLayer->fields();
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope()
<< QgsExpressionContextUtils::layerScope( mLayer );

if ( !filter.prepare( fields ) )
if ( !filter.prepare( &context ) )
{
QMessageBox::critical( this, tr( "Evaluation error" ), filter.evalErrorString() );
return;
@@ -649,7 +661,9 @@ void QgsRendererRulePropsDialog::testFilter()
QgsFeature f;
while ( fit.nextFeature( f ) )
{
QVariant value = filter.evaluate( &f );
context.setFeature( f );

QVariant value = filter.evaluate( &context );
if ( value.toInt() != 0 )
count++;
if ( filter.hasEvalError() )
@@ -949,6 +949,7 @@ void QgsWMSServer::runHitTestLayer( QgsVectorLayer* vl, SymbolV2Set& usedSymbols
QgsFeatureIterator fi = vl->getFeatures( request );
while ( fi.nextFeature( f ) )
{
context.expressionContext().setFeature( f );
if ( moreSymbolsPerFeature )
{
foreach ( QgsSymbolV2* s, r->originalSymbolsForFeature( f, context ) )
@@ -2073,6 +2074,8 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
continue;
}

renderContext.expressionContext().setFeature( feature );

//check if feature is rendered at all
r2->startRender( renderContext, layer->pendingFields() );
bool renderV2 = r2->willRenderFeature( feature, renderContext );
@@ -2683,6 +2686,13 @@ void QgsWMSServer::applyOpacities( const QStringList& layerList, QList< QPair< Q
vectorRenderers.push_back( qMakePair( vl, rendererV2->clone() ) );
//modify symbols of current renderer
QgsRenderContext context;
context.expressionContext() << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope();
if ( vl )
{
context.expressionContext() << QgsExpressionContextUtils::layerScope( vl );
}

QgsSymbolV2List symbolList = rendererV2->symbols( context );
QgsSymbolV2List::iterator symbolIt = symbolList.begin();
for ( ; symbolIt != symbolList.end(); ++symbolIt )

0 comments on commit 0cab6b3

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