mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Serialize atlas settings
This commit is contained in:
parent
83af35275e
commit
f86c2988bb
@ -500,14 +500,14 @@ If ``ok`` is specified, it will be set to true if the load was successful.
|
||||
Returns a list of loaded items.
|
||||
%End
|
||||
|
||||
QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
virtual QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
%Docstring
|
||||
Returns the layout's state encapsulated in a DOM element.
|
||||
|
||||
.. seealso:: :py:func:`readXml()`
|
||||
%End
|
||||
|
||||
bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
virtual bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
Sets the collection's state from a DOM element. ``layoutElement`` is the DOM node corresponding to the layout.
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
|
||||
class QgsLayoutAtlas : QObject
|
||||
class QgsLayoutAtlas : QObject, QgsLayoutSerializableObject
|
||||
{
|
||||
%Docstring
|
||||
Class used to render an Atlas, iterating over geometry features.
|
||||
@ -34,6 +34,15 @@ QgsLayoutAtlas which is automatically created and attached to the composition.
|
||||
Constructor for new QgsLayoutAtlas.
|
||||
%End
|
||||
|
||||
virtual QString stringType() const;
|
||||
|
||||
virtual QgsLayout *layout();
|
||||
|
||||
virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
|
||||
virtual bool readXml( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
|
||||
|
||||
bool enabled() const;
|
||||
%Docstring
|
||||
Returns whether the atlas generation is enabled
|
||||
@ -72,7 +81,7 @@ atlas page.
|
||||
.. seealso:: :py:func:`filenameExpressionErrorString()`
|
||||
%End
|
||||
|
||||
bool setFilenameExpression( const QString &expression, QString &errorString );
|
||||
bool setFilenameExpression( const QString &expression, QString &errorString /Out/ );
|
||||
%Docstring
|
||||
Sets the filename ``expression`` used for generating output filenames for each
|
||||
atlas page.
|
||||
@ -222,7 +231,7 @@ This property has no effect is filterFeatures() is false.
|
||||
.. seealso:: :py:func:`filterFeatures()`
|
||||
%End
|
||||
|
||||
bool setFilterExpression( const QString &expression, QString &errorString );
|
||||
bool setFilterExpression( const QString &expression, QString &errorString /Out/ );
|
||||
%Docstring
|
||||
Sets the ``expression`` used for filtering features in the coverage layer.
|
||||
|
||||
|
@ -31,6 +31,11 @@ Constructor for QgsPrintLayout.
|
||||
Returns the print layout's atlas.
|
||||
%End
|
||||
|
||||
virtual QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
|
||||
virtual bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
@ -514,13 +514,13 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
|
||||
* Returns the layout's state encapsulated in a DOM element.
|
||||
* \see readXml()
|
||||
*/
|
||||
QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
virtual QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const;
|
||||
|
||||
/**
|
||||
* Sets the collection's state from a DOM element. \a layoutElement is the DOM node corresponding to the layout.
|
||||
* \see writeXml()
|
||||
*/
|
||||
bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
virtual bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context );
|
||||
|
||||
/**
|
||||
* Add items from an XML representation to the layout. Used for project file reading and pasting items from clipboard.
|
||||
|
@ -31,6 +31,84 @@ QgsLayoutAtlas::QgsLayoutAtlas( QgsLayout *layout )
|
||||
connect( mLayout->project(), static_cast < void ( QgsProject::* )( const QStringList & ) >( &QgsProject::layersWillBeRemoved ), this, &QgsLayoutAtlas::removeLayers );
|
||||
}
|
||||
|
||||
QString QgsLayoutAtlas::stringType() const
|
||||
{
|
||||
return QStringLiteral( "atlas" );
|
||||
}
|
||||
|
||||
QgsLayout *QgsLayoutAtlas::layout()
|
||||
{
|
||||
return mLayout;
|
||||
}
|
||||
|
||||
bool QgsLayoutAtlas::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & ) const
|
||||
{
|
||||
QDomElement atlasElem = document.createElement( QStringLiteral( "Atlas" ) );
|
||||
atlasElem.setAttribute( QStringLiteral( "enabled" ), mEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
|
||||
if ( mCoverageLayer )
|
||||
{
|
||||
atlasElem.setAttribute( QStringLiteral( "coverageLayer" ), mCoverageLayer.layerId );
|
||||
atlasElem.setAttribute( QStringLiteral( "coverageLayerName" ), mCoverageLayer.name );
|
||||
atlasElem.setAttribute( QStringLiteral( "coverageLayerSource" ), mCoverageLayer.source );
|
||||
atlasElem.setAttribute( QStringLiteral( "coverageLayerProvider" ), mCoverageLayer.provider );
|
||||
}
|
||||
else
|
||||
{
|
||||
atlasElem.setAttribute( QStringLiteral( "coverageLayer" ), QString() );
|
||||
}
|
||||
|
||||
atlasElem.setAttribute( QStringLiteral( "hideCoverage" ), mHideCoverage ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
atlasElem.setAttribute( QStringLiteral( "filenamePattern" ), mFilenameExpressionString );
|
||||
atlasElem.setAttribute( QStringLiteral( "pageNameExpression" ), mPageNameExpression );
|
||||
|
||||
atlasElem.setAttribute( QStringLiteral( "sortFeatures" ), mSortFeatures ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
if ( mSortFeatures )
|
||||
{
|
||||
atlasElem.setAttribute( QStringLiteral( "sortKey" ), mSortExpression );
|
||||
atlasElem.setAttribute( QStringLiteral( "sortAscending" ), mSortAscending ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
}
|
||||
atlasElem.setAttribute( QStringLiteral( "filterFeatures" ), mFilterFeatures ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
if ( mFilterFeatures )
|
||||
{
|
||||
atlasElem.setAttribute( QStringLiteral( "featureFilter" ), mFilterExpression );
|
||||
}
|
||||
|
||||
parentElement.appendChild( atlasElem );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsLayoutAtlas::readXml( const QDomElement &atlasElem, const QDomDocument &, const QgsReadWriteContext & )
|
||||
{
|
||||
mEnabled = atlasElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
|
||||
// look for stored layer name
|
||||
QString layerId = atlasElem.attribute( QStringLiteral( "coverageLayer" ) );
|
||||
QString layerName = atlasElem.attribute( QStringLiteral( "coverageLayerName" ) );
|
||||
QString layerSource = atlasElem.attribute( QStringLiteral( "coverageLayerSource" ) );
|
||||
QString layerProvider = atlasElem.attribute( QStringLiteral( "coverageLayerProvider" ) );
|
||||
|
||||
mCoverageLayer = QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider );
|
||||
mCoverageLayer.resolveWeakly( mLayout->project() );
|
||||
|
||||
mPageNameExpression = atlasElem.attribute( QStringLiteral( "pageNameExpression" ), QString() );
|
||||
QString error;
|
||||
setFilenameExpression( atlasElem.attribute( QStringLiteral( "filenamePattern" ), QString() ), error );
|
||||
|
||||
mSortFeatures = atlasElem.attribute( QStringLiteral( "sortFeatures" ), QStringLiteral( "0" ) ).toInt();
|
||||
mSortExpression = atlasElem.attribute( QStringLiteral( "sortKey" ) );
|
||||
mSortAscending = atlasElem.attribute( QStringLiteral( "sortAscending" ), QStringLiteral( "1" ) ).toInt();
|
||||
mFilterFeatures = atlasElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "0" ) ).toInt();
|
||||
mFilterExpression = atlasElem.attribute( QStringLiteral( "featureFilter" ) );
|
||||
|
||||
mHideCoverage = atlasElem.attribute( QStringLiteral( "hideCoverage" ), QStringLiteral( "0" ) ).toInt();
|
||||
|
||||
emit toggled( mEnabled );
|
||||
emit changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsLayoutAtlas::setEnabled( bool enabled )
|
||||
{
|
||||
if ( enabled == mEnabled )
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgsvectorlayerref.h"
|
||||
#include "qgslayoutserializableobject.h"
|
||||
#include <QObject>
|
||||
|
||||
class QgsLayout;
|
||||
@ -32,7 +33,7 @@ class QgsLayout;
|
||||
* QgsLayoutAtlas which is automatically created and attached to the composition.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsLayoutAtlas : public QObject
|
||||
class CORE_EXPORT QgsLayoutAtlas : public QObject, public QgsLayoutSerializableObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -42,6 +43,11 @@ class CORE_EXPORT QgsLayoutAtlas : public QObject
|
||||
*/
|
||||
QgsLayoutAtlas( QgsLayout *layout SIP_TRANSFERTHIS );
|
||||
|
||||
QString stringType() const override;
|
||||
QgsLayout *layout() override;
|
||||
bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const override;
|
||||
bool readXml( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;
|
||||
|
||||
/**
|
||||
* Returns whether the atlas generation is enabled
|
||||
* \see setEnabled()
|
||||
@ -81,7 +87,7 @@ class CORE_EXPORT QgsLayoutAtlas : public QObject
|
||||
* will be set to the expression error.
|
||||
* \see filenameExpression()
|
||||
*/
|
||||
bool setFilenameExpression( const QString &expression, QString &errorString );
|
||||
bool setFilenameExpression( const QString &expression, QString &errorString SIP_OUT );
|
||||
|
||||
/**
|
||||
* Returns the coverage layer used for the atlas features.
|
||||
@ -209,7 +215,7 @@ class CORE_EXPORT QgsLayoutAtlas : public QObject
|
||||
* \see filterExpression()
|
||||
* \see setFilterFeatures()
|
||||
*/
|
||||
bool setFilterExpression( const QString &expression, QString &errorString );
|
||||
bool setFilterExpression( const QString &expression, QString &errorString SIP_OUT );
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -27,3 +27,20 @@ QgsLayoutAtlas *QgsPrintLayout::atlas()
|
||||
{
|
||||
return mAtlas;
|
||||
}
|
||||
|
||||
QDomElement QgsPrintLayout::writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const
|
||||
{
|
||||
QDomElement layoutElem = QgsLayout::writeXml( document, context );
|
||||
mAtlas->writeXml( layoutElem, document, context );
|
||||
return layoutElem;
|
||||
}
|
||||
|
||||
bool QgsPrintLayout::readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context )
|
||||
{
|
||||
if ( !QgsLayout::readXml( layoutElement, document, context ) )
|
||||
return false;
|
||||
|
||||
QDomElement atlasElem = layoutElement.firstChildElement( QStringLiteral( "Atlas" ) );
|
||||
mAtlas->readXml( atlasElem, document, context );
|
||||
return true;
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ class CORE_EXPORT QgsPrintLayout : public QgsLayout
|
||||
*/
|
||||
QgsLayoutAtlas *atlas();
|
||||
|
||||
QDomElement writeXml( QDomDocument &document, const QgsReadWriteContext &context ) const override;
|
||||
bool readXml( const QDomElement &layoutElement, const QDomDocument &document, const QgsReadWriteContext &context ) override;
|
||||
|
||||
private:
|
||||
|
||||
QgsLayoutAtlas *mAtlas = nullptr;
|
||||
|
@ -84,6 +84,7 @@ ADD_PYTHON_TEST(PyQgsLayerTreeMapCanvasBridge test_qgslayertreemapcanvasbridge.p
|
||||
ADD_PYTHON_TEST(PyQgsLayerTree test_qgslayertree.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayout test_qgslayout.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutAlign test_qgslayoutaligner.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutAtlas test_qgslayoutatlas.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutExporter test_qgslayoutexporter.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutFrame test_qgslayoutframe.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutManager test_qgslayoutmanager.py)
|
||||
|
91
tests/src/python/test_qgslayoutatlas.py
Normal file
91
tests/src/python/test_qgslayoutatlas.py
Normal file
@ -0,0 +1,91 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsLayoutAtlas
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = '19/12/2017'
|
||||
__copyright__ = 'Copyright 2017, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
import sip
|
||||
import tempfile
|
||||
import shutil
|
||||
import os
|
||||
|
||||
from qgis.core import (QgsUnitTypes,
|
||||
QgsLayout,
|
||||
QgsPrintLayout,
|
||||
QgsLayoutAtlas,
|
||||
QgsLayoutItemPage,
|
||||
QgsLayoutGuide,
|
||||
QgsLayoutObject,
|
||||
QgsProject,
|
||||
QgsLayoutItemGroup,
|
||||
QgsLayoutItem,
|
||||
QgsProperty,
|
||||
QgsLayoutPageCollection,
|
||||
QgsLayoutMeasurement,
|
||||
QgsFillSymbol,
|
||||
QgsReadWriteContext,
|
||||
QgsLayoutItemMap,
|
||||
QgsLayoutItemLabel,
|
||||
QgsLayoutSize,
|
||||
QgsLayoutPoint,
|
||||
QgsVectorLayer)
|
||||
from qgis.PyQt.QtCore import QFileInfo
|
||||
from qgis.PyQt.QtTest import QSignalSpy
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
from utilities import unitTestDataPath
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsLayoutAtlas(unittest.TestCase):
|
||||
|
||||
def testReadWriteXml(self):
|
||||
p = QgsProject()
|
||||
vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
|
||||
vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")
|
||||
self.assertTrue(vector_layer.isValid())
|
||||
p.addMapLayer(vector_layer)
|
||||
|
||||
l = QgsPrintLayout(p)
|
||||
atlas = l.atlas()
|
||||
atlas.setEnabled(True)
|
||||
atlas.setHideCoverage(True)
|
||||
atlas.setFilenameExpression('filename exp')
|
||||
atlas.setCoverageLayer(vector_layer)
|
||||
atlas.setPageNameExpression('page name')
|
||||
atlas.setSortFeatures(True)
|
||||
atlas.setSortAscending(False)
|
||||
atlas.setSortExpression('sort exp')
|
||||
atlas.setFilterFeatures(True)
|
||||
atlas.setFilterExpression('filter exp')
|
||||
|
||||
doc = QDomDocument("testdoc")
|
||||
elem = l.writeXml(doc, QgsReadWriteContext())
|
||||
|
||||
l2 = QgsPrintLayout(p)
|
||||
self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext()))
|
||||
atlas2 = l2.atlas()
|
||||
self.assertTrue(atlas2.enabled())
|
||||
self.assertTrue(atlas2.hideCoverage())
|
||||
self.assertEqual(atlas2.filenameExpression(), 'filename exp')
|
||||
self.assertEqual(atlas2.coverageLayer(), vector_layer)
|
||||
self.assertEqual(atlas2.pageNameExpression(), 'page name')
|
||||
self.assertTrue(atlas2.sortFeatures())
|
||||
self.assertFalse(atlas2.sortAscending())
|
||||
self.assertEqual(atlas2.sortExpression(), 'sort exp')
|
||||
self.assertTrue(atlas2.filterFeatures())
|
||||
self.assertEqual(atlas2.filterExpression(), 'filter exp')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user