LCOV - code coverage report
Current view: top level - core/symbology - qgspointclusterrenderer.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 135 0.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                               qgspointclusterrenderer.cpp
       3                 :            :                               ---------------------------
       4                 :            :   begin                : February 2016
       5                 :            :   copyright            : (C) 2016 by Nyall Dawson
       6                 :            :   email                : nyall dot dawson at gmail dot com
       7                 :            :  ***************************************************************************/
       8                 :            : 
       9                 :            : /***************************************************************************
      10                 :            :  *                                                                         *
      11                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      12                 :            :  *   it under the terms of the GNU General Public License as published by  *
      13                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      14                 :            :  *   (at your option) any later version.                                   *
      15                 :            :  *                                                                         *
      16                 :            :  ***************************************************************************/
      17                 :            : 
      18                 :            : #include "qgspointclusterrenderer.h"
      19                 :            : #include "qgspointdisplacementrenderer.h"
      20                 :            : #include "qgssymbollayerutils.h"
      21                 :            : #include "qgspainteffectregistry.h"
      22                 :            : #include "qgspainteffect.h"
      23                 :            : #include "qgsmarkersymbollayer.h"
      24                 :            : #include "qgsproperty.h"
      25                 :            : #include "qgsstyleentityvisitor.h"
      26                 :            : #include <cmath>
      27                 :            : 
      28                 :          0 : QgsPointClusterRenderer::QgsPointClusterRenderer()
      29                 :          0 :   : QgsPointDistanceRenderer( QStringLiteral( "pointCluster" ) )
      30                 :          0 : {
      31                 :          0 :   mClusterSymbol.reset( new QgsMarkerSymbol() );
      32                 :          0 :   mClusterSymbol->setSize( 4 );
      33                 :          0 :   mClusterSymbol->setColor( QColor( 245, 75, 80 ) );
      34                 :            : 
      35                 :          0 :   QgsFontMarkerSymbolLayer *fm = new QgsFontMarkerSymbolLayer();
      36                 :          0 :   fm->setFontFamily( QFont().defaultFamily() );
      37                 :          0 :   fm->setColor( QColor( 255, 255, 255 ) );
      38                 :          0 :   fm->setSize( 3.2 );
      39                 :          0 :   fm->setOffset( QPointF( 0, -0.4 ) );
      40                 :          0 :   fm->setDataDefinedProperty( QgsSymbolLayer::PropertyCharacter, QgsProperty::fromExpression( QStringLiteral( "@cluster_size" ) ) );
      41                 :          0 :   mClusterSymbol->insertSymbolLayer( 1, fm );
      42                 :          0 : }
      43                 :            : 
      44                 :          0 : QgsPointClusterRenderer *QgsPointClusterRenderer::clone() const
      45                 :            : {
      46                 :          0 :   QgsPointClusterRenderer *r = new QgsPointClusterRenderer();
      47                 :          0 :   if ( mRenderer )
      48                 :          0 :     r->setEmbeddedRenderer( mRenderer->clone() );
      49                 :          0 :   r->setLabelFont( mLabelFont );
      50                 :          0 :   r->setLabelColor( mLabelColor );
      51                 :          0 :   r->setMinimumLabelScale( mMinLabelScale );
      52                 :          0 :   r->setTolerance( mTolerance );
      53                 :          0 :   r->setToleranceUnit( mToleranceUnit );
      54                 :          0 :   r->setToleranceMapUnitScale( mToleranceMapUnitScale );
      55                 :          0 :   if ( mClusterSymbol )
      56                 :            :   {
      57                 :          0 :     r->setClusterSymbol( mClusterSymbol->clone() );
      58                 :          0 :   }
      59                 :          0 :   copyRendererData( r );
      60                 :          0 :   return r;
      61                 :          0 : }
      62                 :            : 
      63                 :          0 : void QgsPointClusterRenderer::drawGroup( QPointF centerPoint, QgsRenderContext &context, const ClusteredGroup &group )
      64                 :            : {
      65                 :          0 :   if ( group.size() > 1 )
      66                 :            :   {
      67                 :          0 :     mClusterSymbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, false );
      68                 :          0 :   }
      69                 :            :   else
      70                 :            :   {
      71                 :            :     //single isolated symbol, draw it untouched
      72                 :          0 :     QgsMarkerSymbol *symbol = group.at( 0 ).symbol();
      73                 :          0 :     symbol->startRender( context );
      74                 :          0 :     symbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, group.at( 0 ).isSelected );
      75                 :          0 :     symbol->stopRender( context );
      76                 :            :   }
      77                 :          0 : }
      78                 :            : 
      79                 :          0 : void QgsPointClusterRenderer::startRender( QgsRenderContext &context, const QgsFields &fields )
      80                 :            : {
      81                 :          0 :   if ( mClusterSymbol )
      82                 :            :   {
      83                 :          0 :     mClusterSymbol->startRender( context, fields );
      84                 :          0 :   }
      85                 :          0 :   QgsPointDistanceRenderer::startRender( context, fields );
      86                 :          0 : }
      87                 :            : 
      88                 :          0 : void QgsPointClusterRenderer::stopRender( QgsRenderContext &context )
      89                 :            : {
      90                 :          0 :   QgsPointDistanceRenderer::stopRender( context );
      91                 :          0 :   if ( mClusterSymbol )
      92                 :            :   {
      93                 :          0 :     mClusterSymbol->stopRender( context );
      94                 :          0 :   }
      95                 :          0 : }
      96                 :            : 
      97                 :          0 : QgsFeatureRenderer *QgsPointClusterRenderer::create( QDomElement &symbologyElem, const QgsReadWriteContext &context )
      98                 :            : {
      99                 :          0 :   QgsPointClusterRenderer *r = new QgsPointClusterRenderer();
     100                 :          0 :   r->setTolerance( symbologyElem.attribute( QStringLiteral( "tolerance" ), QStringLiteral( "0.00001" ) ).toDouble() );
     101                 :          0 :   r->setToleranceUnit( QgsUnitTypes::decodeRenderUnit( symbologyElem.attribute( QStringLiteral( "toleranceUnit" ), QStringLiteral( "MapUnit" ) ) ) );
     102                 :          0 :   r->setToleranceMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( symbologyElem.attribute( QStringLiteral( "toleranceUnitScale" ) ) ) );
     103                 :            : 
     104                 :            :   //look for an embedded renderer <renderer-v2>
     105                 :          0 :   QDomElement embeddedRendererElem = symbologyElem.firstChildElement( QStringLiteral( "renderer-v2" ) );
     106                 :          0 :   if ( !embeddedRendererElem.isNull() )
     107                 :            :   {
     108                 :          0 :     r->setEmbeddedRenderer( QgsFeatureRenderer::load( embeddedRendererElem, context ) );
     109                 :          0 :   }
     110                 :            : 
     111                 :            :   //center symbol
     112                 :          0 :   QDomElement centerSymbolElem = symbologyElem.firstChildElement( QStringLiteral( "symbol" ) );
     113                 :          0 :   if ( !centerSymbolElem.isNull() )
     114                 :            :   {
     115                 :          0 :     r->setClusterSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( centerSymbolElem, context ) );
     116                 :          0 :   }
     117                 :          0 :   return r;
     118                 :          0 : }
     119                 :            : 
     120                 :          0 : QgsMarkerSymbol *QgsPointClusterRenderer::clusterSymbol()
     121                 :            : {
     122                 :          0 :   return mClusterSymbol.get();
     123                 :            : }
     124                 :            : 
     125                 :          0 : QDomElement QgsPointClusterRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
     126                 :            : {
     127                 :          0 :   QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
     128                 :          0 :   rendererElement.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
     129                 :          0 :   rendererElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "pointCluster" ) );
     130                 :          0 :   rendererElement.setAttribute( QStringLiteral( "tolerance" ), QString::number( mTolerance ) );
     131                 :          0 :   rendererElement.setAttribute( QStringLiteral( "toleranceUnit" ), QgsUnitTypes::encodeUnit( mToleranceUnit ) );
     132                 :          0 :   rendererElement.setAttribute( QStringLiteral( "toleranceUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mToleranceMapUnitScale ) );
     133                 :            : 
     134                 :          0 :   if ( mRenderer )
     135                 :            :   {
     136                 :          0 :     QDomElement embeddedRendererElem = mRenderer->save( doc, context );
     137                 :          0 :     rendererElement.appendChild( embeddedRendererElem );
     138                 :          0 :   }
     139                 :          0 :   if ( mClusterSymbol )
     140                 :            :   {
     141                 :          0 :     QDomElement centerSymbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "centerSymbol" ), mClusterSymbol.get(), doc, context );
     142                 :          0 :     rendererElement.appendChild( centerSymbolElem );
     143                 :          0 :   }
     144                 :            : 
     145                 :          0 :   if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
     146                 :          0 :     mPaintEffect->saveProperties( doc, rendererElement );
     147                 :            : 
     148                 :          0 :   if ( !mOrderBy.isEmpty() )
     149                 :            :   {
     150                 :          0 :     QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
     151                 :          0 :     mOrderBy.save( orderBy );
     152                 :          0 :     rendererElement.appendChild( orderBy );
     153                 :          0 :   }
     154                 :          0 :   rendererElement.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
     155                 :            : 
     156                 :          0 :   return rendererElement;
     157                 :          0 : }
     158                 :            : 
     159                 :          0 : QSet<QString> QgsPointClusterRenderer::usedAttributes( const QgsRenderContext &context ) const
     160                 :            : {
     161                 :          0 :   QSet<QString> attr = QgsPointDistanceRenderer::usedAttributes( context );
     162                 :          0 :   if ( mClusterSymbol )
     163                 :          0 :     attr.unite( mClusterSymbol->usedAttributes( context ) );
     164                 :          0 :   return attr;
     165                 :          0 : }
     166                 :            : 
     167                 :          0 : bool QgsPointClusterRenderer::accept( QgsStyleEntityVisitorInterface *visitor ) const
     168                 :            : {
     169                 :          0 :   if ( !QgsPointDistanceRenderer::accept( visitor ) )
     170                 :          0 :     return false;
     171                 :            : 
     172                 :          0 :   if ( mClusterSymbol )
     173                 :            :   {
     174                 :          0 :     QgsStyleSymbolEntity entity( mClusterSymbol.get() );
     175                 :          0 :     if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, QStringLiteral( "cluster" ), QObject::tr( "Cluster Symbol" ) ) ) )
     176                 :          0 :       return false;
     177                 :          0 :   }
     178                 :            : 
     179                 :          0 :   return true;
     180                 :          0 : }
     181                 :            : 
     182                 :          0 : void QgsPointClusterRenderer::setClusterSymbol( QgsMarkerSymbol *symbol )
     183                 :            : {
     184                 :          0 :   mClusterSymbol.reset( symbol );
     185                 :          0 : }
     186                 :            : 
     187                 :          0 : QgsPointClusterRenderer *QgsPointClusterRenderer::convertFromRenderer( const QgsFeatureRenderer *renderer )
     188                 :            : {
     189                 :          0 :   if ( renderer->type() == QLatin1String( "pointCluster" ) )
     190                 :            :   {
     191                 :          0 :     return dynamic_cast<QgsPointClusterRenderer *>( renderer->clone() );
     192                 :            :   }
     193                 :          0 :   else if ( renderer->type() == QLatin1String( "singleSymbol" ) ||
     194                 :          0 :             renderer->type() == QLatin1String( "categorizedSymbol" ) ||
     195                 :          0 :             renderer->type() == QLatin1String( "graduatedSymbol" ) ||
     196                 :          0 :             renderer->type() == QLatin1String( "RuleRenderer" ) )
     197                 :            :   {
     198                 :          0 :     QgsPointClusterRenderer *pointRenderer = new QgsPointClusterRenderer();
     199                 :          0 :     pointRenderer->setEmbeddedRenderer( renderer->clone() );
     200                 :          0 :     return pointRenderer;
     201                 :            :   }
     202                 :          0 :   else if ( renderer->type() == QLatin1String( "pointDisplacement" ) )
     203                 :            :   {
     204                 :          0 :     QgsPointClusterRenderer *pointRenderer = new QgsPointClusterRenderer();
     205                 :          0 :     const QgsPointDisplacementRenderer *displacementRenderer = static_cast< const QgsPointDisplacementRenderer * >( renderer );
     206                 :          0 :     if ( displacementRenderer->embeddedRenderer() )
     207                 :          0 :       pointRenderer->setEmbeddedRenderer( displacementRenderer->embeddedRenderer()->clone() );
     208                 :          0 :     pointRenderer->setTolerance( displacementRenderer->tolerance() );
     209                 :          0 :     pointRenderer->setToleranceUnit( displacementRenderer->toleranceUnit() );
     210                 :          0 :     pointRenderer->setToleranceMapUnitScale( displacementRenderer->toleranceMapUnitScale() );
     211                 :          0 :     if ( const_cast< QgsPointDisplacementRenderer * >( displacementRenderer )->centerSymbol() )
     212                 :          0 :       pointRenderer->setClusterSymbol( const_cast< QgsPointDisplacementRenderer * >( displacementRenderer )->centerSymbol()->clone() );
     213                 :          0 :     return pointRenderer;
     214                 :            :   }
     215                 :            :   else
     216                 :            :   {
     217                 :          0 :     return nullptr;
     218                 :            :   }
     219                 :          0 : }

Generated by: LCOV version 1.14