2

I have some large QGIS-Projects where I would like to filter the layerlist that is used for the advanced snapping options. Even if there are a lot of layers used in the project I only have to adjust the snapping options for some of these layers.

enter image description here

I know that I could set the snapping-options programatically for single layers but I need to adjust the snapping options dynamically during my work (snapping mode, tolerance and so on) so this is not an option.

I think I found the item that is used to display the layerlist:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

dlg = iface.mainWindow().findChild(QDialog, 'SnappingOption')

st_widget=dlg.findChildren(QStackedWidget)[0]

test= st_widget.children()[2].children()

l_widget= test[1]
l_widget.setVisible(False)
print l_widget

But how can I filter this list in order to show only some of my layers?

0

I don't know how to directly filter the dialog containing all the layer, but maybe this code could be a workaround, assuming that you need to select only some of your layers and to set specified snapping options for them (same options for the selected layers).

I think it should be clearer if you have a look on this code (run it as a script from the Processing Toolbox):

##Select_Layers=multiple vector

from qgis.core import *

# Get the input files
layers = Select_Layers.split(';')

# Iterate over each selected layer...
for item in QgsMapLayerRegistry.instance().mapLayers().values():
    for layer in layers:
        if item.source() == layer:
            # and set proper snapping options for it
            QgsProject.instance().setSnapSettingsForLayer(item.id(), True, 2, 1, 4, True)

With reference to the terms between the parentheses in the last line of the code, following the sequence:

  • item.id() is the id of your layer (taken from your selection, so don't modify it);
  • Available options: True (to enable the layer snapping); False (to disable the layer snapping);
  • Available options: 0 (to vertex); 1 (to segment); 2 (to vertex and segment);
  • Available options: 0 (layer units); 1 (pixels); 2 (map units);
  • 4 is the tolerance (set it as you want);
  • True: avoid intersections.

For example, if you have four layers ('a', 'b', 'c', 'd') and you run the code only for the layer 'b':

enter image description here

you will have:

enter image description here

as desired. I hope you was looking for something similar to this.

  • Thanks for this idea but the users need to be able to change the snapping settings interactively and can't use pyqgis themselves while their work – markgraeflerland Dec 13 '16 at 8:19
0

In the meantime I found a solution on my yown:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

def filter_snapping_list():
    dlg = iface.mainWindow().findChild(QDialog, 'SnappingOption')
    snapping_mode=dlg.findChild(QComboBox).currentText()
    #check that snapping mode is set to "Advanced"

    #if snapping_mode=="Erweitert": #I use the German UI, so it's "Erweitert" and not "Advanced" in my case
    if snapping_mode=="Advanced": #Choice if English UI is used
        print "Snapping Mode ok"   
        st_widget=dlg.findChildren(QStackedWidget)[0]
        test= st_widget.children()[2].children()
        l_widget= test[1]
        root = l_widget.invisibleRootItem()
        child_count = root.childCount()
        for i in range(child_count):
            item = root.child(i)
            url = item.text(1) # text at first (0) column

            # [Name1, Name2] Names of the layer for which the Snapping should be accessible (Case sensitive)
            if item.text(1) in ["AP_LPO","AP_PPO","AX_BAHNVERKEHR"]:
                print "Found: "+url
            else:
                #Hide unwanted Layer from Snapping-Dialog-Layerlist
                item.setHidden(True)
    else:
        iface.messageBar().pushMessage("Error", "Set Snapping mode to advanced!", level=QgsMessageBar.CRITICAL, duration=3)

filter_snapping_list()

Before applying the filter: enter image description here

After applying the filter: enter image description here

Edit1: Here additionaly a way to interactively select the Layers in the TOC which should be available for the snapping settings:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

filter_List=[]

def filter_snapping_list():
    global filter_List
    print filter_List
    dlg = iface.mainWindow().findChild(QDialog, 'SnappingOption')
    snapping_mode=dlg.findChild(QComboBox).currentText()
    #check that snapping mode is set to "Advanced"

    #if snapping_mode=="Erweitert": #I use the German UI, so it's "Erweitert" and not "Advanced" in my case
    if snapping_mode=="Advanced": #Choice if English UI is used
        print "Snapping Mode ok"   
        st_widget=dlg.findChildren(QStackedWidget)[0]
        test= st_widget.children()[2].children()
        l_widget= test[1]
        root = l_widget.invisibleRootItem()
        child_count = root.childCount()
        for i in range(child_count):
            item = root.child(i)
            url = item.text(1) # text at first (0) column

            # [Name1, Name2] Names of the layer for which the Snapping should be accessible (Case sensitive)
            if item.text(1) in filter_List:
                print "Found: "+url
                item.setHidden(False)
            else:
                #Hide unwanted Layer from Snapping-Dialog-Layerlist
                item.setHidden(True)
    else:
        iface.messageBar().pushMessage("Error", "Set Snapping mode to advanced!", level=QgsMessageBar.CRITICAL, duration=3)

def get_filter_layers():
    selectedLayers = iface.legendInterface().selectedLayers()
    global filter_List
    filter_List=[]
    for i in selectedLayers:
        filter_List.append( i.name() )

get_filter_layers()
filter_snapping_list()

Only Selected Layers are shown in the Snapping Settings Dialog:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.