예제 #1
0
def layerTreeInsertionPoint(tree_view: QgsLayerTreeView) -> tuple:
    """
    Direct copy of the code QgisApp::layerTreeInsertionPoint for QGIS < 3.10
    """
    insert_group = tree_view.layerTreeModel().rootGroup()
    current = tree_view.currentIndex()
    index = 0

    if current.isValid():

        index = current.row()

        current_node = tree_view.currentNode()
        if current_node:

            # if the insertion point is actually a group, insert new layers into the group
            if QgsLayerTree.isGroup(current_node):

                # if the group is embedded go to the first non-embedded group, at worst the top level item
                insert_group = firstGroupWithoutCustomProperty(
                    current_node, "embedded")

                return InsertionPoint(insert_group, 0)

            # otherwise just set the insertion point in front of the current node
            parent_node = current_node.parent()
            if QgsLayerTree.isGroup(parent_node):

                # if the group is embedded go to the first non-embedded group, at worst the top level item
                insert_group = firstGroupWithoutCustomProperty(
                    parent_node, "embedded")
                if parent_node != insert_group:
                    index = 0

    return InsertionPoint(insert_group, index)
예제 #2
0
 def parseTreeRec(self, treeLeaf):
     for el in treeLeaf.children():
         if QgsLayerTree.isLayer(el):
             l = el.layer()
             self.sortInto(l, self.layerDict, self.hierarchyDefinition)
         elif QgsLayerTree.isGroup(el):
             self.parseTreeRec(el)
예제 #3
0
    def createContextMenu(self):
        menu = QMenu()
        actions: QgsLayerTreeViewDefaultActions = self.layerTreeView.defaultActions()
        if not self.layerTreeView.currentIndex().isValid():
            # 不在图层上右键
            self.actionAddGroup = actions.actionAddGroup(menu)
            menu.addAction(self.actionAddGroup)
            menu.addAction('Expand All', self.layerTreeView.expandAll)
            menu.addAction('Collapse All', self.layerTreeView.collapseAll)
            return menu

        node: QgsLayerTreeNode = self.layerTreeView.currentNode()

        if QgsLayerTree.isGroup(node):
            # 图组操作
            print('group')
            pass
        elif QgsLayerTree.isLayer(node):
            print('layer')
            self.actionZoomToLayer = actions.actionZoomToLayer(self.mapCanvas, menu)
            menu.addAction(self.actionZoomToLayer)
            # 图层操作
            layer = self.layerTreeView.currentLayer()
            if layer.type() == QgsMapLayerType.VectorLayer:
                # 矢量图层
                actionOpenAttributeDialog = QAction('open Attribute Table', menu)
                actionOpenAttributeDialog.triggered.connect(lambda: self.openAttributeDialog(layer))
                menu.addAction(actionOpenAttributeDialog)
            else:
                # 栅格图层
                pass
        else:
            print('node type is none')

        return menu
 def _getPosOfPrevGroup(self, groupName):
     topLevelGroups = [
         child.name() for child in self.tocRoot.children()
         if QgsLayerTree.isGroup(child)
     ]
     if groupName in topLevelGroups:
         return topLevelGroups.index(groupName)
     else:
         return None
예제 #5
0
 def nodeOrder(self, group):
     nodeorder = []
     layerTree = QgsLayerTree()
     for node in group:
         if QgsLayerTree.isGroup(node):
             groupname = node.name()
             nodeorder.append(groupname)
             for child in self.nodeOrder(node.children()):
                 nodeorder.append(groupname + '-' + child)
         elif QgsLayerTree.isLayer(node):
             nodeorder.append(node.layer().name())
     return nodeorder
 def nodeOrder(self, group):
     nodeorder = []
     layerTree = QgsLayerTree()
     for node in group:
         if QgsLayerTree.isGroup(node):
             groupname = node.name()
             nodeorder.append(groupname)
             for child in self.nodeOrder(node.children()):
                 nodeorder.append(groupname + '-' + child)
         elif QgsLayerTree.isLayer(node):
             nodeorder.append(node.layer().name())
     return nodeorder
예제 #7
0
 def insertInto(self, origin, destination, reset_initial_visibility):
     for el in origin.children():
         if QgsLayerTree.isLayer(el):
             node = destination.addLayer(el.layer())
             node.setItemVisibilityChecked(
                 self.treeRoot.findLayer(el.layer()).isVisible()
             )
         elif QgsLayerTree.isGroup(el):
             node = destination.addGroup(el.name())
             self.insertInto(el, node, reset_initial_visibility)
         if reset_initial_visibility:
             # overwrite visibility with previously saved visibility
             node.setItemVisibilityChecked(el.itemVisibilityChecked())
