1

I'm writing a simple QgsProcessingAlgorithm and I need to set some labels (to display the azimuths of the sides of a polygon).
I can set the labeling expression alright (the expression is properly set and after the QgsProcessingAlgorithm has run, if I open the properties dialog and simply click OK, the correct labels will be shown) but can't get it to display automatically.
I've commented some lines that I thought could do the trick but don't seem to do anything actually.

def processAlgorithm(self, parameters, context, feedback):
    source = self.parameterAsSource(parameters, self.INPUT, context)

    outputs = {}
    results = {}

    #Polygons to Lines
    alg_params = {
        'INPUT': parameters['INPUT'],
        'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
    }
    outputs['PolygonsToLines'] = processing.run('native:polygonstolines', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

    #Explode Lines
    alg_params = {
        'INPUT': outputs['PolygonsToLines']['OUTPUT'],
        'OUTPUT': parameters['OUTPUT']
    }
    outputs['ExplodeLines'] = processing.run('native:explodelines', alg_params, context=context, feedback=feedback, is_child_algorithm=True)

    results['OUTPUT'] = outputs['ExplodeLines']['OUTPUT']

    layer = QgsProcessingUtils.mapLayerFromString(results['OUTPUT'], context)

    pls = QgsPalLayerSettings()
    pls.isExpression = True
    pls.fieldName = 'CONCAT(format_number(degrees(azimuth(start_point($geometry), end_point($geometry))) % 180, 2), \'°\')'
    #pls.enabled = True
    layer.setLabeling(QgsVectorLayerSimpleLabeling(pls))
    layer.setLabelsEnabled(True)
    #layer.commitChanges()
    #layer.triggerRepaint()

    return results

EDIT:
Although I'm primarily interested in solving the problem for the QgsProcessingAlgorithm, it is worth noting that after running the two algorithms manually, executing the following code (after selecting the Exploded layer) in the python console doesn't work either.

layer = qgis.utils.iface.activeLayer()

pls = QgsPalLayerSettings()
pls.isExpression = True
pls.fieldName = 'CONCAT(format_number(degrees(azimuth(start_point($geometry), end_point($geometry))) % 180, 2), \'°\')'
pls.enabled = True

layer.setLabelsEnabled(True)
layer.setLabeling(QgsVectorLayerSimpleLabeling(pls))
#layer.labeling()

#layer.commitChanges()
#layer.triggerRepaint()
  • I think it's because the layer is only loaded when the line return results is executed. Before this, the layer is not loaded and so applying any labelling or styling will not work. I have had similar issues with this and tried workarounds such as loading the layer manually with QgsProject.instance().addMapLayer(layer) before the return statement but unfortunately it doesn't help. – Joseph Oct 10 at 10:34
  • I've tried to do the styling from the python console but label still don't show, so there must be something else. – YeO Oct 10 at 10:40
  • How did you define layer in the console? – Joseph Oct 10 at 11:51
  • I ran the two algorithms manually so the 'exploded' layer is already loaded. I have layer = iface.activeLayer() (not sure of the exact syntax, I'm not in front of the computer) – YeO Oct 10 at 12:19
  • You console code works for me if you uncomment layer.triggerRepaint(). Which QGIS 3 version are you using? I tested this on 3.8.2. – Joseph Oct 10 at 12:52
0

Thanks to this answer, I've tried adding a placement value to the QgsPalLayerSettings and it works.
The commented lines aren't needed in the QgsAlgorithm.

pls = QgsPalLayerSettings()
pls.isExpression = True
pls.fieldName = 'CONCAT(format_number(degrees(azimuth(start_point($geometry), end_point($geometry))) % 180, 2), \'°\')'
pls.placement = QgsPalLayerSettings.Placement.Line

layer.setLabeling(QgsVectorLayerSimpleLabeling(pls))
layer.setLabelsEnabled(True)

Your Answer

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

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