3

I have the following code snippet I run in QGIS 3.4 which goes through a list of shapefiles (my_wild) and runs a polygon to lines process. It performs the process and adds them to the map as expected, but how do I do work on them from there?

I want to perform some attribute work and do further processing on the outputs. The print function returns:

output_f8c71c3d_8781_4057_8295_3dd7099f214d

but then the next poly2line_result.startEditing() function returns:

AttributeError: 'str' object has no attribute 'startEditing'


for f in my_wild:
    #get perimeter line for the study area
    poly2line_result = processing.runAndLoadResults(
        'qgis:polygonstolines', 
        {
            'INPUT':f,
            'OUTPUT':'memory:'
        }) ['OUTPUT']
    print(poly2line_result)
    #add attribute field and commit changes
    #poly2line_result.getFeatures()
    poly2line_result.startEditing()
    if poly2line_result.dataProvider().fieldNameIndex("Segments") == -1:
            poly2line_result.dataProvider().addAttributes([QgsField("Segments",QVariant.Double)])
    poly2line_result.commitChanges()
  • Result, as expected, is an 'AttributeError' because your 'poly2line_result' is a 'str' object without 'startEditing' method. So, it is preferable that you use 'run' processing method, create a QgsVectorLayer with poly2line_result string and load it to Map Legend with 'QgsProject.instance().addMapLayer'. Please, see my answer. – xunilk Sep 7 '19 at 5:50
1

Result, as expected, is an AttributeError because your poly2line_result is a 'str' object without 'startEditing' method. So, it is preferable that you use 'run' processing method, create a QgsVectorLayer with poly2line_result string and load it to Map Legend with 'QgsProject.instance().addMapLayer'. You can adapt your code from mine (because I only used a vector layer) that it looks as follow:

import processing

f = iface.activeLayer()

poly2line_result = processing.run('qgis:polygonstolines', 
                                                {'INPUT':f,
                                                 'OUTPUT':'memory'}) ['OUTPUT']

print(poly2line_result)

layer = QgsVectorLayer(poly2line_result, 'Lines', 'ogr')
QgsProject.instance().addMapLayer(layer)

#add attribute field and commit changes
#poly2line_result.getFeatures()
layer.startEditing()
if layer.dataProvider().fieldNameIndex("Segments") == -1:
    layer.dataProvider().addAttributes([QgsField("Segments",QVariant.Double)])
layer.commitChanges()

I ran above code with a polygon layer and I got result of following image; where it can be observed that attributes table of vector line has "Segments" field as expected.

enter image description here

|improve this answer|||||
1

Try to modify your code like this:

poly2line_result = processing.run('qgis:polygonstolines', {'INPUT':f,'OUTPUT':'memory'}) ['OUTPUT']
linelayer = poly2line_result['OUTPUT']
newField = QgsField("Segments",QVariant.Double)
linelayer.dataProvider().addAttributes([newField])
linelayer.updateFields()
idx = linelayer.fields().lookupField('Segments')
# in a loop
  attrs = { idx : your_value }
  fid = your_feature.id()
  linelayer.dataProvider().changeAttributeValues({ fid : attrs })
|improve this answer|||||

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.