mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-04 00:06:46 -05:00
[layouts] Keep a separate flag for whether only a subset of layers
are to be clipped from the project, instead of just tracking this by the presence of any checked layers Avoids inconsistencies between the layers which are visibly clipped on the map vs the options which are set in the GUI.
This commit is contained in:
parent
fce4b27644
commit
49e9b613b8
@ -67,13 +67,35 @@ Returns ``True`` if labels should only be placed inside the atlas feature geomet
|
||||
Sets whether labels should only be placed inside the atlas feature geometry.
|
||||
|
||||
.. seealso:: :py:func:`forceLabelsInsideFeature`
|
||||
%End
|
||||
|
||||
bool restrictToLayers() const;
|
||||
%Docstring
|
||||
Returns ``True`` if clipping should be restricted to a subset of layers.
|
||||
|
||||
.. seealso:: :py:func:`layersToClip`
|
||||
|
||||
.. seealso:: :py:func:`setRestrictToLayers`
|
||||
%End
|
||||
|
||||
void setRestrictToLayers( bool enabled );
|
||||
%Docstring
|
||||
Sets whether clipping should be restricted to a subset of layers.
|
||||
|
||||
.. seealso:: :py:func:`setLayersToClip`
|
||||
|
||||
.. seealso:: :py:func:`restrictToLayers`
|
||||
%End
|
||||
|
||||
QList< QgsMapLayer * > layersToClip() const;
|
||||
%Docstring
|
||||
Returns the list of map layers to clip to the atlas feature.
|
||||
|
||||
If the returned list is empty then all layers will be clipped.
|
||||
.. note::
|
||||
|
||||
This setting is only used if :py:func:`~QgsLayoutItemMapAtlasClippingSettings.restrictToLayers` is ``True``.
|
||||
|
||||
.. seealso:: :py:func:`restrictedLayers`
|
||||
|
||||
.. seealso:: :py:func:`setLayersToClip`
|
||||
%End
|
||||
@ -82,7 +104,11 @@ If the returned list is empty then all layers will be clipped.
|
||||
%Docstring
|
||||
Sets the list of map ``layers`` to clip to the atlas feature.
|
||||
|
||||
If the ``layers`` list is empty then all layers will be clipped.
|
||||
.. note::
|
||||
|
||||
This setting is only used if :py:func:`~QgsLayoutItemMapAtlasClippingSettings.restrictToLayers` is ``True``.
|
||||
|
||||
.. seealso:: :py:func:`restrictedLayers`
|
||||
|
||||
.. seealso:: :py:func:`layersToClip`
|
||||
%End
|
||||
|
||||
@ -64,6 +64,24 @@ Sets the feature clipping ``type``.
|
||||
This setting is only used while rendering vector layers, for other layer types it is ignored.
|
||||
|
||||
.. seealso:: :py:func:`featureClip`
|
||||
%End
|
||||
|
||||
bool restrictToLayers() const;
|
||||
%Docstring
|
||||
Returns ``True`` if clipping should be restricted to a subset of layers.
|
||||
|
||||
.. seealso:: :py:func:`restrictedLayers`
|
||||
|
||||
.. seealso:: :py:func:`setRestrictToLayers`
|
||||
%End
|
||||
|
||||
void setRestrictToLayers( bool enabled );
|
||||
%Docstring
|
||||
Sets whether clipping should be restricted to a subset of layers.
|
||||
|
||||
.. seealso:: :py:func:`setRestrictedLayers`
|
||||
|
||||
.. seealso:: :py:func:`restrictToLayers`
|
||||
%End
|
||||
|
||||
void setRestrictedLayers( const QList< QgsMapLayer * > &layers );
|
||||
@ -72,9 +90,14 @@ Sets a list of ``layers`` to restrict the clipping region effects to.
|
||||
|
||||
By default the clipping region applies to all layers.
|
||||
|
||||
.. seealso:: :py:func:`restrictedLayers`
|
||||
%End
|
||||
.. note::
|
||||
|
||||
This setting is only used if :py:func:`~QgsMapClippingRegion.restrictToLayers` is ``True``.
|
||||
|
||||
.. seealso:: :py:func:`restrictedLayers`
|
||||
|
||||
.. seealso:: :py:func:`setRestrictToLayers`
|
||||
%End
|
||||
|
||||
QList< QgsMapLayer * > restrictedLayers() const;
|
||||
%Docstring
|
||||
@ -82,7 +105,13 @@ Returns the list of layers to restrict the clipping region effects to.
|
||||
|
||||
If the list is empty then the clipping will be applied to all layers.
|
||||
|
||||
.. note::
|
||||
|
||||
This setting is only used if :py:func:`~QgsMapClippingRegion.restrictToLayers` is ``True``.
|
||||
|
||||
.. seealso:: :py:func:`setRestrictedLayers`
|
||||
|
||||
.. seealso:: :py:func:`restrictToLayers`
|
||||
%End
|
||||
|
||||
bool appliesToLayer( const QgsMapLayer *layer ) const;
|
||||
|
||||
@ -1554,6 +1554,7 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF
|
||||
QgsMapClippingRegion region( clipGeom );
|
||||
region.setFeatureClip( mAtlasClippingSettings->featureClippingType() );
|
||||
region.setRestrictedLayers( mAtlasClippingSettings->layersToClip() );
|
||||
region.setRestrictToLayers( mAtlasClippingSettings->restrictToLayers() );
|
||||
jobMapSettings.addClippingRegion( region );
|
||||
|
||||
if ( mAtlasClippingSettings->forceLabelsInsideFeature() )
|
||||
@ -2784,6 +2785,20 @@ void QgsLayoutItemMapAtlasClippingSettings::setForceLabelsInsideFeature( bool fo
|
||||
emit changed();
|
||||
}
|
||||
|
||||
bool QgsLayoutItemMapAtlasClippingSettings::restrictToLayers() const
|
||||
{
|
||||
return mRestrictToLayers;
|
||||
}
|
||||
|
||||
void QgsLayoutItemMapAtlasClippingSettings::setRestrictToLayers( bool enabled )
|
||||
{
|
||||
if ( mRestrictToLayers == enabled )
|
||||
return;
|
||||
|
||||
mRestrictToLayers = enabled;
|
||||
emit changed();
|
||||
}
|
||||
|
||||
QList<QgsMapLayer *> QgsLayoutItemMapAtlasClippingSettings::layersToClip() const
|
||||
{
|
||||
return _qgis_listRefToRaw( mLayersToClip );
|
||||
@ -2801,6 +2816,7 @@ bool QgsLayoutItemMapAtlasClippingSettings::writeXml( QDomElement &element, QDom
|
||||
settingsElem.setAttribute( QStringLiteral( "enabled" ), mClipToAtlasFeature ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
settingsElem.setAttribute( QStringLiteral( "forceLabelsInside" ), mForceLabelsInsideFeature ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
settingsElem.setAttribute( QStringLiteral( "clippingType" ), QString::number( static_cast<int>( mFeatureClippingType ) ) );
|
||||
settingsElem.setAttribute( QStringLiteral( "restrictLayers" ), mRestrictToLayers ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
|
||||
//layer set
|
||||
QDomElement layerSetElem = document.createElement( QStringLiteral( "layersToClip" ) );
|
||||
@ -2831,6 +2847,7 @@ bool QgsLayoutItemMapAtlasClippingSettings::readXml( const QDomElement &element,
|
||||
mClipToAtlasFeature = settingsElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
mForceLabelsInsideFeature = settingsElem.attribute( QStringLiteral( "forceLabelsInside" ), QStringLiteral( "0" ) ).toInt();
|
||||
mFeatureClippingType = static_cast< QgsMapClippingRegion::FeatureClippingType >( settingsElem.attribute( QStringLiteral( "clippingType" ), QStringLiteral( "0" ) ).toInt() );
|
||||
mRestrictToLayers = settingsElem.attribute( QStringLiteral( "restrictLayers" ), QStringLiteral( "0" ) ).toInt();
|
||||
|
||||
mLayersToClip.clear();
|
||||
QDomNodeList layerSetNodeList = settingsElem.elementsByTagName( QStringLiteral( "layersToClip" ) );
|
||||
|
||||
@ -89,11 +89,28 @@ class CORE_EXPORT QgsLayoutItemMapAtlasClippingSettings : public QObject
|
||||
*/
|
||||
void setForceLabelsInsideFeature( bool forceInside );
|
||||
|
||||
/**
|
||||
* Returns TRUE if clipping should be restricted to a subset of layers.
|
||||
*
|
||||
* \see layersToClip()
|
||||
* \see setRestrictToLayers()
|
||||
*/
|
||||
bool restrictToLayers() const;
|
||||
|
||||
/**
|
||||
* Sets whether clipping should be restricted to a subset of layers.
|
||||
*
|
||||
* \see setLayersToClip()
|
||||
* \see restrictToLayers()
|
||||
*/
|
||||
void setRestrictToLayers( bool enabled );
|
||||
|
||||
/**
|
||||
* Returns the list of map layers to clip to the atlas feature.
|
||||
*
|
||||
* If the returned list is empty then all layers will be clipped.
|
||||
* \note This setting is only used if restrictToLayers() is TRUE.
|
||||
*
|
||||
* \see restrictedLayers()
|
||||
* \see setLayersToClip()
|
||||
*/
|
||||
QList< QgsMapLayer * > layersToClip() const;
|
||||
@ -101,8 +118,9 @@ class CORE_EXPORT QgsLayoutItemMapAtlasClippingSettings : public QObject
|
||||
/**
|
||||
* Sets the list of map \a layers to clip to the atlas feature.
|
||||
*
|
||||
* If the \a layers list is empty then all layers will be clipped.
|
||||
* \note This setting is only used if restrictToLayers() is TRUE.
|
||||
*
|
||||
* \see restrictedLayers()
|
||||
* \see layersToClip()
|
||||
*/
|
||||
void setLayersToClip( const QList< QgsMapLayer * > &layers );
|
||||
@ -135,6 +153,7 @@ class CORE_EXPORT QgsLayoutItemMapAtlasClippingSettings : public QObject
|
||||
|
||||
QgsLayoutItemMap *mMap = nullptr;
|
||||
bool mClipToAtlasFeature = false;
|
||||
bool mRestrictToLayers = false;
|
||||
QList< QgsMapLayerRef > mLayersToClip;
|
||||
QgsMapClippingRegion::FeatureClippingType mFeatureClippingType = QgsMapClippingRegion::FeatureClippingType::ClipPainterOnly;
|
||||
bool mForceLabelsInsideFeature = false;
|
||||
|
||||
@ -39,9 +39,12 @@ QList<QgsMapLayer *> QgsMapClippingRegion::restrictedLayers() const
|
||||
|
||||
bool QgsMapClippingRegion::appliesToLayer( const QgsMapLayer *layer ) const
|
||||
{
|
||||
if ( mRestrictToLayersList.empty() )
|
||||
if ( !mRestrictToLayers )
|
||||
return true;
|
||||
|
||||
if ( mRestrictToLayersList.empty() )
|
||||
return false;
|
||||
|
||||
auto it = std::find_if( mRestrictToLayersList.begin(), mRestrictToLayersList.end(), [layer]( const QgsWeakMapLayerPointer & item ) -> bool
|
||||
{
|
||||
return item == layer;
|
||||
@ -49,4 +52,14 @@ bool QgsMapClippingRegion::appliesToLayer( const QgsMapLayer *layer ) const
|
||||
return it != mRestrictToLayersList.end();
|
||||
}
|
||||
|
||||
bool QgsMapClippingRegion::restrictToLayers() const
|
||||
{
|
||||
return mRestrictToLayers;
|
||||
}
|
||||
|
||||
void QgsMapClippingRegion::setRestrictToLayers( bool enabled )
|
||||
{
|
||||
mRestrictToLayers = enabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -88,22 +88,43 @@ class CORE_EXPORT QgsMapClippingRegion
|
||||
mFeatureClip = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if clipping should be restricted to a subset of layers.
|
||||
*
|
||||
* \see restrictedLayers()
|
||||
* \see setRestrictToLayers()
|
||||
*/
|
||||
bool restrictToLayers() const;
|
||||
|
||||
/**
|
||||
* Sets whether clipping should be restricted to a subset of layers.
|
||||
*
|
||||
* \see setRestrictedLayers()
|
||||
* \see restrictToLayers()
|
||||
*/
|
||||
void setRestrictToLayers( bool enabled );
|
||||
|
||||
/**
|
||||
* Sets a list of \a layers to restrict the clipping region effects to.
|
||||
*
|
||||
* By default the clipping region applies to all layers.
|
||||
*
|
||||
* \note This setting is only used if restrictToLayers() is TRUE.
|
||||
*
|
||||
* \see restrictedLayers()
|
||||
* \see setRestrictToLayers()
|
||||
*/
|
||||
void setRestrictedLayers( const QList< QgsMapLayer * > &layers );
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of layers to restrict the clipping region effects to.
|
||||
*
|
||||
* If the list is empty then the clipping will be applied to all layers.
|
||||
*
|
||||
* \note This setting is only used if restrictToLayers() is TRUE.
|
||||
*
|
||||
* \see setRestrictedLayers()
|
||||
* \see restrictToLayers()
|
||||
*/
|
||||
QList< QgsMapLayer * > restrictedLayers() const;
|
||||
|
||||
@ -117,6 +138,7 @@ class CORE_EXPORT QgsMapClippingRegion
|
||||
//! Geometry of clipping region (in destination map coordinates and CRS)
|
||||
QgsGeometry mGeometry;
|
||||
|
||||
bool mRestrictToLayers = false;
|
||||
QgsWeakMapLayerPointerList mRestrictToLayersList;
|
||||
|
||||
FeatureClippingType mFeatureClip = FeatureClippingType::ClipToIntersection;
|
||||
|
||||
@ -2016,7 +2016,7 @@ QgsLayoutMapClippingWidget::QgsLayoutMapClippingWidget( QgsLayoutItemMap *map )
|
||||
{
|
||||
mBlockUpdates = true;
|
||||
mMapItem->beginCommand( tr( "Change Atlas Clipping Layers" ) );
|
||||
mMapItem->atlasClippingSettings()->setLayersToClip( mLayerModel->layersChecked( ) );
|
||||
mMapItem->atlasClippingSettings()->setRestrictToLayers( true );
|
||||
mMapItem->endCommand();
|
||||
mBlockUpdates = false;
|
||||
}
|
||||
@ -2027,7 +2027,7 @@ QgsLayoutMapClippingWidget::QgsLayoutMapClippingWidget( QgsLayoutItemMap *map )
|
||||
{
|
||||
mBlockUpdates = true;
|
||||
mMapItem->beginCommand( tr( "Change Atlas Clipping Layers" ) );
|
||||
mMapItem->atlasClippingSettings()->setLayersToClip( QList< QgsMapLayer * >() );
|
||||
mMapItem->atlasClippingSettings()->setRestrictToLayers( false );
|
||||
mMapItem->endCommand();
|
||||
mBlockUpdates = false;
|
||||
}
|
||||
@ -2136,8 +2136,8 @@ void QgsLayoutMapClippingWidget::updateGuiElements()
|
||||
mAtlasClippingTypeComboBox->setCurrentIndex( mAtlasClippingTypeComboBox->findData( static_cast< int >( mMapItem->atlasClippingSettings()->featureClippingType() ) ) );
|
||||
mForceLabelsInsideCheckBox->setChecked( mMapItem->atlasClippingSettings()->forceLabelsInsideFeature() );
|
||||
|
||||
mRadioClipAllLayers->setChecked( mMapItem->atlasClippingSettings()->layersToClip().isEmpty() );
|
||||
mRadioClipSelectedLayers->setChecked( !mMapItem->atlasClippingSettings()->layersToClip().isEmpty() );
|
||||
mRadioClipAllLayers->setChecked( !mMapItem->atlasClippingSettings()->restrictToLayers() );
|
||||
mRadioClipSelectedLayers->setChecked( mMapItem->atlasClippingSettings()->restrictToLayers() );
|
||||
mLayerModel->setLayersChecked( mMapItem->atlasClippingSettings()->layersToClip() );
|
||||
|
||||
mClipToItemCheckBox->setChecked( mMapItem->itemClippingSettings()->enabled() );
|
||||
|
||||
@ -74,6 +74,14 @@ class TestQgsLayoutItemMapAtlasClippingSettings(unittest.TestCase):
|
||||
p.removeMapLayer(l1.id())
|
||||
self.assertCountEqual(settings.layersToClip(), [l2])
|
||||
|
||||
settings.setRestrictToLayers(False)
|
||||
self.assertFalse(settings.restrictToLayers())
|
||||
self.assertEqual(len(spy), 4)
|
||||
|
||||
settings.setRestrictToLayers(True)
|
||||
self.assertTrue(settings.restrictToLayers())
|
||||
self.assertEqual(len(spy), 5)
|
||||
|
||||
def testSaveRestore(self):
|
||||
p = QgsProject()
|
||||
l1 = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
|
||||
@ -89,6 +97,7 @@ class TestQgsLayoutItemMapAtlasClippingSettings(unittest.TestCase):
|
||||
settings.setEnabled(True)
|
||||
settings.setFeatureClippingType(QgsMapClippingRegion.FeatureClippingType.NoClipping)
|
||||
settings.setForceLabelsInsideFeature(True)
|
||||
settings.setRestrictToLayers(True)
|
||||
settings.setLayersToClip([l2])
|
||||
|
||||
# save map to xml
|
||||
@ -107,6 +116,7 @@ class TestQgsLayoutItemMapAtlasClippingSettings(unittest.TestCase):
|
||||
self.assertEqual(map2.atlasClippingSettings().featureClippingType(), QgsMapClippingRegion.FeatureClippingType.NoClipping)
|
||||
self.assertTrue(map2.atlasClippingSettings().forceLabelsInsideFeature())
|
||||
self.assertEqual(map2.atlasClippingSettings().layersToClip(), [l2])
|
||||
self.assertTrue(map2.atlasClippingSettings().restrictToLayers())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -40,6 +40,10 @@ class TestQgsMapClippingRegion(unittest.TestCase):
|
||||
self.assertEqual(len(region.restrictedLayers()), 0)
|
||||
region.setRestrictedLayers([layer, layer2])
|
||||
self.assertCountEqual(region.restrictedLayers(), [layer, layer2])
|
||||
region.setRestrictToLayers(False)
|
||||
self.assertFalse(region.restrictToLayers())
|
||||
region.setRestrictToLayers(True)
|
||||
self.assertTrue(region.restrictToLayers())
|
||||
|
||||
def testAppliesToLayer(self):
|
||||
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
|
||||
@ -58,6 +62,16 @@ class TestQgsMapClippingRegion(unittest.TestCase):
|
||||
region.setRestrictedLayers([layer, layer2])
|
||||
self.assertTrue(region.appliesToLayer(layer))
|
||||
self.assertTrue(region.appliesToLayer(layer2))
|
||||
self.assertTrue(region.appliesToLayer(layer3))
|
||||
|
||||
region.setRestrictToLayers(True)
|
||||
self.assertTrue(region.appliesToLayer(layer))
|
||||
self.assertTrue(region.appliesToLayer(layer2))
|
||||
self.assertFalse(region.appliesToLayer(layer3))
|
||||
|
||||
region.setRestrictedLayers([])
|
||||
self.assertFalse(region.appliesToLayer(layer))
|
||||
self.assertFalse(region.appliesToLayer(layer2))
|
||||
self.assertFalse(region.appliesToLayer(layer3))
|
||||
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ class TestQgsMapClippingUtils(unittest.TestCase):
|
||||
region = QgsMapClippingRegion(QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))'))
|
||||
region2 = QgsMapClippingRegion(QgsGeometry.fromWkt('Polygon((0 0, 0.1 0, 0.1 2, 0 2, 0 0))'))
|
||||
region2.setRestrictedLayers([layer])
|
||||
region2.setRestrictToLayers(True)
|
||||
ms = QgsMapSettings()
|
||||
ms.addClippingRegion(region)
|
||||
ms.addClippingRegion(region2)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user