I can see a few potential problems with your script. Firstly, you have not passed a provider argument to your vector layer constructor. Secondly, your processAlgorithm()
method is returning an empty tuple instead of a dictionary. And finally, an important piece of knowledge is that processing algorithms by default, are run in a background thread. Therefore, doing non thread-safe operations in the processAlgorithm()
method (such as adding layers to the project) will often result in (at worst) crashes or at least unpredictable behaviour. To avoid this problem, it is necessary to re-implement the flags()
method and return the QgsProcessingAlgorithm.FlagNoThreading
flag.
The simplified algorithm below works for me and I am able to successfully edit vertices of the loaded layer.
from qgis.core import (QgsProcessingAlgorithm,
QgsProcessingParameterFile,
QgsProject,
QgsVectorLayer)
class CheckGcpPoints(QgsProcessingAlgorithm):
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFile('input_geojson', 'Properties GEOJSON', behavior=QgsProcessingParameterFile.File, extension='geojson'))
def processAlgorithm(self, parameters, context, model_feedback):
project = QgsProject.instance()
property_layer = QgsVectorLayer(parameters['input_geojson'],'Properties', 'ogr')
project.addMapLayer(property_layer)
return {}
def flags(self):
return QgsProcessingAlgorithm.FlagNoThreading
def name(self):
return 'PropertyEstimates2'
def displayName(self):
return 'Property Estimates2'
def group(self):
return 'SITE scripts'
def groupId(self):
return 'SITE scripts'
def createInstance(self):
return CheckGcpPoints()
I strongly encourage you to thoroughly read the documentation about Writing new Processing algorithms as Python scripts, especially the section on Flags.
P.S. there is one other slightly confusing element to your question in that you state you are trying to load a geojson, but your script makes several references to csv. This is confusing because delimited text layers cannot be edited directly in QGIS. Therefore, I have referenced only geojson in my answer and restricted the input file extension to 'geojson'.
Further Explanation
Of course, it doesn't make much sense to write a processing script just to load a layer. If you are doing further processing, you can just define an output parameter such as a QgsProcessingParameterFeatureSink
for your algorithm, and pass it to the 'OUTPUT'
parameter of the processing.run()
call. This way, any output layer, either temporary or file, will be handled/loaded safely, so you don't need to return the no threading flag. For example, here we run Fix Geometries on the input layer, and output the result to the feature sink.
from qgis.core import (QgsProcessingAlgorithm,
QgsProcessingParameterFile,
QgsProcessingParameterFeatureSink,
QgsProject,
QgsVectorLayer)
import processing
class CheckGcpPoints(QgsProcessingAlgorithm):
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFile('input_geojson', 'Properties GEOJSON', behavior=QgsProcessingParameterFile.File, extension='geojson'))
self.addParameter(QgsProcessingParameterFeatureSink('output', 'Result layer'))
def processAlgorithm(self, parameters, context, model_feedback):
params = {'INPUT': parameters['input_geojson'],
'OUTPUT': parameters['output']}
fixed = processing.run("native:fixgeometries", params, context=context, feedback=model_feedback, is_child_algorithm=True)
return {'RESULT': fixed['OUTPUT']}
def name(self):
return 'PropertyEstimates2'
def displayName(self):
return 'Property Estimates2'
def group(self):
return 'SITE scripts'
def groupId(self):
return 'SITE scripts'
def createInstance(self):
return CheckGcpPoints()
Best Answer
There are several things regarding your code:
the
uri
for a CSV file must include thefile://
prefix, as it is mentioned in the QGIS Documentation:there is a method called
isValid()
from theQgsDataProvider
class:As was already mentioned by @BERA in his comment the reason why you do not see anything on your map canvas is because your coordinates are with
,
(562834,932) instead of.
(562834.932).And there are several solutions available:
A solution without changing the input CSV file
This solution based on adding the
decimalPoint=','
info theuri
.A solution with modifying the input CSV file
There are several solutions available for replacing all commas with dots in your input CSV file:
And then use the following code (either refer to an updated CSV file or a newly created)
to get the output like this:
References: