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

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :   qgs25drenderer.cpp - qgs25drenderer
       3                 :            :   -----------------------------------
       4                 :            : 
       5                 :            :  begin                : 14.1.2016
       6                 :            :  Copyright            : (C) 2016 Matthias Kuhn
       7                 :            :  Email                : matthias at opengis dot ch
       8                 :            :  ***************************************************************************
       9                 :            :  *                                                                         *
      10                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      11                 :            :  *   it under the terms of the GNU General Public License as published by  *
      12                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      13                 :            :  *   (at your option) any later version.                                   *
      14                 :            :  *                                                                         *
      15                 :            :  ***************************************************************************/
      16                 :            : #include "qgs25drenderer.h"
      17                 :            : #include "qgsgeometrygeneratorsymbollayer.h"
      18                 :            : #include "qgsfillsymbollayer.h"
      19                 :            : #include "qgspainteffect.h"
      20                 :            : #include "qgseffectstack.h"
      21                 :            : #include "qgsgloweffect.h"
      22                 :            : #include "qgsproperty.h"
      23                 :            : #include "qgssymbollayerutils.h"
      24                 :            : #include "qgsdatadefinedsizelegend.h"
      25                 :            : #include "qgsstyleentityvisitor.h"
      26                 :            : 
      27                 :            : #define ROOF_EXPRESSION \
      28                 :            :   "translate(" \
      29                 :            :   "  $geometry," \
      30                 :            :   "  cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
      31                 :            :   "  sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
      32                 :            :   ")"
      33                 :            : 
      34                 :            : #define WALL_EXPRESSION \
      35                 :            :   "order_parts( "\
      36                 :            :   "  extrude(" \
      37                 :            :   "    segments_to_lines( $geometry )," \
      38                 :            :   "    cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
      39                 :            :   "    sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
      40                 :            :   "  )," \
      41                 :            :   "  'distance(  $geometry,  translate(    @map_extent_center,    1000 * @map_extent_width * cos( radians( @qgis_25d_angle + 180 ) ),    1000 * @map_extent_width * sin( radians( @qgis_25d_angle + 180 ) )  ))'," \
      42                 :            :   "  False" \
      43                 :            :   ")"
      44                 :            : 
      45                 :            : #define ORDER_BY_EXPRESSION \
      46                 :            :   "distance(" \
      47                 :            :   "  $geometry," \
      48                 :            :   "  translate(" \
      49                 :            :   "    @map_extent_center," \
      50                 :            :   "    1000 * @map_extent_width * cos( radians( @qgis_25d_angle + 180 ) )," \
      51                 :            :   "    1000 * @map_extent_width * sin( radians( @qgis_25d_angle + 180 ) )" \
      52                 :            :   "  )" \
      53                 :            :   ")"
      54                 :            : 
      55                 :            : #define WALL_SHADING_EXPRESSION \
      56                 :            :   "set_color_part( " \
      57                 :            :   "  @symbol_color," \
      58                 :            :   " 'value'," \
      59                 :            :   "  40 + 19 * abs( $pi - azimuth( " \
      60                 :            :   "    point_n( geometry_n($geometry, @geometry_part_num) , 1 ), " \
      61                 :            :   "    point_n( geometry_n($geometry, @geometry_part_num) , 2 )" \
      62                 :            :   "  ) ) " \
      63                 :            :   ")"
      64                 :            : 
      65                 :          0 : Qgs25DRenderer::Qgs25DRenderer()
      66                 :          0 :   : QgsFeatureRenderer( QStringLiteral( "25dRenderer" ) )
      67                 :          0 : {
      68                 :          0 :   mSymbol.reset( new QgsFillSymbol() );
      69                 :            : 
      70                 :          0 :   mSymbol->deleteSymbolLayer( 0 ); // We never asked for the default layer
      71                 :            : 
      72                 :          0 :   QgsSymbolLayer *floor = QgsSimpleFillSymbolLayer::create();
      73                 :            : 
      74                 :          0 :   QVariantMap wallProperties;
      75                 :          0 :   wallProperties.insert( QStringLiteral( "geometryModifier" ), WALL_EXPRESSION );
      76                 :          0 :   wallProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
      77                 :          0 :   QgsSymbolLayer *walls = QgsGeometryGeneratorSymbolLayer::create( wallProperties );
      78                 :            : 
      79                 :          0 :   QVariantMap roofProperties;
      80                 :          0 :   roofProperties.insert( QStringLiteral( "geometryModifier" ), ROOF_EXPRESSION );
      81                 :          0 :   roofProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
      82                 :          0 :   QgsSymbolLayer *roof = QgsGeometryGeneratorSymbolLayer::create( roofProperties );
      83                 :            : 
      84                 :          0 :   floor->setLocked( true );
      85                 :            : 
      86                 :          0 :   mSymbol->appendSymbolLayer( floor );
      87                 :          0 :   mSymbol->appendSymbolLayer( walls );
      88                 :          0 :   mSymbol->appendSymbolLayer( roof );
      89                 :            : 
      90                 :          0 :   QgsEffectStack *effectStack = new QgsEffectStack();
      91                 :          0 :   QgsOuterGlowEffect *glowEffect = new QgsOuterGlowEffect();
      92                 :          0 :   glowEffect->setBlurLevel( 5 );
      93                 :          0 :   glowEffect->setSpreadUnit( QgsUnitTypes::RenderMapUnits );
      94                 :          0 :   effectStack->appendEffect( glowEffect );
      95                 :          0 :   floor->setPaintEffect( effectStack );
      96                 :            : 
      97                 :            :   // These methods must only be used after the above initialization!
      98                 :            : 
      99                 :          0 :   setRoofColor( QColor( 177, 169, 124 ) );
     100                 :          0 :   setWallColor( QColor( 119, 119, 119 ) );
     101                 :            : 
     102                 :          0 :   wallLayer()->setDataDefinedProperty( QgsSymbolLayer::PropertyFillColor, QgsProperty::fromExpression( QString( WALL_SHADING_EXPRESSION ) ) );
     103                 :            : 
     104                 :          0 :   setShadowSpread( 4 );
     105                 :          0 :   setShadowColor( QColor( 17, 17, 17 ) );
     106                 :            : 
     107                 :          0 :   QgsFeatureRequest::OrderBy orderBy;
     108                 :          0 :   orderBy << QgsFeatureRequest::OrderByClause(
     109                 :          0 :             ORDER_BY_EXPRESSION,
     110                 :            :             false );
     111                 :            : 
     112                 :          0 :   setOrderBy( orderBy );
     113                 :          0 :   setOrderByEnabled( true );
     114                 :          0 : }
     115                 :            : 
     116                 :          0 : QDomElement Qgs25DRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
     117                 :            : {
     118                 :          0 :   QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
     119                 :            : 
     120                 :          0 :   rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "25dRenderer" ) );
     121                 :            : 
     122                 :          0 :   QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), mSymbol.get(), doc, context );
     123                 :            : 
     124                 :          0 :   rendererElem.appendChild( symbolElem );
     125                 :            : 
     126                 :          0 :   return rendererElem;
     127                 :          0 : }
     128                 :            : 
     129                 :          0 : QgsFeatureRenderer *Qgs25DRenderer::create( QDomElement &element, const QgsReadWriteContext &context )
     130                 :            : {
     131                 :          0 :   Qgs25DRenderer *renderer = new Qgs25DRenderer();
     132                 :            : 
     133                 :          0 :   QDomNodeList symbols = element.elementsByTagName( QStringLiteral( "symbol" ) );
     134                 :          0 :   if ( symbols.size() )
     135                 :            :   {
     136                 :          0 :     renderer->mSymbol.reset( QgsSymbolLayerUtils::loadSymbol( symbols.at( 0 ).toElement(), context ) );
     137                 :          0 :   }
     138                 :            : 
     139                 :          0 :   return renderer;
     140                 :          0 : }
     141                 :            : 
     142                 :          0 : void Qgs25DRenderer::startRender( QgsRenderContext &context, const QgsFields &fields )
     143                 :            : {
     144                 :          0 :   QgsFeatureRenderer::startRender( context, fields );
     145                 :            : 
     146                 :          0 :   mSymbol->startRender( context, fields );
     147                 :          0 : }
     148                 :            : 
     149                 :          0 : void Qgs25DRenderer::stopRender( QgsRenderContext &context )
     150                 :            : {
     151                 :          0 :   QgsFeatureRenderer::stopRender( context );
     152                 :            : 
     153                 :          0 :   mSymbol->stopRender( context );
     154                 :          0 : }
     155                 :            : 
     156                 :          0 : QSet<QString> Qgs25DRenderer::usedAttributes( const QgsRenderContext &context ) const
     157                 :            : {
     158                 :          0 :   return mSymbol->usedAttributes( context );
     159                 :            : }
     160                 :            : 
     161                 :          0 : QgsFeatureRenderer *Qgs25DRenderer::clone() const
     162                 :            : {
     163                 :          0 :   Qgs25DRenderer *c = new Qgs25DRenderer();
     164                 :          0 :   c->mSymbol.reset( mSymbol->clone() );
     165                 :          0 :   return c;
     166                 :          0 : }
     167                 :            : 
     168                 :          0 : QgsSymbol *Qgs25DRenderer::symbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const
     169                 :            : {
     170                 :          0 :   Q_UNUSED( feature )
     171                 :          0 :   Q_UNUSED( context )
     172                 :          0 :   return mSymbol.get();
     173                 :            : }
     174                 :            : 
     175                 :          0 : QgsSymbolList Qgs25DRenderer::symbols( QgsRenderContext &context ) const
     176                 :            : {
     177                 :          0 :   Q_UNUSED( context )
     178                 :          0 :   QgsSymbolList lst;
     179                 :          0 :   lst.append( mSymbol.get() );
     180                 :          0 :   return lst;
     181                 :          0 : }
     182                 :            : 
     183                 :          0 : bool Qgs25DRenderer::accept( QgsStyleEntityVisitorInterface *visitor ) const
     184                 :            : {
     185                 :          0 :   if ( mSymbol )
     186                 :            :   {
     187                 :          0 :     QgsStyleSymbolEntity entity( mSymbol.get() );
     188                 :          0 :     return visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) );
     189                 :          0 :   }
     190                 :          0 :   return true;
     191                 :          0 : }
     192                 :            : 
     193                 :          0 : QgsFillSymbolLayer *Qgs25DRenderer::roofLayer() const
     194                 :            : {
     195                 :          0 :   return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 2 )->subSymbol()->symbolLayer( 0 ) );
     196                 :            : }
     197                 :            : 
     198                 :          0 : QgsFillSymbolLayer *Qgs25DRenderer::wallLayer() const
     199                 :            : {
     200                 :          0 :   return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 1 )->subSymbol()->symbolLayer( 0 ) );
     201                 :            : }
     202                 :            : 
     203                 :          0 : QgsOuterGlowEffect *Qgs25DRenderer::glowEffect() const
     204                 :            : {
     205                 :          0 :   QgsEffectStack *stack = static_cast<QgsEffectStack *>( mSymbol->symbolLayer( 0 )->paintEffect() );
     206                 :          0 :   return static_cast<QgsOuterGlowEffect *>( stack->effect( 0 ) );
     207                 :            : }
     208                 :            : 
     209                 :          0 : bool Qgs25DRenderer::shadowEnabled() const
     210                 :            : {
     211                 :          0 :   return glowEffect()->enabled();
     212                 :            : }
     213                 :            : 
     214                 :          0 : void Qgs25DRenderer::setShadowEnabled( bool value )
     215                 :            : {
     216                 :          0 :   glowEffect()->setEnabled( value );
     217                 :          0 : }
     218                 :            : 
     219                 :          0 : QColor Qgs25DRenderer::shadowColor() const
     220                 :            : {
     221                 :          0 :   return glowEffect()->color();
     222                 :            : }
     223                 :            : 
     224                 :          0 : void Qgs25DRenderer::setShadowColor( const QColor &shadowColor )
     225                 :            : {
     226                 :          0 :   glowEffect()->setColor( shadowColor );
     227                 :          0 : }
     228                 :            : 
     229                 :          0 : double Qgs25DRenderer::shadowSpread() const
     230                 :            : {
     231                 :          0 :   return glowEffect()->spread();
     232                 :            : }
     233                 :            : 
     234                 :          0 : void Qgs25DRenderer::setShadowSpread( double spread )
     235                 :            : {
     236                 :          0 :   glowEffect()->setSpread( spread );
     237                 :          0 : }
     238                 :            : 
     239                 :          0 : QColor Qgs25DRenderer::wallColor() const
     240                 :            : {
     241                 :          0 :   return wallLayer()->fillColor();
     242                 :            : }
     243                 :            : 
     244                 :          0 : void Qgs25DRenderer::setWallColor( const QColor &wallColor )
     245                 :            : {
     246                 :          0 :   wallLayer()->setFillColor( wallColor );
     247                 :          0 :   wallLayer()->setStrokeColor( wallColor );
     248                 :          0 : }
     249                 :            : 
     250                 :          0 : void Qgs25DRenderer::setWallShadingEnabled( bool enabled )
     251                 :            : {
     252                 :          0 :   wallLayer()->dataDefinedProperties().property( QgsSymbolLayer::PropertyFillColor ).setActive( enabled );
     253                 :          0 : }
     254                 :            : 
     255                 :          0 : bool Qgs25DRenderer::wallShadingEnabled() const
     256                 :            : {
     257                 :          0 :   return wallLayer()->dataDefinedProperties().property( QgsSymbolLayer::PropertyFillColor ).isActive();
     258                 :            : }
     259                 :            : 
     260                 :          0 : QColor Qgs25DRenderer::roofColor() const
     261                 :            : {
     262                 :          0 :   return roofLayer()->fillColor();
     263                 :            : }
     264                 :            : 
     265                 :          0 : void Qgs25DRenderer::setRoofColor( const QColor &roofColor )
     266                 :            : {
     267                 :          0 :   roofLayer()->setFillColor( roofColor );
     268                 :          0 :   roofLayer()->setStrokeColor( roofColor );
     269                 :          0 : }
     270                 :            : 
     271                 :          0 : Qgs25DRenderer *Qgs25DRenderer::convertFromRenderer( QgsFeatureRenderer *renderer )
     272                 :            : {
     273                 :          0 :   if ( renderer->type() == QLatin1String( "25dRenderer" ) )
     274                 :            :   {
     275                 :          0 :     return static_cast<Qgs25DRenderer *>( renderer->clone() );
     276                 :            :   }
     277                 :            :   else
     278                 :            :   {
     279                 :          0 :     return new Qgs25DRenderer();
     280                 :            :   }
     281                 :          0 : }
     282                 :            : 

Generated by: LCOV version 1.14