I am making a model with QGIS 3.4 graphical modeler that should open and process a layer from the GPKG located in the project folder.
Since the folder path may be changed, and QGIS does not allow using relative paths in the processing tools, I decided to write a script that will open a specific GPKG layer from the project folder without any requests to the user for the GPKG path .
Summarize, in the tool, I want to specify the name of the layer and the script opens it from the GPKG in the project folder and outputs it for further processing.
I am new to Pyqgis and Python in general, so the script ends with an unknown error. Here is my code:
from PyQt5.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
QgsFeatureSink,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterString,
QgsProject,
QgsVectorLayer)
import processing
class OpenGpkgLayer(QgsProcessingAlgorithm):
LAYERNAME = 'LAYERNAME'
OUTPUT = 'OUTPUT'
def tr(self, string):
return QCoreApplication.translate('Processing', string)
def createInstance(self):
return OpenGpkgLayer()
def name(self):
return 'OpenGpkgLayer'
def displayName(self):
return self.tr('Open GPKG Layer')
def group(self):
return self.tr('GPZU')
def groupId(self):
return 'GPZU'
def shortHelpString(self):
return self.tr("Open provided layer from GPZU gpkg")
def initAlgorithm(self, config=None):
self.addParameter(
QgsProcessingParameterString(
self.LAYERNAME,
self.tr('Input layer name')
)
)
self.addParameter(
QgsProcessingParameterFeatureSink(
self.OUTPUT,
self.tr('Output layer')
)
)
def processAlgorithm(self, parameters, context, feedback):
#a temporary layer name
lnameTranslated='test_test'
#open promted gpkg layer
layer = QgsVectorLayer(QgsProject.instance().readPath("./") +'/GPZU.gpkg|layername='+self.LAYERNAME,lnameTranslated,"ogr")
source = layer
(sink, dest_id) = self.parameterAsSink(
parameters,
self.OUTPUT,
context,
source.fields(),
source.wkbType(),
source.sourceCrs()
)
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
total = 100.0 / source.featureCount() if source.featureCount() else 0
features = source.getFeatures()
for current, feature in enumerate(features):
# Stop the algorithm if cancel button has been clicked
if feedback.isCanceled():
break
# Add a feature in the sink
sink.addFeature(feature, QgsFeatureSink.FastInsert)
# Update the progress bar
feedback.setProgress(int(current * total))
return {self.OUTPUT: dest_id}
I'm pretty sure I am doing it wrong. I tried a lot of variants (mainly random :-/) But script still fails with unknown error