2

So, I'm trying to automate the creation of layers in QGIS using Python the data in CSV files to drive symbology shading, layer naming and file naming. The part I'm really having trouble with is saving the layers as new files after I'm done grouping them. I think the problem is in this line:

QgsVectorFileWriter.writeAsVectorFormatV2(QgsVectorLayer(csvGroupedLayer.name()), csvLayerUriList[csvLayerIndex], QgsCoordinateTransformContext(), csvSaveOptions)

I would really like to know how to automagically turn that QgsLayerTreeLayer object into a QgsVectorLayer object.

I know I don't have to show all my code, but I felt like it couldn't hurt. I figured, maybe I would get some feedback. I'm sure the code is super verbose, but I'm a beginner. Also, it's unfinished and uncommented, so sorry about that. I would be happy to repost with comments if people would like.

from qgis.core import QgsProject, QgsVectorLayer, QgsLayerTreeGroup, QgsLayerTreeLayer, QgsLayoutNodesItem
from PyQt5 import QtGui
import csv
import os
from pathlib import Path, PureWindowsPath

QgsLayoutNodesItem.deselectNode
root = QgsProject.instance().layerTreeRoot()
#dataGroup = root.addGroup("")
dataGroup = QgsLayerTreeGroup("data_layers")
root.addChildNode(dataGroup)

csvSrcRawUri = r"E:\Jason\Documents\2020-01\mapping project\gis\test_automate_all\sources\datasetsrekeithsstudy"
csvSrcUri = csvSrcRawUri.replace("\\","/")
#print(csvSrcUri)
csvSrcUriList = []
csvSrcUriIndex = 0
csvLayerRawUri = r"E:\Jason\Documents\2020-01\mapping project\gis\test_automate_all\layers\datasets"
csvLayerUriList = []
csvLayerUriIndex = 0
csvLayerNameList = []
csvLayerNameIndex = 0
csvLayerIndex = 0

for root, dirs, files in os.walk(csvSrcUri):
    for file in files:
        if(file.endswith(".csv")):
            csvSrcUriList.append(os.path.join(root,file))
            csvLayerNameList.append(os.path.join(file))

csvSrcUriList.sort()
csvLayerNameList.sort()

for file in csvSrcUriList:
    filePrefix = 'file:///'
    fileSuffix = '?delimeter=,'
    fileLocation = filePrefix + file.replace("\\", "/") + fileSuffix
    csvSrcUriList[csvSrcUriIndex] = fileLocation
    csvSrcUriIndex += 1

while csvLayerUriIndex < csvSrcUriIndex:
    csvLayerUri = csvLayerRawUri.replace("\\","/") + "/" + csvLayerNameList[csvLayerUriIndex]
    csvLayerUriList.append(csvLayerUri)
    csvLayerUriIndex += 1
print(csvLayerUriList)

for file in csvLayerNameList:
    layerName =  file.replace(".csv", "")
    csvLayerNameList[csvLayerNameIndex] = layerName
    csvLayerNameIndex += 1
#print(csvSrcUriList)
#print(csvLayerNameList)

for layerName in csvLayerNameList:
    csvSrcUri = csvSrcUriList[csvLayerIndex]
    csvLayerName = csvLayerNameList[csvLayerIndex]
    csvLayer = QgsVectorLayer(csvSrcUri, csvLayerName, 'delimitedtext')
    QgsProject.instance().addMapLayer(csvLayer)
    if not csvLayer or not csvLayer.isValid():
        csvAddLayerErrorMsg = csvLayerName + " failed to load!"
        print(csvAddLayerErrorMsg)
    root = QgsProject.instance().layerTreeRoot()
    csvGroup = root.findGroup(dataGroup.name())
    csvOriginalLayer = root.findLayer(csvLayer.id())
    csvGroupedLayer = csvOriginalLayer.clone()
    csvGroup.insertChildNode(-1, csvGroupedLayer)
    csvSaveOptions = QgsVectorFileWriter.SaveVectorOptions()
    csvSaveOptions.driverName = "CSV"
    csvSaveOptions.fileEncoding = "UTF-8"
    QgsVectorFileWriter.writeAsVectorFormatV2(QgsVectorLayer(csvGroupedLayer.name()), csvLayerUriList[csvLayerIndex], QgsCoordinateTransformContext(), csvSaveOptions)
    parent = csvOriginalLayer.parent()
    parent.removeChildNode(root.findLayer(csvLayer.id()))
    csvLayerIndex +=1

"""
layers = list(QgsProject.instance().mapLayers().values())

myColumn = ''
myRangeList = []
myOpacity = 1

ranges = []

gradientIndex = 0
gradientLevels = 20

while gradientIndex < gradientLevels:
    myMin = gradientIndex * 5
    myMax = (gradientIndex + 1) * 5
    myLabel = "{}-{}".format(myMin, myMax)
    colorRGB = '{:x}'.format(255-(gradientIndex * (255 // gradientLevels)))
    myColor = QtGui.QColor("#{}{}{}".format(colorRGB, colorRGB, colorRGB))
    ranges.append((myMin, myMax, myLabel, myColor))
    gradientIndex += 1

for myMin, myMax, myLabel, myColor in ranges:
    mySymbol = QgsSymbol.defaultSymbol(2)
    mySymbol.setColor(myColor)
    mySymbol.setOpacity(myOpacity)
    myRange = QgsRendererRange(myMin, myMax, mySymbol, myLabel)
    myRangeList.append(myRange)

myRenderer = QgsGraduatedSymbolRenderer('', myRangeList)
myRenderer.setMode(QgsGraduatedSymbolRenderer.Quantile)
myRenderer.setClassAttribute(myColumn)

for layer in layers:
    layerType = layer.type()
    if layerType == QgsMapLayerType.VectorLayer:
        layer.setRenderer(myRenderer)
"""
3
  • It's actually easy to get a QgsVectorLayer from your QgsLayerTreeLayer. You can do it in this way: my_qgs_vector_layer = my_qgs_layer_tree_layer.layer() You can find that in the docs. – Germán Carrillo Dec 30 '20 at 1:41
  • @Germán Thanks so much. I usually use this resource for API documentation. Is there any difference between that and the one you provided? – sajonainnominado Dec 30 '20 at 17:22
  • I find the one that I mentioned easier to read. But it might be a matter of taste. If you feel fine using the Python API docs, then go ahead with it. – Germán Carrillo Dec 30 '20 at 18:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.