Skip to content

Commit

Permalink
[API] Add new map layer class "QgsGroupLayer"
Browse files Browse the repository at this point in the history
A group layer is a map layer which consists of a set of
child layers, where all component layers are rendered as a single
flattened object during map renders.

This commit sets up the base framework for QgsGroupLayer only
(i.e. no rendering changes).
  • Loading branch information
nyalldawson committed Nov 23, 2021
1 parent d75c4c8 commit bab7a91
Show file tree
Hide file tree
Showing 48 changed files with 885 additions and 18 deletions.
17 changes: 10 additions & 7 deletions python/core/auto_additions/qgis.py
Expand Up @@ -3,26 +3,29 @@
# monkey patching scoped based enum
QgsMapLayer.VectorLayer = QgsMapLayerType.VectorLayer
QgsMapLayer.VectorLayer.is_monkey_patched = True
QgsMapLayer.VectorLayer.__doc__ = ""
QgsMapLayer.VectorLayer.__doc__ = "Vector layer"
QgsMapLayer.RasterLayer = QgsMapLayerType.RasterLayer
QgsMapLayer.RasterLayer.is_monkey_patched = True
QgsMapLayer.RasterLayer.__doc__ = ""
QgsMapLayer.RasterLayer.__doc__ = "Raster layer"
QgsMapLayer.PluginLayer = QgsMapLayerType.PluginLayer
QgsMapLayer.PluginLayer.is_monkey_patched = True
QgsMapLayer.PluginLayer.__doc__ = ""
QgsMapLayer.PluginLayer.__doc__ = "Plugin based layer"
QgsMapLayer.MeshLayer = QgsMapLayerType.MeshLayer
QgsMapLayer.MeshLayer.is_monkey_patched = True
QgsMapLayer.MeshLayer.__doc__ = "Added in 3.2"
QgsMapLayer.MeshLayer.__doc__ = "Mesh layer. Added in QGIS 3.2"
QgsMapLayer.VectorTileLayer = QgsMapLayerType.VectorTileLayer
QgsMapLayer.VectorTileLayer.is_monkey_patched = True
QgsMapLayer.VectorTileLayer.__doc__ = "Added in 3.14"
QgsMapLayer.VectorTileLayer.__doc__ = "Vector tile layer. Added in QGIS 3.14"
QgsMapLayer.AnnotationLayer = QgsMapLayerType.AnnotationLayer
QgsMapLayer.AnnotationLayer.is_monkey_patched = True
QgsMapLayer.AnnotationLayer.__doc__ = "Contains freeform, georeferenced annotations. Added in QGIS 3.16"
QgsMapLayer.PointCloudLayer = QgsMapLayerType.PointCloudLayer
QgsMapLayer.PointCloudLayer.is_monkey_patched = True
QgsMapLayer.PointCloudLayer.__doc__ = "Added in 3.18"
QgsMapLayerType.__doc__ = 'Types of layers that can be added to a map\n\n.. versionadded:: 3.8\n\n' + '* ``VectorLayer``: ' + QgsMapLayerType.VectorLayer.__doc__ + '\n' + '* ``RasterLayer``: ' + QgsMapLayerType.RasterLayer.__doc__ + '\n' + '* ``PluginLayer``: ' + QgsMapLayerType.PluginLayer.__doc__ + '\n' + '* ``MeshLayer``: ' + QgsMapLayerType.MeshLayer.__doc__ + '\n' + '* ``VectorTileLayer``: ' + QgsMapLayerType.VectorTileLayer.__doc__ + '\n' + '* ``AnnotationLayer``: ' + QgsMapLayerType.AnnotationLayer.__doc__ + '\n' + '* ``PointCloudLayer``: ' + QgsMapLayerType.PointCloudLayer.__doc__
QgsMapLayer.PointCloudLayer.__doc__ = "Point cloud layer. Added in QGIS 3.18"
QgsMapLayer.GroupLayer = QgsMapLayerType.GroupLayer
QgsMapLayer.GroupLayer.is_monkey_patched = True
QgsMapLayer.GroupLayer.__doc__ = "Composite group layer. Added in QGIS 3.24"
QgsMapLayerType.__doc__ = 'Types of layers that can be added to a map\n\n.. versionadded:: 3.8\n\n' + '* ``VectorLayer``: ' + QgsMapLayerType.VectorLayer.__doc__ + '\n' + '* ``RasterLayer``: ' + QgsMapLayerType.RasterLayer.__doc__ + '\n' + '* ``PluginLayer``: ' + QgsMapLayerType.PluginLayer.__doc__ + '\n' + '* ``MeshLayer``: ' + QgsMapLayerType.MeshLayer.__doc__ + '\n' + '* ``VectorTileLayer``: ' + QgsMapLayerType.VectorTileLayer.__doc__ + '\n' + '* ``AnnotationLayer``: ' + QgsMapLayerType.AnnotationLayer.__doc__ + '\n' + '* ``PointCloudLayer``: ' + QgsMapLayerType.PointCloudLayer.__doc__ + '\n' + '* ``GroupLayer``: ' + QgsMapLayerType.GroupLayer.__doc__
# --
Qgis.MessageLevel.baseClass = Qgis
# monkey patching scoped based enum
Expand Down
1 change: 1 addition & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -28,6 +28,7 @@ enum class QgsMapLayerType
VectorTileLayer,
AnnotationLayer,
PointCloudLayer,
GroupLayer,
};


