[Qgis-user] PyQGIS to set masked symbol layer and mask source in ver. 3.30

Anne B. Nilsen anne.b.nilsen at nibio.no
Thu Apr 27 00:27:14 PDT 2023


Thanks!

Not sure if I do this the best way (I'm not a programmer nor a pyQGIS-expert)...
I ended up with adding two procedures and changing the code-line for setting the mask (****) accordingly:

def get_symbollayer(layer, ruleId, symbollayer_ids):
    """
    Returns the symbol layer according to given layer, ruleId (None if no rule) and the path
    to symbol layer id (for instance [0, 1])
    """
    renderer = layer.renderer()
    symbol = None
    if renderer.type() == "categorizedSymbol":
        i = renderer.categoryIndexForValue(ruleId)
        cat = renderer.categories()[i]
        symbol = cat.symbol()
    elif renderer.type() == "singleSymbol":
        symbol = renderer.symbol()

    symbollayer = symbol.symbolLayer(symbollayer_ids[0])
    for i in range(1, len(symbollayer_ids)):
        symbol = symbollayer.subSymbol()
        symbollayer = symbol.symbolLayer(symbollayer_ids[i])

    return symbollayer

def get_symbollayer_ref(layer, ruleId, symbollayer_ids):
       """
       Returns the symbol layer according to given layer, ruleId (None if no rule) and the path
       to symbol layer id (for instance [0, 1])
       """
       symbollayer = get_symbollayer(layer, ruleId, symbollayer_ids)
       return QgsSymbolLayerReference(layer.id(), symbollayer.id())
...
fileName = "./gpkg/karplantehoyder.gpkg"
layer = QgsVectorLayer(fileName, "hoyder", "ogr")
layer.loadNamedStyle('./qml/n5hoyder.qml')      # Load qml
QgsProject.instance().addMapLayer(layer, False) # Add layer False to be able
root.insertLayer(4,layer)                       # to specify a custom position
label_settings = layer.labeling().settings()    # Get current settings of the layer
text_format = label_settings.format()           # Get text format of the settings
text_format.mask().setMaskedSymbolLayers([get_symbollayer_ref(layer,"",[0])])  # set masked symbol layers ****
...

It woks, but is this the most convenient way to do it?

It seems to me like label masking information is not stored in the qml-file?
Is there a good reason for that?

Kind regards
Anne

-----Opprinnelig melding-----
Fra: Julien Cabieces <julien.cabieces at oslandia.com>
Sendt: onsdag 26. april 2023 18:02
Til: Anne B. Nilsen <anne.b.nilsen at nibio.no>
Kopi: qgis-user at lists.osgeo.org
Emne: Re: [Qgis-user] PyQGIS to set masked symbol layer and mask source in ver. 3.30


Hi,

I changed the way we referenced symbol layer to make it more simple and robust. Now, symbol layer have a generated unique id so it's easier to reference each of them (instead of a path of indices in the symbol layers tree before).

I see 2 solutions here:

1. You keep your old references and call
QgsProjectFileTransform.fixOldSymbolLayerReferences() on your layers

2. You change the way you create the references. here[0] is an example on how you can create QgsSymbolLayerReference.

I would favor solution 2 because you wouldn't rely on deprecated method and so you would be more future proof for when we eventually drop these methods.

Regards,
Julien

[0] https://github.com/qgis/QGIS/pull/50786/files#diff-c7f779c945b0e9c401ddb964691ec0d6a07c6c3fcfca0e3db146f97aec2d17e2R177

> Thanks to the answer to this post
> https://gis.stackexchange.com/questions/447362/pyqgis-to-set-masked-sy
> mbol-layer-and-mask-source
>
> I managed to set the mask layer in QGIS version 3.28.
>
>
>
> The code is not working In ver. 3.30 due to a change in the QgsSymbolLayerReference class.
>
> However I’m not able to change the original code so it fits with the
> new specification
>
>
>
> I just don’t understand how to set the input parameters to fulfil the
> requirements in
> https://qgis.org/pyqgis/3.30/core/QgsSymbolLayerReference.html#qgis.co
> re.QgsSymbolLayerReference
>
>
>
> # Set masked symbol layers :  setMaskedSymbolLayers(self,
> maskedLayers: Iterable[QgsSymbolLayerReference])
>
>
>
> fileName = "./gpkg/karplantehoyder.gpkg"
>
> layer = QgsVectorLayer(fileName, "hoyder", "ogr")
>
> layer.loadNamedStyle('./qml/n5hoyder.qml')      # Load qml
>
> QgsProject.instance().addMapLayer(layer, False) # Add layer False to
> be able
>
> root.insertLayer(4,layer)                       # to specify a custom position
>
> label_settings = layer.labeling().settings()    # Get current settings of the layer
>
> text_format = label_settings.format()           # Get text format of the settings
>
>
>
> # old code (working in 3.28)
>
> #
> text_format.mask().setMaskedSymbolLayers([QgsSymbolLayerReference(laye
> r.id(), QgsSymbolLayerId("", 0))])  # set masked symbol layers *****
>
>
>
> # -- New code
>
> linesymbol = QgsLineSymbol()
>
> lyr = linesymbol.symbolLayer(0)                 # Trying to get the id of the line layer (hoyder)
>
> text_format.mask().setMaskedSymbolLayers([layer.id(), lyr.id()])  #
> set masked symbol layers – not working
>
> # --
>
>
>
> label_settings.setFormat(text_format)           # set format
>
> layer.labeling().setSettings(label_settings)    # set settings
>
> layer.saveStyleToDatabase(layer.name(),'style n5hoyder',True,'')  #
> Save style in gpkg
>
>
>
> Anyone who knows how I should write the code marked with *****?
>
>
>
> Kind regards
>
> Anne
>
> _______________________________________________
> QGIS-User mailing list
> QGIS-User at lists.osgeo.org<mailto:QGIS-User at lists.osgeo.org>
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-user
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-user


--

Julien Cabieces
Senior Developer at Oslandia
julien.cabieces at oslandia.com<mailto:julien.cabieces at oslandia.com>
09.72.52.52.76

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-user/attachments/20230427/95411d8b/attachment.htm>


More information about the QGIS-User mailing list