Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE][symbology] Allow data-defined offset for fill symbol layers
Any fill symbol layer which supports offsetting polygons (i.e. simple
fills, raster image fills, shapeburst and gradent fills) now allows
for data-defined offsets
  • Loading branch information
nyalldawson committed Sep 9, 2020
1 parent 014de96 commit 029f067
Show file tree
Hide file tree
Showing 13 changed files with 432 additions and 34 deletions.
87 changes: 83 additions & 4 deletions python/core/auto_generated/symbology/qgsfillsymbollayer.sip.in
Expand Up @@ -79,7 +79,26 @@ Caller takes ownership of the returned symbol layer.
void setPenJoinStyle( Qt::PenJoinStyle style );

void setOffset( QPointF offset );
%Docstring
Sets an ``offset`` by which polygons will be translated during rendering.

Units are specified by :py:func:`~QgsSimpleFillSymbolLayer.offsetUnit`.

.. seealso:: :py:func:`offset`

.. seealso:: :py:func:`setOffsetUnit`
%End

QPointF offset();
%Docstring
Returns the offset by which polygons will be translated during rendering.

Units are specified by :py:func:`~QgsSimpleFillSymbolLayer.offsetUnit`.

.. seealso:: :py:func:`setOffset`

.. seealso:: :py:func:`offsetUnit`
%End

void setStrokeWidthUnit( QgsUnitTypes::RenderUnit unit );
%Docstring
Expand All @@ -102,9 +121,9 @@ Returns the units for the width of the fill's stroke.

void setOffsetUnit( QgsUnitTypes::RenderUnit unit );
%Docstring
Sets the units for the fill's offset.
Sets the ``unit`` for the fill's offset.

:param unit: offset units
.. seealso:: :py:func:`offset`

.. seealso:: :py:func:`offsetUnit`
%End
Expand All @@ -114,10 +133,27 @@ Sets the units for the fill's offset.
Returns the units for the fill's offset.

.. seealso:: :py:func:`setOffsetUnit`

.. seealso:: :py:func:`offset`
%End

void setOffsetMapUnitScale( const QgsMapUnitScale &scale );
%Docstring
Sets the map unit ``scale`` for the fill's offset.

.. seealso:: :py:func:`setOffset`

.. seealso:: :py:func:`offsetMapUnitScale`
%End

const QgsMapUnitScale &offsetMapUnitScale() const;
%Docstring
Returns the map unit scale for the fill's offset.

.. seealso:: :py:func:`offset`

.. seealso:: :py:func:`setOffsetMapUnitScale`
%End

virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );

Expand Down Expand Up @@ -304,18 +340,61 @@ Sets the end point of the gradient to be the feature centroid

void setOffset( QPointF offset );
%Docstring
Offset for gradient fill
Sets an ``offset`` by which polygons will be translated during rendering.

Units are specified by :py:func:`~QgsGradientFillSymbolLayer.offsetUnit`.

.. seealso:: :py:func:`offset`

.. seealso:: :py:func:`setOffsetUnit`
%End

QPointF offset() const;
%Docstring
Returns the offset by which polygons will be translated during rendering.

Units are specified by :py:func:`~QgsGradientFillSymbolLayer.offsetUnit`.

.. seealso:: :py:func:`setOffset`

.. seealso:: :py:func:`offsetUnit`
%End

void setOffsetUnit( QgsUnitTypes::RenderUnit unit );
%Docstring
Units for gradient fill offset
Sets the ``unit`` for the fill's offset.

.. seealso:: :py:func:`offset`

.. seealso:: :py:func:`offsetUnit`
%End

QgsUnitTypes::RenderUnit offsetUnit() const;
%Docstring
Returns the units for the fill's offset.

.. seealso:: :py:func:`setOffsetUnit`

.. seealso:: :py:func:`offset`
%End

void setOffsetMapUnitScale( const QgsMapUnitScale &scale );
%Docstring
Sets the map unit ``scale`` for the fill's offset.

.. seealso:: :py:func:`setOffset`

.. seealso:: :py:func:`offsetMapUnitScale`
%End

const QgsMapUnitScale &offsetMapUnitScale() const;
%Docstring
Returns the map unit scale for the fill's offset.

.. seealso:: :py:func:`offset`

.. seealso:: :py:func:`setOffsetMapUnitScale`
%End

virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );

Expand Down
100 changes: 75 additions & 25 deletions src/core/symbology/qgsfillsymbollayer.cpp
Expand Up @@ -279,11 +279,22 @@ void QgsSimpleFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVe

applyDataDefinedSymbology( context, mBrush, mPen, mSelPen );

QPointF offset;
if ( !mOffset.isNull() )
QPointF offset = mOffset;

if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyOffset ) )
{
context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePoint( mOffset ) );
const QVariant val = mDataDefinedProperties.value( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), QString() );
bool ok = false;
const QPointF res = QgsSymbolLayerUtils::toPoint( val, &ok );
if ( ok )
offset = res;
}

