From 53ace200c380cf8564cd6c68c20dd9885d688f02 Mon Sep 17 00:00:00 2001 From: Christian Heider Nielsen Date: Fri, 19 Apr 2024 15:30:03 +0200 Subject: [PATCH] bump --- jord/__init__.py | 2 +- jord/qgis_utilities/helpers/copying.py | 18 +++++ jord/qgis_utilities/helpers/groups.py | 96 ++++++++++++++++++------ jord/qgis_utilities/helpers/randomize.py | 37 ++++++--- 4 files changed, 121 insertions(+), 32 deletions(-) create mode 100644 jord/qgis_utilities/helpers/copying.py diff --git a/jord/__init__.py b/jord/__init__.py index f7bae3c..36e5534 100755 --- a/jord/__init__.py +++ b/jord/__init__.py @@ -16,7 +16,7 @@ __project__ = "Jord" __author__ = "Christian Heider Lindbjerg" -__version__ = "0.5.3" +__version__ = "0.5.4" __doc__ = r""" .. module:: jord :platform: Unix, Windows diff --git a/jord/qgis_utilities/helpers/copying.py b/jord/qgis_utilities/helpers/copying.py new file mode 100644 index 0000000..f94a7b3 --- /dev/null +++ b/jord/qgis_utilities/helpers/copying.py @@ -0,0 +1,18 @@ +from typing import Any + +__all__ = ["deepcopy_layer"] + + +def deepcopy_layer(layer) -> Any: + # noinspection PyUnresolvedReferences + from qgis.core import QgsFeatureRequest + + new_layer = layer.materialize( + QgsFeatureRequest().setFilterFids(layer.allFeatureIds()) + ) + + if True: + for r in layer.featureRendererGenerators(): + new_layer.addFeatureRendererGenerator(r) + + return new_layer diff --git a/jord/qgis_utilities/helpers/groups.py b/jord/qgis_utilities/helpers/groups.py index 2499a22..43b17e2 100644 --- a/jord/qgis_utilities/helpers/groups.py +++ b/jord/qgis_utilities/helpers/groups.py @@ -1,14 +1,40 @@ -from typing import Optional, Any +import logging +from typing import Optional, Any, Union # noinspection PyUnresolvedReferences -from qgis.core import QgsLayerTreeGroup +from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer, QgsProject + +# noinspection PyUnresolvedReferences +from qgis.utils import iface __all__ = ["duplicate_groups", "select_layer_in_group", "is_group_selected"] +from jord.qgis_utilities.helpers.copying import deepcopy_layer + +try: + from types import EllipsisType +except ImportError: + EllipsisType = type(...) + +logger = logging.getLogger(__name__) + def duplicate_groups( - group_to_duplicate, *, group_parent: Optional[Any] = None, appendix: str = " (Copy)" + group_to_duplicate, + *, + group_parent: Optional[Any] = None, + new_name: Union[str, EllipsisType, None] = None, ) -> QgsLayerTreeGroup: + if group_to_duplicate is None: + logger.error("Group was None") + return + + logger.info(f"Duplicating {group_to_duplicate.name()}") + + if new_name is ... or new_name == "" or new_name is None: + new_name = f"{group_to_duplicate.name()} (Copy)" + + sub_items = [] assert ( group_to_duplicate is not None ), f"{group_to_duplicate=} is required to create a duplicate group" @@ -19,25 +45,57 @@ def duplicate_groups( if group_parent is None: raise ValueError(f"Group parent was not found for {group_to_duplicate}") - new_group_parent = group_parent.addGroup(f"{group_to_duplicate.name()}{appendix}") + new_group_parent = group_parent.addGroup(new_name) for original_group_child in group_to_duplicate.children(): if isinstance(original_group_child, QgsLayerTreeGroup): - new_child_group = duplicate_groups( - original_group_child, group_parent=new_group_parent, appendix="" - ) # Only top level + new_sub_group, sub_sub_items = duplicate_groups( + original_group_child, group_parent=new_group_parent, new_name=... + ) + sub_items.extend([new_sub_group, *sub_sub_items]) + elif isinstance(original_group_child, QgsLayerTreeLayer): + sub_items.append( + duplicate_tree_node(new_group_parent, original_group_child) + ) else: - new_group_parent.addChildNode(original_group_child.clone()) - - return new_group_parent + logger.error(f"{original_group_child} no supported in duplication") + + return new_group_parent, sub_items + + +def duplicate_tree_node(new_group_parent, original_group_child): + original_layer = original_group_child.layer() + new_layer_copy = deepcopy_layer(original_layer) + QgsProject.instance().addMapLayer(new_layer_copy, False) + + if True: + new_layer_tree_node = QgsLayerTreeLayer( + new_layer_copy + ) # WORKS BUT MISSING STYLING + elif False: + # Does not WORK EITHER + new_layer_tree_node = QgsLayerTreeLayer( + new_layer_copy.id(), + original_layer.name(), + new_layer_copy.source(), + original_layer.providerType(), + ) + elif False: + # THIS DOES NOT WORK!!! + new_layer_tree_node = ( + original_group_child.clone() + ) # THIS JUST CREATES NEW VIEW of the same data!!!! + new_layer_tree_node.layer().setDataSource( + new_layer_copy.source(), + new_layer_copy.name(), + new_layer_copy.providerType(), + ) + else: + raise Exception() + + new_group_parent.addChildNode(new_layer_tree_node) def select_layer_in_group(layer_name, group_name): - # noinspection PyUnresolvedReferences - from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer, QgsProject - - # noinspection PyUnresolvedReferences - from qgis.utils import iface - group = QgsProject.instance().layerTreeRoot().findGroup(group_name) if group is not None: for child in group.children(): @@ -46,11 +104,5 @@ def select_layer_in_group(layer_name, group_name): def is_group_selected(group_name): - # noinspection PyUnresolvedReferences - from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer, QgsProject - - # noinspection PyUnresolvedReferences - from qgis.utils import iface - group = QgsProject.instance().layerTreeRoot().findGroup(group_name) return group in iface.layerTreeView().selectedNodes() diff --git a/jord/qgis_utilities/helpers/randomize.py b/jord/qgis_utilities/helpers/randomize.py index e33e6dc..68ff245 100644 --- a/jord/qgis_utilities/helpers/randomize.py +++ b/jord/qgis_utilities/helpers/randomize.py @@ -1,19 +1,27 @@ +import logging import uuid __all__ = ["randomize_field", "randomize_sub_tree_field"] +logger = logging.getLogger(__name__) + def randomize_sub_tree_field(selected_nodes, field_name: str) -> None: # noinspection PyUnresolvedReferences from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer - for group in selected_nodes: - if isinstance(group, QgsLayerTreeLayer): - randomize_field(group, field_name=field_name) - elif isinstance(group, QgsLayerTreeGroup): - randomize_sub_tree_field(group.children(), field_name=field_name) - else: - ... + if isinstance(selected_nodes, QgsLayerTreeLayer): + randomize_field(selected_nodes, field_name=field_name) + elif isinstance(selected_nodes, QgsLayerTreeGroup): + randomize_sub_tree_field(selected_nodes.children(), field_name=field_name) + else: + for group in iter(selected_nodes): + if isinstance(group, QgsLayerTreeLayer): + randomize_field(group, field_name=field_name) + elif isinstance(group, QgsLayerTreeGroup): + randomize_sub_tree_field(group.children(), field_name=field_name) + else: + ... def randomize_field(tree_layer, field_name: str) -> None: #: QgsLayerTreeLayer @@ -27,16 +35,27 @@ def randomize_field(tree_layer, field_name: str) -> None: #: QgsLayerTreeLayer :param tree_layer: :return: """ + if tree_layer is None: + logger.error(f"Tree layer was None") + return + # logger.info(f'Randomizing {field_name} in {tree_layer.layer().name()}') + layer = tree_layer.layer() field_idx = layer.fields().indexFromName(field_name) if field_idx >= 0: layer.startEditing() - layer.beginEditCommand(f"Regenerate {field_name}") + # layer.beginEditCommand(f"Regenerate {field_name}") + logger.info( + f"Randomizing {field_name}:{field_idx} in {tree_layer.layer().name()}" + ) + for i in range(layer.featureCount() + 1): layer.changeAttributeValue(i, field_idx, uuid.uuid4().hex) # layer.rollBack() - layer.endEditCommand() + # layer.endEditCommand() layer.commitChanges() + else: + logger.error(f"Did not find {field_name} in {layer.name()}")