Skip to main content
4 of 5
added 2195 characters in body
francois
  • 315
  • 1
  • 8

Making output shapefile taking fields of input, and adding new field populated with list using PyQGIS?

I found a couple of good answers like [here][1] for example, but I do not manage to adapt them and make them work...

What i am trying to do: take the input, create new output with same fields, add a new field with values calculated from another field. For the moment, I managed to get the new values for the new field in a list:

from collections import Counter as counter

layer = qgis.utils.iface.activeLayer()
features = layer.getFeatures()

# find the index of the 'relict_id' field.
idx = layer.fieldNameIndex('RELICT_ID')

relict_id = []
for feat in features:
    attrs = feat.attributes()
    relict_id.append(attrs[idx])

relict_id_new = [x for x in relict_id]

c = counter(relict_id)
idx = 0
while idx in range(len(relict_id)):
    rel_id = relict_id[idx]  
    if c[rel_id] != 1:
        for x in range(c[rel_id]):
            relict_id_new[idx+x] = '{}_{}'.format(relict_id[idx],x)
        idx += c[rel_id]
    else:
        idx +=1

I would like now to adapt this [answer][1], but all I get is a bunch of errors. I tried to get rid off Processings since it does not seem to work for me (QGIS 2.18.2). I am not understanding pretty well the implication of the processes, I do not know if it is the good way to do it and what are the problems.

Here is the code for creating the new shapefile and new field:

##testes=group
##Ratio =name
##layer=vector
##output_file=output vector

from PyQt4.QtCore import QVariant, QFileInfo
from qgis.core import QGis, QgsFeature, QgsField, QgsFields, QgsProject
import processing

layer= iface.activeLayer().dataProvider().dataSourceUri()
layer = path[:path.rfind('|')]

mylayer = QgsVectorLayer(layer, "inventaris_points_in_roi_single_new", "ogr")
if not mylayer.isValid():
    print("Layer failed to load!")

vectorLayer = processing.getObject(mylayer)
provider = vectorLayer.dataProvider()

New_layer= processing.getObject(layer)
fields = QgsFields()
fields = provider.fields()
fields.append(QgsField('AREA', QVariant.Double,'',20,3))
fields.append(QgsField('PERIMETER', QVariant.Double,'',20,3))
fields.append(QgsField('RATIO', QVariant.Double,'',20,3))

writer = processing.VectorWriter(output_file, None, fields.toList(),
                              QGis.WKBMultiPolygon, New_layer.crs())

features = processing.features(vectorLayer)
for feat in features:
    writer.addFeature(feat)

del writer

And the error :

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "c:/users/hocquetfp/appdata/local/temp/tmp_oajpe.py", line 18, in <module>
    vectorLayer = processing.getObject(mylayer)
  File "C:/Program Files/QGIS 2.18/apps/qgis/./python/plugins\processing\tools\dataobjects.py", line 216, in getObject
    ret = getObjectFromUri(uriorname)
  File "C:/Program Files/QGIS 2.18/apps/qgis/./python/plugins\processing\tools\dataobjects.py", line 244, in getObjectFromUri
    if normalizeLayerSource(layer.source()) == normalizeLayerSource(uri):
  File "C:/Program Files/QGIS 2.18/apps/qgis/./python/plugins\processing\tools\dataobjects.py", line 222, in normalizeLayerSource
    source = source.replace('\\', '/')
AttributeError: 'QgsVectorLayer' object has no attribute 'replace'

And of course, make the link between the two codes. [1]: Creating new layer from another one and adding new fields with Qgis processing python scripts?

francois
  • 315
  • 1
  • 8