예제 #8
0
 def get_layers_and_visibility_from_node(
         root: QgsLayerTree,
         node: QgsLayerTreeNode) -> List[Tuple[QgsMapLayer, bool]]:
     layers = []
     child: QgsLayerTreeNode
     for child in node.children():
         if root.isGroup(child):
             # noinspection PyTypeChecker
             layers += LayerHandler.get_layers_and_visibility_from_node(
                 root, child)
         else:
             layer = child.layer()
             visibility = child.itemVisibilityChecked(
             ) and node.itemVisibilityChecked()
             if layer:
                 layers.append((layer, visibility))
     return layers
예제 #9
0
def firstGroupWithoutCustomProperty(group: QgsLayerTreeGroup,
                                    _property: str) -> QgsLayerTreeGroup:
    """
    Taken from QgsLayerTreeUtils::firstGroupWithoutCustomProperty
    :param group:
    :param _property:
    :return:
    """
    # if the group is embedded go to the first non-embedded group, at worst the top level item
    while group.customProperty(_property):
        if not group.parent():
            break
        if QgsLayerTree.isGroup(group.parent()):
            group = group.parent()
        else:
            dbg_info(group)
            assert False

    return group
예제 #10
0
    def groupSelected(self):
        nodes = self.mView.selectedNodes(True)
        if len(nodes) < 2 or not QgsLayerTree.isGroup(nodes[0].parent()):
            return

        parentGroup = nodes[0].parent()
        insertIdx = parentGroup.children().index(nodes[0])

        newGroup = QgsLayerTreeGroup(self.uniqueGroupName(parentGroup))
        for node in nodes:
            newGroup.addChildNode(node.clone())

        parentGroup.insertChildNode(insertIdx, newGroup)

        for node in nodes:
            group = node.parent()
            if group != None:
                group.removeChildNode(node)
        self.mView.setCurrentIndex(
            self.mView.layerTreeModel().node2index(newGroup))
    def isPluginLayerTreeNode(self, node: QgsLayerTree) -> bool:
        # for some reason even the normal nodes are behaving like groups...
        if QgsLayerTree.isGroup(node):
            # unfortunately this does not work in Python, it's cpp only...
            # group = QgsLayerTree.toGroup(node)

            # All my other attempts also failed miserably
            # group = self.layerTree.findGroup(self.groupName)
            # return group is get_group()
            pass
        else:
            layer = self.project.mapLayer(node.layerId())

            if layer in (self.simplifiedSegmentsLayer, self.verticesLayer, self.candidatesLayer, self.finalLayer):
                return True

            if self.wasBaseRasterLayerInitiallyInLegend and layer is self.baseRasterLayer:
                return True
            if self.wasSegmentsLayerInitiallyInLegend and layer is self.segmentsLayer:
                return True

        return False
예제 #12
0
    def createContextMenu(self):
        menu = QMenu()
        actionAddGroup = QgisHelper.createAction(menu, "&Add GroupLayer",
                                                 self.addGroup)
        actionAddVectorLayer = QgisHelper.createAction(menu,
                                                       "&Add VectorLayer",
                                                       self.addVectorLayer)
        actionZoomToGroup = QgisHelper.createAction(menu, "&Zoom To Group",
                                                    self.zoomToGroup)
        actionRenameGroupOrLayer = QgisHelper.createAction(
            menu, "&Rename", self.rename)
        actionRemoveLayer = QgisHelper.createAction(menu, "&Remove",
                                                    self.removeLayer)
        actionGroupSelected = QgisHelper.createAction(menu, "&Group Selected",
                                                      self.groupSelected)
        actionZoomToLayer = QgisHelper.createAction(menu, "&Zoom To Layer",
                                                    self.zoomToLayer)
        actionOpenAttributetable = QgisHelper.createAction(
            menu, "&Open Attribute Table", self.openAttriTable)
        actionSaveAs = QgisHelper.createAction(menu, "&Save as...",
                                               self.saveAs)
        actionLayerProperty = QgisHelper.createAction(menu, "&Property",
                                                      self.layerProperty)
        self.actionShowOverview = QgisHelper.createAction(
            menu, "&Show in overview...", self.showOverview, None, None, None,
            True)

        idx = self.mView.currentIndex()
        node = self.mView.layerTreeModel().index2node(idx)
        if not idx.isValid():
            #global menu
            menu.addAction(actionAddGroup)
            menu.addAction(actionAddVectorLayer)
