5

I'm writing a QGIS plugin that

  1. The user selects 2 input layers and fields via a combo box (which is fine).
  2. Creates a buffer around the first layer's features. (it's fine too)
  3. select elements of the second layer that are inside the buffer, which the user will choose the second layer via combo box also(here is the problem)
  4. it has a couple more combo boxes that show the second layer's fields. and I want to save user-defined attributes of the second layer's selected features into a list of lists.

Here is the code:

def run(self):
"""Run method """
    # region adding vector layers
    layers = self.iface.legendInterface().layers()
    layer_list = []
    for layer in layers:
        if layer.type() == qgis.core.QgsMapLayer.VectorLayer:
            layer_list.append(layer.name())
        else:
            continue
    # endregion

    # region first layer inputs
    self.cInput = self.dlg.comboBox_input_Crime
    self.cInput.clear()
    self.cInput.addItems(layer_list)
    # endregion

    # region second layer, layer and combo boxes
    self.pgInput = self.dlg.comboBox_input_polygon
    self.pgInput.clear()
    self.pgInput.addItems(layer_list)

    # these are the target fields of selected features that must be written in a list of list
    self.pgFactor = self.dlg.comboBox__factor_polygon 
    self.pgLyr = self.dlg.comboBox_layer_polygon

    # update fields
    def pgField_select():
        self.pgFactor.clear()
        self.pgLyr.clear()
        selectedLayerIndex = self.pgInput.currentIndex()
        selectedLayer = layers[selectedLayerIndex]
        fields = [field.name() for field in selectedLayer.pendingFields()]

        self.pgFactor.addItems(fields)
        self.pgLyr.addItems(fields)

    self.pgInput.currentIndexChanged.connect(pgField_select)
    # endregion

    # show the dialog
    self.dlg.show()

    result = self.dlg.exec_()

    if result:

        # get points as list
        self.pic = self.cInput.currentIndex()

        self.buff =  processing.runalg('qgis:fixeddistancebuffer', layers[self.pic], 10 , 5, True, None)

        self.buffLyr = qgis.core.QgsVectorLayer(self.buff['OUTPUT'], "buffer1", "ogr")

        qgis.core.QgsMapLayerRegistry.instance().addMapLayer(self.buffLyr)


        #here is the problem, it does not selects anything
        processing.runalg("qgis:selectbylocation", layers[self.pgInput.currentIndex()], self.buffLyr, ['touches'], 0)

How can I select features by location and save their attributes in a list of a list like:

[['river', 'Dallas'], ['pond', 'Houston'], ...]
9
  • 1
    If you run the tool manually from QGIS Gui in processing toolbox on the same layer does it work? If yes, go to processing > History > and you will find the correct parameters to pass to "qgis:selectbylocation". If no, make sure that your layers are in the same CRS.
    – YoLecomte
    Commented Oct 24, 2017 at 7:03
  • 1
    Please see my answer, the geometric predicates, should be pass as a list
    – YoLecomte
    Commented Oct 24, 2017 at 7:24
  • 1
    The selected object will be highlighted on the canvas after the selection and the corresponding line in the attribute table will also be highlighted.
    – YoLecomte
    Commented Oct 24, 2017 at 11:33
  • 1
    What happen if you replace touches by within??
    – YoLecomte
    Commented Oct 24, 2017 at 11:52
  • 1
    and you also probably don't get the right layer with your layers[self.pInput.currentIndex()] because the index of your combobox may be not the same as the index in your layers list... Do you use Qt Combobox or QgsMapLayerCombobox?
    – YoLecomte
    Commented Oct 24, 2017 at 12:03

1 Answer 1

7

As you can see below the right syntax to use qgis:selectbylocation algorithm with processing is (using QGIS 2.18.12):

processing.runalg("qgis:selectbylocation", layer1, layer2, ['touches'], 0, 0)

So you must give the geometric predicates as a list (['touches', 'intersect', 'within', ...])

After that, you can access the selected features of a layer with:

layer.selectedFeatures()

which is a list of the selected features then you can loop on this list and append the attributes of your selected features with something like:

list_of_attribute_list = []
for feat in layer.selectedFeatures():
    attributes = feat.attributes()
    list_of_attribute_list.append(attributes)

at the end of the loop, you will get your list of attributes filled with the attributes of your previously selected features.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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