In my project layers (QGIS 3.6.2) I use data-defined label placement. I am trying to set up the placement as follows:
- By default, the placement chosen in Label Settings is used (in my case, "around centroid").
- If the X and Y fields are populated (i.e., the label has been placed manually), these values are used.
- I have a boolean T/F field called "UsePOS" in my data; if it is checked (true), and if the X and Y fields are null, then the X/Y placement uses a calculated point (in my case, a point-on-surface). If it is false, the null X and Y fields are used (i.e., the default placement).
Here's what I tried: in Label Settings, I defined the X placement with the following expression…
if( "X" is not NULL,
"X",
if( "UsePOS",
x( point_on_surface( $geometry ) ),
"X"
)
)
…and the Y field with a like expression. This worked perfectly as expected—by default the label is placed at the centroid; if the box is checked, it jumps to the point-on-surface, and if there is data in the X/Y fields, then the label is pinned there.
However, the problem arises when I try to manually place a label. In that case, because the X/Y placement isn't directly defined by the X/Y fields, QGIS invokes auxiliary storage, which is not what I am using for label placement, and which apparently cannot be suppressed (see my comment in this thread).
So I assume that 1) I need to directly assign label placement to my X/Y fields, 2) I need to use an expression in Field Calculator to populate those fields, and 3) those fields need to be virtual so that they respond dynamically to whether I manually move the label, whether the checkbox is checked, etc. However, entering the above expression in Field Calculator causes QGIS to crash when the label is moved manually, or when I check the checkbox (which I expected, since I don't think a virtual field can reference itself).
The question is, what is the proper way to set up what I want, so that I can still manually move labels, using only data-defined labeling and not auxiliary storage?