Friday 29 May 2015

qgis plugins - pyqgis: select features inside a buffer, then return some attributes of the selection as a list


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'],...]



Answer



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.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...