#             menu.addAction( QgsApplication.getThemeIcon( "/mActionExpandTree.png" ),  "&Expand All" , self.mView,  "expandAll()"  )
#             menu.addAction( QgsApplication.getThemeIcon( "/mActionCollapseTree.png" ), "&Collapse All" , self.mView,  "collapseAll()"  )
        elif (node != None):
            if (QgsLayerTree.isGroup(node)):
                menu.addAction(actionZoomToGroup)
                menu.addAction(actionRemoveLayer)
                #       menu.addAction( QgsApplication.getThemeIcon( "/mActionSetCRS.png" ),
                #                        tr( "&Set Group CRS" ), QgisApp.instance(), SLOT( legendGroupSetCRS() ) );
                menu.addAction(actionRenameGroupOrLayer)

                if (str(self.mView.selectedNodes(True)) >= 2):
                    menu.addAction(actionGroupSelected)
                menu.addAction(actionAddGroup)
                menu.addAction(actionAddVectorLayer)

            elif (QgsLayerTree.isLayer(node)):
                menu.addAction(actionZoomToLayer)
                menu.addAction(actionRemoveLayer)
                menu.addAction(self.actionShowOverview)
                if self.mView.currentLayer().type() == QgsMapLayer.VectorLayer:
                    menu.addAction(actionOpenAttributetable)
                menu.addAction(actionLayerProperty)
                menu.addAction(actionSaveAs)
#                 menu.addAction( actions.actionShowInOverview( menu ) )
#                 if layer.type() == QgsMapLayer.RasterLayer :
#                     menu.addAction(  "&Zoom to Best Scale (100%)" , QgisApp.instance(), " legendLayerZoomNative() " )
#                     rasterLayer =  qobject_cast<QgsRasterLayer *>( layer );
#                     if ( rasterLayer && rasterLayer.rastertype() != QgsRasterLayer.Palette )
#                       menu.addAction( tr( "&Stretch Using Current Extent" ), QgisApp.instance(), SLOT( legendLayerStretchUsingCurrentExtent() ) );
#                   }

#                 menu.addAction( QgsApplication.getThemeIcon( "/mActionRemoveLayer.svg" ), tr( "&Remove" ), QgisApp.instance(), " removeLayer() ");

#       // duplicate layer
#       QAction* duplicateLayersAction = menu.addAction( QgsApplication.getThemeIcon( "/mActionDuplicateLayer.svg" ), tr( "&Duplicate" ), QgisApp.instance(), SLOT( duplicateLayers() ) );
#
#       // set layer scale visibility
#       menu.addAction( tr( "&Set Layer Scale Visibility" ), QgisApp.instance(), SLOT( setLayerScaleVisibility() ) );
#
#       // set layer crs
#       menu.addAction( QgsApplication.getThemeIcon( "/mActionSetCRS.png" ), tr( "&Set Layer CRS" ), QgisApp.instance(), SLOT( setLayerCRS() ) );
#
#       // assign layer crs to project
#       menu.addAction( QgsApplication.getThemeIcon( "/mActionSetProjectCRS.png" ), tr( "Set &Project CRS from Layer" ), QgisApp.instance(), SLOT( setProjectCRSFromLayer() ) );
#
#       menu.addSeparator();
#
#       if ( layer && layer.type() == QgsMapLayer.VectorLayer )
#       {
#         QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( layer );
#
#         QAction *toggleEditingAction = QgisApp.instance().actionToggleEditing();
#         QAction *saveLayerEditsAction = QgisApp.instance().actionSaveActiveLayerEdits();
#         QAction *allEditsAction = QgisApp.instance().actionAllEdits();
#
#         // attribute table
#         menu.addAction( QgsApplication.getThemeIcon( "/mActionOpenTable.png" ), tr( "&Open Attribute Table" ),
#                          QgisApp.instance(), SLOT( attributeTable() ) );
#
#         // allow editing
#         int cap = vlayer.dataProvider().capabilities();
#         if ( cap & QgsVectorDataProvider.EditingCapabilities )
#         {
#           if ( toggleEditingAction )
#           {
#             menu.addAction( toggleEditingAction );
#             toggleEditingAction.setChecked( vlayer.isEditable() );
#           }
#           if ( saveLayerEditsAction && vlayer.isModified() )
#           {
#             menu.addAction( saveLayerEditsAction );
#           }
#         }
#
#         if ( allEditsAction.isEnabled() )
#           menu.addAction( allEditsAction );
#
#         // disable duplication of memory layers
#         if ( vlayer.storageType() == "Memory storage" && self.mView.selectedLayerNodes().count() == 1 )
#           duplicateLayersAction.setEnabled( false );
#
#         // save as vector file
#         menu.addAction( tr( "Save As..." ), QgisApp.instance(), SLOT( saveAsFile() ) );
#         menu.addAction( tr( "Save As Layer Definition File..." ), QgisApp.instance(), SLOT( saveAsLayerDefinition() ) );
#
#         if ( !vlayer.isEditable() && vlayer.dataProvider().supportsSubsetString() && vlayer.vectorJoins().isEmpty() )
#           menu.addAction( tr( "&Filter..." ), QgisApp.instance(), SLOT( layerSubsetString() ) );
#
#         menu.addAction( actions.actionShowFeatureCount( menu ) );
#
#         menu.addSeparator();
#       }
#       else if ( layer && layer.type() == QgsMapLayer.RasterLayer )
#       {
#         menu.addAction( tr( "Save As..." ), QgisApp.instance(), SLOT( saveAsRasterFile() ) );
#         menu.addAction( tr( "Save As Layer Definition File..." ), QgisApp.instance(), SLOT( saveAsLayerDefinition() ) );
#       }
#       else if ( layer && layer.type() == QgsMapLayer.PluginLayer && self.mView.selectedLayerNodes().count() == 1 )
#       {
#         // disable duplication of plugin layers
#         duplicateLayersAction.setEnabled( false );
#       }

