Open Forna73 opened 2 years ago
@Forna73 have you
"Select this mask shape as a mask source in the overlapping layer properties labelmask Mask tab (see Masks Properties)."
as explained here?
When you do that:
I selcted them. I have only 1 layer, so it's the layer label that should mask its line, not an element of another layer.
I've just noticed that the check box doesn't remain selected. If I exit the layer properties panel and then I reopen it, the check boxes aren't selected. I tried "apply" maintaining the panel opened but nothing happens.
as you can see:
as you can see:
@Forna73 attach a sample project+data, the issue may be data/expression dependent.
it's done all from scratch. you can simply create a line layer and a label.....
it's done all from scratch. you can simply create a line layer and a label.....
@Forna73 in your screenshot you are using rule based labeling with an expression. With the most simple case ("you can simply create a line layer and a label") it works.
Ok.... You are right... simplest way works, I continued applying my rule; but this mean I can't use rule based labelling... is that expected to be right?
is that expected to be right?
@Forna73 please attach a minimal sample project with data that shows the behavior you describe.
Hi! In the meanwhile I was saving the file to attach I did some more tests and I discovered that only with "Rule based label" the mask doesn't work. With "single label", even with expression, it works. So the problem is apparently only with "rule based label".
So the problem is apparently only with "rule based label".
@Forna73 still works fine here. You really should attach a sample project with data that shows the issue.
@Forna73 nevermind, as soon as two mask sources are enabled masking stops to work. Thanks for the report.
The problem seems to be that when there are more than 1 masking sources then the selection for the sources and "masked symbol layer" do not stick in the layer properties, it seems that on ok/apply the selections are removed.
I do confirm!
Any progress on this bug? I am experiencing it with v 3.28.8-Firenze. I am new to GIS and QGIS, but I can attach my minimal qgz file and layer file if you tell me what is the expected layer file format.
The issue can be replicated with the snippet below. Up to QGIS 3.28.15, the masks works with a rule based labeling but it disappears if I open the layer properties window and click "OK". It doesn't matter if I change a setting or not, simply clicking "OK" does the job. However, clicking "Cancel" does not cause the mask to disappear. It must be noted that trying to set the same label parameters manually via the GUI does not allow to successfully apply the mask.
Starting at QGIS 3.30.0, my snippet breaks because of a change to the QgsSymbolLayerReference class. I haven't been able to figure out how to reference the symbol id in the new QgsSymbolLayerReference class...
# Make two simple lines
elev_fieldname = "ELEV"
layer = QgsVectorLayer(f"linestring?crs=epsg:32198&field={elev_fieldname}:integer", "contours", "memory")
for wkt, elev in [('LineString (0 400000, 100 400000)', 5), ('LineString (0 400010, 100 400010)', 10)]:
geom = QgsGeometry.fromWkt(wkt)
fet = QgsFeature(layer.fields())
fet.setGeometry(geom)
fet[elev_fieldname] = elev
layer.dataProvider().addFeature(fet)
QgsProject.instance().addMapLayer(layer)
# Labeling
# Only the label of the upper line, with an elevation of 10, should be displayed
label_settings = QgsPalLayerSettings()
label_settings.placement = QgsPalLayerSettings.Line
label_settings.placementFlags = QgsPalLayerSettings.OnLine
label_settings.fieldName = elev_fieldname
mask = QgsTextMaskSettings()
mask.setEnabled(True)
mask.setSize(2)
mask.setMaskedSymbolLayers( [QgsSymbolLayerReference(layer.id(), QgsSymbolLayerId("", 0))] ) # Breaks starting at QGIS 3.30
text_format = label_settings.format()
text_format.setMask(mask)
label_settings.setFormat(text_format)
root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
rule = QgsRuleBasedLabeling.Rule(label_settings)
rule.setDescription("Only 10s")
rule.setFilterExpression(f"\"{elev_fieldname}\" % 10 = 0")
rule.setActive(True)
root.appendChild(rule)
rules_settings = QgsRuleBasedLabeling(root)
layer.setLabelsEnabled(True)
layer.setLabeling(rules_settings)
layer.labeling().setSettings(label_settings)
layer.triggerRepaint()
The problem still exists in the settings dialog in version 3.34.6 and 3.34.10. Also, it still is possible to turn on masking in the layer style dock.
I'm trying to understand what exactly QgsSymbolLayerReference
expects as a second argument now (since 3.30) in place of a QgsSymbolLayerId
. The documentation says to use a QUuid
string, but I can't find how to construct that string. I thought that there was a way to extract a uuid from a QgsSymbolLayerId
object but that doesn't seem possible (and the QgsSymbolLayerId
class is deprecated since 3.30). I'm at a loss...
@troopa81 Could you help on this matter as you seems to have edited the related lines of code related to these classes? Thanks.
Just discovering this issue
The problem seems to be that when there are more than 1 masking sources then the selection for the sources and "masked symbol layer" do not stick in the layer properties, it seems that on ok/apply the selections are removed.
You mean like this (2 mask sources, 1 masked symbol layer) ?
And it does work (in master but pretty sure it works with recent one)
It would be very better if someone could share a project so I can reproduce the issue
I'm trying to understand what exactly QgsSymbolLayerReference expects as a second argument now (since 3.30) in place of a QgsSymbolLayerId
The unique symbol layer id. Like for instance
>>> iface.activeLayer().renderer()
<qgis._core.QgsSingleSymbolRenderer object at 0x7f7b5034c3a0>
>>> iface.activeLayer().renderer().symbol().symbolLayers()
[<qgis._core.QgsSimpleLineSymbolLayer object at 0x7f7b5044a290>, <qgis._core.QgsSimpleLineSymbolLayer object at 0x7f7b50331120>]
>>> iface.activeLayer().renderer().symbol().symbolLayers()[0].id()
'{6220c894-fcba-4f9f-86cf-d8884f4c49a5}'
The last one is the expected id. Before my modifications, it was the order of the symbol layer regarding its parent symbol and it was a mess (like for instance when you were changing the order). So now we have a generated unique id.
Thanks!
My snippet below now works for >= 3.30. It displays two parallel lines with a label only on the upper one with a mask applied. The mask work, but like I said in my first comment, it stops working if the layer properties window is opened and then closed by clicking "OK", even without changing any setting.
Before opening the layer properties window
After opening and closing the layer properties window
# Make two simple lines
elev_fieldname = "ELEV"
layer = QgsVectorLayer(f"linestring?crs=epsg:32198&field={elev_fieldname}:integer", "contours", "memory")
for wkt, elev in [('LineString (0 400000, 100 400000)', 5), ('LineString (0 400010, 100 400010)', 10)]:
geom = QgsGeometry.fromWkt(wkt)
fet = QgsFeature(layer.fields())
fet.setGeometry(geom)
fet[elev_fieldname] = elev
layer.dataProvider().addFeature(fet)
QgsProject.instance().addMapLayer(layer)
# Labeling
# Only the label of the upper line, with an elevation of 10, should be displayed
label_settings = QgsPalLayerSettings()
label_settings.placement = QgsPalLayerSettings.Line
label_settings.placementFlags = QgsPalLayerSettings.OnLine
label_settings.fieldName = elev_fieldname
mask = QgsTextMaskSettings()
mask.setEnabled(True)
mask.setSize(2)
mask.setMaskedSymbolLayers([
QgsSymbolLayerReference(
layer.id(),
layer.renderer().symbol().symbolLayers()[0].id()
)
])
text_format = label_settings.format()
text_format.setMask(mask)
label_settings.setFormat(text_format)
root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
rule = QgsRuleBasedLabeling.Rule(label_settings)
rule.setDescription("Only 10s")
rule.setFilterExpression(f"\"{elev_fieldname}\" % 10 = 0")
rule.setActive(True)
root.appendChild(rule)
rules_settings = QgsRuleBasedLabeling(root)
layer.setLabelsEnabled(True)
layer.setLabeling(rules_settings)
layer.labeling().setSettings(label_settings)
layer.triggerRepaint()
@jfbourdon OK, thanks! I I manage to reproduce the issue.
I'll fix the issue for next bugfix round (in january 2025) except if someone is willing to fund the fix
What is the bug or the crash?
Simple... I've any masking for labels even enabling the mask in label and selecting the masking options in layer properties
Steps to reproduce the issue
Versions
Versione di QGIS 3.16.6-Hannover Revisione codice QGIS bfd36fddc9 Compilato con Qt 5.11.2 Esecuzione con Qt 5.11.2 Compilato con GDAL/OGR 3.1.4 Esecuzione con GDAL/OGR 3.1.4 Compilato con GEOS 3.8.1-CAPI-1.13.3 Esecuzione con GEOS 3.8.1-CAPI-1.13.3 Compilato su SQLite 3.29.0 In esecuzione su SQLite 3.29.0 Versione client PostgreSQL 11.5 Versione SpatiaLite 4.3.0 Versione QWT 6.1.3 Versione QScintilla2 2.10.8 Compilato con PROJ 6.3.2 Esecuzione con PROJ Rel. 6.3.2, May 1st, 2020 Versione SO Windows 10 (10.0) Attiva python plugin AzimuthDistanceCalculator; batch_hillshader-master; clipper; coordinates_converter; DigitizingTools; latlontools; map-coords-plugin; points2one; profiletool; Qgis2threejs; zoom_level; db_manager; MetaSearch; processing
Supported QGIS version
New profile
Additional context
No response