Expand Down
106 changes: 106 additions & 0 deletions python/core/auto_generated/qgsgrouplayer.sip.in
@@ -0,0 +1,106 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsgrouplayer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsGroupLayer : QgsMapLayer
{
%Docstring(signature="appended")

A map layer which consists of a set of child layers, where all component layers are rendered as a single
flattened object during map renders.

Child layers are never owned by :py:class:`QgsGroupLayer`. References to layers in a group are stored as weak
references only, which wills be automatically cleaned up whenever the linked child layer is deleted.

.. versionadded:: 3.24
%End

%TypeHeaderCode
#include "qgsgrouplayer.h"
%End
public:

struct LayerOptions
{

explicit LayerOptions( const QgsCoordinateTransformContext &transformContext );
%Docstring
Constructor for LayerOptions.
%End

QgsCoordinateTransformContext transformContext;

};

QgsGroupLayer( const QString &name, const QgsGroupLayer::LayerOptions &options );
%Docstring
Constructor for a new QgsGroupLayer with the specified layer ``name``.

The ``options`` argument specifies load-time layer options.
%End
~QgsGroupLayer();

SIP_PYOBJECT __repr__();
%MethodCode
QString str = QStringLiteral( "<QgsGroupLayer: '%1'>" ).arg( sipCpp->name() );
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
%End

virtual QgsGroupLayer *clone() const /Factory/;

virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/;

virtual QgsRectangle extent() const;

virtual void setTransformContext( const QgsCoordinateTransformContext &context );

virtual bool readXml( const QDomNode &layerNode, QgsReadWriteContext &context );

virtual bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const;

virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &, StyleCategories categories = AllStyleCategories ) const;

virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );

virtual QgsDataProvider *dataProvider();

virtual QString htmlMetadata() const;

virtual void resolveReferences( QgsProject *project );


void setChildLayers( const QList< QgsMapLayer * > &layers );
%Docstring
Sets the child ``layers`` contained by the group.

This method does not take ownership of the layers, but rather assigns them to the group. Layers should be already added to
the parent :py:class:`QgsProject` wherever appropriate.

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

QList< QgsMapLayer * > childLayers();
%Docstring
Returns the child layers contained by the group.

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

};


/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsgrouplayer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
3 changes: 3 additions & 0 deletions python/core/auto_generated/qgsmaplayer.sip.in
Expand Up @@ -54,6 +54,9 @@ This is the base class for all map layer types (vector, raster).
case QgsMapLayerType::PointCloudLayer:
sipType = sipType_QgsPointCloudLayer;
break;
case QgsMapLayerType::GroupLayer:
sipType = sipType_QgsGroupLayer;
break;
default:
sipType = nullptr;
break;
Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -75,6 +75,7 @@
%Include auto_generated/qgsgeometryvalidator.sip
%Include auto_generated/qgsgml.sip
%Include auto_generated/qgsgmlschema.sip
%Include auto_generated/qgsgrouplayer.sip
%Include auto_generated/qgshistogram.sip
%Include auto_generated/qgshstoreutils.sip
%Include auto_generated/qgshtmlutils.sip
Expand Down
1 change: 1 addition & 0 deletions src/3d/qgs3dmapscene.cpp
Expand Up @@ -1085,6 +1085,7 @@ void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings )
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
notParsedLayers.push_back( layer->name() );
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/analysis/processing/qgsalgorithmfilterbygeometry.cpp
Expand Up @@ -310,6 +310,7 @@ QVariantMap QgsFilterByLayerTypeAlgorithm::processAlgorithm( const QVariantMap &
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}

Expand Down
6 changes: 6 additions & 0 deletions src/analysis/processing/qgsalgorithmpackage.cpp
Expand Up @@ -202,6 +202,12 @@ QVariantMap QgsPackageAlgorithm::processAlgorithm( const QVariantMap &parameters
feedback->pushDebugInfo( QObject::tr( "Packaging annotation layers is not supported." ) );
errored = true;
break;

case QgsMapLayerType::GroupLayer:
//not supported
feedback->pushDebugInfo( QObject::tr( "Packaging group layers is not supported." ) );
errored = true;
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/app/browser/qgsinbuiltdataitemproviders.cpp
Expand Up @@ -928,6 +928,7 @@ void QgsLayerItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *men
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}
} );
Expand Down
2 changes: 2 additions & 0 deletions src/app/labeling/qgsmaptoollabel.cpp
Expand Up @@ -88,6 +88,7 @@ bool QgsMapToolLabel::labelAtPosition( QMouseEvent *e, QgsLabelPosition &p )
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
return true;
}
}
Expand Down Expand Up @@ -178,6 +179,7 @@ bool QgsMapToolLabel::calloutAtPosition( QMouseEvent *e, QgsCalloutPosition &p,
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
return true;
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -5945,6 +5945,7 @@ void QgisApp::postProcessAddedLayer( QgsMapLayer *layer )
}

