Data defined label position for more than one scale in one layer

I have to say that what you are requesting is complicated a little bit because you want the labeling to be visible at small scale clearly as well as at large scale (best fit). So, the idea here is how to place the point that can be visible at different scales.

After several testing, I found that instead of creating several columns for each scale range and put coordinates for x and y at fixed points, you can create only one column for priority positions for each point for best location, as you can see below (I followed the locations in your file):

enter image description here

Then, you go to Layer propoerties -> Labels -> Placement -> Offset from point or Around point, both are OK, but I chose Offset from point.

  1. At Quadrant Select Data defined override -> Edit, and enter the following formula:

    enter image description here

    CASE 
    WHEN  $scale >= 200000 THEN  "priority"  
    WHEN  $scale < 200000 and $scale >= 75000 THEN  "priority"   
    WHEN  $scale < 75000 and $scale >=10000 THEN  5
    WHEN  $scale < 10000 THEN 2 
    END
    

    Here, "Priority" is the location of points defined in the field name Priority

  2. You need to use offset to shift the points for better visibility, and I used the following formula:

    CASE
    WHEN  $scale >= 200000 THEN '0.001,0'
    WHEN  $scale < 200000 and $scale >= 75000 THEN '0.001,0'
    WHEN  $scale < 75000 and $scale >=10000 THEN '0.0005,0'
    WHEN  $scale < 10000 THEN '0.0001,0'
    END
    

Here is the output at different scales:

enter image description here

enter image description here

enter image description here

enter image description here

In order to see what each number [0-8] represents in which location, please have a look at following image:

enter image description here

You can control the position of the labels by adding the value corresponding with each position. But unfortunately, you cannot do it by 'click-and-move' approach. You need to do it in the attribute table.

Update:

Based on your requirement that 9 quadrant positions are not enough, I found if you select Cartography instead of Offset from point, and select priority, as in the image below, you will have 12 priority positions instead of 9. You need to create a field of Text type, then put only the abbreviation that you want for the best position 'TL', 'TSL', 'T'...etc. Also, you can enter a distance to avoid the label from covering the point.

enter image description here


You can get rid of the multiple layers by using expressions.

From what I could see in your example the main difference between the layers is the Data defined Coordinate X Y definitions pointing to the different scale x,y values.

You can accomplish this in a single layer by selecting the dropdowns next to X and Y and selecting edit... which will bring up an expression string builder.

For X you can use something like

if(@map_scale <=10000, "scale1-x", if(@map_scale <=75000, "scale2-x", "scale3-x"))

And for Y you can use something like

if(@map_scale <=10000,  "scale1-y" , if(@map_scale <=75000, "scale2-y", "scale3-y"))

This should use scale1 x,y values if the map scale is less than or equal to 1:10,000 and scale 2 x,y if the map scale is less than or equal to 1:75,000 and scale 3 x,y for anything above that.

If you have to manually position for each scale I don't see how you can get away from scale#-x and scale#-y columns for each level you have defined.