PyQGIS – Copying Attributes from Point Layer to Memory Linestring Layer in PyQGIS

copyfields-attributespythonqgis

I've stacked a little bit with copying attributes.

I have a Point Layer created from .csv file. For each feature in this layer, I'm creating a new Polyline geometry in memory layer. Cannot add attributes from Point layer to newly created Polyline.

Here's my code:

#mcvLayer - Point Layer

nl = Create_layer("New_line", "LineString")
nl.show_layer
hh = iface.activeLayer()
a = QgsPoint(0,0) # Here will be another point

for point in mcvLayer.dataProvider().getFeatures():
        pattrs = point.attributes()
        pgeom = point.geometry().asPoint()
        nl.create_line(a, pgeom, pattrs)

class Create_layer(object):

def __init__(self,name,type):
    self.type = type
    self.name = name
    self.layer = QgsVectorLayer(self.type, self.name, "memory")
    self.pr = self.layer.dataProvider()
def create_line(self, startpoint, endpoint, attributelist):
    self.feat = QgsFeature()
    self.feat.setGeometry(QgsGeometry.fromPolyline([startpoint,endpoint]))
    self.pr.addFeatures([attributelist])
    self.layer.updateExtents()

But all I get is:

TypeError: QgsVectorDataProvider.addFeatures(list-of-QgsFeature) ->
(bool, list-of-QgsFeature): argument 1 has unexpected type 'list'

I'm using QGIS 2.8.1

Best Answer

You create a memory layer without any fields. To set some attributes you need corresponding fields. When creating memory layers you can give field definitions as part of the argument type:

self.layer = QgsVectorLayer(self.type+'?field_a:string(20)&field_b:int', self.name, "memory")

For your layer to work you have to define the same fields as for the Point layer. Another way is to add attributes to the created memory layer.

prov = mcvLayer.dataProvider()
fields = prov.fields()
nl = Create_layer("New_line", "LineString", fields)

Then in init():

def __init__(self, name, type, fields):
    self.type = type
    self.name = name
    self.layer = QgsVectorLayer(self.type, self.name, "memory")
    self.layer.startEditing()
    for field in fields:
        self.layer.addAttribute(field)
    self.layer.commitChanges()
    self.pr = self.layer.dataProvider()
    QgsMapLayerRegistry.instance().addMapLayer(self.layer)

def create_line(self, startpoint, endpoint, attributelist):
    feat = QgsFeature(fields)
    feat.setGeometry(QgsGeometry.fromPolyline([startpoint,endpoint]))
    feat.setAttributes(attributelist)
    self.pr.addFeatures([feat])
    self.layer.updateExtents()

Hope you get the idea.

Related Question