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

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                          qgslayoutitemmapoverview.cpp
       3                 :            :                          --------------------
       4                 :            :     begin                : October 2017
       5                 :            :     copyright            : (C) 2017 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 "qgslayoutitemmapoverview.h"
      19                 :            : #include "qgslayoutitemmap.h"
      20                 :            : #include "qgslayout.h"
      21                 :            : #include "qgssymbollayerutils.h"
      22                 :            : #include "qgssymbol.h"
      23                 :            : #include "qgsmapsettings.h"
      24                 :            : #include "qgspainting.h"
      25                 :            : #include "qgspathresolver.h"
      26                 :            : #include "qgsreadwritecontext.h"
      27                 :            : #include "qgslayoututils.h"
      28                 :            : #include "qgsexception.h"
      29                 :            : #include "qgsvectorlayer.h"
      30                 :            : #include "qgssinglesymbolrenderer.h"
      31                 :            : #include "qgsstyleentityvisitor.h"
      32                 :            : 
      33                 :            : #include <QPainter>
      34                 :            : 
      35                 :          0 : QgsLayoutItemMapOverview::QgsLayoutItemMapOverview( const QString &name, QgsLayoutItemMap *map )
      36                 :          0 :   : QgsLayoutItemMapItem( name, map )
      37                 :          0 :   , mExtentLayer( std::make_unique< QgsVectorLayer >( QStringLiteral( "Polygon?crs=EPSG:4326" ), tr( "Overview" ), QStringLiteral( "memory" ), QgsVectorLayer::LayerOptions( map && map->layout() && map->layout()->project() ? map->layout()->project()->transformContext() : QgsCoordinateTransformContext() ) ) )
      38                 :          0 : {
      39                 :          0 :   createDefaultFrameSymbol();
      40                 :          0 : }
      41                 :            : 
      42                 :          0 : QgsLayoutItemMapOverview::~QgsLayoutItemMapOverview() = default;
      43                 :            : 
      44                 :          0 : void QgsLayoutItemMapOverview::createDefaultFrameSymbol()
      45                 :            : {
      46                 :          0 :   QVariantMap properties;
      47                 :          0 :   properties.insert( QStringLiteral( "color" ), QStringLiteral( "255,0,0,75" ) );
      48                 :          0 :   properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
      49                 :          0 :   properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "no" ) );
      50                 :          0 :   mFrameSymbol.reset( QgsFillSymbol::createSimple( properties ) );
      51                 :            : 
      52                 :          0 :   mExtentLayer->setRenderer( new QgsSingleSymbolRenderer( mFrameSymbol->clone() ) );
      53                 :          0 : }
      54                 :            : 
      55                 :          0 : void QgsLayoutItemMapOverview::draw( QPainter *painter )
      56                 :            : {
      57                 :          0 :   if ( !mEnabled || !mFrameMap || !mMap || !mMap->layout() )
      58                 :            :   {
      59                 :          0 :     return;
      60                 :            :   }
      61                 :          0 :   if ( !painter )
      62                 :            :   {
      63                 :          0 :     return;
      64                 :            :   }
      65                 :            : 
      66                 :          0 :   const QgsLayoutItemMap *overviewFrameMap = linkedMap();
      67                 :          0 :   if ( !overviewFrameMap )
      68                 :            :   {
      69                 :          0 :     return;
      70                 :            :   }
      71                 :            : 
      72                 :            :   //get polygon for other overview frame map's extent (use visibleExtentPolygon as it accounts for map rotation)
      73                 :          0 :   QPolygonF otherExtent = overviewFrameMap->visibleExtentPolygon();
      74                 :          0 :   if ( overviewFrameMap->crs() !=
      75                 :          0 :        mMap->crs() )
      76                 :            :   {
      77                 :          0 :     QgsGeometry g = QgsGeometry::fromQPolygonF( otherExtent );
      78                 :            : 
      79                 :            :     // reproject extent
      80                 :          0 :     QgsCoordinateTransform ct( overviewFrameMap->crs(),
      81                 :          0 :                                mMap->crs(), mLayout->project() );
      82                 :          0 :     g = g.densifyByCount( 20 );
      83                 :            :     try
      84                 :            :     {
      85                 :          0 :       g.transform( ct );
      86                 :          0 :     }
      87                 :            :     catch ( QgsCsException & )
      88                 :            :     {
      89                 :          0 :     }
      90                 :            : 
      91                 :          0 :     otherExtent = g.asQPolygonF();
      92                 :          0 :   }
      93                 :            : 
      94                 :            :   //get current map's extent as a QPolygonF
      95                 :          0 :   QPolygonF thisExtent = mMap->visibleExtentPolygon();
      96                 :            :   //intersect the two
      97                 :          0 :   QPolygonF intersectExtent = thisExtent.intersected( otherExtent );
      98                 :            : 
      99                 :            :   //setup painter scaling to dots so that raster symbology is drawn to scale
     100                 :          0 :   double dotsPerMM = painter->device()->logicalDpiX() / 25.4;
     101                 :            : 
     102                 :            :   //setup render context
     103                 :          0 :   QgsRenderContext context = QgsLayoutUtils::createRenderContextForLayout( mLayout, painter );
     104                 :          0 :   context.setForceVectorOutput( true );
     105                 :          0 :   QgsExpressionContext expressionContext = createExpressionContext();
     106                 :          0 :   context.setExpressionContext( expressionContext );
     107                 :            : 
     108                 :          0 :   QgsScopedQPainterState painterState( painter );
     109                 :          0 :   context.setPainterFlagsUsingContext( painter );
     110                 :            : 
     111                 :          0 :   painter->setCompositionMode( mBlendMode );
     112                 :          0 :   painter->translate( mMap->mXOffset, mMap->mYOffset );
     113                 :          0 :   painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
     114                 :            : 
     115                 :          0 :   mFrameSymbol->startRender( context );
     116                 :            : 
     117                 :            :   //construct a polygon corresponding to the intersecting map extent
     118                 :            :   //need to scale line to dots, rather then mm, since the painter has been scaled to dots
     119                 :          0 :   QTransform mapTransform;
     120                 :          0 :   QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, dotsPerMM * mMap->rect().width(), dotsPerMM * mMap->rect().height() ) );
     121                 :            : 
     122                 :            :   //workaround QT Bug #21329
     123                 :          0 :   thisRectPoly.pop_back();
     124                 :          0 :   thisExtent.pop_back();
     125                 :            : 
     126                 :            :   //create transform from map coordinates to painter coordinates
     127                 :          0 :   QTransform::quadToQuad( thisExtent, thisRectPoly, mapTransform );
     128                 :          0 :   QPolygonF intersectPolygon;
     129                 :          0 :   intersectPolygon = mapTransform.map( intersectExtent );
     130                 :            : 
     131                 :          0 :   QVector<QPolygonF> rings; //empty list
     132                 :          0 :   if ( !mInverted )
     133                 :            :   {
     134                 :            :     //Render the intersecting map extent
     135                 :          0 :     mFrameSymbol->renderPolygon( intersectPolygon, &rings, nullptr, context );
     136                 :          0 :   }
     137                 :            :   else
     138                 :            :   {
     139                 :            :     //We are inverting the overview frame (ie, shading outside the intersecting extent)
     140                 :            :     //Construct a polygon corresponding to the overview map extent
     141                 :          0 :     QPolygonF outerPolygon;
     142                 :          0 :     outerPolygon << QPointF( 0, 0 )
     143                 :          0 :                  << QPointF( mMap->rect().width() * dotsPerMM, 0 )
     144                 :          0 :                  << QPointF( mMap->rect().width() * dotsPerMM, mMap->rect().height() * dotsPerMM )
     145                 :          0 :                  << QPointF( 0, mMap->rect().height() * dotsPerMM )
     146                 :          0 :                  << QPointF( 0, 0 );
     147                 :            : 
     148                 :            :     //Intersecting extent is an inner ring for the shaded area
     149                 :          0 :     rings.append( intersectPolygon );
     150                 :          0 :     mFrameSymbol->renderPolygon( outerPolygon, &rings, nullptr, context );
     151                 :          0 :   }
     152                 :            : 
     153                 :          0 :   mFrameSymbol->stopRender( context );
     154                 :          0 : }
     155                 :            : 
     156                 :          0 : bool QgsLayoutItemMapOverview::writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
     157                 :            : {
     158                 :          0 :   if ( elem.isNull() )
     159                 :            :   {
     160                 :          0 :     return false;
     161                 :            :   }
     162                 :            : 
     163                 :            :   //overview map frame
     164                 :          0 :   QDomElement overviewFrameElem = doc.createElement( QStringLiteral( "ComposerMapOverview" ) );
     165                 :            : 
     166                 :          0 :   overviewFrameElem.setAttribute( QStringLiteral( "frameMap" ), mFrameMap ? mFrameMap ->uuid() : QString() );
     167                 :          0 :   overviewFrameElem.setAttribute( QStringLiteral( "blendMode" ), QgsPainting::getBlendModeEnum( mBlendMode ) );
     168                 :          0 :   overviewFrameElem.setAttribute( QStringLiteral( "inverted" ), mInverted );
     169                 :          0 :   overviewFrameElem.setAttribute( QStringLiteral( "centered" ), mCentered );
     170                 :            : 
     171                 :          0 :   QDomElement frameStyleElem = QgsSymbolLayerUtils::saveSymbol( QString(), mFrameSymbol.get(), doc, context );
     172                 :          0 :   overviewFrameElem.appendChild( frameStyleElem );
     173                 :            : 
     174                 :          0 :   bool ok = QgsLayoutItemMapItem::writeXml( overviewFrameElem, doc, context );
     175                 :          0 :   elem.appendChild( overviewFrameElem );
     176                 :          0 :   return ok;
     177                 :          0 : }
     178                 :            : 
     179                 :          0 : bool QgsLayoutItemMapOverview::readXml( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context )
     180                 :            : {
     181                 :          0 :   Q_UNUSED( doc )
     182                 :          0 :   if ( itemElem.isNull() )
     183                 :            :   {
     184                 :          0 :     return false;
     185                 :            :   }
     186                 :            : 
     187                 :          0 :   bool ok = QgsLayoutItemMapItem::readXml( itemElem, doc, context );
     188                 :            : 
     189                 :          0 :   mFrameMapUuid = itemElem.attribute( QStringLiteral( "frameMap" ) );
     190                 :          0 :   setLinkedMap( nullptr );
     191                 :            : 
     192                 :          0 :   mBlendMode = QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( itemElem.attribute( QStringLiteral( "blendMode" ), QStringLiteral( "0" ) ).toUInt() ) );
     193                 :          0 :   mInverted = ( itemElem.attribute( QStringLiteral( "inverted" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
     194                 :          0 :   mCentered = ( itemElem.attribute( QStringLiteral( "centered" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
     195                 :            : 
     196                 :          0 :   QDomElement frameStyleElem = itemElem.firstChildElement( QStringLiteral( "symbol" ) );
     197                 :          0 :   if ( !frameStyleElem.isNull() )
     198                 :            :   {
     199                 :          0 :     mFrameSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( frameStyleElem, context ) );
     200                 :          0 :   }
     201                 :          0 :   return ok;
     202                 :          0 : }
     203                 :            : 
     204                 :          0 : void QgsLayoutItemMapOverview::finalizeRestoreFromXml()
     205                 :            : {
     206                 :          0 :   if ( !mFrameMapUuid.isEmpty() )
     207                 :            :   {
     208                 :          0 :     setLinkedMap( qobject_cast< QgsLayoutItemMap * >( mLayout->itemByUuid( mFrameMapUuid, true ) ) );
     209                 :          0 :   }
     210                 :          0 : }
     211                 :            : 
     212                 :          0 : bool QgsLayoutItemMapOverview::usesAdvancedEffects() const
     213                 :            : {
     214                 :          0 :   return mBlendMode != QPainter::CompositionMode_SourceOver;
     215                 :            : }
     216                 :            : 
     217                 :          0 : void QgsLayoutItemMapOverview::setLinkedMap( QgsLayoutItemMap *map )
     218                 :            : {
     219                 :          0 :   if ( mFrameMap == map )
     220                 :            :   {
     221                 :            :     //no change
     222                 :          0 :     return;
     223                 :            :   }
     224                 :            : 
     225                 :            :   //disconnect old map
     226                 :          0 :   if ( mFrameMap )
     227                 :            :   {
     228                 :          0 :     disconnect( mFrameMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemMapOverview::overviewExtentChanged );
     229                 :          0 :     disconnect( mFrameMap, &QgsLayoutItemMap::mapRotationChanged, this, &QgsLayoutItemMapOverview::overviewExtentChanged );
     230                 :          0 :   }
     231                 :          0 :   mFrameMap = map;
     232                 :            :   //connect to new map signals
     233                 :          0 :   connectSignals();
     234                 :          0 :   mMap->invalidateCache();
     235                 :          0 : }
     236                 :            : 
     237                 :          0 : QgsLayoutItemMap *QgsLayoutItemMapOverview::linkedMap()
     238                 :            : {
     239                 :          0 :   return mFrameMap;
     240                 :            : }
     241                 :            : 
     242                 :          0 : void QgsLayoutItemMapOverview::connectSignals()
     243                 :            : {
     244                 :          0 :   if ( !mMap )
     245                 :            :   {
     246                 :          0 :     return;
     247                 :            :   }
     248                 :            : 
     249                 :          0 :   if ( mFrameMap )
     250                 :            :   {
     251                 :          0 :     connect( mFrameMap, &QgsLayoutItemMap::extentChanged, this, &QgsLayoutItemMapOverview::overviewExtentChanged );
     252                 :          0 :     connect( mFrameMap, &QgsLayoutItemMap::mapRotationChanged, this, &QgsLayoutItemMapOverview::overviewExtentChanged );
     253                 :          0 :   }
     254                 :          0 : }
     255                 :          0 : 
     256                 :          0 : QgsVectorLayer *QgsLayoutItemMapOverview::asMapLayer()
     257                 :            : {
     258                 :          0 :   if ( !mEnabled || !mFrameMap || !mMap || !mMap->layout() )
     259                 :            :   {
     260                 :          0 :     return nullptr;
     261                 :          0 :   }
     262                 :            : 
     263                 :          0 :   const QgsLayoutItemMap *overviewFrameMap = linkedMap();
     264                 :          0 :   if ( !overviewFrameMap )
     265                 :            :   {
     266                 :          0 :     return nullptr;
     267                 :            :   }
     268                 :            : 
     269                 :            :   //get polygon for other overview frame map's extent (use visibleExtentPolygon as it accounts for map rotation)
     270                 :          0 :   QPolygonF otherExtent = overviewFrameMap->visibleExtentPolygon();
     271                 :          0 :   QgsGeometry g = QgsGeometry::fromQPolygonF( otherExtent );
     272                 :            : 
     273                 :          0 :   if ( overviewFrameMap->crs() != mMap->crs() )
     274                 :            :   {
     275                 :            :     // reproject extent
     276                 :          0 :     QgsCoordinateTransform ct( overviewFrameMap->crs(),
     277                 :          0 :                                mMap->crs(), mLayout->project() );
     278                 :          0 :     g = g.densifyByCount( 20 );
     279                 :            :     try
     280                 :            :     {
     281                 :          0 :       g.transform( ct );
     282                 :          0 :     }
     283                 :            :     catch ( QgsCsException & )
     284                 :            :     {
     285                 :          0 :     }
     286                 :          0 :   }
     287                 :            : 
     288                 :            :   //get current map's extent as a QPolygonF
     289                 :          0 :   QPolygonF thisExtent = mMap->visibleExtentPolygon();
     290                 :          0 :   QgsGeometry thisGeom = QgsGeometry::fromQPolygonF( thisExtent );
     291                 :            :   //intersect the two
     292                 :          0 :   QgsGeometry intersectExtent = thisGeom.intersection( g );
     293                 :            : 
     294                 :          0 :   mExtentLayer->setBlendMode( mBlendMode );
     295                 :            : 
     296                 :          0 :   static_cast< QgsSingleSymbolRenderer * >( mExtentLayer->renderer() )->setSymbol( mFrameSymbol->clone() );
     297                 :          0 :   mExtentLayer->dataProvider()->truncate();
     298                 :          0 :   mExtentLayer->setCrs( mMap->crs() );
     299                 :            : 
     300                 :          0 :   if ( mInverted )
     301                 :            :   {
     302                 :          0 :     intersectExtent = thisGeom.difference( intersectExtent );
     303                 :          0 :   }
     304                 :            : 
     305                 :          0 :   QgsFeature f;
     306                 :          0 :   f.setGeometry( intersectExtent );
     307                 :          0 :   mExtentLayer->dataProvider()->addFeature( f );
     308                 :            : 
     309                 :          0 :   return mExtentLayer.get();
     310                 :          0 : }
     311                 :            : 
     312                 :          0 : QgsMapLayer *QgsLayoutItemMapOverview::mapLayer()
     313                 :            : {
     314                 :          0 :   return mExtentLayer.get();
     315                 :            : }
     316                 :            : 
     317                 :          0 : bool QgsLayoutItemMapOverview::accept( QgsStyleEntityVisitorInterface *visitor ) const
     318                 :            : {
     319                 :          0 :   if ( mFrameSymbol )
     320                 :            :   {
     321                 :          0 :     QgsStyleSymbolEntity entity( mFrameSymbol.get() );
     322                 :          0 :     if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, QStringLiteral( "overview" ), QObject::tr( "Overview" ) ) ) )
     323                 :          0 :       return false;
     324                 :          0 :   }
     325                 :            : 
     326                 :          0 :   return true;
     327                 :          0 : }
     328                 :            : 
     329                 :          0 : void QgsLayoutItemMapOverview::setFrameSymbol( QgsFillSymbol *symbol )
     330                 :            : {
     331                 :          0 :   mFrameSymbol.reset( symbol );
     332                 :          0 : }
     333                 :            : 
     334                 :          0 : QgsFillSymbol *QgsLayoutItemMapOverview::frameSymbol()
     335                 :            : {
     336                 :          0 :   return mFrameSymbol.get();
     337                 :            : }
     338                 :            : 
     339                 :          0 : const QgsFillSymbol *QgsLayoutItemMapOverview::frameSymbol() const
     340                 :            : {
     341                 :          0 :   return mFrameSymbol.get();
     342                 :            : }
     343                 :            : 
     344                 :          0 : void QgsLayoutItemMapOverview::setBlendMode( const QPainter::CompositionMode blendMode )
     345                 :            : {
     346                 :          0 :   mBlendMode = blendMode;
     347                 :          0 : }
     348                 :            : 
     349                 :          0 : void QgsLayoutItemMapOverview::setInverted( const bool inverted )
     350                 :            : {
     351                 :          0 :   mInverted = inverted;
     352                 :          0 : }
     353                 :            : 
     354                 :          0 : void QgsLayoutItemMapOverview::setCentered( const bool centered )
     355                 :            : {
     356                 :          0 :   mCentered = centered;
     357                 :          0 :   overviewExtentChanged();
     358                 :          0 : }
     359                 :            : 
     360                 :          0 : void QgsLayoutItemMapOverview::overviewExtentChanged()
     361                 :            : {
     362                 :          0 :   if ( !mMap )
     363                 :            :   {
     364                 :          0 :     return;
     365                 :            :   }
     366                 :            : 
     367                 :            :   //if using overview centering, update the map's extent
     368                 :          0 :   if ( mMap->layout() && mCentered && mFrameMap )
     369                 :            :   {
     370                 :          0 :     QgsRectangle extent = mMap->extent();
     371                 :          0 :     QgsRectangle otherExtent = mFrameMap->extent();
     372                 :            : 
     373                 :          0 :     QgsPointXY center = otherExtent.center();
     374                 :          0 :     QgsRectangle movedExtent( center.x() - extent.width() / 2,
     375                 :          0 :                               center.y() - extent.height() / 2,
     376                 :          0 :                               center.x() - extent.width() / 2 + extent.width(),
     377                 :          0 :                               center.y() - extent.height() / 2 + extent.height() );
     378                 :          0 :     mMap->setExtent( movedExtent );
     379                 :          0 :   }
     380                 :            : 
     381                 :            :   //repaint map so that overview gets updated
     382                 :          0 :   mMap->invalidateCache();
     383                 :          0 : }
     384                 :            : 
     385                 :            : 
     386                 :            : //
     387                 :            : // QgsLayoutItemMapOverviewStack
     388                 :            : //
     389                 :            : 
     390                 :          0 : QgsLayoutItemMapOverviewStack::QgsLayoutItemMapOverviewStack( QgsLayoutItemMap *map )
     391                 :          0 :   : QgsLayoutItemMapItemStack( map )
     392                 :          0 : {
     393                 :            : 
     394                 :          0 : }
     395                 :            : 
     396                 :          0 : void QgsLayoutItemMapOverviewStack::addOverview( QgsLayoutItemMapOverview *overview )
     397                 :            : {
     398                 :          0 :   QgsLayoutItemMapItemStack::addItem( overview );
     399                 :          0 : }
     400                 :            : 
     401                 :          0 : void QgsLayoutItemMapOverviewStack::removeOverview( const QString &overviewId )
     402                 :            : {
     403                 :          0 :   QgsLayoutItemMapItemStack::removeItem( overviewId );
     404                 :          0 : }
     405                 :            : 
     406                 :          0 : void QgsLayoutItemMapOverviewStack::moveOverviewUp( const QString &overviewId )
     407                 :            : {
     408                 :          0 :   QgsLayoutItemMapItemStack::moveItemUp( overviewId );
     409                 :          0 : }
     410                 :            : 
     411                 :          0 : void QgsLayoutItemMapOverviewStack::moveOverviewDown( const QString &overviewId )
     412                 :            : {
     413                 :          0 :   QgsLayoutItemMapItemStack::moveItemDown( overviewId );
     414                 :          0 : }
     415                 :            : 
     416                 :          0 : QgsLayoutItemMapOverview *QgsLayoutItemMapOverviewStack::overview( const QString &overviewId ) const
     417                 :            : {
     418                 :          0 :   QgsLayoutItemMapItem *item = QgsLayoutItemMapItemStack::item( overviewId );
     419                 :          0 :   return qobject_cast<QgsLayoutItemMapOverview *>( item );
     420                 :            : }
     421                 :            : 
     422                 :          0 : QgsLayoutItemMapOverview *QgsLayoutItemMapOverviewStack::overview( const int index ) const
     423                 :            : {
     424                 :          0 :   QgsLayoutItemMapItem *item = QgsLayoutItemMapItemStack::item( index );
     425                 :          0 :   return qobject_cast<QgsLayoutItemMapOverview *>( item );
     426                 :            : }
     427                 :            : 
     428                 :          0 : QgsLayoutItemMapOverview &QgsLayoutItemMapOverviewStack::operator[]( int idx )
     429                 :            : {
     430                 :          0 :   QgsLayoutItemMapItem *item = mItems.at( idx );
     431                 :          0 :   QgsLayoutItemMapOverview *overview = qobject_cast<QgsLayoutItemMapOverview *>( item );
     432                 :          0 :   return *overview;
     433                 :            : }
     434                 :            : 
     435                 :          0 : QList<QgsLayoutItemMapOverview *> QgsLayoutItemMapOverviewStack::asList() const
     436                 :            : {
     437                 :          0 :   QList< QgsLayoutItemMapOverview * > list;
     438                 :          0 :   QList< QgsLayoutItemMapItem * >::const_iterator it = mItems.begin();
     439                 :          0 :   for ( ; it != mItems.end(); ++it )
     440                 :            :   {
     441                 :          0 :     QgsLayoutItemMapOverview *overview = qobject_cast<QgsLayoutItemMapOverview *>( *it );
     442                 :          0 :     if ( overview )
     443                 :            :     {
     444                 :          0 :       list.append( overview );
     445                 :          0 :     }
     446                 :          0 :   }
     447                 :          0 :   return list;
     448                 :          0 : }
     449                 :            : 
     450                 :          0 : bool QgsLayoutItemMapOverviewStack::readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context )
     451                 :            : {
     452                 :          0 :   removeItems();
     453                 :            : 
     454                 :            :   //read overview stack
     455                 :          0 :   QDomNodeList mapOverviewNodeList = elem.elementsByTagName( QStringLiteral( "ComposerMapOverview" ) );
     456                 :          0 :   for ( int i = 0; i < mapOverviewNodeList.size(); ++i )
     457                 :            :   {
     458                 :          0 :     QDomElement mapOverviewElem = mapOverviewNodeList.at( i ).toElement();
     459                 :          0 :     QgsLayoutItemMapOverview *mapOverview = new QgsLayoutItemMapOverview( mapOverviewElem.attribute( QStringLiteral( "name" ) ), mMap );
     460                 :          0 :     mapOverview->readXml( mapOverviewElem, doc, context );
     461                 :          0 :     mItems.append( mapOverview );
     462                 :          0 :   }
     463                 :            : 
     464                 :            :   return true;
     465                 :          0 : }
     466                 :            : 
     467                 :          0 : QList<QgsMapLayer *> QgsLayoutItemMapOverviewStack::modifyMapLayerList( const QList<QgsMapLayer *> &layers )
     468                 :            : {
     469                 :          0 :   QList<QgsMapLayer *> res = layers;
     470                 :          0 :   res.reserve( layers.count() + mItems.count() );
     471                 :          0 :   for ( QgsLayoutItemMapItem  *item : std::as_const( mItems ) )
     472                 :            :   {
     473                 :          0 :     if ( !item )
     474                 :          0 :       continue;
     475                 :            : 
     476                 :          0 :     QgsVectorLayer *l = static_cast< QgsLayoutItemMapOverview * >( item )->asMapLayer();
     477                 :          0 :     if ( !l )
     478                 :          0 :       continue;
     479                 :            : 
     480                 :          0 :     switch ( item->stackingPosition() )
     481                 :            :     {
     482                 :            :       case QgsLayoutItemMapItem::StackAboveMapLabels:
     483                 :          0 :         continue;
     484                 :            : 
     485                 :            :       case QgsLayoutItemMapItem::StackAboveMapLayer:
     486                 :            :       case QgsLayoutItemMapItem::StackBelowMapLayer:
     487                 :            :       {
     488                 :          0 :         QgsMapLayer *stackLayer = item->stackingLayer();
     489                 :          0 :         if ( !stackLayer )
     490                 :          0 :           continue;
     491                 :            : 
     492                 :          0 :         auto pos = std::find( res.begin(), res.end(), stackLayer );
     493                 :          0 :         if ( pos == res.end() )
     494                 :          0 :           continue;
     495                 :            : 
     496                 :          0 :         if ( item->stackingPosition() == QgsLayoutItemMapItem::StackBelowMapLayer )
     497                 :            :         {
     498                 :          0 :           pos++;
     499                 :          0 :           if ( pos == res.end() )
     500                 :            :           {
     501                 :          0 :             res.push_back( l );
     502                 :          0 :             break;
     503                 :            :           }
     504                 :          0 :         }
     505                 :          0 :         res.insert( pos, l );
     506                 :          0 :         break;
     507                 :            :       }
     508                 :            : 
     509                 :            :       case QgsLayoutItemMapItem::StackBelowMap:
     510                 :          0 :         res.push_back( l );
     511                 :          0 :         break;
     512                 :            : 
     513                 :            :       case QgsLayoutItemMapItem::StackBelowMapLabels:
     514                 :          0 :         res.push_front( l );
     515                 :          0 :         break;
     516                 :            :     }
     517                 :            :   }
     518                 :            : 
     519                 :          0 :   return res;
     520                 :          0 : }

Generated by: LCOV version 1.14