#                 addCustomLayerActions( menu, layer );
#
#       if ( layer && QgsProject.instance().layerIsEmbedded( layer.id() ).isEmpty() )
#         menu.addAction( tr( "&Properties" ), QgisApp.instance(), SLOT( layerProperties() ) );

#             if ( node.parent() != self.mView.layerTreeModel().rootGroup() ):
#                 menu.addAction( actions.actionMakeTopLevel( menu ) )
            menu.addAction(actionRenameGroupOrLayer)

            if (len(self.mView.selectedNodes(True)) >= 2):
                menu.addAction(actionGroupSelected)

#       if ( self.mView.selectedLayerNodes().count() == 1 )
#       {
#         QgisApp* app = QgisApp.instance();
#         menu.addAction( tr( "Copy Style" ), app, SLOT( copyStyle() ) );
#         if ( app.clipboard().hasFormat( QGSCLIPBOARD_STYLE_MIME ) )
#         {
#           menu.addAction( tr( "Paste Style" ), app, SLOT( pasteStyle() ) );
#         }
#       }

        return menu
예제 #13
0
    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return

        node = self.index2node(index)
        legend_node = self.index2legendNode(index)

        if legend_node and role == Qt.DecorationRole:
            pixmap = pixmapForLegendNode(legend_node)
            if pixmap:
                return pixmap

        if not node:
            return super().data(index, role)

        if role == Qt.FontRole:
            f = iface.layerTreeView().font()

            if node.customProperty("plugins/customTreeIcon/font"):
                f.fromString(node.customProperty("plugins/customTreeIcon/font"))
            elif QgsLayerTree.isLayer(node):
                f = self.layerTreeNodeFont(QgsLayerTree.NodeLayer)
            elif QgsLayerTree.isGroup(node):
                f = self.layerTreeNodeFont(QgsLayerTree.NodeGroup)

            if index == self.currentIndex():
                f.setUnderline(not f.underline())

            if QgsLayerTree.isLayer(node):
                _, _, scale = self.legendMapViewData()
                layer = node.layer()
                if (not node.isVisible() and (not layer or layer.isSpatial())) or (
                    layer and not layer.isInScaleRange(scale)
                ):
                    f.setItalic(not f.italic())

            return f

        if role == Qt.ForegroundRole:
            color = None
            if node.customProperty("plugins/customTreeIcon/textColor"):
                color = QColor(node.customProperty("plugins/customTreeIcon/textColor"))
            elif QgsLayerTree.isGroup(node):
                if self.settings.value("group_text_color"):
                    color = QColor(self.settings.value("group_text_color"))
            else:
                if self.settings.value("layer_text_color"):
                    color = QColor(self.settings.value("layer_text_color"))
            if color:
                if QgsLayerTree.isLayer(node):
                    _, _, scale = self.legendMapViewData()
                    layer = node.layer()
                    if (not node.isVisible() and (not layer or layer.isSpatial())) or (
                        layer and not layer.isInScaleRange(scale)
                    ):
                        color.setAlpha(128)
                return color

        if role == Qt.BackgroundRole:
            if node.customProperty("plugins/customTreeIcon/backgroundColor"):
                return QColor(
                    node.customProperty("plugins/customTreeIcon/backgroundColor")
                )
            elif QgsLayerTree.isGroup(node):
                if self.settings.value("group_background_color"):
                    return QColor(self.settings.value("group_background_color"))
            else:
                if self.settings.value("layer_background_color"):
                    return QColor(self.settings.value("layer_background_color"))

        # Override data for DecorationRole (Icon)
        if role == Qt.DecorationRole and index.column() == 0:
            icon = None
            pixmap = None

            # If a custom icon was set for this node
            if node.customProperty("plugins/customTreeIcon/icon"):
                icon = QIcon(node.customProperty("plugins/customTreeIcon/icon"))

            # If an icon was set for the node type
            elif QgsLayerTree.isGroup(node):
                if self.settings.value("defaulticons/group", ""):
                    icon = QIcon(self.settings.value("defaulticons/group"))
                else:
                    icon = QIcon(":/images/themes/default/mActionFolder.svg")

            elif QgsLayerTree.isLayer(node):
                layer = node.layer()

                if not layer:
                    return super().data(index, role)

                if layer.type() == QgsMapLayer.RasterLayer:
                    if self.settings.value("defaulticons/raster", ""):
                        icon = QIcon(self.settings.value("defaulticons/raster"))
                    else:
                        icon = QIcon(":/images/themes/default/mIconRaster.svg")

                if layer.type() == QgsMapLayer.VectorLayer:

                    if self.testFlag(
                        QgsLayerTreeModel.ShowLegend
                    ) and self.legendEmbeddedInParent(node):
                        size = iface.layerTreeView().iconSize()

                        legend_node = self.legendNodeEmbeddedInParent(node)
                        pixmap = pixmapForLegendNode(legend_node)

                    else:

                        if layer.geometryType() == QgsWkbTypes.PointGeometry:
                            if self.settings.value("defaulticons/point", ""):
                                icon = QIcon(self.settings.value("defaulticons/point"))
                            else:
                                icon = QIcon(
                                    ":/images/themes/default/mIconPointLayer.svg"
                                )
                        elif layer.geometryType() == QgsWkbTypes.LineGeometry:
                            if self.settings.value("defaulticons/line", ""):
                                icon = QIcon(self.settings.value("defaulticons/line"))
                            else:
                                icon = QIcon(
                                    ":/images/themes/default/mIconLineLayer.svg"
                                )
                        elif layer.geometryType() == QgsWkbTypes.PolygonGeometry:
                            if self.settings.value("defaulticons/polygon", ""):
                                icon = QIcon(
                                    self.settings.value("defaulticons/polygon")
                                )
                            else:
                                icon = QIcon(
                                    ":/images/themes/default/mIconPolygonLayer.svg"
                                )
                        elif layer.geometryType() == QgsWkbTypes.NullGeometry:
                            if self.settings.value("defaulticons/nogeometry", ""):
                                icon = QIcon(
                                    self.settings.value("defaulticons/nogeometry")
                                )
                            else:
                                icon = QIcon(
                                    ":/images/themes/default/mIconTableLayer.svg"
                                )

                try:
                    if layer.type() == QgsMapLayer.MeshLayer:
                        if self.settings.value("defaulticons/mesh", ""):
                            icon = QIcon(self.settings.value("defaulticons/mesh"))
                        else:
                            icon = QIcon(":/images/themes/default/mIconMeshLayer.svg")

                except AttributeError:
                    pass

            # Special case: In-edition vector layer. Draw an editing icon over
            # the custom icon. Adapted from QGIS source code (qgslayertreemodel.cpp)
            if (pixmap or icon) and QgsLayerTree.isLayer(node):
                layer = node.layer()
                if layer and isinstance(layer, QgsVectorLayer) and layer.isEditable():
                    icon_size = iface.layerTreeView().iconSize().width()
                    if icon_size == -1:
                        icon_size = 16
                    if not pixmap and icon:
                        pixmap = QPixmap(icon.pixmap(icon_size, icon_size))
                    painter = QPainter(pixmap)
                    painter.drawPixmap(
                        0,
                        0,
                        icon_size,
                        icon_size,
                        QgsApplication.getThemeIcon(
                            ("/mIconEditableEdits.svg")
                            if layer.isModified()
                            else ("/mActionToggleEditing.svg")
                        ).pixmap(icon_size, icon_size),
                    )
                    painter.end()
                    del painter

            if pixmap:
                return pixmap
            if icon:
                return icon

        # call QgsLayerTreeModel implementation
        return super().data(index, role)
예제 #14
0
 def _getPosOfPrevGroup(self, groupName):
     topLevelGroups = [child.name() for child in self.tocRoot.children() if QgsLayerTree.isGroup(child)]
     if groupName in topLevelGroups:
         return topLevelGroups.index(groupName)
     else:
         return None