Skip to content

Commit

Permalink
Strip non-spatial and nullptrs from list when calling
Browse files Browse the repository at this point in the history
QgsMapSettings::setLayers

Since neither can be rendered, we filter them from the list
of layers to be rendered in the map.

(cherry-picked from 5b8599e)
  • Loading branch information
nyalldawson committed Mar 6, 2018
1 parent 48410c4 commit d97ea9c
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
4 changes: 4 additions & 0 deletions python/core/qgsmapsettings.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ The layers are stored in the reverse order of how they are rendered (layer with
%Docstring
Set list of layers for map rendering. The layers must be registered in :py:class:`QgsProject`.
The layers are stored in the reverse order of how they are rendered (layer with index 0 will be on top)

.. note::

Any non-spatial layers will be automatically stripped from the list (since they cannot be rendered!).
%End

QMap<QString, QString> layerStyleOverrides() const;
Expand Down
10 changes: 9 additions & 1 deletion src/core/qgsmapsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,15 @@ QList<QgsMapLayer *> QgsMapSettings::layers() const

void QgsMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
{
mLayers = _qgis_listRawToQPointer( layers );
// filter list, removing null layers and non-spatial layers
auto filteredList = layers;
filteredList.erase( std::remove_if( filteredList.begin(), filteredList.end(),
[]( QgsMapLayer * layer )
{
return !layer || !layer->isSpatial();
} ), filteredList.end() );

mLayers = _qgis_listRawToQPointer( filteredList );
}

QMap<QString, QString> QgsMapSettings::layerStyleOverrides() const
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsmapsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class CORE_EXPORT QgsMapSettings
/**
* Set list of layers for map rendering. The layers must be registered in QgsProject.
* The layers are stored in the reverse order of how they are rendered (layer with index 0 will be on top)
*
* \note Any non-spatial layers will be automatically stripped from the list (since they cannot be rendered!).
*/
void setLayers( const QList<QgsMapLayer *> &layers );

Expand Down
18 changes: 18 additions & 0 deletions tests/src/core/testqgsmapsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class TestQgsMapSettings: public QObject
void testIsLayerVisible();
void testMapLayerListUtils();
void testXmlReadWrite();
void testSetLayers();

private:
QString toString( const QPolygonF &p, int decimalPlaces = 2 ) const;
Expand Down Expand Up @@ -281,5 +282,22 @@ void TestQgsMapSettings::testXmlReadWrite()
QVERIFY( !s2.destinationCrs().isValid() );
}

void TestQgsMapSettings::testSetLayers()
{
std::unique_ptr< QgsVectorLayer > vlA = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Point" ), QStringLiteral( "a" ), QStringLiteral( "memory" ) );
std::unique_ptr< QgsVectorLayer > vlB = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Point" ), QStringLiteral( "b" ), QStringLiteral( "memory" ) );
std::unique_ptr< QgsVectorLayer > nonSpatial = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "none" ), QStringLiteral( "a" ), QStringLiteral( "memory" ) );

QgsMapSettings ms;
ms.setLayers( QList< QgsMapLayer * >() << vlA.get() );
QCOMPARE( ms.layers(), QList< QgsMapLayer * >() << vlA.get() );
ms.setLayers( QList< QgsMapLayer * >() << vlB.get() << vlA.get() );
QCOMPARE( ms.layers(), QList< QgsMapLayer * >() << vlB.get() << vlA.get() );

// non spatial and null layers should be stripped
ms.setLayers( QList< QgsMapLayer * >() << vlA.get() << nonSpatial.get() << nullptr << vlB.get() );
QCOMPARE( ms.layers(), QList< QgsMapLayer * >() << vlA.get() << vlB.get() );
}

QGSTEST_MAIN( TestQgsMapSettings )
#include "testqgsmapsettings.moc"

0 comments on commit d97ea9c

Please sign in to comment.