[GIS] Adding attributes to the table PyQgis

pyqgispython-2.7qgis

I want to save number of vertices of every object from my line vector layer in attribute table. The code I have was able to:

  1. Save in table correct number of vertices for layer with only Polylines.
  2. Save in table correct number of vertices for layer with only MultiPolylines.

But it was useless when on the layer there were both MultiPolylines and Polylines (it was counting correct number of vertices (both for multi and poly) but it didn't add everything in proper order to table)

I wrote 'it was able' because suddenly (I changed nothing) error occurred:

line 12, in <module>
suma= sum (int (i) for i in  vertsMulti)
TypeError: 'int' object is not callable

and now it doesn't work for MultiPolylines. (Still works for Polylines)

So, my questions are:

Why the error occur, and how to handle it?

How to make the code adding to table number of vertices when there are both MultiPolylines and Polylines on the layer.

The code is:

from PyQt4.QtCore import *        
layer = qgis.utils.iface.activeLayer()
feat = layer.getFeatures()
provider = layer.dataProvider()

a = [] 
b = []
for feature in feat:
    if feature.geometry().isMultipart(): 
       vertices = feature.geometry().asMultiPolyline()
       vertsMulti = [len(v) for v in vertices]
       suma = sum (int (i) for i in vertsMulti) # should sum number of vertices of every segment of MultiPolyline but ERROR happens
       a.append(suma)
    else:
       vertices = feature.geometry().asPolyline()
       n = len(vertices)
       b.append(n)

ab = b+a
field = QgsField("vert", QVariant.Int)
provider.addAttributes([field])
layer.updateFields()        
idx = layer.fieldNameIndex('vert')

for vert in ab:
    new_values = {idx : int(vert)}
    provider.changeAttributeValues({ab.index(vert):new_values})
    print new_values

layer.updateFeature(feature)

Best Answer

For the first question, the error means that for an unknown reason in your data, the result of vertsMulti is not a list but an integer in suma = sum (int (i) for i in vertsMulti) (line 12)

Try with a less verbose approach

a = [] 
b = []
for feature in layer.getFeatures():
    if feature.geometry().isMultipart(): 
       a.append(sum(len(i)  for i in feature.geometry().asMultiPolyline()))
    else:
       b.append(len(feature.geometry().asPolyline()))

For the second question, the result of a+b is a list and sum(a,b) an integer

Then look a "Modify Vector Layer" in Using Vector Layers

The logic is (in the same loop)

a = [] 
b = []
for feature in layer.getFeatures():
    if feature.geometry().isMultipart(): 
       a.append(sum(len(i)  for i in feature.geometry().asMultiPolyline()))
       feature.setAttribute('vert',a) 
    else:
       b.append(len(feature.geometry().asPolyline()))
       feature.setAttribute('vert',b) 
Related Question