if ( !offset.isNull() )
{
offset.setX( context.renderContext().convertToPainterUnits( mOffset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( mOffset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setX( context.renderContext().convertToPainterUnits( offset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( offset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
p->translate( offset );
}

Expand Down Expand Up @@ -311,7 +322,7 @@ void QgsSimpleFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVe
}
#endif

if ( !mOffset.isNull() )
if ( !offset.isNull() )
{
p->translate( -offset );
}
Expand Down Expand Up @@ -880,17 +891,27 @@ void QgsGradientFillSymbolLayer::renderPolygon( const QPolygonF &points, const Q
p->setBrush( context.selected() ? mSelBrush : mBrush );
p->setPen( Qt::NoPen );

QPointF offset;
if ( !mOffset.isNull() )
QPointF offset = mOffset;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyOffset ) )
{
context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePoint( mOffset ) );
const QVariant val = mDataDefinedProperties.value( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), QString() );
bool ok = false;
const QPointF res = QgsSymbolLayerUtils::toPoint( val, &ok );
if ( ok )
offset = res;
}

if ( !offset.isNull() )
{
offset.setX( context.renderContext().convertToPainterUnits( mOffset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( mOffset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setX( context.renderContext().convertToPainterUnits( offset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( offset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
p->translate( offset );
}

_renderPolygon( p, points, rings, context );

if ( !mOffset.isNull() )
if ( !offset.isNull() )
{
p->translate( -offset );
}
Expand Down Expand Up @@ -1166,15 +1187,26 @@ void QgsShapeburstFillSymbolLayer::renderPolygon( const QPolygonF &points, const
{
//feature is selected, draw using selection style
p->setBrush( mSelBrush );
QPointF offset;
if ( !mOffset.isNull() )
QPointF offset = mOffset;

if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyOffset ) )
{
offset.setX( context.renderContext().convertToPainterUnits( mOffset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( mOffset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePoint( mOffset ) );
const QVariant val = mDataDefinedProperties.value( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), QString() );
bool ok = false;
const QPointF res = QgsSymbolLayerUtils::toPoint( val, &ok );
if ( ok )
offset = res;
}

if ( !offset.isNull() )
{
offset.setX( context.renderContext().convertToPainterUnits( offset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( offset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
p->translate( offset );
}
_renderPolygon( p, points, rings, context );
if ( !mOffset.isNull() )
if ( !offset.isNull() )
{
p->translate( -offset );
}
Expand Down Expand Up @@ -1298,17 +1330,26 @@ void QgsShapeburstFillSymbolLayer::renderPolygon( const QPolygonF &points, const
//draw shapeburst image in correct place in the destination painter

QgsScopedQPainterState painterState( p );
QPointF offset;
if ( !mOffset.isNull() )
QPointF offset = mOffset;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyOffset ) )
{
offset.setX( context.renderContext().convertToPainterUnits( mOffset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( mOffset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePoint( mOffset ) );
const QVariant val = mDataDefinedProperties.value( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), QString() );
bool ok = false;
const QPointF res = QgsSymbolLayerUtils::toPoint( val, &ok );
if ( ok )
offset = res;
}
if ( !offset.isNull() )
{
offset.setX( context.renderContext().convertToPainterUnits( offset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( offset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
p->translate( offset );
}

p->drawImage( points.boundingRect().left() - sideBuffer, points.boundingRect().top() - sideBuffer, *fillImage );

if ( !mOffset.isNull() )
if ( !offset.isNull() )
{
p->translate( -offset );
}
Expand Down Expand Up @@ -4042,11 +4083,20 @@ void QgsRasterFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVe
return;
}

QPointF offset;
if ( !mOffset.isNull() )
QPointF offset = mOffset;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyOffset ) )
{
context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePoint( mOffset ) );
const QVariant val = mDataDefinedProperties.value( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), QString() );
bool ok = false;
const QPointF res = QgsSymbolLayerUtils::toPoint( val, &ok );
if ( ok )
offset = res;
}
if ( !offset.isNull() )
{
offset.setX( context.renderContext().convertToPainterUnits( mOffset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( mOffset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setX( context.renderContext().convertToPainterUnits( offset.x(), mOffsetUnit, mOffsetMapUnitScale ) );
offset.setY( context.renderContext().convertToPainterUnits( offset.y(), mOffsetUnit, mOffsetMapUnitScale ) );
p->translate( offset );
}
if ( mCoordinateMode == Feature )
Expand All @@ -4057,7 +4107,7 @@ void QgsRasterFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVe
}

QgsImageFillSymbolLayer::renderPolygon( points, rings, context );
if ( !mOffset.isNull() )
if ( !offset.isNull() )
{
p->translate( -offset );
}
Expand Down

0 comments on commit 029f067

Please sign in to comment.