5

I am working with QGIS 3.4 and I have written the next code in the Python editor. This aims to create a layer without geometry and save it as CSV file. This works fine but my problem concerns the two last lines: The layer displayed to the layer panel are not permanent despite the CSV file.

from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtCore import *

root = QgsProject.instance().layerTreeRoot()

# create memory layer
layer = QgsVectorLayer("Point", "tp2", "memory")
pr = layer.dataProvider()

# Enter editing mode
layer.startEditing()

# add fields
pr.addAttributes( [ QgsField("name", QVariant.String),
                QgsField("age",  QVariant.Int),
                QgsField("size", QVariant.Double) ] )

# Commit changes
layer.commitChanges()

# add a feature
feat = QgsFeature(layer.fields())
#feat.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(10,10)))

feat.setAttribute('name', 'john')
feat.setAttribute('age', 10)
feat.setAttribute('size', 180)

pr.addFeatures( [ feat ] )

# Commit changes
layer.commitChanges()

# get absolute file path
projectPath = QDir(QgsProject.instance().absolutePath())
file =  QFileInfo(projectPath,"output.csv")

error = QgsVectorFileWriter.writeAsVectorFormat( layer,file.absoluteFilePath(), "utf-8",driverName="CSV")

if error[0] == QgsVectorFileWriter.NoError:
    print("success! writing new memory layer")
else:
    print("faillure! writing new memory layer,", error)

QgsProject.instance().addMapLayer(layer,False)
root.addChildNode(QgsLayerTreeLayer(layer))

Edit: erratum in the code

1
  • When I run your script, I get added to the layers panel the tp2 memory layer. You want to delete tp2 and add the csv in the layers panel? Commented Dec 4, 2019 at 8:14

3 Answers 3

8

You can simply update the data source of the layer once it is written to disk:

# reference to memory layer
layer = iface.activeLayer()

# save location
geopackage = r"C:\path\to\geopackage.gpkg"

# write the layer to disk
options = QgsVectorFileWriter.SaveVectorOptions()
options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer 
options.layerName = layer.name() 
_writer = QgsVectorFileWriter.writeAsVectorFormatV2(layer, geopackage, QgsCoordinateTransformContext(), options) 

# change the data source
layer.setDataSource(geopackage + f'|layername={layer.name()}', layer.name(), 'ogr')
1
  • Works perfectly! For those using QGIS 3.20+, writeAsVectorFormatV2 is deprecated. Use writeAsVectorFormatV3 instead.
    – Andre Geo
    Commented Jan 25 at 16:14
6

The following script exports your csv if successful and adds it to your QGIS project.

The point layer'tp2' is therefore not added. Replace your if block with mine and delete your last 2 lines.

if error[0] == QgsVectorFileWriter.NoError:
    print("success! writing new memory layer")
    uri = "file:///"+file.absoluteFilePath()+"?delimiter=%s" % (",") # path and delimiter of my csv
    layer_csv = QgsVectorLayer(uri, 'output_csv', 'delimitedtext') # Parameters of my csv 
    QgsProject.instance().addMapLayer(layer_csv) # Add the csv 

else:
    print("faillure! writing new memory layer,", error)

Tell me if this is the result you were expecting.

1
  • thank you, so the created file must be opened and the memory layer must be deleted. I was wrong: I though there was a method to make permanent the memory layer (in the user interface of QGIS, a contextual menu contains an action to do this). Nevertheless I think this is a waste: the layer exists with data but we need to create another layer with the same data.
    – vincentM
    Commented Dec 4, 2019 at 21:02
3

your last two lines of your script are just adding your in memory layer again. If you want to add the saved out csv, take a look at this post Using non-spatial csv with PyQGIS?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.