2

I'm a python and pyqgis beginner (2 months-self taught) and I found it really hard to learn pyqgis API in comparison to the other APIs like kivy or Pyqt4.

I'm writing a qgis plugin that

  1. user select 2 input layers and fields via 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 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 list.

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)

however, I faced a nightmare learning pyqgis and completing this task.

how can I select features by location and save their attributes in a list of list like: [['river','Dallas'],['pond', 'Houston'],...]

  • 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 Oct 24 '17 at 7:03
  • 1
    Please see my answer, the geometric predicates, should be pass as a list – YoLecomte Oct 24 '17 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 Oct 24 '17 at 11:33
  • 1
    What happen if you replace touches by within?? – YoLecomte Oct 24 '17 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 Oct 24 '17 at 12:03
1

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 to 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 list fill with the attributes of your previously selected features.

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.