Skip to content

Commit

Permalink
Make @cluster_size, @cluster_color usable in displacement renderer too
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 29, 2016
1 parent 7acb07f commit 1725182
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 37 deletions.
34 changes: 0 additions & 34 deletions src/core/symbology-ng/qgspointclusterrenderer.cpp
Expand Up @@ -55,40 +55,6 @@ void QgsPointClusterRenderer::drawGroup( QPointF centerPoint, QgsRenderContext&
{
if ( group.size() > 1 )
{
//scan through symbols to check color, eg if all clustered symbols are same color
QColor groupColor;
ClusteredGroup::const_iterator groupIt = group.constBegin();
for ( ; groupIt != group.constEnd(); ++groupIt )
{
if ( !groupIt->symbol )
continue;

if ( !groupColor.isValid() )
{
groupColor = groupIt->symbol->color();
}
else
{
if ( groupColor != groupIt->symbol->color() )
{
groupColor = QColor();
break;
}
}
}

if ( groupColor.isValid() )
{
context.expressionContext().lastScope()->setVariable( "cluster_color", QgsSymbolLayerUtils::encodeColor( groupColor ) );
}
else
{
//mixed colors
context.expressionContext().lastScope()->setVariable( "cluster_color", "" );
}

//multiple clustered symbols, so draw just the cluster symbol
context.expressionContext().lastScope()->setVariable( "cluster_size", group.size() );
mClusterSymbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, false );
}
else
Expand Down
3 changes: 2 additions & 1 deletion src/core/symbology-ng/qgspointdisplacementrenderer.cpp
Expand Up @@ -64,6 +64,7 @@ QgsPointDisplacementRenderer* QgsPointDisplacementRenderer::clone() const

void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderContext& context, const ClusteredGroup& group )
{

//calculate max diagonal size from all symbols in group
double diagonal = 0;

Expand All @@ -88,9 +89,9 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
if ( circleRadius > 0 )
drawCircle( circleRadius, symbolContext, centerPoint, group.size() );

//draw mid point
if ( group.size() > 1 )
{
//draw mid point
QgsFeature firstFeature = group.at( 0 ).feature;
if ( mCenterSymbol )
{
Expand Down
44 changes: 44 additions & 0 deletions src/core/symbology-ng/qgspointdistancerenderer.cpp
Expand Up @@ -140,7 +140,9 @@ void QgsPointDistanceRenderer::drawGroup( const ClusteredGroup& group, QgsRender
QgsGeometry centroid = groupGeom.centroid();
QPointF pt = _getPoint( context, *static_cast<QgsPointV2*>( centroid.geometry() ) );

context.expressionContext().appendScope( createGroupScope( group ) );
drawGroup( pt, context, group );
delete context.expressionContext().popScope();
}

void QgsPointDistanceRenderer::setEmbeddedRenderer( QgsFeatureRenderer* r )
Expand Down Expand Up @@ -407,6 +409,48 @@ void QgsPointDistanceRenderer::drawLabels( QPointF centerPoint, QgsSymbolRenderC
}
}

QgsExpressionContextScope* QgsPointDistanceRenderer::createGroupScope( const ClusteredGroup& group ) const
{
QgsExpressionContextScope* clusterScope = new QgsExpressionContextScope();
if ( group.size() > 1 )
{
//scan through symbols to check color, eg if all clustered symbols are same color
QColor groupColor;
ClusteredGroup::const_iterator groupIt = group.constBegin();
for ( ; groupIt != group.constEnd(); ++groupIt )
{
if ( !groupIt->symbol )
continue;

if ( !groupColor.isValid() )
{
groupColor = groupIt->symbol->color();
}
else
{
if ( groupColor != groupIt->symbol->color() )
{
groupColor = QColor();
break;
}
}
}

if ( groupColor.isValid() )
{
clusterScope->setVariable( "cluster_color", QgsSymbolLayerUtils::encodeColor( groupColor ) );
}
else
{
//mixed colors
clusterScope->setVariable( "cluster_color", "" );
}

clusterScope->setVariable( "cluster_size", group.size() );
}
return clusterScope;
}

QgsMarkerSymbol* QgsPointDistanceRenderer::firstSymbolForFeature( QgsFeature& feature, QgsRenderContext &context )
{
if ( !mRenderer )
Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology-ng/qgspointdistancerenderer.h
Expand Up @@ -276,6 +276,12 @@ class CORE_EXPORT QgsPointDistanceRenderer: public QgsFeatureRenderer
*/
QgsMarkerSymbol* firstSymbolForFeature( QgsFeature& feature, QgsRenderContext& context );

/** Creates an expression context scope for a clustered group, with variables reflecting the group's properties.
* @param group clustered group
* @returns new expression context scope
*/
QgsExpressionContextScope* createGroupScope( const ClusteredGroup& group ) const;

};

#endif // QGSPOINTDISTANCERENDERER_H
21 changes: 20 additions & 1 deletion tests/src/python/test_qgspointclusterrenderer.py
Expand Up @@ -40,7 +40,8 @@
QgsMarkerSymbol,
QgsSingleSymbolRenderer,
QgsPointDisplacementRenderer,
QgsMapSettings
QgsMapSettings,
QgsDataDefined
)
from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath)
Expand Down Expand Up @@ -162,6 +163,24 @@ def testRenderWithin(self):
renderchecker.setControlName('expected_cluster_cluster')
self.assertTrue(renderchecker.runTest('expected_cluster_cluster'))

