4

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

  • point.attributes() returns a list. Thus you pass a list of list to addFeatures(), instead of a list of features – Detlev Jul 23 '15 at 14:04
  • Thanks, that's better. I'm updating feature attributes, but changes are not applied. During creating polylines - I have attributes. When layer is updated - I have only feature.id() and non-editable fields. – justhateme Jul 24 '15 at 14:17
4

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.

  • Thanks it's awesome, that helped me a lot. Unfortunately, can't vote for answer, low reputation. – justhateme Jul 24 '15 at 15:16

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.