Skip to content

Commit

Permalink
Move creation of minSize/maxSize symbol to QgsSymbolLayerUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Jun 30, 2020
1 parent 80b3a81 commit c399f08
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 49 deletions.
15 changes: 9 additions & 6 deletions python/core/auto_generated/symbology/qgssymbollayerutils.sip.in
Expand Up @@ -815,15 +815,18 @@ Converts a set of symbol layer id to a set of pointers to actual symbol layers c
.. versionadded:: 3.12
%End

static bool restrictSymbolSize( double &size, double minSize, double maxSize );
static QgsSymbol *restrictedSizeSymbol( const QgsSymbol *s, double minSize, double maxSize, QgsRenderContext *context, double &width, double &height );
%Docstring
Restricts size value to min/max size
Creates a new symbol with size restricted to min/max size if original size is out of min/max range

:param size: value will be set so minSize if below minimum or to maxSize if above minimum
:param minSize: the minimum symbolSize
:param maxSize: the maximum symbol size
:param s: the original symbol
:param minSize: the minimum size in mm
:param maxSize: the maximum size in mm
:param context: the render context
:param width: expected width, can be changed by the function
:param height: expected height, can be changed by this function

:return: true if size value has been changed
:return: 0 if size is within minSize/maxSize range. New symbol if size was out of min/max range. Caller takes ownership
%End
};

Expand Down
36 changes: 6 additions & 30 deletions src/core/layertree/qgslayertreemodellegendnode.cpp
Expand Up @@ -560,23 +560,14 @@ QSizeF QgsSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemC
double maxSymbolSize = settings.maxSymbolSize();
double minSymbolSize = settings.minSymbolSize();

std::unique_ptr<QgsMarkerSymbol> minMaxSizeMarkerSymbol;
if ( QgsMarkerSymbol *markerSymbol = dynamic_cast<QgsMarkerSymbol *>( s ) )
std::unique_ptr<QgsSymbol> minMaxSizeSymbol( QgsSymbolLayerUtils::restrictedSizeSymbol( s, minSymbolSize, maxSymbolSize, context, width, height ) );
if ( minMaxSizeSymbol )
{
// allow marker symbol to occupy bigger area if necessary
double size = markerSymbol->size( *context ) / context->scaleFactor();

//If marker size exceeds max marker size, clone symbol and set max size in mm
if ( QgsSymbolLayerUtils::restrictSymbolSize( size, minSymbolSize, maxSymbolSize ) )
{
minMaxSizeMarkerSymbol.reset( dynamic_cast<QgsMarkerSymbol *>( s->clone() ) );
minMaxSizeMarkerSymbol->setSize( size );
minMaxSizeMarkerSymbol->setSizeUnit( QgsUnitTypes::RenderMillimeters );
s = minMaxSizeMarkerSymbol.get();
}
s = minMaxSizeSymbol.get();
}

height = size;
width = size;
if ( s->type() == QgsSymbol::Marker )
{
if ( width < desiredWidth )
{
widthOffset = ( desiredWidth - width ) / 2.0;
Expand All @@ -586,21 +577,6 @@ QSizeF QgsSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemC
heightOffset = ( desiredHeight - height ) / 2.0;
}
}

std::unique_ptr<QgsLineSymbol> minMaxSizeLineSymbol;
if ( QgsLineSymbol *lineSymbol = dynamic_cast<QgsLineSymbol *>( s ) )
{
double width = lineSymbol->width( *context ) / context->scaleFactor();
if ( QgsSymbolLayerUtils::restrictSymbolSize( width, minSymbolSize, maxSymbolSize ) )
{
minMaxSizeLineSymbol.reset( dynamic_cast<QgsLineSymbol *>( s->clone() ) );
minMaxSizeLineSymbol->setWidth( width );
minMaxSizeLineSymbol->setWidthUnit( QgsUnitTypes::RenderMillimeters );
s = minMaxSizeLineSymbol.get();
height = width;
}
}

if ( ctx && ctx->painter )
{
double currentYCoord = ctx->top + ( itemHeight - desiredHeight ) / 2;
Expand Down
54 changes: 48 additions & 6 deletions src/core/symbology/qgssymbollayerutils.cpp
Expand Up @@ -4474,17 +4474,59 @@ QSet<const QgsSymbolLayer *> QgsSymbolLayerUtils::toSymbolLayerPointers( QgsFeat
return visitor.mSymbolLayers;
}

bool QgsSymbolLayerUtils::restrictSymbolSize( double &size, double minSize, double maxSize )
QgsSymbol *QgsSymbolLayerUtils::restrictedSizeSymbol( const QgsSymbol *s, double minSize, double maxSize, QgsRenderContext *context, double &width, double &height )
{
if ( size < minSize )
if ( !s || !context )
{
return 0;
}

double size;
const QgsMarkerSymbol *markerSymbol = dynamic_cast<const QgsMarkerSymbol *>( s );
const QgsLineSymbol *lineSymbol = dynamic_cast<const QgsLineSymbol *>( s );
if ( markerSymbol )
{
size = markerSymbol->size( *context );
}
else if ( lineSymbol )
{
size = lineSymbol->width( *context );
}
else
{
return 0; //not size restriction implemented for other symbol types
}

size /= context->scaleFactor();

if ( minSize > 0 && size < minSize )
{
size = minSize;
return true;
}
if ( size > maxSize )
else if ( maxSize > 0 && size > maxSize )
{
size = maxSize;
return true;
}
return false;
else
{
return 0;
}

if ( markerSymbol )
{
QgsMarkerSymbol *ms = dynamic_cast<QgsMarkerSymbol *>( s->clone() );
ms->setSize( size );
ms->setSizeUnit( QgsUnitTypes::RenderMillimeters );
width = size;
height = size;
return ms;
}
else if ( lineSymbol )
{
QgsLineSymbol *ls = dynamic_cast<QgsLineSymbol *>( s->clone() );
ls->setWidth( size );
ls->setWidthUnit( QgsUnitTypes::RenderMillimeters );
height = size;
return ls;
}
}
17 changes: 10 additions & 7 deletions src/core/symbology/qgssymbollayerutils.h
Expand Up @@ -730,13 +730,16 @@ class CORE_EXPORT QgsSymbolLayerUtils
static QSet<const QgsSymbolLayer *> toSymbolLayerPointers( QgsFeatureRenderer *renderer, const QSet<QgsSymbolLayerId> &symbolLayerIds );

/**
* \brief Restricts size value to min/max size
* \param size value will be set so minSize if below minimum or to maxSize if above minimum
* \param minSize the minimum symbolSize
* \param maxSize the maximum symbol size
* \return true if size value has been changed
*/
static bool restrictSymbolSize( double &size, double minSize, double maxSize );
* \brief Creates a new symbol with size restricted to min/max size if original size is out of min/max range
* \param s the original symbol
* \param minSize the minimum size in mm
* \param maxSize the maximum size in mm
* \param context the render context
* \param width expected width, can be changed by the function
* \param height expected height, can be changed by this function
* \return 0 if size is within minSize/maxSize range. New symbol if size was out of min/max range. Caller takes ownership
*/
static QgsSymbol *restrictedSizeSymbol( const QgsSymbol *s, double minSize, double maxSize, QgsRenderContext *context, double &width, double &height );
};

class QPolygonF;
Expand Down

0 comments on commit c399f08

Please sign in to comment.