def testRenderVariables(self):
""" test rendering with expression variables in marker """
self.layer.renderer().setTolerance(10)

old_marker = self.layer.renderer().clusterSymbol().clone()

new_marker = QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'})
new_marker.symbolLayer(0).setDataDefinedProperty('color', QgsDataDefined('@cluster_color'))
new_marker.symbolLayer(0).setDataDefinedProperty('size', QgsDataDefined('@cluster_size*2'))
self.layer.renderer().setClusterSymbol(new_marker)
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(self.mapsettings)
renderchecker.setControlPathPrefix('cluster_renderer')
renderchecker.setControlName('expected_cluster_variables')
result = renderchecker.runTest('expected_cluster_variables')
self.layer.renderer().setClusterSymbol(old_marker)
self.assertTrue(result)


if __name__ == '__main__':
unittest.main()
20 changes: 19 additions & 1 deletion tests/src/python/test_qgspointdisplacementrenderer.py
Expand Up @@ -42,7 +42,8 @@
QgsMarkerSymbol,
QgsSingleSymbolRenderer,
QgsPointClusterRenderer,
QgsMapSettings
QgsMapSettings,
QgsDataDefined
)
from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath)
Expand Down Expand Up @@ -185,6 +186,23 @@ def testRenderWithin(self):
renderchecker.setControlName('expected_displacement_cluster')
self.assertTrue(renderchecker.runTest('expected_displacement_cluster'))

def testRenderVariables(self):
""" test rendering with expression variables in marker """
self.layer.renderer().setTolerance(10)

old_marker = self.layer.renderer().centerSymbol().clone()

new_marker = QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'})
new_marker.symbolLayer(0).setDataDefinedProperty('color', QgsDataDefined('@cluster_color'))
new_marker.symbolLayer(0).setDataDefinedProperty('size', QgsDataDefined('@cluster_size*2'))
self.layer.renderer().setCenterSymbol(new_marker)
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(self.mapsettings)
renderchecker.setControlPathPrefix('displacement_renderer')
renderchecker.setControlName('expected_displacement_variables')
result = renderchecker.runTest('expected_displacement_variables')
self.layer.renderer().setCenterSymbol(old_marker)
self.assertTrue(result)

if __name__ == '__main__':
unittest.main()

0 comments on commit 1725182

Please sign in to comment.