[GIS] Saving vector memory layer to file using PyQGIS gives empty file

layersmemorypyqgisstandalone

I am learning to write standalone scripts with Pyqgis.

I am trying to read a file with a big shapefile of polylines (64MB), create a memory layer, copy the features to, and save into another file all the features of the memory layer.

The code looks ok, no errors, but I get an empty (no features) output file from memory layer.

Why ? I can list the features into the memory layer, but they are not write to the output file.

This is the code:

#!/usr/bin/env python

from qgis.core import *

QgsApplication.setPrefixPath("/usr", True)
qgs = QgsApplication([], False)

qgs.initQgis()


# Origin vector layer into file 
vlayer = QgsVectorLayer("BigShapefile64MB.shp", "bigShapeMB", "ogr")

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

mem_layer = QgsVectorLayer("Lines?crs=epsg:4326&index=yes", "duplicated_layer", "memory")

# Add field and populate to memory
attr = vlayer.dataProvider().fields().toList()
mem_layer_data = mem_layer.dataProvider()
mem_layer_data.addAttributes(attr)
mem_layer.updateFields()
mem_layer_data.addFeatures(feats)

mem_layer.updateExtents()

# Check mem layer
print " Mem Layer features:", mem_layer_data.featureCount()
print "fields:", len(mem_layer_data.fields())
e = mem_layer_data.extent()
print "extent:", e.xMinimum(), e.yMinimum(), e.xMaximum(), e.yMaximum()


mem_layer.commitChanges()

crs=QgsCoordinateReferenceSystem("epsg:4326")

# Save memory layer to file
error = QgsVectorFileWriter.writeAsVectorFormat(mem_layer, "outShapefile.shp", "UTF-8", crs , "ESRI Shapefile")

if error == QgsVectorFileWriter.NoError:
    print "success! writing new memory layer"

qgs.exitQgis()

All ok, but outShapefile.shp has 0 features, is created, but empty, why ?

Note: (last line: qgs.exitQgis() give me a segmentation fault, but this not the problem, I think. )

Best Answer

When defining a new memory layer, you need to include one of the following as the data source:

  • Point - For a point layer.
  • LineString - For a line layer.
  • Polygon - For a polygon layer.

So in your case, you should replace:

mem_layer = QgsVectorLayer("Lines?crs=epsg:4326&index=yes", "duplicated_layer", "memory")

with

mem_layer = QgsVectorLayer("LineString?crs=epsg:4326&index=yes", "duplicated_layer", "memory")
Related Question