6

Seems like a basic operation using PyQGIS but can't see what I am missing. I want to create a memory layer with the exact same features and attributes from a shapefile. I have looked several posts such as:

The following script creates a memory layer, gets the correct fields and correct number of features but it doesn't populate the fields with data:

input = "C:/Users/Me/Desktop//example.shp"
layer = QgsVectorLayer(example,"line","ogr")

temp = QgsVectorLayer("LineString?crs=epsg:4326", "result", "memory")
temp_data = temp.dataProvider()
temp.startEditing()

layer_fields = layer.dataProvider().fields().toList()
attr = layer.dataProvider().fields().toList()
temp_data.addAttributes(attr)
temp.updateFields()

feat = QgsFeature()
for elem in layer.getFeatures():
    feat.setGeometry(elem.geometry())
    feat.setAttributes(attr)
    temp.addFeatures([feat])
    temp.updateExtents()

temp.commitChanges()
QgsMapLayerRegistry.instance().addMapLayer(temp)
2

Hmm, you set attributes to a list of fields instead a list of values. Try this:

feat.setAttributes(elem.attributes())
3

I modified your code to consider a polygon vector layer. However, if you get the features of the original layer, you only need a little portion of your original code for working adequately (without any editing session if you use the QgsDataProvider class). This is my code:

input = "/home/zeito/pyqgis_data/polygon8.shp"

layer = QgsVectorLayer(input,"polygon","ogr")

feats = [ feat for feat in layer.getFeatures() ]

temp = QgsVectorLayer("Polygon?crs=epsg:32612", 
                      "result", 
                      "memory")

QgsMapLayerRegistry.instance().addMapLayer(temp)

temp_data = temp.dataProvider()

attr = layer.dataProvider().fields().toList()
temp_data.addAttributes(attr)
temp.updateFields()

temp_data.addFeatures(feats)

When above code was running at the Python Console of QGIS, fields of original layer were correctly copied at the memory layer named "result"; as can be observed at the next image. It worked for me.

enter image description here

On the other hand, your approach of set attributes to a list of fields instead a list of values is correct because if I comment these code lines:

attr = layer.dataProvider().fields().toList()
temp_data.addAttributes(attr)

it doesn't populate the fields with data; as it also observed at the next image:

enter image description here

  • I very much appreciate your answer, much shorter alternative to what I had. Thank you! – Joseph Dec 16 '15 at 10:13

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.