Skip to content

Commit

Permalink
[api]Allow layers to be set for layout elevation profile item
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 18, 2023
1 parent f286225 commit f58e870
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 4 deletions.
Expand Up @@ -50,6 +50,20 @@ set plot appearance and properties.
%End


QList< QgsMapLayer * > layers() const;
%Docstring
Returns the list of map layers participating in the elevation profile.

.. seealso:: :py:func:`setLayers`
%End

void setLayers( const QList< QgsMapLayer * > &layers );
%Docstring
Sets the list of map ``layers`` participating in the elevation profile.

.. seealso:: :py:func:`layers`
%End

protected:
virtual void draw( QgsLayoutItemRenderContext &context );

Expand Down
58 changes: 55 additions & 3 deletions src/core/layout/qgslayoutitemelevationprofile.cpp
Expand Up @@ -18,7 +18,9 @@
#include "qgslayoutitemelevationprofile.h"
#include "qgslayoutitemregistry.h"
#include "qgsplot.h"
#include "qgslayout.h"
#include "qgsmessagelog.h"
#include "qgsmaplayerlistutils_p.h"

///@cond PRIVATE
class QgsLayoutItemElevationProfilePlot : public Qgs2DPlot
Expand Down Expand Up @@ -379,6 +381,19 @@ const Qgs2DPlot *QgsLayoutItemElevationProfile::plot() const
return mPlot.get();
}

QList<QgsMapLayer *> QgsLayoutItemElevationProfile::layers() const
{
return _qgis_listRefToRaw( mLayers );
}

void QgsLayoutItemElevationProfile::setLayers( const QList<QgsMapLayer *> &layers )
{
if ( layers == _qgis_listRefToRaw( mLayers ) )
return;

mLayers = _qgis_listRawToRef( layers );
}

void QgsLayoutItemElevationProfile::draw( QgsLayoutItemRenderContext &context )
{
// size must be in pixels, not layout units
Expand All @@ -388,9 +403,26 @@ void QgsLayoutItemElevationProfile::draw( QgsLayoutItemRenderContext &context )

bool QgsLayoutItemElevationProfile::writePropertiesToElement( QDomElement &layoutProfileElem, QDomDocument &doc, const QgsReadWriteContext &rwContext ) const
{
QDomElement plotElement = doc.createElement( QStringLiteral( "plot" ) );
mPlot->writeXml( plotElement, doc, rwContext );
layoutProfileElem.appendChild( plotElement );
{
QDomElement plotElement = doc.createElement( QStringLiteral( "plot" ) );
mPlot->writeXml( plotElement, doc, rwContext );
layoutProfileElem.appendChild( plotElement );
}

{
QDomElement layersElement = doc.createElement( QStringLiteral( "layers" ) );
for ( const QgsMapLayerRef &layer : mLayers )
{
QDomElement layerElement = doc.createElement( QStringLiteral( "layer" ) );
layerElement.setAttribute( QStringLiteral( "id" ), layer.layerId );
layerElement.setAttribute( QStringLiteral( "name" ), layer.name );
layerElement.setAttribute( QStringLiteral( "source" ), layer.source );
layerElement.setAttribute( QStringLiteral( "provider" ), layer.provider );
layersElement.appendChild( layerElement );
}
layoutProfileElem.appendChild( layersElement );
}

return true;
}

Expand All @@ -401,6 +433,26 @@ bool QgsLayoutItemElevationProfile::readPropertiesFromElement( const QDomElement
{
mPlot->readXml( plotElement, context );
}

{
mLayers.clear();
const QDomElement layersElement = itemElem.firstChildElement( QStringLiteral( "layers" ) );
QDomElement layerElement = layersElement.firstChildElement( QStringLiteral( "layer" ) );
while ( !layerElement.isNull() )
{
const QString layerId = layerElement.attribute( QStringLiteral( "id" ) );
const QString layerName = layerElement.attribute( QStringLiteral( "name" ) );
const QString layerSource = layerElement.attribute( QStringLiteral( "source" ) );
const QString layerProvider = layerElement.attribute( QStringLiteral( "provider" ) );

QgsMapLayerRef ref = QgsMapLayerRef( layerId, layerName, layerSource, layerProvider );
ref.resolveWeakly( mLayout->project() );
mLayers.append( ref );

layerElement = layerElement.nextSiblingElement( QStringLiteral( "layer" ) );
}
}

return true;
}

17 changes: 17 additions & 0 deletions src/core/layout/qgslayoutitemelevationprofile.h
Expand Up @@ -19,6 +19,7 @@

#include "qgis_core.h"
#include "qgslayoutitem.h"
#include "qgsmaplayerref.h"

class QgsLayoutItemElevationProfilePlot;
class Qgs2DPlot;
Expand Down Expand Up @@ -64,6 +65,20 @@ class CORE_EXPORT QgsLayoutItemElevationProfile: public QgsLayoutItem
*/
const Qgs2DPlot *plot() const SIP_SKIP;

/**
* Returns the list of map layers participating in the elevation profile.
*
* \see setLayers()
*/
QList< QgsMapLayer * > layers() const;

/**
* Sets the list of map \a layers participating in the elevation profile.
*
* \see layers()
*/
void setLayers( const QList< QgsMapLayer * > &layers );

protected:
void draw( QgsLayoutItemRenderContext &context ) override;
bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
Expand All @@ -73,6 +88,8 @@ class CORE_EXPORT QgsLayoutItemElevationProfile: public QgsLayoutItem

std::unique_ptr< QgsLayoutItemElevationProfilePlot > mPlot;

QList< QgsMapLayerRef > mLayers;

};