case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::GroupLayer:
break;

case QgsMapLayerType::PointCloudLayer:
Expand Down Expand Up @@ -7597,6 +7598,7 @@ bool QgisApp::openLayer( const QString &fileName, bool allowInteractive )
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::GroupLayer:
// not supported here yet!
break;

Expand Down Expand Up @@ -9040,6 +9042,7 @@ QString QgisApp::saveAsFile( QgsMapLayer *layer, const bool onlySelected, const
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
return QString();
}
return QString();
Expand Down Expand Up @@ -9208,6 +9211,7 @@ void QgisApp::saveStyleFile( QgsMapLayer *layer )

case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::GroupLayer:
break;

}
Expand Down Expand Up @@ -11259,6 +11263,7 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}
return false;
Expand Down Expand Up @@ -11561,6 +11566,7 @@ void QgisApp::saveEdits( QgsMapLayer *layer, bool leaveEditable, bool triggerRep
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}
}
Expand Down Expand Up @@ -11625,6 +11631,7 @@ void QgisApp::cancelEdits( QgsMapLayer *layer, bool leaveEditable, bool triggerR
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}
}
Expand Down Expand Up @@ -11842,6 +11849,7 @@ void QgisApp::updateLayerModifiedActions()
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}
}
Expand Down Expand Up @@ -12278,6 +12286,10 @@ void QgisApp::duplicateLayers( const QList<QgsMapLayer *> &lyrList )
unSppType = tr( "Plugin layer" );
break;

case QgsMapLayerType::GroupLayer:
unSppType = tr( "Group layer" );
break;

case QgsMapLayerType::VectorLayer:
{
if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( selectedLyr ) )
Expand Down Expand Up @@ -15911,6 +15923,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
break;

case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::GroupLayer:
break;

case QgsMapLayerType::AnnotationLayer:
Expand Down Expand Up @@ -16853,6 +16866,8 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page )
break;
}

case QgsMapLayerType::GroupLayer:
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Expand Up @@ -571,6 +571,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
break;

case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::GroupLayer:
break;

case QgsMapLayerType::PluginLayer:
Expand Down
1 change: 1 addition & 0 deletions src/app/qgshandlebadlayers.cpp
Expand Up @@ -298,6 +298,7 @@ void QgsHandleBadLayers::browseClicked()

case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::GroupLayer:
break;
}

Expand Down
3 changes: 2 additions & 1 deletion src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -521,7 +521,7 @@ void QgsIdentifyResultsDialog::addFeature( const QgsMapToolIdentify::IdentifyRes
break;
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::AnnotationLayer:

case QgsMapLayerType::GroupLayer:
break;
}
}
Expand Down Expand Up @@ -2115,6 +2115,7 @@ void QgsIdentifyResultsDialog::highlightFeature( QTreeWidgetItem *item )
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::GroupLayer:
return; // not supported
}

Expand Down
3 changes: 3 additions & 0 deletions src/app/qgslayerstylingwidget.cpp
Expand Up @@ -262,6 +262,7 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::GroupLayer:
break;
}

Expand Down Expand Up @@ -673,6 +674,7 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer()

case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::GroupLayer:
{
break;
}
Expand Down Expand Up @@ -828,6 +830,7 @@ bool QgsLayerStyleManagerWidgetFactory::supportsLayer( QgsMapLayer *layer ) cons
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::GroupLayer:
return false;
}
return false; // no warnings
Expand Down
1 change: 1 addition & 0 deletions src/app/qgslayertreeviewtemporalindicator.cpp
Expand Up @@ -64,6 +64,7 @@ void QgsLayerTreeViewTemporalIndicatorProvider::onIndicatorClicked( const QModel
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
case QgsMapLayerType::GroupLayer:
break;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -373,6 +373,7 @@ set(QGIS_CORE_SRCS
qgsgeometryoptions.cpp
qgsgml.cpp
qgsgmlschema.cpp
qgsgrouplayer.cpp
qgshistogram.cpp
qgshstoreutils.cpp
qgshtmlutils.cpp
Expand Down Expand Up @@ -1008,6 +1009,7 @@ set(QGIS_CORE_HDRS
qgsgeometryvalidator.h
qgsgml.h
qgsgmlschema.h
qgsgrouplayer.h
qgshistogram.h
qgshstoreutils.h
qgshtmlutils.h
Expand Down

0 comments on commit bab7a91

Please sign in to comment.