I have a PyQGIS code made partially with graphical modeler and some personal completion.
Basically, based on this code I want:
- Type any city from my point shapefile, select it by attribute.
- Zoom to the point shapefile at a specific scale.
Issue: On the second part of the script, while trying to zoom at a specific scale, the map canvas freezes, trying to zoom in or out does not rescale the map canvas.
Example:
a) 4 cities as example
b) Selecting a specific city by attribute
c) Zooming to specific scale (from here starts the issue).
d) Trying to zoom out it does not render anything else except what it was already rendered.
This is the first part exported from graphical modeler which works perfecly:
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterVectorLayer('cities', 'Cities', types=[QgsProcessing.TypeVectorPoint], defaultValue=None))
self.addParameter(QgsProcessingParameterExpression('city_names', 'City Names', parentLayerParameterName='', defaultValue=''))
def processAlgorithm(self, parameters, context, model_feedback):
feedback = QgsProcessingMultiStepFeedback(1, model_feedback)
results = {}
outputs = {}
# Select by attribute
alg_params = {
'FIELD': 'Name',
'INPUT': parameters['cities'],
'METHOD': 0, # creating new selection
'OPERATOR': 0, # =
'VALUE': parameters['city_names']
}
outputs['SelectByAttribute'] = processing.run('qgis:selectbyattribute', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
This is the second part completed by me (where the issue starts at zoomscale):
iface.actionZoomToSelected().trigger()
layer = iface.activeLayer()
canvas_city = iface.mapCanvas()
area = layer.selectedFeatures()[0]['Area_km2']
if area > 400:
canvas_city.zoomScale(100000)
else:
canvas_city.zoomScale(50000)
canvas_city.refresh()
return results
def name(self):
return 'model'
def displayName(self):
return 'model'
def group(self):
return ''
def groupId(self):
return ''
def createInstance(self):
return Model()
I have also tried inserting the zoom scale values into a variable like this (with no success):
iface.actionZoomToSelected().trigger()
layer = iface.activeLayer()
area = layer.selectedFeatures()[0]['Area_km2']
canvas_city = iface.mapCanvas()
if area > 400:
scale = 10000
else:
scale = 50000
canvas_city.zoomScale(scale)
# refresh the canvas
canvas_city.refresh()
return results
def name(self):
return 'model'
def displayName(self):
return 'model'
def group(self):
return ''
def groupId(self):
return ''
def createInstance(self):
return Model()
Does anyone know if I did something wrong regarding the second part of the code lines, or is a QGIS issue?
processAlgorithm()
method is definitely not thread safe. Try re-implementing theflags()
method and returnQgsProcessingAlgorithm.FlagNoThreading
. Not really what it's intended for, but you could also try putting the zooming logic in the postProcessAlgorithm() method.