#endif //QGSLAYOUTITEMELEVATIONPROFILE_H
41 changes: 40 additions & 1 deletion tests/src/python/test_qgslayoutelevationprofile.py
Expand Up @@ -11,6 +11,8 @@
__copyright__ = 'Copyright 2023, The QGIS Project'

import os
import tempfile

from time import sleep

from qgis.PyQt.QtCore import QRectF, QDir
Expand Down Expand Up @@ -39,7 +41,7 @@
QgsMapThemeCollection,
QgsCategorizedSymbolRenderer,
QgsRendererCategory,
QgsFillSymbol,
QgsRasterLayer,
QgsApplication)
from qgis.testing import (start_app,
unittest
Expand All @@ -65,6 +67,43 @@ def tearDownClass(cls):
with open(report_file_path, 'a') as report_file:
report_file.write(cls.report)

def test_layers(self):
project = QgsProject()
layout = QgsPrintLayout(project)
profile = QgsLayoutItemElevationProfile(layout)
layout.addLayoutItem(profile)

self.assertFalse(profile.layers())

layer1 = QgsVectorLayer(os.path.join(unitTestDataPath(), 'france_parts.shp'), 'france', "ogr")
self.assertTrue(layer1.isValid())
project.addMapLayers([layer1])

layer2 = QgsRasterLayer(os.path.join(unitTestDataPath(), 'landsat.tif'), 'landsat', "gdal")
self.assertTrue(layer2.isValid())
project.addMapLayers([layer2])

layer3 = QgsVectorLayer(os.path.join(unitTestDataPath(), 'lines.shp'), 'lines', "ogr")
self.assertTrue(layer3.isValid())
project.addMapLayers([layer3])

profile.setLayers([layer2, layer3])
self.assertEqual(profile.layers(), [layer2, layer3])

project.layoutManager().addLayout(layout)

# test that layers are written/restored
with tempfile.TemporaryDirectory() as temp_dir:
self.assertTrue(project.write(os.path.join(temp_dir, 'p.qgs')))

p2 = QgsProject()
self.assertTrue(p2.read(os.path.join(temp_dir, 'p.qgs')))

layout2 = p2.layoutManager().printLayouts()[0]
profile2 = [i for i in layout2.items() if isinstance(i, QgsLayoutItemElevationProfile)][0]

self.assertEqual([m.id() for m in profile2.layers()], [layer2.id(), layer3.id()])


if __name__ == '__main__':
unittest.main()

0 comments on commit f58e870

Please sign in to comment.