10

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)

Taras
  • 32,823
  • 4
  • 66
  • 137
Joseph
  • 75,746
  • 7
  • 171
  • 282

2 Answers2

8

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")

QgsProject.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 (Ctrl+Alt+P) 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

Taras
  • 32,823
  • 4
  • 66
  • 137
xunilk
  • 29,891
  • 4
  • 41
  • 80
4

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

feat.setAttributes(elem.attributes())
Detlev
  • 4,608
  • 19
  • 26