Monday 6 February 2017

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


I'm looking for a better labeling-solution for my projects. It seems to be difficult - but maybe I'm just blind?


My projects: I build printed bike-hike-books. The main scale is 1:75k and there are a city scale of 10k and a overview scale of 200k. Because I like to have a "cartographic" quality of labels placements, I touch every single label and move it to it's best position. I have to do this for every single scale so my labeling columns for 3 scales look like this ('scale 1' stands for 10k 'scale 2' for 75k and 'scale 3' for 200k):


enter image description here


But before I try to explain in detail, I build this simple Example-Project where you can see and test my (old) labeling solution for 3 scales: http://www.map-site.de/tmp/LabelingExample.zip


Well, it is working but:




  • You need labeling columns for every scale

  • You need a layer for every scale


I'm looking for a much better solution without duplicate layers and tons of columns. I count on your creative minds!


EDIT: I added this two very dense map as examples:


enter image description here


There is only one single possible position for "St. Paulus Dom" and it's not any quadrant: enter image description here


Every label has to be moved manually. Some of the labels are not in a quadrant.



Answer




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


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...